2011-12-19 33 views
1

私は多くのプロジェクトで繰り返し実行しているルーチンを一般化したいと思います。私はiTextをPDF操作に使用しました。テンプレートパターンを使用した一般的なプロセスの設計

私はフォルダ内に2000個のPDFを持っており、これらを一緒に圧縮する必要があるとしましょう。制限は1つのファイルにつき1000個のPDFです。したがって、ジップの名前はこの規則に従います:job name + job sequence。たとえば、最初の1000個のPDFのジップ名はXNKXMN + AA、2番目のジップ名はXNKXMN + ABとなります。これらのPDFを圧縮する前に、各PDFにテキストを追加する必要があります。テキストは次のようになりますjob name + job sequence + pdf sequenceだから、最初ジップ内側の最初のPDFには、このテキストXNKXMN + AA + 000001を持つことになり、その後1はXNKXMN + AA + 000002です。ここに私の試みです

私は抽象クラスGenericTextが私のテキストを表しています。

public abstract class GenericText { 

    private float x; 

    private float y; 

    private float rotation; 

    /** 
    * Since the text that the user want to insert onto the Pdf might vary 
    * from page to page, or from logical document to logical document, we allow 
    * the user to write their own implementation of the text. To give the user enough 
    * flexibility, we give them the reference to the physical page index, the logical page index. 
    * @param physcialPage The actual page number that the user current looking at 
    * @param logicalPage A Pdf might contain multiples sub-documents, <code>logicalPage</code> 
    * tell the user which logical sub-document the system currently looking at 
    */ 
    public abstract String generateText(int physicalPage, int logicalPage); 

    GenericText(float x, float y, float rotation){ 
      this.x = x; 
      ... 
    } 

} 

JobGenerator.java:私は私のメインクラスでだから今

public String generatePrintJob(List<File> pdfList, String outputPath, 
     String printName, String seq, List<GenericText> textList, int maxSize) 
for (int currentPdfDocument = 0; currentPdfDocument < pdfList.size(); currentPdfDocument++) { 
    File pdf = pdfList.get(currentPdfDocument); 
    if (currentPdfDocument % maxSize != 0) { 
     if(textList != null && !textList.isEmpty()){ 
      for(GenericText gt : textList){ 
       String text = gt.generateText(currentPdfDocument, currentPdfDocument) 
       //Add the text content to the PDF using PdfReader and PdfWriter 
      } 
     } 
     ... 
    }else{ 
      //Close the current output stream and zip output stream 
      seq = Utils.getNextSeq(seq); 
      jobPath = outputPath + File.separator + printName + File.separator + seq + ".zip" 
      //Open new zip output stream with the new <code>jobPath</code> 
    } 
} 
} 

上述私はちょうど私が持っています。この

final String printName = printNameLookup.get(baseOutputName); 
String jobSeq = config.getPrintJobSeq(); 
final String seq = jobSeq; 
GenericText keyline = new GenericText(90, 640, 0){ 
    @Override 
    public String generateText(int physicalPage, int logicalPage) { 
     //if logicalPage = 1, Utils.right(String.valueOf(logicalPage), 6, '0') -> 000001 
     return printName + seq + " " + Utils.right(String.valueOf(logicalPage), 6, '0'); 
    } 
}; 
textList.add(keyline); 
JobGenerator pjg = new JobGenerator(); 
pjg.generatePrintJob(...,..., printName, jobSeq, textList, 1000); 

問題を行うだろう、私の一般的なAPIを行うにはこの設計では、PDFを2つのジップに正しくアーカイブする処理を行っても、テキストが正しく反映されていないということです。印刷およびシーケンスは、それが最初の1000のためのPDFの代わりに、XNKXMN + + AA滞在し、後で1000のためXNKXMN + ABに変更、それに応じて変更されません私の設計に不備があるようです、助けてください

EDIT

toto2コードを見た後、私は私の問題を参照してください。私はGenericTextを作成して、プロセスの基本ロジックに影響を与えずにpdfページのどこにでもテキストを追加できるようにします。しかし、ジョブシーケンスはロジックに依存して定義されています。処理するPDFが多すぎるとインクリメントする必要があります(>maxSize)。私はこれを再考する必要があります。

