Source Code Cross Referenced for PdfManager.java in  » PDF » pjx » com » etymon » pjx » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » PDF » pjx » com.etymon.pjx 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          Copyright (C) Etymon Systems, Inc. <http://www.etymon.com/>
003:         */
004:
005:        package com.etymon.pjx;
006:
007:        import java.io.*;
008:        import java.util.*;
009:
010:        /**
011:         Manages the modification or creation of a PDF document.  This class
012:         is synchronized.
013:         @author Nassib Nassar
014:         */
015:        public final class PdfManager {
016:
017:            protected long _last_startxref;
018:
019:            /**
020:               @deprecated Do not use this method.
021:             */
022:            public long getStartxref() {
023:                return _last_startxref;
024:            }
025:
026:            protected static final PdfName PDFNAME_PREV = new PdfName("Prev");
027:
028:            protected static final PdfName PDFNAME_SIZE = new PdfName("Size");
029:
030:            /**
031:               The collection of PDF objects that have been modified.  Each
032:               PDF object is keyed by its associated object number (stored
033:               as type Integer).
034:             */
035:            protected Map _modobj;
036:
037:            /**
038:               The total size of the cross-reference table, taking
039:               together both the PDF input document and the modified
040:               objects.  This is also used as the next free object number.
041:             */
042:            protected int _modsize;
043:
044:            /**
045:               The PDF input document.
046:             */
047:            protected PdfReader _reader;
048:
049:            /**
050:               Returns the <code>PdfReader</code> instance associated with
051:               this document.
052:             */
053:            public PdfReader getReader() {
054:                synchronized (this ) {
055:
056:                    return _reader;
057:
058:                }
059:            }
060:
061:            /**
062:               The beginning offset of the cross-reference table in the
063:               PDF input document.
064:             */
065:            protected long _startxref;
066:
067:            /**
068:               The document's trailer dictionary, in its current (possibly
069:               modified) state.
070:             */
071:            protected PdfDictionary _trailer;
072:
073:            /**
074:               The cross-reference table and associated trailer read from
075:               the PDF input document.
076:             */
077:            protected XrefTable _xt;
078:
079:            /**
080:                   Constructs a <code>PdfManager</code> representing an empty
081:                   PDF document.  The document in this initial state contains
082:                   no objects and therefore does not correspond to a valid PDF
083:                   file.
084:               @param init if false, specifies that the document contain
085:               no objects (and therefore will not correspond to a valid
086:               PDF file); if true, that the document be initialized with
087:               a minimal set of objects to create a single blank page.
088:             */
089:            public PdfManager(boolean init) {
090:
091:                _reader = null;
092:                _startxref = 0;
093:                _xt = null;
094:
095:                _trailer = new PdfDictionary(new HashMap());
096:
097:                _modsize = 1;
098:                construct();
099:
100:                if (init) {
101:                    initialize();
102:                }
103:            }
104:
105:            /**
106:               Creates the minimal set of objects in a newly constructed
107:               document in order to create a single blank page.  This
108:               method assumes that the document contains no objects.
109:               (This method is adapted from
110:               com.etymon.pj.Pdf.createEmpty().)
111:             */
112:            private void initialize() {
113:
114:                List list;
115:                Map map;
116:                PdfName nameType = new PdfName("Type");
117:
118:                // Make a ProcSet.
119:                list = new ArrayList(2);
120:                list.add(new PdfName("PDF"));
121:                list.add(new PdfName("Text"));
122:                PdfArray procSet = new PdfArray(list);
123:                int procSetId = addObject(procSet);
124:
125:                // Make a Resources dictionary.
126:                map = new HashMap(1);
127:                map.put(new PdfName("ProcSet"), new PdfReference(procSetId, 0));
128:                PdfDictionary resources = new PdfDictionary(map);
129:                int resourcesId = addObject(resources);
130:
131:                // Make a MediaBox.
132:                list = new ArrayList(4);
133:                list.add(new PdfInteger(0));
134:                list.add(new PdfInteger(0));
135:                list.add(new PdfInteger(612));
136:                list.add(new PdfInteger(792));
137:                PdfArray mediaBox = new PdfArray(list);
138:
139:                // Make a Page placeholder.
140:                int pageId = addObject(new PdfDictionary());
141:
142:                // Make a Kids array.
143:                list = new ArrayList(1);
144:                list.add(new PdfReference(pageId, 0));
145:                PdfArray kids = new PdfArray(list);
146:
147:                // Make the root Pages node.
148:                map = new HashMap(5);
149:                map.put(nameType, new PdfName("Pages"));
150:                map.put(new PdfName("Resources"), new PdfReference(resourcesId,
151:                        0));
152:                map.put(new PdfName("MediaBox"), mediaBox);
153:                map.put(new PdfName("Count"), new PdfInteger(1));
154:                map.put(new PdfName("Kids"), kids);
155:                int rootId = addObject(new PdfDictionary(map));
156:
157:                // Go back and recreate the Page correctly, including
158:                // the Parent pointer.
159:                map = new HashMap(2);
160:                map.put(nameType, new PdfName("Page"));
161:                map.put(new PdfName("Parent"), new PdfReference(rootId, 0));
162:                PdfDictionary page = new PdfDictionary(map);
163:                setObject(page, pageId);
164:
165:                // Make the Catalog.
166:                map = new HashMap(2);
167:                map.put(nameType, new PdfName("Catalog"));
168:                map.put(new PdfName("Pages"), new PdfReference(rootId, 0));
169:                int catalogId = addObject(new PdfDictionary(map));
170:
171:                // Create Info dictionary with default fields. ?
172:
173:                // Update trailer dictionary.
174:                map = new HashMap(getTrailerDictionary().getMap());
175:                map.put(new PdfName("Root"), new PdfReference(catalogId, 0));
176:                setTrailerDictionary(new PdfDictionary(map));
177:
178:            }
179:
180:            /**
181:                   Constructs a <code>PdfManager</code> representing an
182:                   existing PDF document.
183:                   @param pdfReader specifies the existing PDF document to
184:                   read.
185:               @throws IOException
186:               @throws PdfFormatException
187:             */
188:            public PdfManager(PdfReader pdfReader) throws IOException,
189:                    PdfFormatException {
190:
191:                _startxref = pdfReader.readStartxref();
192:                _xt = pdfReader.readXrefTable(_startxref);
193:                _trailer = _xt.getTrailerDictionary();
194:                _reader = pdfReader;
195:                _modsize = _xt.size();
196:                construct();
197:            }
198:
199:            /**
200:               Adds a PDF object to the document and assigns a new object
201:               number to it.
202:               @param obj the PDF object to be added.
203:               @return the new object number assigned to the PDF object.
204:               The generation number of the object will be 0.
205:             */
206:            public int addObject(PdfObject obj) {
207:                synchronized (this ) {
208:
209:                    int id = _modsize++;
210:
211:                    setObject(obj, id);
212:
213:                    return id;
214:                }
215:            }
216:
217:            /**
218:               Retrieves the PDF object associated with a specified object
219:               number.
220:               @param objectNumber specifies the object number of the PDF
221:               object to be retrieved.
222:               @return the retrieved PDF object.
223:               @throws IOException
224:               @throws PdfFormatException
225:             */
226:            public PdfObject getObject(int objectNumber) throws IOException,
227:                    PdfFormatException {
228:                synchronized (this ) {
229:
230:                    // first check hashmap
231:                    PdfObject obj = (PdfObject) _modobj.get(new Integer(
232:                            objectNumber));
233:                    if (obj != null) {
234:                        return obj;
235:                    }
236:
237:                    // next try the xref
238:                    if (_reader == null) {
239:                        return null;
240:                    }
241:                    if (_xt.unwrapUsageArray()[objectNumber] != XrefTable.ENTRY_IN_USE) {
242:                        return null;
243:                    }
244:                    long start = _xt.getIndex(objectNumber);
245:                    long end = _xt.estimateObjectEnd(objectNumber);
246:                    return _reader.readObject(start, end, true, _xt);
247:                }
248:
249:            }
250:
251:            /**
252:               Retrieves the PDF object referred to by a specified
253:               indirect reference object.  If the specified object is not
254:               an indirect reference but a direct object, that object
255:               itself is returned.  If the specified object is
256:               <code>null</code>, then <code>null</code> is returned.
257:               @param obj the indirect reference object (or direct object,
258:               or <code>null</code>).
259:               @return the retrieved object (or direct object).
260:               @throws IOException
261:               @throws PdfFormatException
262:             */
263:            public PdfObject getObjectIndirect(PdfObject obj)
264:                    throws IOException, PdfFormatException {
265:                synchronized (this ) {
266:
267:                    if (obj == null) {
268:                        return null;
269:                    }
270:
271:                    if (obj instanceof  PdfReference) {
272:                        // this should be changed from
273:                        // recursive to iterative, for best
274:                        // efficiency
275:                        return getObjectIndirect(getObject(((PdfReference) obj)
276:                                .getObjectNumber()));
277:                    } else {
278:                        return obj;
279:                    }
280:
281:                }
282:            }
283:
284:            /**
285:               Returns the document's trailer dictionary.
286:               @return the trailer dictionary.
287:             */
288:            public PdfDictionary getTrailerDictionary() {
289:                synchronized (this ) {
290:                    return _trailer;
291:                }
292:            }
293:
294:            /**
295:               Returns the current size of the cross-reference table,
296:               taking into account any modifications that have been made
297:               to the document via this PdfManager.
298:               @return the size of the cross-reference table.
299:             */
300:            public int getXrefTableSize() {
301:                synchronized (this ) {
302:                    return _modsize;
303:                }
304:            }
305:
306:            /**
307:               Performs initialization common to multiple constructors of
308:               this class.  This method is only intended to be called from
309:               the constructors.
310:             */
311:            protected void construct() {
312:                _modobj = new HashMap();
313:            }
314:
315:            /**
316:               Adds a PDF object to the document and assigns the specified
317:               object number to it.  If an object in the document is
318:               already assigned to the specified object number, that
319:               object is replaced with the new one.
320:               @param obj the PDF object to be added.
321:               @param objectNumber the object number to assign to the PDF
322:               object.
323:             */
324:            public void setObject(PdfObject obj, int objectNumber) {
325:                synchronized (this ) {
326:                    _modobj.put(new Integer(objectNumber), obj);
327:                    if (objectNumber >= _modsize) {
328:                        _modsize = objectNumber + 1;
329:                    }
330:                }
331:            }
332:
333:            /**
334:               Assigns the document a new trailer dictionary, replacing
335:               the existing one (if any).
336:               @param dictionary specifies the new trailer dictionary.
337:             */
338:            public void setTrailerDictionary(PdfDictionary dictionary) {
339:                synchronized (this ) {
340:                    _trailer = dictionary;
341:                }
342:            }
343:
344:            /**
345:               Writes the document in PDF format, including all
346:               modifications made through this <code>PdfManager</code>.
347:               This method is equivalent to using {@link
348:               #writeDocument(PdfWriter, boolean) writeDocument(...,
349:               true)}; i.e. it uses incremental update if applicable.
350:               Note that this means the resultant document will be larger
351:               than the original document; otherwise use {@link
352:               #writeDocument(PdfWriter, boolean) writeDocument(...,
353:               false)} to get a smaller resultant file, although it will
354:               usually take longer to generate.  The
355:               <code>PdfWriter</code> should be newly created (i.e. it
356:               should not have been previously used for anything); and
357:               after this method has been called, the
358:               <code>PdfWriter</code> should be closed and discarded.
359:               @param pdfWriter specifies the PDF document to write.
360:               @return the number of bytes written.
361:               @throws IOException
362:               @throws PdfFormatException
363:             */
364:            public long writeDocument(PdfWriter pdfWriter) throws IOException,
365:                    PdfFormatException {
366:                return writeDocument(pdfWriter, true);
367:            }
368:
369:            /**
370:               Writes the document in PDF format, including all
371:               modifications made through this <code>PdfManager</code>.
372:               This method will optionally use PDF's incremental update
373:               format, which often takes significantly less processing
374:               time but creates a larger resultant PDF file and may be
375:               slower for a reader to open (if the file has been updated
376:               many times in this way).  Incremental update should not be
377:               used when the original document is a Linearized PDF file if
378:               changes have been made that would invalidate its
379:               correctness, unless the resultant PDF file will not be used
380:               in an application that depends on its correct
381:               Linearization.  If this <code>PdfManager</code> represents
382:               a new document rather than modifying an existing one, then
383:               the incremental update option is not applicable and is
384:               disregarded.  The <code>PdfWriter</code> should be newly
385:               created (i.e. it should not have been previously used for
386:               anything); and after this method has been called, the
387:               <code>PdfWriter</code> should be closed and discarded.
388:               @param pdfWriter specifies the PDF document to write.
389:               @param useIncrementalUpdate specifies whether incremental
390:               update format should be used.  A value of <code>true</code>
391:               enables incremental update.
392:               @return the number of bytes written.
393:               @throws IOException
394:               @throws PdfFormatException
395:             */
396:            public long writeDocument(PdfWriter pdfWriter,
397:                    boolean useIncrementalUpdate) throws IOException,
398:                    PdfFormatException {
399:                synchronized (this ) {
400:
401:                    int modsize = _modsize;
402:                    XrefTable xt = _xt;
403:                    PdfReader reader = _reader;
404:                    Map modobj = _modobj;
405:
406:                    boolean incUpdate;
407:                    if (reader == null) {
408:                        incUpdate = false;
409:                    } else {
410:                        incUpdate = useIncrementalUpdate;
411:                    }
412:
413:                    PdfWriter w = pdfWriter;
414:                    long pos = 0;
415:
416:                    if (incUpdate) {
417:                        pos += w.writeCopy(reader);
418:                    } else {
419:                        pos += w.writeHeader();
420:                    }
421:
422:                    long[] nindex = new long[modsize];
423:                    int[] ngeneration = new int[modsize];
424:                    byte[] nusage = new byte[modsize];
425:                    // (maybe we should ideally clone the
426:                    // trailer instead of modifying the original)
427:                    HashMap ntrailerMap = new HashMap(_trailer.getMap());
428:
429:                    long[] index = null;
430:                    int[] generation = null;
431:                    byte[] usage = null;
432:
433:                    if (reader != null) {
434:                        index = xt.unwrapIndexArray();
435:                        generation = xt.unwrapGenerationArray();
436:                        usage = xt.unwrapUsageArray();
437:                    }
438:
439:                    int id;
440:                    // iterate through modified objects, adding
441:                    // them to the new XrefTrailer
442:                    for (Iterator it = modobj.keySet().iterator(); it.hasNext();) {
443:                        Integer key = (Integer) it.next();
444:                        id = key.intValue();
445:                        nusage[id] = XrefTable.ENTRY_IN_USE;
446:                        nindex[id] = pos;
447:                        PdfObject obj = (PdfObject) modobj.get(key);
448:
449:                        // determine generation number
450:                        if (reader == null) {
451:                            ngeneration[id] = 0;
452:                        } else {
453:                            if ((id < xt.size())
454:                                    && (usage[id] != XrefTable.ENTRY_UNDEFINED)) {
455:                                ngeneration[id] = generation[id];
456:                            } else {
457:                                ngeneration[id] = 0;
458:                            }
459:                        }
460:
461:                        if ((incUpdate) || (reader == null)) {
462:                            pos += w.writeObjectIndirect(obj, id,
463:                                    ngeneration[id]);
464:                        }
465:                    }
466:
467:                    // always keep entry 0
468:                    ngeneration[0] = 65535;
469:                    nusage[0] = XrefTable.ENTRY_FREE;
470:
471:                    if (!incUpdate) {
472:                        for (id = 1; id < modsize; id++) {
473:                            PdfObject obj = null;
474:                            if ((reader != null)
475:                                    && (nusage[id] == XrefTable.ENTRY_UNDEFINED)) {
476:                                if ((id < xt.size())
477:                                        && (usage[id] != XrefTable.ENTRY_UNDEFINED)) {
478:                                    if (usage[id] == XrefTable.ENTRY_IN_USE) {
479:                                        long start = index[id];
480:                                        long end = xt.estimateObjectEnd(id);
481:                                        obj = reader.readObject(start, end,
482:                                                true, xt);
483:                                    }
484:                                    ngeneration[id] = generation[id];
485:                                    nusage[id] = usage[id];
486:                                }
487:                            } else {
488:                                obj = (PdfObject) modobj.get(new Integer(id));
489:                            }
490:                            if (nusage[id] == XrefTable.ENTRY_IN_USE) {
491:                                nindex[id] = pos;
492:                                pos += w.writeObjectIndirect(obj, id,
493:                                        ngeneration[id]);
494:                            }
495:
496:                        }
497:                    }
498:
499:                    if (incUpdate) {
500:                        ntrailerMap.put(PDFNAME_PREV, new PdfLong(_startxref));
501:                    } else {
502:                        ntrailerMap.remove(PDFNAME_PREV);
503:                    }
504:                    ntrailerMap.put(PDFNAME_SIZE, new PdfInteger(modsize));
505:
506:                    XrefTable nxt = XrefTable.wrap(nindex, ngeneration, nusage,
507:                            new PdfDictionary(ntrailerMap));
508:
509:                    _last_startxref = pos;
510:
511:                    pos += w.writeXrefTable(nxt, pos);
512:
513:                    return pos;
514:                }
515:            }
516:
517:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.