Source Code Cross Referenced for COSWriter.java in  » PDF » jPod » de » intarsys » pdf » writer » 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 » jPod » de.intarsys.pdf.writer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2007, intarsys consulting GmbH
003:         *
004:         * Redistribution and use in source and binary forms, with or without
005:         * modification, are permitted provided that the following conditions are met:
006:         *
007:         * - Redistributions of source code must retain the above copyright notice,
008:         *   this list of conditions and the following disclaimer.
009:         *
010:         * - 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:         *
014:         * - Neither the name of intarsys nor the names of its contributors may be used
015:         *   to endorse or promote products derived from this software without specific
016:         *   prior written permission.
017:         *
018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028:         * POSSIBILITY OF SUCH DAMAGE.
029:         */
030:        package de.intarsys.pdf.writer;
031:
032:        import java.io.IOException;
033:        import java.text.NumberFormat;
034:        import java.util.ArrayList;
035:        import java.util.Collection;
036:        import java.util.Iterator;
037:        import java.util.List;
038:        import java.util.Locale;
039:        import java.util.Map;
040:
041:        import de.intarsys.pdf.content.CSContent;
042:        import de.intarsys.pdf.content.CSOperation;
043:        import de.intarsys.pdf.cos.COSArray;
044:        import de.intarsys.pdf.cos.COSBoolean;
045:        import de.intarsys.pdf.cos.COSDictionary;
046:        import de.intarsys.pdf.cos.COSDocumentElement;
047:        import de.intarsys.pdf.cos.COSFixed;
048:        import de.intarsys.pdf.cos.COSIndirectObject;
049:        import de.intarsys.pdf.cos.COSInteger;
050:        import de.intarsys.pdf.cos.COSName;
051:        import de.intarsys.pdf.cos.COSNull;
052:        import de.intarsys.pdf.cos.COSObject;
053:        import de.intarsys.pdf.cos.COSObjectKey;
054:        import de.intarsys.pdf.cos.COSObjectProxy;
055:        import de.intarsys.pdf.cos.COSStream;
056:        import de.intarsys.pdf.cos.COSString;
057:        import de.intarsys.pdf.cos.COSVisitorException;
058:        import de.intarsys.pdf.cos.ICOSObjectVisitor;
059:        import de.intarsys.pdf.cos.ICOSProxyVisitor;
060:        import de.intarsys.pdf.crypt.COSSecurityException;
061:        import de.intarsys.pdf.crypt.ISystemSecurityHandler;
062:        import de.intarsys.pdf.parser.PDFParser;
063:        import de.intarsys.pdf.st.AbstractXRefWriter;
064:        import de.intarsys.pdf.st.STDocument;
065:        import de.intarsys.pdf.st.STXRefEntryOccupied;
066:        import de.intarsys.pdf.st.STXRefSection;
067:        import de.intarsys.tools.hex.HexTools;
068:        import de.intarsys.tools.randomaccess.IRandomAccess;
069:        import de.intarsys.tools.randomaccess.RandomAccessByteArray;
070:        import de.intarsys.tools.string.StringTools;
071:
072:        /**
073:         * A writer for PDF related data structures.
074:         */
075:        public class COSWriter implements  ICOSObjectVisitor, ICOSProxyVisitor {
076:            public static final byte[] ARRAY_CLOSE = "]".getBytes(); //$NON-NLS-1$
077:
078:            public static final byte[] ARRAY_OPEN = "[".getBytes(); //$NON-NLS-1$
079:
080:            public static final byte[] COMMENT = "%".getBytes(); //$NON-NLS-1$
081:
082:            /*
083:             * todo 1 @mit break up streams longer than allowed line (255 chars, pp67)
084:             */
085:
086:            /** To be used when 2 byte sequence is enforced. */
087:            public static final byte[] CRLF = "\r\n".getBytes(); //$NON-NLS-1$
088:
089:            public static final byte[] DICT_CLOSE = ">>".getBytes(); //$NON-NLS-1$
090:
091:            public static final byte[] DICT_OPEN = "<<".getBytes(); //$NON-NLS-1$
092:
093:            /** a fast lookup for serializing digits */
094:            protected static final char[] DIGITS = new char[] { '0', '1', '2',
095:                    '3', '4', '5', '6', '7', '8', '9', '9' };
096:
097:            public static final byte[] ENDOBJ = "endobj".getBytes(); //$NON-NLS-1$
098:
099:            public static final byte[] ENDSTREAM = "endstream".getBytes(); //$NON-NLS-1$
100:
101:            public static final byte[] EOF = "%%EOF".getBytes(); //$NON-NLS-1$
102:
103:            /** standard line separator on this platform */
104:            public static final byte[] EOL = System.getProperty(
105:                    "line.separator") //$NON-NLS-1$
106:                    .getBytes();
107:
108:            public static final byte[] FALSE = "false".getBytes(); //$NON-NLS-1$
109:
110:            public static final byte[] GARBAGE = "öäüß".getBytes(); //$NON-NLS-1$
111:
112:            /** Line feed character. */
113:            public static final byte[] LF = "\n".getBytes(); //$NON-NLS-1$
114:
115:            public static final byte[] LITERAL_ESCAPED_BS = "\\b".getBytes(); //$NON-NLS-1$
116:
117:            public static final byte[] LITERAL_ESCAPED_CR = "\\r".getBytes(); //$NON-NLS-1$
118:
119:            public static final byte[] LITERAL_ESCAPED_FF = "\\f".getBytes(); //$NON-NLS-1$
120:
121:            public static final byte[] LITERAL_ESCAPED_HT = "\\t".getBytes(); //$NON-NLS-1$
122:
123:            public static final byte[] LITERAL_ESCAPED_LF = "\\n".getBytes(); //$NON-NLS-1$
124:
125:            public static final byte[] NAME_ESCAPE = "#".getBytes(); //$NON-NLS-1$
126:
127:            public static final byte[] NAME_PREFIX = "/".getBytes(); //$NON-NLS-1$
128:
129:            public static final byte[] NULL = "null".getBytes(); //$NON-NLS-1$
130:
131:            public static final byte[] OBJ = "obj".getBytes(); //$NON-NLS-1$
132:
133:            public static final byte[] PDF_ESCAPE = "\\".getBytes(); //$NON-NLS-1$
134:
135:            public static final byte[] REFERENCE = "R".getBytes(); //$NON-NLS-1$
136:
137:            public static final byte[] SPACE = " ".getBytes(); //$NON-NLS-1$
138:
139:            public static final byte[] STREAM = "stream".getBytes(); //$NON-NLS-1$
140:
141:            public static final byte[] STRING_CLOSE = ")".getBytes(); //$NON-NLS-1$
142:
143:            public static final byte[] STRING_HEX_CLOSE = ">".getBytes(); //$NON-NLS-1$
144:
145:            public static final byte[] STRING_HEX_OPEN = "<".getBytes(); //$NON-NLS-1$
146:
147:            public static final byte[] STRING_OPEN = "(".getBytes(); //$NON-NLS-1$
148:
149:            public static final byte[] TRAILER = "trailer".getBytes(); //$NON-NLS-1$
150:
151:            public static final byte[] TRUE = "true".getBytes(); //$NON-NLS-1$
152:
153:            /*
154:             * (non-Javadoc)
155:             * 
156:             * @see de.intarsys.pdf.cos.COSObject#writeOn(java.io.OutputStream)
157:             */
158:            public static void basicWriteFixed(IRandomAccess randomAccess,
159:                    float value, int precision) throws IOException {
160:                NumberFormat format = NumberFormat
161:                        .getIntegerInstance(Locale.US);
162:                format.setMaximumFractionDigits(precision);
163:                format.setGroupingUsed(false);
164:                randomAccess.write(StringTools
165:                        .toByteArray(format.format(value)));
166:            }
167:
168:            /*
169:             * (non-Javadoc)
170:             * 
171:             * @see de.intarsys.pdf.cos.COSObject#writeOn(java.io.OutputStream)
172:             */
173:            public static void basicWriteInteger(IRandomAccess randomAccess,
174:                    int value) throws IOException {
175:                randomAccess.write(StringTools.toByteArray(Integer
176:                        .toString(value)));
177:            }
178:
179:            /**
180:             * create the byte stream for the representation of a name
181:             * 
182:             * @param randomAccess
183:             *            the randomAccessData to write to
184:             * @param name
185:             *            the names byte stream
186:             * 
187:             * @throws IOException
188:             */
189:            public static void basicWriteName(IRandomAccess randomAccess,
190:                    byte[] name) throws IOException {
191:                randomAccess.write(NAME_PREFIX);
192:                for (int i = 0; i < name.length; i++) {
193:                    int current = name[i] & 0xff; // convert to unsigned byte
194:                    if ((current <= 32) || (current >= 127)
195:                            || PDFParser.isDelimiter(current)
196:                            || (current == 35)) {
197:                        randomAccess.write(NAME_ESCAPE);
198:                        randomAccess.write(HexTools.ByteToHex[current]);
199:                    } else {
200:                        randomAccess.write(current);
201:                    }
202:                }
203:            }
204:
205:            /**
206:             * create a hex encoded byte stream representation of string
207:             * 
208:             * @param randomAccess
209:             *            the randomAccessData to write to
210:             * @param string
211:             *            the string to write
212:             * 
213:             * @throws IOException
214:             */
215:            public static void basicWriteStringHex(IRandomAccess randomAccess,
216:                    byte[] string) throws IOException {
217:                randomAccess.write(STRING_HEX_OPEN);
218:                for (int i = 0; i < string.length; i++) {
219:                    randomAccess.write(HexTools.ByteToHex[string[i] & 0xFF]);
220:                }
221:                randomAccess.write(STRING_HEX_CLOSE);
222:            }
223:
224:            /**
225:             * create the literal byte stream representation of string
226:             * 
227:             * @param randomAccess
228:             *            the randomAccessData to write to
229:             * @param string
230:             *            the string to write
231:             * 
232:             * @throws IOException
233:             */
234:            public static void basicWriteStringLiteral(
235:                    IRandomAccess randomAccess, byte[] string)
236:                    throws IOException {
237:                randomAccess.write(STRING_OPEN);
238:                for (int i = 0; i < string.length; i++) {
239:                    int b = string[i];
240:                    if (b == '\n') {
241:                        randomAccess.write(LITERAL_ESCAPED_LF);
242:                    } else if (b == '\r') {
243:                        randomAccess.write(LITERAL_ESCAPED_CR);
244:                    } else if (b == '\t') {
245:                        randomAccess.write(LITERAL_ESCAPED_HT);
246:                    } else if (b == '\f') {
247:                        randomAccess.write(LITERAL_ESCAPED_FF);
248:                    } else if (b == '\b') {
249:                        randomAccess.write(LITERAL_ESCAPED_BS);
250:                    } else if ((b == '(') || (b == ')') || (b == '\\')) {
251:                        randomAccess.write(PDF_ESCAPE);
252:                        randomAccess.write(b);
253:                    } else {
254:                        randomAccess.write(b);
255:                    }
256:                }
257:                randomAccess.write(STRING_CLOSE);
258:            }
259:
260:            /**
261:             * Create a byte array representation from a COSObject.
262:             * 
263:             * @param object
264:             *            The object to be serialized.
265:             * 
266:             * @return A byte array representation from a COSObject.
267:             */
268:            public static final byte[] toByteArray(COSObject object) {
269:                RandomAccessByteArray tempRandom = new RandomAccessByteArray(
270:                        null);
271:                COSWriter writer = new COSWriter(tempRandom, null);
272:                try {
273:                    writer.writeObject(object);
274:                } catch (IOException e) {
275:                    return "*** not printable ***".getBytes(); //$NON-NLS-1$
276:                }
277:                return tempRandom.toByteArray();
278:            }
279:
280:            private COSIndirectObject currentObject;
281:
282:            private ISystemSecurityHandler securityHandler;
283:
284:            private boolean incremental = true;
285:
286:            /** flag to prevent generating two newlines in sequence */
287:            private boolean onNewLine = false;
288:
289:            private List proxies = new ArrayList();
290:
291:            /**
292:             * The IRandomAccess we write to.
293:             */
294:            private IRandomAccess randomAccess;
295:
296:            public COSWriter(IRandomAccess randomAccess,
297:                    ISystemSecurityHandler securityHandler) {
298:                this .securityHandler = securityHandler;
299:                this .randomAccess = randomAccess;
300:            }
301:
302:            protected void basicWriteDocument(STDocument doc)
303:                    throws IOException {
304:                if (doc.isDirty()) {
305:                    doc.updateModificationDate();
306:                    doc.getTrailer().updateFileID();
307:                }
308:                if (doc.isNew()) {
309:                    // force complete write on new document
310:                    setIncremental(false);
311:                }
312:                synchronized (doc.getAccessLock()) {
313:                    if (!isIncremental()) {
314:                        doc.garbageCollect();
315:                        getRandomAccess().setLength(0);
316:                        writeHeader(doc);
317:                    } else {
318:                        doc.incrementalGarbageCollect();
319:                    }
320:                    Collection changes = doc.getChanges();
321:                    if (changes.size() > 0) {
322:                        seekToEnd();
323:                        STXRefSection xrefSection = doc.createNewXRefSection();
324:                        for (Iterator it = changes.iterator(); it.hasNext();) {
325:                            COSIndirectObject object = (COSIndirectObject) it
326:                                    .next();
327:                            writeEntry(xrefSection, object);
328:                            object.setDirty(false);
329:                        }
330:                        seekToEnd();
331:                        writeXRef(xrefSection);
332:                        writeEOF();
333:                        doc.setXRefSection(xrefSection);
334:                        doc.setDirty(false);
335:                    }
336:                }
337:            }
338:
339:            protected void close(STDocument doc) throws IOException {
340:                for (Iterator it = getProxies().iterator(); it.hasNext();) {
341:                    COSObjectProxy proxy = (COSObjectProxy) it.next();
342:                    proxy.ended(this );
343:                }
344:                getRandomAccess().flush();
345:                // todo 1 change dirty
346:            }
347:
348:            protected ISystemSecurityHandler getSecurityHandler() {
349:                return securityHandler;
350:            }
351:
352:            protected byte[] encryptString(byte[] bytes) throws IOException {
353:                if ((getSecurityHandler() != null)
354:                        && (getCurrentObject() != null)
355:                        && getCurrentObject().isEncryptOnWrite()) {
356:                    try {
357:                        return getSecurityHandler().encryptString(
358:                                getCurrentObject().getKey(), bytes);
359:                    } catch (COSSecurityException e) {
360:                        IOException ioe = new IOException(
361:                                "error encrypting data"); //$NON-NLS-1$
362:                        ioe.initCause(e);
363:                        throw ioe;
364:                    }
365:                }
366:                return bytes;
367:            }
368:
369:            protected byte[] encryptStream(COSDictionary dict, byte[] bytes)
370:                    throws IOException {
371:                if ((getSecurityHandler() != null)
372:                        && (getCurrentObject() != null)
373:                        && getCurrentObject().isEncryptOnWrite()) {
374:                    try {
375:                        return getSecurityHandler().encryptStream(
376:                                getCurrentObject().getKey(), dict, bytes);
377:                    } catch (COSSecurityException e) {
378:                        IOException ioe = new IOException(
379:                                "error encrypting data"); //$NON-NLS-1$
380:                        ioe.initCause(e);
381:                        throw ioe;
382:                    }
383:                }
384:                return bytes;
385:            }
386:
387:            protected COSIndirectObject getCurrentObject() {
388:                return currentObject;
389:            }
390:
391:            /**
392:             * The collection of proxies to COSObjects visited by the writer.
393:             * 
394:             * @return The collection of proxies to COSObjects visited by the writer.
395:             */
396:            public List getProxies() {
397:                return proxies;
398:            }
399:
400:            public IRandomAccess getRandomAccess() {
401:                return randomAccess;
402:            }
403:
404:            public boolean isIncremental() {
405:                return incremental;
406:            }
407:
408:            /**
409:             * This will tell if we are on a new line.
410:             * 
411:             * @return true If we are on a new line.
412:             */
413:            protected boolean isOnNewLine() {
414:                return onNewLine;
415:            }
416:
417:            protected void reset() {
418:                onNewLine = false;
419:            }
420:
421:            public void seekToEnd() throws IOException {
422:                randomAccess.seek(randomAccess.getLength());
423:                reset();
424:            }
425:
426:            protected void setCurrentObject(COSIndirectObject currentObject) {
427:                this .currentObject = currentObject;
428:            }
429:
430:            public void setIncremental(boolean incremental) {
431:                this .incremental = incremental;
432:            }
433:
434:            /**
435:             * visitFromArray.
436:             * 
437:             * @param obj
438:             *            The object that is being visited.
439:             * 
440:             * @return unused
441:             * 
442:             * @throws COSVisitorException
443:             *             If there is an exception while visiting this object.
444:             */
445:            public Object visitFromArray(COSArray obj)
446:                    throws COSVisitorException {
447:                try {
448:                    int count = 0;
449:                    write(ARRAY_OPEN);
450:                    for (Iterator i = obj.basicIterator(); i.hasNext();) {
451:                        COSDocumentElement current = (COSDocumentElement) i
452:                                .next();
453:                        current.accept(this );
454:                        count++;
455:                        if (i.hasNext()) {
456:                            if ((count % 10) == 0) {
457:                                writeEOL();
458:                            } else {
459:                                write(SPACE);
460:                            }
461:                        }
462:                    }
463:                    write(ARRAY_CLOSE);
464:                    writeEOL();
465:                } catch (IOException e) {
466:                    throw new COSVisitorException(e);
467:                }
468:                return null;
469:            }
470:
471:            /**
472:             * visitFromBoolean.
473:             * 
474:             * @param obj
475:             *            The object that is being visited.
476:             * 
477:             * @return unused
478:             * 
479:             * @throws COSVisitorException
480:             *             If there is an exception while visiting this object.
481:             */
482:            public Object visitFromBoolean(COSBoolean obj)
483:                    throws COSVisitorException {
484:                try {
485:                    if (obj.booleanValue()) {
486:                        write(TRUE);
487:                    } else {
488:                        write(FALSE);
489:                    }
490:                } catch (IOException e) {
491:                    throw new COSVisitorException(e);
492:                }
493:                return null;
494:            }
495:
496:            /**
497:             * visitFromDictionary.
498:             * 
499:             * @param obj
500:             *            The object that is being visited.
501:             * 
502:             * @return unused
503:             * 
504:             * @throws COSVisitorException
505:             *             If there is an exception while visiting this object.
506:             */
507:            public Object visitFromDictionary(COSDictionary obj)
508:                    throws COSVisitorException {
509:                try {
510:                    write(DICT_OPEN);
511:                    writeEOL();
512:                    for (Iterator i = obj.basicEntryIterator(); i.hasNext();) {
513:                        Map.Entry entry = (Map.Entry) i.next();
514:                        COSName name = (COSName) entry.getKey();
515:                        COSDocumentElement current = (COSDocumentElement) entry
516:                                .getValue();
517:                        if (current != null) {
518:                            // this is purely defensive, if entry is set to null instead
519:                            // of removed
520:                            basicWriteName(randomAccess, name.byteValue());
521:                            write(SPACE);
522:                            current.accept(this );
523:                            writeEOL();
524:                        }
525:                    }
526:                    write(DICT_CLOSE);
527:                    writeEOL();
528:                } catch (IOException e) {
529:                    throw new COSVisitorException(e);
530:                }
531:                return null;
532:            }
533:
534:            /**
535:             * visitFromFixed.
536:             * 
537:             * @param obj
538:             *            The object that is being visited.
539:             * 
540:             * @return unused
541:             * 
542:             * @throws COSVisitorException
543:             *             If there is an exception while visiting this object.
544:             */
545:            public Object visitFromFixed(COSFixed obj)
546:                    throws COSVisitorException {
547:                try {
548:                    basicWriteFixed(randomAccess, obj.floatValue(), obj
549:                            .getPrecision());
550:                    onNewLine = false;
551:                } catch (IOException e) {
552:                    throw new COSVisitorException(e);
553:                }
554:                return null;
555:            }
556:
557:            /**
558:             * This will write an indirect object reference
559:             * 
560:             * @param obj
561:             *            The indirect object to write.
562:             * @throws COSVisitorException
563:             *             If there is an exception while visiting this object.
564:             */
565:            public Object visitFromIndirectObject(COSIndirectObject obj)
566:                    throws COSVisitorException {
567:                reset();
568:                try {
569:                    COSObjectKey key = obj.getKey();
570:                    write(StringTools.toByteArray(Integer.toString(key
571:                            .getObjectNumber())));
572:                    write(SPACE);
573:                    write(StringTools.toByteArray(Integer.toString(key
574:                            .getGenerationNumber())));
575:                    write(SPACE);
576:                    write(REFERENCE);
577:                } catch (IOException e) {
578:                    throw new COSVisitorException(e);
579:                }
580:                return null;
581:            }
582:
583:            /**
584:             * visitFromInteger.
585:             * 
586:             * @param obj
587:             *            The object that is being visited.
588:             * 
589:             * @return unused
590:             * 
591:             * @throws COSVisitorException
592:             *             If there is an exception while visiting this object.
593:             */
594:            public Object visitFromInteger(COSInteger obj)
595:                    throws COSVisitorException {
596:                try {
597:                    basicWriteInteger(randomAccess, obj.intValue());
598:                    onNewLine = false;
599:                } catch (IOException e) {
600:                    throw new COSVisitorException(e);
601:                }
602:                return null;
603:            }
604:
605:            /**
606:             * visitFromName.
607:             * 
608:             * @param obj
609:             *            The object that is being visited.
610:             * 
611:             * @return unused
612:             * 
613:             * @throws COSVisitorException
614:             *             If there is an exception while visiting this object.
615:             */
616:            public Object visitFromName(COSName obj) throws COSVisitorException {
617:                try {
618:                    basicWriteName(randomAccess, obj.byteValue());
619:                    onNewLine = false;
620:                } catch (IOException e) {
621:                    throw new COSVisitorException(e);
622:                }
623:                return null;
624:            }
625:
626:            /**
627:             * visitFromNull.
628:             * 
629:             * @param obj
630:             *            The object that is being visited.
631:             * 
632:             * @return unused
633:             * 
634:             * @throws COSVisitorException
635:             *             If there is an exception while visiting this object.
636:             */
637:            public Object visitFromNull(COSNull obj) throws COSVisitorException {
638:                try {
639:                    write(NULL);
640:                } catch (IOException e) {
641:                    throw new COSVisitorException(e);
642:                }
643:                return null;
644:            }
645:
646:            protected void writeOperation(CSOperation obj)
647:                    throws COSVisitorException, IOException {
648:                if ((obj.getOperatorToken().length > 1)
649:                        && (obj.getOperatorToken()[0] == 'E')
650:                        && (obj.getOperatorToken()[1] == 'I')) {
651:                    COSString operand;
652:
653:                    // expect 1 COSString operand
654:                    operand = (COSString) obj.getOperand(0);
655:                    writeImageData(operand);
656:                } else {
657:                    for (Iterator i = obj.getOperands(); i.hasNext();) {
658:                        COSObject operand = (COSObject) i.next();
659:                        operand.accept(this );
660:                        write(' ');
661:                    }
662:                }
663:                write(obj.getOperatorToken());
664:            }
665:
666:            public Object visitFromProxy(COSObjectProxy obj)
667:                    throws COSVisitorException {
668:                try {
669:                    obj.setPosition(getRandomAccess().getOffset());
670:                    for (int i = 0; i < obj.getLength(); i++) {
671:                        write(' ');
672:                    }
673:                } catch (IOException e) {
674:                    throw new COSVisitorException(e);
675:                }
676:                proxies.add(obj);
677:                return null;
678:            }
679:
680:            /**
681:             * visitFromStream.
682:             * 
683:             * @param obj
684:             *            The object that is being visited.
685:             * 
686:             * @return unused
687:             * 
688:             * @throws COSVisitorException
689:             *             If there is an exception while visiting this object.
690:             */
691:            public Object visitFromStream(COSStream obj)
692:                    throws COSVisitorException {
693:                try {
694:                    byte[] bytes = new byte[0];
695:                    if (!obj.isExternal()) {
696:                        // only standard (internal) streams have a writable byte content
697:                        bytes = obj.getEncodedBytes();
698:                    }
699:                    // MUST encrypt before dict is written - length may be changed
700:                    byte[] encrypted = encryptStream(obj.getDict(), bytes);
701:                    // stream dictionaries are not indirect
702:                    obj.getDict().accept(this );
703:                    writeCRLF();
704:                    // write the stream content
705:                    writeStreamContent(encrypted);
706:                } catch (IOException e) {
707:                    throw new COSVisitorException(e);
708:                }
709:                return null;
710:            }
711:
712:            /**
713:             * visitFromString.
714:             * 
715:             * @param obj
716:             *            The object that is being visited.
717:             * 
718:             * @return unused
719:             * 
720:             * @throws COSVisitorException
721:             *             If there is an exception while visiting this object.
722:             */
723:            public Object visitFromString(COSString obj)
724:                    throws COSVisitorException {
725:                try {
726:                    byte[] bytes = obj.byteValue();
727:                    if (obj.isHexMode()) {
728:                        writeStringHex(encryptString(bytes));
729:                    } else {
730:                        writeStringLiteral(encryptString(bytes));
731:                    }
732:                    onNewLine = false;
733:                } catch (IOException e) {
734:                    throw new COSVisitorException(e);
735:                }
736:                return null;
737:            }
738:
739:            /**
740:             * This will write some byte to the stream.
741:             * 
742:             * @param b
743:             *            The source byte array.
744:             * 
745:             * @throws IOException
746:             *             If the underlying stream throws an exception.
747:             */
748:            public void write(byte[] b) throws IOException {
749:                onNewLine = false;
750:                randomAccess.write(b);
751:            }
752:
753:            /**
754:             * This will write some byte to the stream.
755:             * 
756:             * @param b
757:             *            The source byte array.
758:             * @param off
759:             *            The offset into the array to start writing.
760:             * @param len
761:             *            The number of bytes to write.
762:             * 
763:             * @throws IOException
764:             *             If the underlying stream throws an exception.
765:             */
766:            public void write(byte[] b, int off, int len) throws IOException {
767:                onNewLine = false;
768:                randomAccess.write(b, off, len);
769:            }
770:
771:            /**
772:             * This will write a single byte to the stream.
773:             * 
774:             * @param b
775:             *            The byte to write to the stream.
776:             * 
777:             * @throws IOException
778:             *             If there is an error writing to the underlying stream.
779:             */
780:            public void write(int b) throws IOException {
781:                onNewLine = false;
782:                randomAccess.write(b);
783:            }
784:
785:            public void writeContentStream(CSContent contentStream)
786:                    throws IOException {
787:                int len = contentStream.size();
788:                for (int i = 0; i < len; i++) {
789:                    CSOperation operation = contentStream.getOperation(i);
790:                    try {
791:                        writeOperation(operation);
792:                    } catch (COSVisitorException e) {
793:                        IOException ioe = new IOException(e.getMessage());
794:                        ioe.initCause(e);
795:                        throw ioe;
796:                    }
797:                    write(' ');
798:                }
799:            }
800:
801:            /**
802:             * This will write a CRLF to the stream
803:             * 
804:             * @throws IOException
805:             *             If there is an error writing the data to the stream.
806:             */
807:            protected void writeCRLF() throws IOException {
808:                randomAccess.write(CRLF);
809:            }
810:
811:            public void writeDocument(STDocument doc) throws IOException {
812:                basicWriteDocument(doc);
813:                close(doc);
814:            }
815:
816:            protected void writeEntry(STXRefSection xrefSection,
817:                    COSIndirectObject object) throws IOException {
818:                STXRefEntryOccupied entry = new STXRefEntryOccupied(object
819:                        .getKey(), getRandomAccess().getOffset());
820:                xrefSection.addEntry(entry);
821:                writeIndirectObject(object);
822:            }
823:
824:            protected void writeEOF() throws IOException {
825:                write(COSWriter.EOF);
826:                writeEOL();
827:            }
828:
829:            /**
830:             * This will write an EOL to the stream.
831:             * 
832:             * @throws IOException
833:             *             If there is an error writing to the stream
834:             */
835:            public void writeEOL() throws IOException {
836:                if (!isOnNewLine()) {
837:                    randomAccess.write(EOL);
838:                    onNewLine = true;
839:                }
840:            }
841:
842:            /**
843:             * This will write the header to the PDF document.
844:             * 
845:             * @throws IOException
846:             *             If there is an error writing to the stream.
847:             */
848:            protected void writeHeader(STDocument stdoc) throws IOException {
849:                write(COMMENT);
850:                write(stdoc.getVersion().getBytes());
851:                writeEOL();
852:                write(COMMENT);
853:                write(GARBAGE);
854:                writeEOL();
855:            }
856:
857:            protected void writeImageData(COSString imageData)
858:                    throws IOException {
859:                randomAccess.write(imageData.byteValue());
860:                randomAccess.write('\r');
861:            }
862:
863:            public void writeIndirectObject(COSIndirectObject object)
864:                    throws IOException {
865:                setCurrentObject(object);
866:                reset();
867:                COSObjectKey key = object.getKey();
868:                write(StringTools.toByteArray(Integer.toString(key
869:                        .getObjectNumber())));
870:                write(SPACE);
871:                write(StringTools.toByteArray(Integer.toString(key
872:                        .getGenerationNumber())));
873:                write(SPACE);
874:                write(OBJ);
875:                writeEOL();
876:                try {
877:                    object.dereference().accept(this );
878:                } catch (COSVisitorException e) {
879:                    Throwable cause = (e.getCause() == null) ? e : e.getCause();
880:                    IOException ioe = new IOException(cause.getMessage());
881:                    ioe.initCause(e);
882:                    throw ioe;
883:                }
884:                writeEOL();
885:                write(ENDOBJ);
886:                writeEOL();
887:                setCurrentObject(null);
888:            }
889:
890:            /**
891:             * This will write a cos object to the stream
892:             * 
893:             * @param object
894:             *            the object to write
895:             * 
896:             * @throws IOException
897:             *             If an error occurs while generating the data.
898:             */
899:            public void writeObject(COSObject object) throws IOException {
900:                try {
901:                    object.accept(this );
902:                } catch (COSVisitorException e) {
903:                    IOException ioe = new IOException(e.getMessage());
904:                    ioe.initCause(e);
905:                    throw ioe;
906:                }
907:            }
908:
909:            protected void writeStreamContent(byte[] bytes) throws IOException {
910:                write(STREAM);
911:                writeCRLF();
912:                if (bytes != null) {
913:                    write(bytes);
914:                }
915:                writeCRLF();
916:                write(ENDSTREAM);
917:                writeEOL();
918:            }
919:
920:            protected void writeStringHex(byte[] bytes) throws IOException {
921:                basicWriteStringHex(randomAccess, bytes);
922:            }
923:
924:            protected void writeStringLiteral(byte[] bytes) throws IOException {
925:                basicWriteStringLiteral(randomAccess, bytes);
926:            }
927:
928:            protected void writeXRef(STXRefSection xrefSection)
929:                    throws IOException {
930:                AbstractXRefWriter xrefWriter = xrefSection.getWriter(this);
931:                xrefWriter.writeXRef(xrefSection);
932:            }
933:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.