KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > etymon > pjx > util > PdfModifier


1 package com.etymon.pjx.util;
2
3 import java.io.*;
4 import java.util.*;
5 import com.etymon.pj.*;
6 import com.etymon.pj.exception.*;
7 import com.etymon.pj.object.*;
8 import com.etymon.pj.object.pagemark.*;
9 import com.etymon.pjx.*;
10
11 /**
12    Provides methods for retrieving and modifying various elements of a
13    PDF document.
14    @author Nassib Nassar
15    @deprecated
16 */

17 public class PdfModifier {
18
19     /**
20        Returns the number of pages in the document.
21        @return the number of pages.
22        @throws IOException
23        @throws PdfFormatException
24        @deprecated Use {@link PdfPageTree#getNumberOfPages()
25        PdfPageTree.getNumberOfPages()}.
26      */

27     public int getPageCount() throws IOException, com.etymon.pjx.PdfFormatException {
28         return new PdfPageTree(_m).getNumberOfPages();
29     }
30
31     /**
32            A <code>PdfName</code> object representing the name
33            <code>AcroForm</code>.
34     */

35     protected static final PdfName PDFNAME_ACROFORM = new PdfName("AcroForm");
36
37     /**
38            A <code>PdfName</code> object representing the name
39            <code>Fields</code>.
40     */

41     protected static final PdfName PDFNAME_FIELDS = new PdfName("Fields");
42
43     /**
44            A <code>PdfName</code> object representing the name
45            <code>Kids</code>.
46     */

47     protected static final PdfName PDFNAME_KIDS = new PdfName("Kids");
48
49     /**
50            A <code>PdfName</code> object representing the name
51            <code>Pages</code>.
52     */

53     protected static final PdfName PDFNAME_PAGES = new PdfName("Pages");
54
55     /**
56            A <code>PdfName</code> object representing the name
57            <code>Root</code>.
58     */

59     protected static final PdfName PDFNAME_ROOT = new PdfName("Root");
60
61     /**
62        The manager associated with this document.
63     */

64     protected PdfManager _m;
65
66     /**
67        Constructs a <code>PdfModifier</code> instance based on a
68        specified <code>PdfManager</code>.
69      */

70     public PdfModifier(PdfManager manager) {
71
72         _m = manager;
73         
74     }
75
76     /**
77        Retrieves an indirect reference to the document's catalog.
78        @return the indirect reference.
79        @throws PdfFormatException
80        @deprecated Use {@link PdfCatalog#getCatalog() PdfCatalog.getCatalog()}.
81      */

82     public PdfReference getCatalogReference() throws com.etymon.pjx.PdfFormatException {
83         synchronized (this) {
84
85             PdfDictionary trailer = _m.getTrailerDictionary();
86             
87             Map map = trailer.getMap();
88             
89             Object JavaDoc root = map.get(PdfModifier.PDFNAME_ROOT);
90             
91             if ( !(root instanceof PdfReference) ) {
92                 throw new com.etymon.pjx.PdfFormatException("Catalog dictionary is not an indirect reference.");
93             }
94             
95             return (PdfReference)root;
96         }
97     }
98     
99     /**
100        Retrieves the document's catalog.
101        @return the catalog object.
102        @throws IOException
103        @throws PdfFormatException
104        @deprecated Use {@link PdfCatalog#getCatalog() PdfCatalog.getCatalog()}.
105      */

106     public PdfDictionary getCatalog() throws IOException, com.etymon.pjx.PdfFormatException {
107         synchronized (this) {
108
109             PdfReference catalogRef = getCatalogReference();
110
111             if (catalogRef == null) {
112                 return null;
113             }
114             
115             Object JavaDoc catalog = _m.getObjectIndirect(catalogRef);
116
117             if ( !(catalog instanceof PdfDictionary) ) {
118                 throw new com.etymon.pjx.PdfFormatException("Catalog is not a dictionary.");
119             }
120
121             return (PdfDictionary)catalog;
122         }
123     }
124
125     /**
126        Sets the document's catalog to a specified value.
127        @param catalog the new catalog.
128        @throws PdfFormatException
129        @deprecated Use {@link PdfManager#setObject(PdfObject, int)
130        PdfManager.setObject(PdfObject, int)}.
131      */

132     public void setCatalog(PdfDictionary catalog) throws com.etymon.pjx.PdfFormatException {
133         synchronized (this) {
134         
135             PdfReference catalogRef = getCatalogReference();
136
137             if (catalogRef != null) {
138                 
139                 _m.setObject(catalog, catalogRef.getObjectNumber());
140                          
141             } else {
142
143                 // add catalog as a new indirect object
144
int catalogId = _m.addObject(catalog);
145
146                 // add reference to catalog in file
147
// trailer dictionary
148

149                 PdfDictionary trailer = _m.getTrailerDictionary();
150             
151                 Map map = trailer.getMap();
152
153                 HashMap h = new HashMap(map.size());
154                 h.putAll(map);
155
156                 h.put(PdfModifier.PDFNAME_ROOT,
157                      new PdfReference(catalogId, 0) );
158
159                 _m.setTrailerDictionary(new PdfDictionary(h));
160             }
161
162         }
163     }
164
165     /**
166        Retrieves an indirect reference to the root node of the
167        document's page tree.
168        @return the indirect reference.
169        @throws IOException
170        @throws PdfFormatException
171        @deprecated Use {@link PdfPageTree#getRoot()
172        PdfPageTree.getRoot()}.
173      */

174     public PdfReference getPageTreeRootReference() throws IOException, com.etymon.pjx.PdfFormatException {
175         synchronized (this) {
176
177             PdfDictionary catalog = getCatalog();
178
179             Map map = catalog.getMap();
180             
181             Object JavaDoc pages = map.get(PdfModifier.PDFNAME_PAGES);
182             
183             if ( !(pages instanceof PdfReference) ) {
184                 throw new com.etymon.pjx.PdfFormatException("Page tree root (Pages) is not an indirect reference.");
185             }
186             
187             return (PdfReference)pages;
188         }
189     }
190
191     /**
192        Retrieves the root node of the document's page tree.
193        @return the root node object.
194        @throws IOException
195        @throws PdfFormatException
196        @deprecated Use {@link PdfPageTree#getRoot() PdfPageTree.getRoot()}.
197      */

198     public PdfDictionary getPageTreeRoot() throws IOException, com.etymon.pjx.PdfFormatException {
199         synchronized (this) {
200
201             PdfReference pageTreeRootRef = getPageTreeRootReference();
202
203             if (pageTreeRootRef == null) {
204                 return null;
205             }
206             
207             Object JavaDoc pageTreeRoot = _m.getObjectIndirect(pageTreeRootRef);
208
209             if ( !(pageTreeRoot instanceof PdfDictionary) ) {
210                 throw new com.etymon.pjx.PdfFormatException("Page tree root is not a dictionary.");
211             }
212
213             return (PdfDictionary)pageTreeRoot;
214         }
215     }
216
217     /**
218        Sets the root node of the document's page tree to a
219        specified value.
220        @param pageTreeNode the new root node.
221        @throws IOException
222        @throws PdfFormatException
223        @deprecated Use {@link PdfManager#setObject(PdfObject, int)
224        PdfManager.setObject(PdfObject, int)}.
225      */

226     public void setPageTreeRoot(PdfDictionary pageTreeRoot) throws IOException, com.etymon.pjx.PdfFormatException {
227         synchronized (this) {
228         
229             PdfReference pageTreeRootRef = getPageTreeRootReference();
230
231             if (pageTreeRootRef != null) {
232                 
233                 _m.setObject(pageTreeRoot, pageTreeRootRef.getObjectNumber());
234                          
235             } else {
236
237                 // add page tree root as a new indirect object
238
int pageTreeRootId = _m.addObject(pageTreeRoot);
239
240                 // add reference to page tree root in catalog
241

242                 PdfDictionary catalog = getCatalog();
243             
244                 Map map = catalog.getMap();
245
246                 HashMap h = new HashMap(map.size());
247                 h.putAll(map);
248
249                 h.put(PdfModifier.PDFNAME_PAGES,
250                      new PdfReference(pageTreeRootId, 0) );
251
252                 setCatalog(new PdfDictionary(h));
253             }
254
255         }
256     }
257
258     /**
259        @deprecated
260      */

261     private void getFieldsAddField(ArrayList fieldList, PdfReference fieldRef)
262         throws IOException, com.etymon.pjx.PdfFormatException {
263
264         // resolve field reference
265
PdfDictionary field;
266         try {
267             field = (PdfDictionary)(_m.getObjectIndirect(fieldRef));
268         }
269         catch (ClassCastException JavaDoc e) {
270             throw new com.etymon.pjx.PdfFormatException("Field object is not a dictionary.");
271         }
272
273         Map fieldHt = field.getMap();
274
275         // add the field to the list
276
fieldList.add(field);
277         
278         // check if there are any kids
279
PdfArray kids;
280         try {
281             kids = (PdfArray)(_m.getObjectIndirect((PdfObject)(fieldHt.get(PDFNAME_KIDS))));
282         }
283         catch (ClassCastException JavaDoc e) {
284             throw new com.etymon.pjx.PdfFormatException("Kids object is not an array.");
285         }
286         
287         // if there are kids, descend the tree
288
if (kids != null) {
289             List kidsV = kids.getList();
290             int kidsV_n = kidsV.size();
291             for (int x = 0; x < kidsV_n; x++) {
292
293                 // get the field object
294
PdfReference fieldRef2;
295                 try {
296                     fieldRef2 = (PdfReference)(kidsV.get(x));
297                 }
298                 catch (ClassCastException JavaDoc e) {
299                     throw new com.etymon.pjx.PdfFormatException("Kids array element is not a reference.");
300                 }
301                 
302                 getFieldsAddField(fieldList, fieldRef2);
303
304             }
305         }
306         
307     }
308
309     /**
310        This method is provided for compatibility with PJ. It will
311        be transitioned toward a dedicated field class.
312        @throws PdfFormatException
313        @deprecated
314      */

315     public PdfDictionary pjUpdateFieldValue(PdfDictionary origField, PdfDictionary field, String JavaDoc value)
316         throws IOException, com.etymon.pjx.PdfFormatException {
317
318         synchronized (this) {
319
320             try {
321
322                 Map origFieldHt = new HashMap(origField.getMap());
323                 
324                 Map fieldHt = field.getMap();
325                 
326                 // store old value for use in search/replace within appeareances stream(s)
327
PdfString oldValue = (PdfString)(fieldHt.get(new PdfName("V")));
328                 
329                 PdfString valueString = new PdfString(value);
330                 origFieldHt.put(new PdfName("V"), valueString);
331                 origFieldHt.put(new PdfName("DV"), valueString);
332                 
333                 // determine quadding
334
PdfInteger q = (PdfInteger)(_m.getObjectIndirect((PdfObject)(fieldHt.get(new PdfName("Q")))));
335                 boolean leftJustified = false;
336                 boolean centered = false;
337                 boolean rightJustified = false;
338                 if (q == null) {
339                     leftJustified = true;
340                 } else {
341                     switch (q.getInt()) {
342                     case 1:
343                         centered = true;
344                         break;
345                     case 2:
346                         rightJustified = true;
347                         break;
348                     default:
349                         leftJustified = true;
350                     }
351                 }
352                 
353                 PdfDictionary ap =
354                     (PdfDictionary)(_m.getObjectIndirect((PdfObject)(fieldHt.get(new PdfName("AP")))));
355                 Map apHt;
356                 if (ap == null) {
357                     apHt = null;
358                 } else {
359                     apHt = new HashMap(ap.getMap());
360                     PdfObject apnObj = (PdfObject)(apHt.get(new PdfName("N")));
361                     int apnId;
362                     PdfReference apnRef;
363                     PdfObject apn;
364                     PdfDictionary apnDict;
365                     byte[] apnBuffer;
366                     if (apnObj instanceof PdfReference) {
367                         // it's an indirect object
368
apnRef = (PdfReference)apnObj;
369                         apnId = apnRef.getObjectNumber();
370                         apn = _m.getObjectIndirect(apnRef);
371                     } else {
372                         // if it's not an indirect object, let's make it indirect
373
apnId = _m.addObject(apnObj);
374                         apnRef = new PdfReference(apnId, 0);
375                         apHt.put(new PdfName("N"), apnRef);
376                         apn = apnObj;
377                     }
378                     
379                     // "/C" = center text
380
// this assumes Courier 10 pt; we can add support
381
// for others if needed.
382
// it also assumes a page width of 8.5"; this also could
383
// be adjusted or read from the document.
384

385                     float rectX1 = 0;
386                     float rectX2 = 0;
387                     float rectWidth = 0;
388                     if (centered) {
389                         // adjust RECT
390
PdfArray rect =
391                             (PdfArray)(fieldHt.get(new PdfName("Rect")));
392                         List rectList = rect.getList();
393                         rectX1 = ((PdfNumber)rectList.get(0)).getFloat();
394                         rectX2 = ((PdfNumber)rectList.get(2)).getFloat();
395                         rectWidth = rectX2 - rectX1;
396                     }
397                     
398                     if ( (apn != null) && (apn instanceof PdfStream) ) {
399                         // if centered: remove any text matrix adjustments.
400
// get page mark operators
401
PjStream apnPj = (PjStream)PjxConvert.toPjObject(apn);
402                         Vector pmVector = new StreamParser().parse(
403                             apnPj.flateDecompress());
404                         if (oldValue != null) {
405                             replaceTextData(pmVector, oldValue, valueString);
406                         }
407                         if (centered) {
408                             adjustTextMatrixX(pmVector, rectWidth);
409                         }
410                         // reconstruct stream from modified pmVector
411
ByteArrayOutputStream baos =
412                             new ByteArrayOutputStream();
413                         for (int pmX = 0; pmX < pmVector.size(); pmX++) {
414                             PageMark pm = (PageMark)(pmVector.elementAt(pmX));
415                             try {
416                                 pm.writePdf(baos);
417                             }
418                             catch (IOException e) {
419                                 e.printStackTrace();
420                             }
421                         }
422                         byte[] ba = baos.toByteArray();
423                         PjStream temp = new PjStream( apnPj.getStreamDictionary(), ba );
424                         _m.setObject(PjxConvert.toPjxObject(temp), apnId);
425                     }
426                 }
427
428                 if (apHt != null) {
429                     origFieldHt.put(new PdfName("AP"), new PdfDictionary(apHt));
430                 }
431                 
432                 return new PdfDictionary(origFieldHt);
433                 
434             }
435             catch (com.etymon.pj.exception.PdfFormatException e) {
436                 throw new com.etymon.pjx.PdfFormatException(e.getMessage());
437             }
438             catch (com.etymon.pj.exception.InvalidPdfObjectException f) {
439                 throw new com.etymon.pjx.PdfFormatException(f.getMessage());
440             }
441         }
442     }
443
444     // used exclusively by updateFieldValue()
445
/**
446        @deprecated
447      */

448     private static void replaceTextData(Vector pmVector, PdfString oldText, PdfString newText)
449         throws com.etymon.pj.exception.PdfFormatException {
450         
451         // this method replaces text data oldS with newS
452

453         int pmX = pmVector.size();
454
455         PjString oldTextPj = (PjString)PjxConvert.toPjObject(oldText);
456         PjString newTextPj = (PjString)PjxConvert.toPjObject(newText);
457
458         // no particular reason for searching backwards; just
459
// because this was adapted from clearTextMatrixX()
460
while (pmX > 0) {
461             
462             pmX--;
463             PageMark pm = (PageMark)(pmVector.elementAt(pmX));
464             
465             if (pm instanceof XTj) {
466                 XTj tj = (XTj)pm;
467                 if (tj.getText().equals(oldTextPj)) {
468                     XTj newTj = new XTj(newTextPj);
469                     pmVector.setElementAt(newTj, pmX);
470                 }
471             }
472             
473         }
474     }
475     
476     // used exclusively by updateFieldValue()
477
/**
478        @deprecated
479      */

480     private static void adjustTextMatrixX(Vector pmVector, float rectWidth) {
481         // this method examines the last text matrix in
482
// pmVector and sets the X matrix value in order to
483
// center the text written by the subsequent Tj
484
// operator.
485

486         int pmX = pmVector.size();
487         float textWidth = 0;
488         float rectCenter = rectWidth / 2;
489         
490         while (pmX > 0) {
491             
492             pmX--;
493             PageMark pm = (PageMark)(pmVector.elementAt(pmX));
494             
495             if (pm instanceof XTj) {
496                 XTj tj = (XTj)pm;
497                 textWidth = tj.getText().getString().length() * 6;
498             }
499             
500             if (pm instanceof XTm) {
501                 float newX = rectCenter - (textWidth / 2);
502                 if (newX < 0) {
503                     newX = 0;
504                 }
505                 XTm tm = (XTm)pm;
506                 XTm newTm = new XTm(
507                     tm.getA(),
508                     tm.getB(),
509                     tm.getC(),
510                     tm.getD(),
511                     new PjNumber(newX),
512                     tm.getY());
513                 pmVector.setElementAt(newTm, pmX);
514                 pmX = 0; // Tm found, now we can stop
515
}
516             
517         }
518     }
519     
520     // used exclusively by updateFieldValue()
521
/**
522        @deprecated
523      */

524     private static void clearTextMatrixX(Vector pmVector) {
525         // this method examines the last text matrix in
526
// pmVector and sets the X matrix value to 0.
527

528         int pmX = pmVector.size();
529
530         while (pmX > 0) {
531             
532             pmX--;
533             PageMark pm = (PageMark)(pmVector.elementAt(pmX));
534             
535             if (pm instanceof XTm) {
536                 XTm tm = (XTm)pm;
537                 XTm newTm = new XTm(
538                     tm.getA(),
539                     tm.getB(),
540                     tm.getC(),
541                     tm.getD(),
542                     PjNumber.ZERO,
543                     tm.getY());
544                 pmVector.setElementAt(newTm, pmX);
545                 pmX = 0; // Tm found, now we can stop
546
}
547             
548         }
549     }
550
551     // used exclusively by inheritFieldAttributes()
552
/**
553        @deprecated
554      */

555     private void inheritFieldAttributesCollapse(PjName name, Hashtable ht, PjDictionary newNode, PjDictionary parent) {
556         if (ht.get(name) == null) {
557             Object JavaDoc obj = parent.getHashtable().get(name);
558             if (obj != null) {
559                 ht.put(name, obj);
560             }
561         }
562     }
563     
564 }
565
Popular Tags