+1

私は少し混乱しています。上記のコードはリストに単一の 'GenericText'を追加していますが、これ以上のものはありますか? 'generatePrintJob'メソッドはPDFをループし、その中で全てのGenericTextをループします。たとえ複数のGenericTextがあったとしても、それらがすべて同じ場所に印刷されていれば、混乱を招くようです。 1つの 'GenericText'を1つのPDFに関連づけたいのであれば、それだけじゃないの? –

+1

あなたはファイル0,1000などを処理していません。それらは 'else'で分岐し、' if'でファイルを処理します。 – toto2

+0

@DaveNewton:PDFにテキストを追加する柔軟な方法であるGenericTextの私の計画。ご覧のとおり、テキストの回転だけでなく、(x、y)座標も含まれています。抽象メソッド 'generateText(int physicalPage、int logicalPage)'は、シーケンス番号を生成するのに役立ちます。たとえば、ページ1を見ると、シーケンス番号は '000001'またはその他の形式なので、そこに抽象メソッドがあるのですしたがって、ユーザは、シーケンス番号をどのように見せたいか、独自の実装を記述することができます。私はデザインに欠陥があることを知っている。私はそれを正しくしようとしています。 –

答えて

4

GenerateTextを匿名で作成すると、オーバーライドされたgenerateTextメソッドで使用するfinal seqは本当に最終的なものであり、作成時に与えられた値のままです。​​にelseの中にseqを入れた更新は何もしません。

もっと一般的には、コードは非常に複雑に見えます。おそらく一歩前に戻って、大きなリファクタリングを行うべきです。

EDIT

私の代わりにノーテンプレートメソッドパターンで、異なる何かをしようとするだろう:

int numberOfZipFiles = 
     (int) Math.ceil((double) pdfList.size()/maxSize); 

for (int iZip = 0; iZip < numberOfZipFiles; iZip++) { 
    String batchSubName = generateBatchSubName(iZip); // gives AA, AB,... 

    for (int iFile = 0; iFile < maxSize; iFile++) { 
    int fileNumber = iZip * maxSize + iFile; 
    if (fileNumber >= pdfList.size()) // can happen for last batch 
     return; 
    String text = jobName + batchSubName + iFile; 
    ... add "text" to pdfList.get(fileNumber) 
    } 
} 

はしかし、あなたはまた、テンプレートパターンを維持したい場合があります。その場合、Iは、forループIは上記書い続けるだろうが、私はiZip = 0 AAを与え、iZip = 1などABを与えるgenericText.generateText(iZip, iFile)に生成方法を変更します

for (int iZip = 0; iZip < numberOfZipFiles; iZip++) { 
    for (int iFile = 0; iFile < maxSize; iFile++) { 
    int fileNumber = iZip * maxSize + iFile; 
    if (fileNumber >= pdfList.size()) // can happen for last batch 
     return; 
    String text = genericText.generateText(iZip, iFile); 
    ... add "text" to pdfList.get(fileNumber) 
    } 
} 

それが可能ですまた、genericText.generateText(fileNumber)を持っていて、それ自体AA000001などのファイル番号を分解することができます。しかし、maxSizeは2つの異なる場所で使用され、そのような重複データを持つ可能性があるため、やや危険です。

+0

ありがとう、私はあなたが 'seq'について言ったことを理解しています、' seq'は実際に 'String' jobSeqの' final'バージョンです。私はコードにそのことを忘れていました。どのようにこのより良いデザインを持っている上の任意のポインタ?私はデザインに欠陥があることを知っている、私はこの権利を得ることを学んでいる。もう一度ありがとう –

+0

@ハリーいくつかの提案を私の編集を参照してください。 – toto2

+0

あなたのコードを見て、私は私の問題を参照してください。プロセスの基本的なロジックに影響を与えずに、pdfページのどこにでもテキストを追加できるように、 'GenericText'を作成します。しかし、「ジョブシーケンス」は論理的には定義されていますが、1つのZIPで扱えるPDFが多すぎるために増やす必要があるためです。私はこれを再考する必要があります。 –

関連する問題