Source Code Cross Referenced for COSWriter.java in  » PDF » PDFBox-0.7.3 » org » pdfbox » pdfwriter » 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 » PDFBox 0.7.3 » org.pdfbox.pdfwriter 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Copyright (c) 2003-2006, www.pdfbox.org
003:         * All rights reserved.
004:         *
005:         * Redistribution and use in source and binary forms, with or without
006:         * modification, are permitted provided that the following conditions are met:
007:         *
008:         * 1. Redistributions of source code must retain the above copyright notice,
009:         *    this list of conditions and the following disclaimer.
010:         * 2. Redistributions in binary form must reproduce the above copyright notice,
011:         *    this list of conditions and the following disclaimer in the documentation
012:         *    and/or other materials provided with the distribution.
013:         * 3. Neither the name of pdfbox; nor the names of its
014:         *    contributors may be used to endorse or promote products derived from this
015:         *    software without specific prior written permission.
016:         *
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020:         * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021:         * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022:         * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024:         * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027:         *
028:         * http://www.pdfbox.org
029:         *
030:         */package org.pdfbox.pdfwriter;
031:
032:        import java.io.IOException;
033:        import java.io.InputStream;
034:        import java.io.OutputStream;
035:        import java.security.MessageDigest;
036:        import java.security.NoSuchAlgorithmException;
037:        import java.text.DecimalFormat;
038:        import java.text.NumberFormat;
039:        import java.util.ArrayList;
040:        import java.util.Collections;
041:        import java.util.HashSet;
042:        import java.util.Hashtable;
043:        import java.util.Iterator;
044:        import java.util.List;
045:        import java.util.Locale;
046:        import java.util.Map;
047:        import java.util.Set;
048:
049:        import org.pdfbox.cos.COSArray;
050:        import org.pdfbox.cos.COSBase;
051:        import org.pdfbox.cos.COSBoolean;
052:        import org.pdfbox.cos.COSDictionary;
053:        import org.pdfbox.cos.COSDocument;
054:        import org.pdfbox.cos.COSFloat;
055:        import org.pdfbox.cos.COSInteger;
056:        import org.pdfbox.cos.COSName;
057:        import org.pdfbox.cos.COSNull;
058:        import org.pdfbox.cos.COSObject;
059:        import org.pdfbox.cos.COSStream;
060:        import org.pdfbox.cos.COSString;
061:        import org.pdfbox.cos.ICOSVisitor;
062:        import org.pdfbox.exceptions.COSVisitorException;
063:        import org.pdfbox.exceptions.CryptographyException;
064:        import org.pdfbox.pdmodel.PDDocument;
065:        import org.pdfbox.pdmodel.encryption.SecurityHandler;
066:        import org.pdfbox.persistence.util.COSObjectKey;
067:
068:        /**
069:         * this class acts on a in-memory representation of a pdf document.
070:         *
071:         * todo no support for incremental updates
072:         * todo single xref section only
073:         * todo no linearization
074:         *
075:         * @author Michael Traut
076:         * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
077:         * @version $Revision: 1.36 $
078:         */
079:        public class COSWriter implements  ICOSVisitor {
080:            /**
081:             * The dictionary open token.
082:             */
083:            public static final byte[] DICT_OPEN = "<<".getBytes();
084:            /**
085:             * The dictionary close token.
086:             */
087:            public static final byte[] DICT_CLOSE = ">>".getBytes();
088:            /**
089:             * space character.
090:             */
091:            public static final byte[] SPACE = " ".getBytes();
092:            /**
093:             * The start to a PDF comment.
094:             */
095:            public static final byte[] COMMENT = "%".getBytes();
096:
097:            /**
098:             * The output version of the PDF.
099:             */
100:            public static final byte[] VERSION = "PDF-1.4".getBytes();
101:            /**
102:             * Garbage bytes used to create the PDF header.
103:             */
104:            public static final byte[] GARBAGE = new byte[] { (byte) 0xf6,
105:                    (byte) 0xe4, (byte) 0xfc, (byte) 0xdf };
106:            /**
107:             * The EOF constant.
108:             */
109:            public static final byte[] EOF = "%%EOF".getBytes();
110:            // pdf tokens
111:
112:            /**
113:             * The reference token.
114:             */
115:            public static final byte[] REFERENCE = "R".getBytes();
116:            /**
117:             * The XREF token.
118:             */
119:            public static final byte[] XREF = "xref".getBytes();
120:            /**
121:             * The xref free token.
122:             */
123:            public static final byte[] XREF_FREE = "f".getBytes();
124:            /**
125:             * The xref used token.
126:             */
127:            public static final byte[] XREF_USED = "n".getBytes();
128:            /**
129:             * The trailer token.
130:             */
131:            public static final byte[] TRAILER = "trailer".getBytes();
132:            /**
133:             * The start xref token.
134:             */
135:            public static final byte[] STARTXREF = "startxref".getBytes();
136:            /**
137:             * The starting object token.
138:             */
139:            public static final byte[] OBJ = "obj".getBytes();
140:            /**
141:             * The end object token.
142:             */
143:            public static final byte[] ENDOBJ = "endobj".getBytes();
144:            /**
145:             * The array open token.
146:             */
147:            public static final byte[] ARRAY_OPEN = "[".getBytes();
148:            /**
149:             * The array close token.
150:             */
151:            public static final byte[] ARRAY_CLOSE = "]".getBytes();
152:            /**
153:             * The open stream token.
154:             */
155:            public static final byte[] STREAM = "stream".getBytes();
156:            /**
157:             * The close stream token.
158:             */
159:            public static final byte[] ENDSTREAM = "endstream".getBytes();
160:
161:            private NumberFormat formatXrefOffset = new DecimalFormat(
162:                    "0000000000");
163:            /**
164:             * The decimal format for the xref object generation number data.
165:             */
166:            private NumberFormat formatXrefGeneration = new DecimalFormat(
167:                    "00000");
168:
169:            private NumberFormat formatDecimal = NumberFormat
170:                    .getNumberInstance(Locale.US);
171:
172:            // the stream where we create the pdf output
173:            private OutputStream output;
174:            // the stream used to write standard cos data
175:            private COSStandardOutputStream standardOutput;
176:
177:            // the start position of the x ref section
178:            private long startxref = 0;
179:
180:            // the current object number
181:            private long number = 0;
182:
183:            // maps the object to the keys generated in the writer
184:            // these are used for indirect refrences in other objects
185:            //A hashtable is used on purpose over a hashmap 
186:            //so that null entries will not get added.
187:            private Map objectKeys = new Hashtable();
188:
189:            // the list of x ref entries to be made so far
190:            private List xRefEntries = new ArrayList();
191:
192:            //A list of objects to write.
193:            private List objectsToWrite = new ArrayList();
194:
195:            //a list of objects already written
196:            private Set writtenObjects = new HashSet();
197:            //An 'actual' is any COSBase that is not a COSObject.
198:            //need to keep a list of the actuals that are added
199:            //as well as the objects because there is a problem
200:            //when adding a COSObject and then later adding
201:            //the actual for that object, so we will track
202:            //actuals separately.
203:            private Set actualsAdded = new HashSet();
204:
205:            private COSObjectKey currentObjectKey = null;
206:
207:            private PDDocument document = null;
208:
209:            private boolean willEncrypt = false;
210:
211:            /**
212:             * COSWriter constructor comment.
213:             *
214:             * @param os The wrapped output stream.
215:             */
216:            public COSWriter(OutputStream os) {
217:                super ();
218:                setOutput(os);
219:                setStandardOutput(new COSStandardOutputStream(getOutput()));
220:                formatDecimal.setMaximumFractionDigits(10);
221:                formatDecimal.setGroupingUsed(false);
222:            }
223:
224:            /**
225:             * add an entry in the x ref table for later dump.
226:             *
227:             * @param entry The new entry to add.
228:             */
229:            protected void addXRefEntry(COSWriterXRefEntry entry) {
230:                getXRefEntries().add(entry);
231:            }
232:
233:            /**
234:             * This will close the stream.
235:             *
236:             * @throws IOException If the underlying stream throws an exception.
237:             */
238:            public void close() throws IOException {
239:                if (getStandardOutput() != null) {
240:                    getStandardOutput().close();
241:                }
242:                if (getOutput() != null) {
243:                    getOutput().close();
244:                }
245:            }
246:
247:            /**
248:             * This will get the current object number.
249:             *
250:             * @return The current object number.
251:             */
252:            protected long getNumber() {
253:                return number;
254:            }
255:
256:            /**
257:             * This will get all available object keys.
258:             *
259:             * @return A map of all object keys.
260:             */
261:            public java.util.Map getObjectKeys() {
262:                return objectKeys;
263:            }
264:
265:            /**
266:             * This will get the output stream.
267:             *
268:             * @return The output stream.
269:             */
270:            protected java.io.OutputStream getOutput() {
271:                return output;
272:            }
273:
274:            /**
275:             * This will get the standard output stream.
276:             *
277:             * @return The standard output stream.
278:             */
279:            protected COSStandardOutputStream getStandardOutput() {
280:                return standardOutput;
281:            }
282:
283:            /**
284:             * This will get the current start xref.
285:             *
286:             * @return The current start xref.
287:             */
288:            protected long getStartxref() {
289:                return startxref;
290:            }
291:
292:            /**
293:             * This will get the xref entries.
294:             *
295:             * @return All available xref entries.
296:             */
297:            protected java.util.List getXRefEntries() {
298:                return xRefEntries;
299:            }
300:
301:            /**
302:             * This will set the current object number.
303:             *
304:             * @param newNumber The new object number.
305:             */
306:            protected void setNumber(long newNumber) {
307:                number = newNumber;
308:            }
309:
310:            /**
311:             * This will set the output stream.
312:             *
313:             * @param newOutput The new output stream.
314:             */
315:            private void setOutput(OutputStream newOutput) {
316:                output = newOutput;
317:            }
318:
319:            /**
320:             * This will set the standard output stream.
321:             *
322:             * @param newStandardOutput The new standard output stream.
323:             */
324:            private void setStandardOutput(
325:                    COSStandardOutputStream newStandardOutput) {
326:                standardOutput = newStandardOutput;
327:            }
328:
329:            /**
330:             * This will set the start xref.
331:             *
332:             * @param newStartxref The new start xref attribute.
333:             */
334:            protected void setStartxref(long newStartxref) {
335:                startxref = newStartxref;
336:            }
337:
338:            /**
339:             * This will write the body of the document.
340:             *
341:             * @param doc The document to write the body for.
342:             *
343:             * @throws IOException If there is an error writing the data.
344:             * @throws COSVisitorException If there is an error generating the data.
345:             */
346:            protected void doWriteBody(COSDocument doc) throws IOException,
347:                    COSVisitorException {
348:                COSDictionary trailer = doc.getTrailer();
349:                COSDictionary root = (COSDictionary) trailer
350:                        .getDictionaryObject(COSName.ROOT);
351:                COSDictionary info = (COSDictionary) trailer
352:                        .getDictionaryObject(COSName.getPDFName("Info"));
353:                COSDictionary encrypt = (COSDictionary) trailer
354:                        .getDictionaryObject(COSName.getPDFName("Encrypt"));
355:                if (root != null) {
356:                    addObjectToWrite(root);
357:                }
358:                if (info != null) {
359:                    addObjectToWrite(info);
360:                }
361:
362:                while (objectsToWrite.size() > 0) {
363:                    COSBase nextObject = (COSBase) objectsToWrite.remove(0);
364:                    doWriteObject(nextObject);
365:                }
366:
367:                willEncrypt = false;
368:
369:                if (encrypt != null) {
370:                    addObjectToWrite(encrypt);
371:                }
372:
373:                while (objectsToWrite.size() > 0) {
374:                    COSBase nextObject = (COSBase) objectsToWrite.remove(0);
375:                    doWriteObject(nextObject);
376:                }
377:
378:                // write all objects
379:                /**
380:                for (Iterator i = doc.getObjects().iterator(); i.hasNext();)
381:                {
382:                    COSObject obj = (COSObject) i.next();
383:                    doWriteObject(obj);
384:                }**/
385:            }
386:
387:            private void addObjectToWrite(COSBase object) {
388:                COSBase actual = object;
389:                if (actual instanceof  COSObject) {
390:                    actual = ((COSObject) actual).getObject();
391:                }
392:
393:                if (!writtenObjects.contains(object)
394:                        && !objectsToWrite.contains(object)
395:                        && !actualsAdded.contains(actual)) {
396:                    objectsToWrite.add(object);
397:                    if (actual != null) {
398:                        actualsAdded.add(actual);
399:                    }
400:                }
401:            }
402:
403:            /**
404:             * This will write a COS object.
405:             *
406:             * @param obj The object to write.
407:             *
408:             * @throws COSVisitorException If there is an error visiting objects.
409:             */
410:            public void doWriteObject(COSBase obj) throws COSVisitorException {
411:                try {
412:                    writtenObjects.add(obj);
413:                    // find the physical reference
414:                    currentObjectKey = getObjectKey(obj);
415:                    // add a x ref entry
416:                    addXRefEntry(new COSWriterXRefEntry(getStandardOutput()
417:                            .getPos(), obj, currentObjectKey));
418:                    // write the object
419:                    getStandardOutput().write(
420:                            String.valueOf(currentObjectKey.getNumber())
421:                                    .getBytes());
422:                    getStandardOutput().write(SPACE);
423:                    getStandardOutput().write(
424:                            String.valueOf(currentObjectKey.getGeneration())
425:                                    .getBytes());
426:                    getStandardOutput().write(SPACE);
427:                    getStandardOutput().write(OBJ);
428:                    getStandardOutput().writeEOL();
429:                    obj.accept(this );
430:                    getStandardOutput().writeEOL();
431:                    getStandardOutput().write(ENDOBJ);
432:                    getStandardOutput().writeEOL();
433:                } catch (IOException e) {
434:                    throw new COSVisitorException(e);
435:                }
436:            }
437:
438:            /**
439:             * This will write the header to the PDF document.
440:             *
441:             * @param doc The document to get the data from.
442:             *
443:             * @throws IOException If there is an error writing to the stream.
444:             */
445:            protected void doWriteHeader(COSDocument doc) throws IOException {
446:                getStandardOutput().write(doc.getHeaderString().getBytes());
447:                getStandardOutput().writeEOL();
448:                getStandardOutput().write(COMMENT);
449:                getStandardOutput().write(GARBAGE);
450:                getStandardOutput().writeEOL();
451:            }
452:
453:            /**
454:             * This will write the trailer to the PDF document.
455:             *
456:             * @param doc The document to create the trailer for.
457:             *
458:             * @throws IOException If there is an IOError while writing the document.
459:             * @throws COSVisitorException If there is an error while generating the data.
460:             */
461:            protected void doWriteTrailer(COSDocument doc) throws IOException,
462:                    COSVisitorException {
463:                getStandardOutput().write(TRAILER);
464:                getStandardOutput().writeEOL();
465:
466:                COSDictionary trailer = doc.getTrailer();
467:                //sort xref, needed only if object keys not regenerated
468:                Collections.sort(getXRefEntries());
469:                COSWriterXRefEntry lastEntry = (COSWriterXRefEntry) getXRefEntries()
470:                        .get(getXRefEntries().size() - 1);
471:                trailer.setInt(COSName.getPDFName("Size"), (int) lastEntry
472:                        .getKey().getNumber() + 1);
473:                trailer.removeItem(COSName.PREV);
474:                /**
475:                COSObject catalog = doc.getCatalog();
476:                if (catalog != null)
477:                {
478:                    trailer.setItem(COSName.getPDFName("Root"), catalog);
479:                }
480:                 */
481:                trailer.accept(this );
482:
483:                getStandardOutput().write(STARTXREF);
484:                getStandardOutput().writeEOL();
485:                getStandardOutput().write(
486:                        String.valueOf(getStartxref()).getBytes());
487:                getStandardOutput().writeEOL();
488:                getStandardOutput().write(EOF);
489:            }
490:
491:            /**
492:             * write the x ref section for the pdf file
493:             *
494:             * currently, the pdf is reconstructed from the scratch, so we write a single section
495:             *
496:             * todo support for incremental writing?
497:             *
498:             * @param doc The document to write the xref from.
499:             *
500:             * @throws IOException If there is an error writing the data to the stream.
501:             */
502:            protected void doWriteXRef(COSDocument doc) throws IOException {
503:                String offset;
504:                String generation;
505:
506:                // sort xref, needed only if object keys not regenerated
507:                Collections.sort(getXRefEntries());
508:                COSWriterXRefEntry lastEntry = (COSWriterXRefEntry) getXRefEntries()
509:                        .get(getXRefEntries().size() - 1);
510:
511:                // remember the position where x ref is written
512:                setStartxref(getStandardOutput().getPos());
513:                //
514:                getStandardOutput().write(XREF);
515:                getStandardOutput().writeEOL();
516:                // write start object number and object count for this x ref section
517:                // we assume starting from scratch
518:                getStandardOutput().write(String.valueOf(0).getBytes());
519:                getStandardOutput().write(SPACE);
520:                getStandardOutput().write(
521:                        String.valueOf(lastEntry.getKey().getNumber() + 1)
522:                                .getBytes());
523:                getStandardOutput().writeEOL();
524:                // write initial start object with ref to first deleted object and magic generation number
525:                offset = formatXrefOffset.format(0);
526:                generation = formatXrefGeneration.format(65535);
527:                getStandardOutput().write(offset.getBytes());
528:                getStandardOutput().write(SPACE);
529:                getStandardOutput().write(generation.getBytes());
530:                getStandardOutput().write(SPACE);
531:                getStandardOutput().write(XREF_FREE);
532:                getStandardOutput().writeCRLF();
533:                // write entry for every object
534:                long lastObjectNumber = 0;
535:                for (Iterator i = getXRefEntries().iterator(); i.hasNext();) {
536:                    COSWriterXRefEntry entry = (COSWriterXRefEntry) i.next();
537:                    while (lastObjectNumber < entry.getKey().getNumber() - 1) {
538:                        offset = formatXrefOffset.format(0);
539:                        generation = formatXrefGeneration.format(65535);
540:                        getStandardOutput().write(offset.getBytes());
541:                        getStandardOutput().write(SPACE);
542:                        getStandardOutput().write(generation.getBytes());
543:                        getStandardOutput().write(SPACE);
544:                        getStandardOutput().write(XREF_FREE);
545:                        getStandardOutput().writeCRLF();
546:                        lastObjectNumber++;
547:                    }
548:                    lastObjectNumber = entry.getKey().getNumber();
549:                    offset = formatXrefOffset.format(entry.getOffset());
550:                    generation = formatXrefGeneration.format(entry.getKey()
551:                            .getGeneration());
552:                    getStandardOutput().write(offset.getBytes());
553:                    getStandardOutput().write(SPACE);
554:                    getStandardOutput().write(generation.getBytes());
555:                    getStandardOutput().write(SPACE);
556:                    getStandardOutput().write(
557:                            entry.isFree() ? XREF_FREE : XREF_USED);
558:                    getStandardOutput().writeCRLF();
559:                }
560:            }
561:
562:            /**
563:             * This will get the object key for the object.
564:             *
565:             * @param obj The object to get the key for.
566:             *
567:             * @return The object key for the object.
568:             */
569:            private COSObjectKey getObjectKey(COSBase obj) {
570:                COSBase actual = obj;
571:                if (actual instanceof  COSObject) {
572:                    actual = ((COSObject) obj).getObject();
573:                }
574:                COSObjectKey key = null;
575:                if (actual != null) {
576:                    key = (COSObjectKey) objectKeys.get(actual);
577:                }
578:                if (key == null) {
579:                    key = (COSObjectKey) objectKeys.get(obj);
580:                }
581:                if (key == null) {
582:                    setNumber(getNumber() + 1);
583:                    key = new COSObjectKey(getNumber(), 0);
584:                    objectKeys.put(obj, key);
585:                    if (actual != null) {
586:                        objectKeys.put(actual, key);
587:                    }
588:                }
589:                return key;
590:            }
591:
592:            /**
593:             * visitFromArray method comment.
594:             *
595:             * @param obj The object that is being visited.
596:             *
597:             * @throws COSVisitorException If there is an exception while visiting this object.
598:             *
599:             * @return null
600:             */
601:            public Object visitFromArray(COSArray obj)
602:                    throws COSVisitorException {
603:                try {
604:                    int count = 0;
605:                    getStandardOutput().write(ARRAY_OPEN);
606:                    for (Iterator i = obj.iterator(); i.hasNext();) {
607:                        COSBase current = (COSBase) i.next();
608:                        if (current instanceof  COSDictionary) {
609:                            addObjectToWrite(current);
610:                            writeReference(current);
611:                        } else if (current instanceof  COSObject) {
612:                            COSBase subValue = ((COSObject) current)
613:                                    .getObject();
614:                            if (subValue instanceof  COSDictionary
615:                                    || subValue == null) {
616:                                addObjectToWrite(current);
617:                                writeReference(current);
618:                            } else {
619:                                subValue.accept(this );
620:                            }
621:                        } else if (current == null) {
622:                            COSNull.NULL.accept(this );
623:                        } else {
624:                            current.accept(this );
625:                        }
626:                        count++;
627:                        if (i.hasNext()) {
628:                            if (count % 10 == 0) {
629:                                getStandardOutput().writeEOL();
630:                            } else {
631:                                getStandardOutput().write(SPACE);
632:                            }
633:                        }
634:                    }
635:                    getStandardOutput().write(ARRAY_CLOSE);
636:                    getStandardOutput().writeEOL();
637:                    return null;
638:                } catch (IOException e) {
639:                    throw new COSVisitorException(e);
640:                }
641:            }
642:
643:            /**
644:             * visitFromBoolean method comment.
645:             *
646:             * @param obj The object that is being visited.
647:             *
648:             * @throws COSVisitorException If there is an exception while visiting this object.
649:             *
650:             * @return null
651:             */
652:            public Object visitFromBoolean(COSBoolean obj)
653:                    throws COSVisitorException {
654:
655:                try {
656:                    obj.writePDF(getStandardOutput());
657:                    return null;
658:                } catch (IOException e) {
659:                    throw new COSVisitorException(e);
660:                }
661:            }
662:
663:            /**
664:             * visitFromDictionary method comment.
665:             *
666:             * @param obj The object that is being visited.
667:             *
668:             * @throws COSVisitorException If there is an exception while visiting this object.
669:             *
670:             * @return null
671:             */
672:            public Object visitFromDictionary(COSDictionary obj)
673:                    throws COSVisitorException {
674:                try {
675:                    getStandardOutput().write(DICT_OPEN);
676:                    getStandardOutput().writeEOL();
677:                    for (Iterator i = obj.keyList().iterator(); i.hasNext();) {
678:                        COSName name = (COSName) i.next();
679:                        COSBase value = obj.getItem(name);
680:                        if (value != null) {
681:                            name.accept(this );
682:                            getStandardOutput().write(SPACE);
683:                            if (value instanceof  COSDictionary) {
684:                                addObjectToWrite(value);
685:                                writeReference(value);
686:                            } else if (value instanceof  COSObject) {
687:                                COSBase subValue = ((COSObject) value)
688:                                        .getObject();
689:                                if (subValue instanceof  COSDictionary
690:                                        || subValue == null) {
691:                                    addObjectToWrite(value);
692:                                    writeReference(value);
693:                                } else {
694:                                    subValue.accept(this );
695:                                }
696:                            } else {
697:                                value.accept(this );
698:                            }
699:                            getStandardOutput().writeEOL();
700:
701:                        } else {
702:                            //then we won't write anything, there are a couple cases
703:                            //were the value of an entry in the COSDictionary will
704:                            //be a dangling reference that points to nothing
705:                            //so we will just not write out the entry if that is the case
706:                        }
707:                    }
708:                    getStandardOutput().write(DICT_CLOSE);
709:                    getStandardOutput().writeEOL();
710:                    return null;
711:                } catch (IOException e) {
712:                    throw new COSVisitorException(e);
713:                }
714:            }
715:
716:            /**
717:             * The visit from document method.
718:             *
719:             * @param doc The object that is being visited.
720:             *
721:             * @throws COSVisitorException If there is an exception while visiting this object.
722:             *
723:             * @return null
724:             */
725:            public Object visitFromDocument(COSDocument doc)
726:                    throws COSVisitorException {
727:                try {
728:                    doWriteHeader(doc);
729:                    doWriteBody(doc);
730:                    doWriteXRef(doc);
731:                    doWriteTrailer(doc);
732:                    return null;
733:                } catch (IOException e) {
734:                    throw new COSVisitorException(e);
735:                }
736:            }
737:
738:            /**
739:             * visitFromFloat method comment.
740:             *
741:             * @param obj The object that is being visited.
742:             *
743:             * @throws COSVisitorException If there is an exception while visiting this object.
744:             *
745:             * @return null
746:             */
747:            public Object visitFromFloat(COSFloat obj)
748:                    throws COSVisitorException {
749:
750:                try {
751:                    obj.writePDF(getStandardOutput());
752:                    return null;
753:                } catch (IOException e) {
754:                    throw new COSVisitorException(e);
755:                }
756:            }
757:
758:            /**
759:             * visitFromFloat method comment.
760:             *
761:             * @param obj The object that is being visited.
762:             *
763:             * @throws COSVisitorException If there is an exception while visiting this object.
764:             *
765:             * @return null
766:             */
767:            public Object visitFromInt(COSInteger obj)
768:                    throws COSVisitorException {
769:                try {
770:                    obj.writePDF(getStandardOutput());
771:                    return null;
772:                } catch (IOException e) {
773:                    throw new COSVisitorException(e);
774:                }
775:            }
776:
777:            /**
778:             * visitFromName method comment.
779:             *
780:             * @param obj The object that is being visited.
781:             *
782:             * @throws COSVisitorException If there is an exception while visiting this object.
783:             *
784:             * @return null
785:             */
786:            public Object visitFromName(COSName obj) throws COSVisitorException {
787:                try {
788:                    obj.writePDF(getStandardOutput());
789:                    return null;
790:                } catch (IOException e) {
791:                    throw new COSVisitorException(e);
792:                }
793:            }
794:
795:            /**
796:             * visitFromNull method comment.
797:             *
798:             * @param obj The object that is being visited.
799:             *
800:             * @throws COSVisitorException If there is an exception while visiting this object.
801:             *
802:             * @return null
803:             */
804:            public Object visitFromNull(COSNull obj) throws COSVisitorException {
805:                try {
806:                    obj.writePDF(getStandardOutput());
807:                    return null;
808:                } catch (IOException e) {
809:                    throw new COSVisitorException(e);
810:                }
811:            }
812:
813:            /**
814:             * visitFromObjRef method comment.
815:             *
816:             * @param obj The object that is being visited.
817:             *
818:             * @throws COSVisitorException If there is an exception while visiting this object.
819:             */
820:            public void writeReference(COSBase obj) throws COSVisitorException {
821:                try {
822:                    COSObjectKey key = getObjectKey(obj);
823:                    getStandardOutput().write(
824:                            String.valueOf(key.getNumber()).getBytes());
825:                    getStandardOutput().write(SPACE);
826:                    getStandardOutput().write(
827:                            String.valueOf(key.getGeneration()).getBytes());
828:                    getStandardOutput().write(SPACE);
829:                    getStandardOutput().write(REFERENCE);
830:                } catch (IOException e) {
831:                    throw new COSVisitorException(e);
832:                }
833:            }
834:
835:            /**
836:             * visitFromStream method comment.
837:             *
838:             * @param obj The object that is being visited.
839:             *
840:             * @throws COSVisitorException If there is an exception while visiting this object.
841:             *
842:             * @return null
843:             */
844:            public Object visitFromStream(COSStream obj)
845:                    throws COSVisitorException {
846:                try {
847:                    if (willEncrypt) {
848:                        document.getSecurityHandler().decryptStream(obj,
849:                                currentObjectKey.getNumber(),
850:                                currentObjectKey.getGeneration());
851:                    }
852:
853:                    InputStream input = obj.getFilteredStream();
854:                    // set the length of the stream and write stream dictionary
855:                    COSObject lengthObject = new COSObject(null);
856:
857:                    obj.setItem(COSName.LENGTH, lengthObject);
858:                    //obj.accept(this);
859:                    // write the stream content
860:                    visitFromDictionary(obj);
861:                    getStandardOutput().write(STREAM);
862:                    getStandardOutput().writeCRLF();
863:                    byte[] buffer = new byte[1024];
864:                    int amountRead = 0;
865:                    int totalAmountWritten = 0;
866:                    while ((amountRead = input.read(buffer, 0, 1024)) != -1) {
867:                        getStandardOutput().write(buffer, 0, amountRead);
868:                        totalAmountWritten += amountRead;
869:                    }
870:                    lengthObject.setObject(new COSInteger(totalAmountWritten));
871:                    getStandardOutput().writeCRLF();
872:                    getStandardOutput().write(ENDSTREAM);
873:                    getStandardOutput().writeEOL();
874:                    return null;
875:                } catch (Exception e) {
876:                    throw new COSVisitorException(e);
877:                }
878:            }
879:
880:            /**
881:             * visitFromString method comment.
882:             *
883:             * @param obj The object that is being visited.
884:             *
885:             * @return null
886:             *
887:             * @throws COSVisitorException If there is an exception while visiting this object.
888:             */
889:            public Object visitFromString(COSString obj)
890:                    throws COSVisitorException {
891:                try {
892:                    if (willEncrypt) {
893:                        document.getSecurityHandler().decryptString(obj,
894:                                currentObjectKey.getNumber(),
895:                                currentObjectKey.getGeneration());
896:                    }
897:
898:                    obj.writePDF(getStandardOutput());
899:                } catch (Exception e) {
900:                    throw new COSVisitorException(e);
901:                }
902:                return null;
903:            }
904:
905:            /**
906:             * This will write the pdf document.
907:             *
908:             * @param doc The document to write.
909:             *
910:             * @throws COSVisitorException If an error occurs while generating the data.
911:             */
912:            public void write(COSDocument doc) throws COSVisitorException {
913:                PDDocument pdDoc = new PDDocument(doc);
914:                write(pdDoc);
915:            }
916:
917:            /**
918:             * This will write the pdf document.
919:             *
920:             * @param doc The document to write.
921:             *
922:             * @throws COSVisitorException If an error occurs while generating the data.
923:             */
924:            public void write(PDDocument doc) throws COSVisitorException {
925:                document = doc;
926:
927:                SecurityHandler securityHandler = document.getSecurityHandler();
928:                if (securityHandler != null) {
929:                    try {
930:                        securityHandler.prepareDocumentForEncryption(document);
931:                        this .willEncrypt = true;
932:                    } catch (IOException e) {
933:                        throw new COSVisitorException(e);
934:                    } catch (CryptographyException e) {
935:                        throw new COSVisitorException(e);
936:                    }
937:                } else {
938:                    this .willEncrypt = false;
939:                }
940:
941:                COSDocument cosDoc = document.getDocument();
942:                COSDictionary trailer = cosDoc.getTrailer();
943:                COSArray idArray = (COSArray) trailer.getDictionaryObject("ID");
944:                if (idArray == null) {
945:                    try {
946:
947:                        //algothim says to use time/path/size/values in doc to generate
948:                        //the id.  We don't have path or size, so do the best we can
949:                        MessageDigest md = MessageDigest.getInstance("MD5");
950:                        md.update(Long.toString(System.currentTimeMillis())
951:                                .getBytes());
952:                        COSDictionary info = (COSDictionary) trailer
953:                                .getDictionaryObject("Info");
954:                        if (info != null) {
955:                            Iterator values = info.getValues().iterator();
956:                            while (values.hasNext()) {
957:                                md.update(values.next().toString().getBytes());
958:                            }
959:                        }
960:                        idArray = new COSArray();
961:                        COSString id = new COSString(md.digest());
962:                        idArray.add(id);
963:                        idArray.add(id);
964:                        trailer.setItem("ID", idArray);
965:                    } catch (NoSuchAlgorithmException e) {
966:                        throw new COSVisitorException(e);
967:                    }
968:                }
969:
970:                /*
971:                List objects = doc.getObjects();
972:                Iterator iter = objects.iterator();
973:                long maxNumber = 0;
974:                while( iter.hasNext() )
975:                {
976:                    COSObject object = (COSObject)iter.next();
977:                    if( object.getObjectNumber() != null &&
978:                        object.getGenerationNumber() != null )
979:                    {
980:                        COSObjectKey key = new COSObjectKey( object.getObjectNumber().longValue(),
981:                                                             object.getGenerationNumber().longValue() );
982:                        objectKeys.put( object.getObject(), key );
983:                        objectKeys.put( object, key );
984:                        maxNumber = Math.max( key.getNumber(), maxNumber );
985:                        setNumber( maxNumber );
986:                    }
987:                }*/
988:                cosDoc.accept(this);
989:            }
990:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.