Source Code Cross Referenced for COSStream.java in  » PDF » jPod » de » intarsys » pdf » cos » 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.cos 
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.cos;
031:
032:        import java.io.File;
033:        import java.io.IOException;
034:        import java.util.Iterator;
035:        import java.util.Map;
036:
037:        import de.intarsys.pdf.filter.FilterFactory;
038:        import de.intarsys.pdf.filter.IFilter;
039:        import de.intarsys.tools.collection.SingleObjectIterator;
040:        import de.intarsys.tools.file.FileTools;
041:
042:        /**
043:         * An object representing stream data in a PDF document. Unlike a string, stream
044:         * data is not restricted in length. Stream data may be encoded with the filter
045:         * implementation.
046:         */
047:        public class COSStream extends COSCompositeObject {
048:            public static final Object SLOT_BYTES = new Object();
049:
050:            public static final COSName DK_DecodeParms = COSName
051:                    .constant("DecodeParms"); //$NON-NLS-1$
052:
053:            public static final COSName DK_DP = COSName.constant("DP"); //$NON-NLS-1$
054:
055:            public static final COSName DK_F = COSName.constant("F"); //$NON-NLS-1$
056:
057:            public static final COSName DK_FDecodeParams = COSName
058:                    .constant("FDecodeParams"); //$NON-NLS-1$
059:
060:            public static final COSName DK_FFilter = COSName
061:                    .constant("FFilter"); //$NON-NLS-1$
062:
063:            public static final COSName DK_Filter = COSName.constant("Filter"); //$NON-NLS-1$
064:
065:            public static final COSName DK_Length = COSName.constant("Length"); //$NON-NLS-1$
066:
067:            public static final COSName DK_Resources = COSName
068:                    .constant("Resources"); //$NON-NLS-1$
069:
070:            /**
071:             * Create a new {@link COSStream}.
072:             * 
073:             * @param dict
074:             *            An optional dictionary to be used as the streams dictionary.
075:             * @return Create a new {@link COSStream}.
076:             */
077:            public static COSStream create(COSDictionary dict) {
078:                COSStream result = new COSStream(dict);
079:                result.beIndirect();
080:                return result;
081:            }
082:
083:            /**
084:             * The options or an array of options for filtering.
085:             * 
086:             * @return The options or an array of options for filtering.
087:             */
088:            static public COSObject getDecodeParams(COSDictionary dict) {
089:                if (isExternal(dict)) {
090:                    return dict.get(DK_FDecodeParams);
091:                }
092:                COSObject result = dict.get(DK_DP);
093:                if (!result.isNull()) {
094:                    return result;
095:                }
096:                return dict.get(DK_DecodeParms);
097:            }
098:
099:            /**
100:             * The options corresponding to the first occurence of the filter
101:             * <code>name</code>.
102:             * 
103:             * @return The options corresponding to the first occurence of the filter
104:             *         <code>name</code>.
105:             */
106:            static public COSDictionary getDecodeParams(COSDictionary dict,
107:                    COSName name) {
108:                COSObject basicFilters = getFilters(dict);
109:                if (basicFilters instanceof  COSName) {
110:                    COSName filter = basicFilters.asName();
111:                    if (filter.equals(name)) {
112:                        return dict.get(COSStream.DK_DecodeParms)
113:                                .asDictionary();
114:                    }
115:                } else if (basicFilters instanceof  COSArray) {
116:                    COSArray filters = basicFilters.asArray();
117:                    int i = 0;
118:                    Iterator it = filters.iterator();
119:                    while (it.hasNext()) {
120:                        COSName filter = ((COSObject) it.next()).asName();
121:                        if (filter != null && filter.equals(name)) {
122:                            COSArray decodeParamsArray = dict.get(
123:                                    COSStream.DK_DecodeParms).asArray();
124:                            if (decodeParamsArray != null) {
125:                                return decodeParamsArray.get(i).asDictionary();
126:                            }
127:                        }
128:                        i++;
129:                    }
130:                }
131:                return null;
132:            }
133:
134:            /**
135:             * Return the filter or the collection of filters for the stream.
136:             * 
137:             * @return The filter or the collection of filters for the stream.
138:             */
139:            static public COSObject getFilters(COSDictionary dict) {
140:                if (isExternal(dict)) {
141:                    return dict.get(DK_FFilter);
142:                }
143:                COSObject result = dict.get(DK_F);
144:                if (!result.isNull()) {
145:                    return result;
146:                }
147:                return dict.get(DK_Filter);
148:            }
149:
150:            /**
151:             * <code>true</code> if the stream hs declared a filter <code>name</code>.
152:             * 
153:             * @param name
154:             *            The name of the filter.
155:             * @return <code>true</code> if the stream hs declared a filter
156:             *         <code>name</code>.
157:             */
158:            static public boolean hasFilter(COSDictionary dict, COSName name) {
159:                COSObject filters = getFilters(dict);
160:                if (filters.isNull()) {
161:                    return false;
162:                }
163:                if (filters instanceof  COSName) {
164:                    return filters.equals(name);
165:                }
166:                if (filters instanceof  COSArray) {
167:                    for (Iterator i = ((COSArray) filters).iterator(); i
168:                            .hasNext();) {
169:                        COSName filterName = ((COSObject) i.next()).asName();
170:                        if (filterName != null && filterName.equals(name)) {
171:                            return true;
172:                        }
173:                    }
174:                }
175:                return false;
176:            }
177:
178:            /**
179:             * <code>true</code> if the stream dictionary contains the F key.
180:             * 
181:             * @return <code>true</code> if the stream dictionary contains the F key.
182:             */
183:            static public boolean isExternal(COSDictionary dict) {
184:                // check for F key
185:                // if it is a Array or Name, it is used as an abbreviation for Filter
186:                COSObject result = dict.get(DK_F);
187:                if (!result.isNull()) {
188:                    if (result instanceof  COSName || result instanceof  COSArray) {
189:                        return false;
190:                    }
191:                    return true;
192:                }
193:                return false;
194:            }
195:
196:            /** The logical byte stream */
197:            private byte[] decodedBytes;
198:
199:            /** the dictionary describing the stream */
200:            private COSDictionary dict;
201:
202:            /** The physical byte stream */
203:            private byte[] encodedBytes;
204:
205:            /**
206:             * COSStream constructor.
207:             * 
208:             * @param newDict
209:             *            The stream dictionary for the new stream. Can be null, a new
210:             *            dictionary will be created.
211:             */
212:            protected COSStream(COSDictionary newDict) {
213:                super ();
214:                if (newDict == null) {
215:                    newDict = COSDictionary.create();
216:                }
217:                setDict(newDict);
218:            }
219:
220:            protected COSStream(COSStream stream) {
221:                super (stream);
222:                encodedBytes = stream.encodedBytes;
223:                decodedBytes = stream.decodedBytes;
224:                // if (stream.filteredBytes != null) {
225:                // encodedBytes = new byte[stream.filteredBytes.length];
226:                // System.arraycopy(stream.filteredBytes, 0, encodedBytes, 0,
227:                // encodedBytes.length);
228:                // }
229:                // if (stream.unfilteredBytes != null) {
230:                // decodedBytes = new byte[stream.unfilteredBytes.length];
231:                // System.arraycopy(stream.unfilteredBytes, 0, decodedBytes, 0,
232:                // decodedBytes.length);
233:                // }
234:            }
235:
236:            /*
237:             * (non-Javadoc)
238:             * 
239:             * @see de.intarsys.pdf.cos.COSObject#accept(de.intarsys.pdf.cos.ICOSObjectVisitor)
240:             */
241:            public java.lang.Object accept(ICOSObjectVisitor visitor)
242:                    throws COSVisitorException {
243:                return visitor.visitFromStream(this );
244:            }
245:
246:            /**
247:             * Add a new filter to this.
248:             * 
249:             * @param name
250:             *            The logical naem of the filter.
251:             */
252:            public void addFilter(COSName name) {
253:                // be sure decoded stream is available
254:                getDecodedBytes();
255:                encodedBytes = null;
256:                COSArray result;
257:                COSObject filters = getFilters();
258:                if (filters.isNull()) {
259:                    result = COSArray.create();
260:                    result.add(name);
261:                    getDict().put(DK_Filter, result);
262:                } else if (filters instanceof  COSName) {
263:                    result = COSArray.create(2);
264:                    getDict().put(DK_Filter, result);
265:                    result.add(filters);
266:                    result.add(name);
267:                } else {
268:                    result = (COSArray) filters;
269:                    result.add(name);
270:                }
271:            }
272:
273:            /*
274:             * (non-Javadoc)
275:             * 
276:             * @see de.intarsys.pdf.cos.COSCompositeObject#addObjectListener(de.intarsys.pdf.cos.ICOSObjectListener)
277:             */
278:            public void addObjectListener(ICOSObjectListener listener) {
279:                super .addObjectListener(listener);
280:                if (dict != null) {
281:                    dict.addObjectListener(listener);
282:                }
283:            }
284:
285:            /*
286:             * (non-Javadoc)
287:             * 
288:             * @see de.intarsys.pdf.cos.COSObject#asStream()
289:             */
290:            public COSStream asStream() {
291:                return this ;
292:            }
293:
294:            /*
295:             * (non-Javadoc)
296:             * 
297:             * @see de.intarsys.pdf.cos.COSObject#basicIterator()
298:             */
299:            public Iterator basicIterator() {
300:                return new SingleObjectIterator(getDict());
301:            }
302:
303:            /**
304:             * Set the streams logical content.
305:             * 
306:             * @param newBytes
307:             *            the logical content for the stream
308:             */
309:            public void basicSetDecodedBytes(byte[] newBytes) {
310:                decodedBytes = newBytes;
311:                encodedBytes = null;
312:            }
313:
314:            /**
315:             * Set the streams physical content.
316:             * 
317:             * @param newBytes
318:             *            the physical content for the stream
319:             */
320:            public void basicSetEncodedBytes(byte[] newBytes) {
321:                encodedBytes = newBytes;
322:                decodedBytes = null;
323:            }
324:
325:            /*
326:             * (non-Javadoc)
327:             * 
328:             * @see de.intarsys.pdf.cos.COSObject#basicToString()
329:             */
330:            protected String basicToString() {
331:                return "stream"; //$NON-NLS-1$
332:            }
333:
334:            /*
335:             * (non-Javadoc)
336:             * 
337:             * @see de.intarsys.pdf.cos.COSObject#copyBasic()
338:             */
339:            protected COSObject copyBasic() {
340:                return create(null);
341:            }
342:
343:            /**
344:             * A copy of this, bytes decoded.
345:             * 
346:             * @return A copy of this, bytes decoded.
347:             * @throws IOException
348:             */
349:            public COSStream copyDecodeFirst() throws IOException {
350:                COSStream newStream;
351:                COSName filter;
352:                byte[] bytes;
353:
354:                // prepare new stream
355:                newStream = (COSStream) copyShallow();
356:                if (getFilters().isNull()) {
357:                    return newStream;
358:                }
359:                newStream.basicSetDecodedBytes(null);
360:                newStream.getDict().remove(DK_Filter);
361:                newStream.getDict().remove(DK_Length);
362:                // prepare content
363:                bytes = getEncodedBytes();
364:                if ((filter = getFirstFilter()) != null) {
365:                    bytes = doDecode(filter, getFirstDecodeParam(), bytes, 0,
366:                            getAnyLength());
367:                }
368:                if (getFilters() instanceof  COSArray) {
369:                    for (int index = ((COSArray) getFilters()).size() - 1; index > 0; index--) {
370:                        newStream.addFilter((COSName) ((COSArray) getFilters())
371:                                .get(index).copyShallow());
372:                    }
373:                }
374:                newStream.setEncodedBytes(bytes);
375:                return newStream;
376:            }
377:
378:            /*
379:             * (non-Javadoc)
380:             * 
381:             * @see de.intarsys.pdf.cos.COSCompositeObject#copyDeep(java.util.Map)
382:             */
383:            public COSObject copyDeep(Map copied) {
384:                COSStream result = (COSStream) super .copyDeep(copied);
385:                result.setDict((COSDictionary) getDict().copyDeep(copied));
386:                if (encodedBytes != null) {
387:                    result.setEncodedBytes(encodedBytes);
388:                } else {
389:                    result.setDecodedBytes(decodedBytes);
390:                }
391:                return result;
392:            }
393:
394:            /*
395:             * (non-Javadoc)
396:             * 
397:             * @see de.intarsys.pdf.cos.COSObject#copyShallow()
398:             */
399:            public COSObject copyShallow() {
400:                COSStream result = (COSStream) super .copyShallow();
401:                result.setDict((COSDictionary) getDict().copyShallow());
402:                if (encodedBytes != null) {
403:                    result.setEncodedBytes(encodedBytes);
404:                } else {
405:                    result.setDecodedBytes(decodedBytes);
406:                }
407:                return result;
408:            }
409:
410:            /*
411:             * (non-Javadoc)
412:             * 
413:             * @see de.intarsys.pdf.cos.COSObject#copySubGraph(java.util.Map)
414:             */
415:            protected COSObject copySubGraph(Map copied) {
416:                COSStream result = (COSStream) super .copySubGraph(copied);
417:                result.setDict((COSDictionary) getDict().copySubGraph(copied));
418:                if (encodedBytes != null) {
419:                    result.setEncodedBytes(encodedBytes);
420:                } else {
421:                    result.setDecodedBytes(decodedBytes);
422:                }
423:                return result;
424:            }
425:
426:            /**
427:             * Decode the filtered stream content using the filters defined in the
428:             * /Filter entry in the stream dictionary
429:             * 
430:             * @return The decoded bytes.
431:             * @throws IOException
432:             */
433:            protected byte[] doDecode() throws IOException {
434:                byte[] newBytes;
435:
436:                if (isExternal() && isBytesArrayEmpty(encodedBytes)) {
437:                    // reset the encodedbytes because of later null checks
438:                    encodedBytes = null;
439:                    parseFKeyedFile();
440:                }
441:                if (encodedBytes == null) {
442:                    return null;
443:                }
444:
445:                // get the filters
446:                COSObject filters = getFilters();
447:                if (filters.isNull()) {
448:                    int length = getLength();
449:                    if ((length != -1) && (encodedBytes.length > length)) {
450:                        newBytes = new byte[length];
451:                        System.arraycopy(encodedBytes, 0, newBytes, 0, length);
452:                    } else {
453:                        newBytes = encodedBytes;
454:                    }
455:                    return newBytes;
456:                }
457:
458:                // get the options
459:                COSObject options = getDecodeParams();
460:
461:                // decode
462:                if (filters instanceof  COSName) {
463:                    newBytes = doDecode((COSName) filters, options
464:                            .asDictionary(), encodedBytes, 0, getAnyLength());
465:                } else {
466:                    byte[] temp = encodedBytes;
467:                    int length = getAnyLength();
468:                    for (int i = 0; i < ((COSArray) filters).size(); i++) {
469:                        COSObject option = COSNull.NULL;
470:                        if (!options.isNull()) {
471:                            option = ((COSArray) options).get(i);
472:                        }
473:                        COSName filter = ((COSArray) filters).get(i).asName();
474:                        temp = doDecode(filter, option.asDictionary(), temp, 0,
475:                                length);
476:                        if (temp != null) {
477:                            length = temp.length;
478:                        }
479:                    }
480:                    newBytes = temp;
481:                }
482:                return newBytes;
483:            }
484:
485:            /**
486:             * Perform the decoding process of the underlying byte stream.
487:             * 
488:             * @param filterName
489:             *            The name of a filter to use for this step.
490:             * @param options
491:             *            The options to use for the filter.
492:             * @param bytes
493:             *            The bytes to decode.
494:             * @param offset
495:             *            The offset to start.
496:             * @param length
497:             *            The length to be decoded.
498:             * 
499:             * @return The decoded bytes.
500:             * 
501:             * @throws IOException
502:             */
503:            protected byte[] doDecode(COSName filterName,
504:                    COSDictionary options, byte[] bytes, int offset, int length)
505:                    throws IOException {
506:                if (bytes == null) {
507:                    return new byte[0];
508:                }
509:                IFilter filter = FilterFactory.get().createFilter(filterName,
510:                        options);
511:                filter.setStream(this );
512:                return filter.decode(bytes, offset, length);
513:            }
514:
515:            /**
516:             * encode the filtered stream content using the filters defined in the
517:             * /Filter entry in the stream dictionary in reverse order
518:             * 
519:             * @throws IOException
520:             */
521:            protected void doEncode() throws IOException {
522:                if (decodedBytes == null) {
523:                    return;
524:                }
525:
526:                // get the filters
527:                COSObject filters = getFilters();
528:                if (filters.isNull()) {
529:                    encodedBytes = decodedBytes;
530:                    return;
531:                }
532:
533:                // get the options
534:                COSObject options = getDecodeParams();
535:
536:                // encode
537:                if (filters instanceof  COSName) {
538:                    encodedBytes = doEncode((COSName) filters, options
539:                            .asDictionary(), decodedBytes, 0,
540:                            decodedBytes.length);
541:                } else {
542:                    byte[] temp = decodedBytes;
543:                    int length = decodedBytes.length;
544:                    for (int i = ((COSArray) filters).size() - 1; i >= 0; i--) {
545:                        COSDictionary option = null;
546:                        if (!options.isNull()) {
547:                            option = ((COSArray) options).get(i).asDictionary();
548:                        }
549:
550:                        COSName filter = ((COSArray) filters).get(i).asName();
551:                        temp = doEncode(filter, option, temp, 0, length);
552:                        length = temp.length;
553:                    }
554:                    encodedBytes = temp;
555:                }
556:            }
557:
558:            /**
559:             * Perform the encoding process of the underlying byte stream.
560:             * 
561:             * @param filterName
562:             *            The name of a filter to use for this step.
563:             * @param options
564:             *            The options to use for the filter.
565:             * @param bytes
566:             *            The bytes to encode .
567:             * @param offset
568:             *            The offset to start.
569:             * @param length
570:             *            The length to be encoded.
571:             * 
572:             * @return The encoded bytes.
573:             * 
574:             * @throws IOException
575:             */
576:            protected byte[] doEncode(COSName filterName,
577:                    COSDictionary options, byte[] bytes, int offset, int length)
578:                    throws IOException {
579:                if (bytes == null) {
580:                    return new byte[0];
581:                }
582:                IFilter filter = FilterFactory.get().createFilter(filterName,
583:                        options);
584:                filter.setStream(this );
585:                return filter.encode(bytes, offset, length);
586:            }
587:
588:            /**
589:             * The declared or real length for this.
590:             * 
591:             * @return The declared or real length for this.
592:             */
593:            public int getAnyLength() {
594:                int result = getLength();
595:                if (result == -1) {
596:                    return encodedBytes.length;
597:                }
598:                return result;
599:            }
600:
601:            /**
602:             * The unfiltered (logical) stream content. It is not intended to manipulate
603:             * the byte array directly.
604:             * 
605:             * @return The unfiltered (logical) stream content
606:             * 
607:             * @throws IOException
608:             */
609:            public byte[] getDecodedBytes() {
610:                if (decodedBytes == null) {
611:                    try {
612:                        decodedBytes = doDecode();
613:                    } catch (IOException e) {
614:                        handleException(new COSRuntimeException(
615:                                "error decoding stream", e)); //$NON-NLS-1$
616:                    }
617:                }
618:                return decodedBytes;
619:            }
620:
621:            /**
622:             * The unfiltered content as in getDecodedBytes, but allow the caller to
623:             * manipulate the result by copying/not caching the returned bytes
624:             * 
625:             * @return The unfiltered content as in getDecodedBytes
626:             */
627:            public byte[] getDecodedBytesWritable() {
628:                byte[] bytes;
629:                byte[] copiedBytes;
630:
631:                if (decodedBytes != null) {
632:                    bytes = decodedBytes;
633:                }
634:                try {
635:                    bytes = doDecode();
636:                    // take care; doDecode does not always create a new array
637:                    if (bytes != encodedBytes) {
638:                        return bytes;
639:                    }
640:                } catch (IOException e) {
641:                    handleException(new COSRuntimeException(
642:                            "error decoding stream", e)); //$NON-NLS-1$
643:                    return new byte[0];
644:                }
645:                copiedBytes = new byte[bytes.length];
646:                System.arraycopy(bytes, 0, copiedBytes, 0, bytes.length);
647:                return copiedBytes;
648:            }
649:
650:            /**
651:             * The options or an array of options for filtering.
652:             * 
653:             * @return The options or an array of options for filtering.
654:             */
655:            public COSObject getDecodeParams() {
656:                return getDecodeParams(getDict());
657:            }
658:
659:            /**
660:             * The options corresponding to the first occurence of the filter
661:             * <code>name</code>.
662:             * 
663:             * @return The options corresponding to the first occurence of the filter
664:             *         <code>name</code>.
665:             */
666:            public COSObject getDecodeParams(COSName name) {
667:                return getDecodeParams(getDict(), name);
668:            }
669:
670:            /**
671:             * The stream dictionary
672:             * 
673:             * @return The stream dictionary
674:             */
675:            public COSDictionary getDict() {
676:                return dict;
677:            }
678:
679:            /**
680:             * The filtered (physical) stream content. If it must be generated first,
681:             * then the content length is adjusted as a side effect. It is not intended
682:             * to manipulate the byte array directly.
683:             * 
684:             * @return The filtered (physical) stream content
685:             */
686:            public byte[] getEncodedBytes() {
687:                if (encodedBytes == null) {
688:                    try {
689:                        doEncode();
690:                    } catch (IOException e) {
691:                        handleException(new COSRuntimeException(
692:                                "error encoding stream", e)); //$NON-NLS-1$
693:                    }
694:                    int length = (encodedBytes == null) ? 0
695:                            : encodedBytes.length;
696:                    getDict().basicPutSilent(DK_Length,
697:                            COSInteger.create(length));
698:                }
699:                return encodedBytes;
700:            }
701:
702:            /**
703:             * Return the filter or the collection of filters for the stream.
704:             * 
705:             * @return The filter or the collection of filters for the stream.
706:             */
707:            public COSObject getFilters() {
708:                return getFilters(getDict());
709:            }
710:
711:            /**
712:             * A dictionary with filter options or the first element of an array of such
713:             * dictionaries for each filter.
714:             * 
715:             * @return A dictionary with filter options or the first element of an array
716:             *         of such dictionaries for each filter.
717:             */
718:            public COSDictionary getFirstDecodeParam() {
719:                COSObject dictionaryOrArray;
720:
721:                dictionaryOrArray = getDecodeParams();
722:                if (dictionaryOrArray.isNull()) {
723:                    return null;
724:                }
725:                if (dictionaryOrArray instanceof  COSDictionary) {
726:                    return (COSDictionary) dictionaryOrArray;
727:                }
728:                if (dictionaryOrArray instanceof  COSArray) {
729:                    return ((COSArray) dictionaryOrArray).get(0).asDictionary();
730:                }
731:                return null;
732:            }
733:
734:            /**
735:             * The filter or the first element of the collection of filters for the
736:             * stream.
737:             * 
738:             * @return The filter or the first element of the collection of filters for
739:             *         the stream.
740:             */
741:            public COSName getFirstFilter() {
742:                COSObject nameOrArray;
743:
744:                nameOrArray = getFilters();
745:                if (nameOrArray.isNull()) {
746:                    return null;
747:                }
748:                if (nameOrArray instanceof  COSName) {
749:                    return (COSName) nameOrArray;
750:                }
751:                if (nameOrArray instanceof  COSArray) {
752:                    return ((COSArray) nameOrArray).get(0).asName();
753:                }
754:                return null;
755:            }
756:
757:            /**
758:             * The length of the filtered content
759:             * 
760:             * @return The length of the filtered content
761:             */
762:            public int getLength() {
763:                COSNumber length = dict.get(DK_Length).asInteger();
764:                if (length != null) {
765:                    return length.intValue();
766:                }
767:                return -1;
768:            }
769:
770:            /**
771:             * <code>true</code> if the stream hs declared a filter <code>name</code>.
772:             * 
773:             * @param name
774:             *            The name of the filter.
775:             * @return <code>true</code> if the stream hs declared a filter
776:             *         <code>name</code>.
777:             */
778:            public boolean hasFilter(COSName name) {
779:                return hasFilter(getDict(), name);
780:            }
781:
782:            /**
783:             * tests a byte array for null, length=0 or crlf emptiness
784:             * 
785:             * @param toTest
786:             * @return
787:             */
788:            private boolean isBytesArrayEmpty(byte[] toTest) {
789:                if ((toTest == null) || (toTest.length == 0)) {
790:                    return true;
791:                }
792:                if ((toTest.length == 2) && (toTest[0] == 13)
793:                        && (toTest[1] == 10)) {
794:                    return true;
795:                }
796:                return false;
797:            }
798:
799:            /**
800:             * <code>true</code> if the stream dictionary contains the F key.
801:             * 
802:             * @return <code>true</code> if the stream dictionary contains the F key.
803:             */
804:            public boolean isExternal() {
805:                return isExternal(getDict());
806:            }
807:
808:            /*
809:             * (non-Javadoc)
810:             * 
811:             * @see de.intarsys.pdf.cos.COSObject#iterator()
812:             */
813:            public Iterator iterator() {
814:                return new SingleObjectIterator(getDict());
815:            }
816:
817:            /**
818:             * Parse the file referenced by the F key in this stream and set as the
819:             * filtered content.
820:             */
821:            protected void parseFKeyedFile() {
822:                COSObject fileSpec = dict.get(DK_F);
823:                String filepath = ""; //$NON-NLS-1$
824:                if (fileSpec instanceof  COSString) {
825:                    filepath = ((COSString) fileSpec).stringValue();
826:                } else {
827:                    // todo 2 implement PDF fileSpecification logic
828:                    return;
829:                }
830:                File externalFile = new File(filepath);
831:                if (!externalFile.exists()) {
832:                    return;
833:                }
834:                byte[] content;
835:                try {
836:                    content = FileTools.toBytes(externalFile);
837:                } catch (IOException e) {
838:                    return;
839:                }
840:                if (content != null) {
841:                    encodedBytes = content;
842:                }
843:            }
844:
845:            /**
846:             * Remove all filters from this.
847:             */
848:            public void removeFilters() {
849:                // be sure decoded stream is available
850:                getDecodedBytes();
851:                encodedBytes = null;
852:                getDict().remove(DK_Filter);
853:            }
854:
855:            /*
856:             * (non-Javadoc)
857:             * 
858:             * @see de.intarsys.pdf.cos.COSCompositeObject#removeObjectListener(de.intarsys.pdf.cos.ICOSObjectListener)
859:             */
860:            public void removeObjectListener(ICOSObjectListener listener) {
861:                super .removeObjectListener(listener);
862:                if (dict != null) {
863:                    dict.removeObjectListener(listener);
864:                }
865:            }
866:
867:            /*
868:             * (non-Javadoc)
869:             * 
870:             * @see de.intarsys.pdf.cos.COSObject#restoreState(java.lang.Object)
871:             */
872:            public void restoreState(Object object) {
873:                super .restoreState(object);
874:                COSStream stream = (COSStream) object;
875:                encodedBytes = stream.encodedBytes;
876:                decodedBytes = stream.decodedBytes;
877:                triggerChanged(null, null, null);
878:            }
879:
880:            /*
881:             * (non-Javadoc)
882:             * 
883:             * @see de.intarsys.tools.objectsession.ISaveStateSupport#saveState()
884:             */
885:            public Object saveState() {
886:                return new COSStream(this );
887:            }
888:
889:            /**
890:             * Set the streams logical content
891:             * 
892:             * @param newBytes
893:             *            The logical content for the stream
894:             */
895:            public void setDecodedBytes(byte[] newBytes) {
896:                willChange(this );
897:                basicSetDecodedBytes(newBytes);
898:                clearLength();
899:                if (objectListeners != null) {
900:                    triggerChanged(SLOT_BYTES, null, null);
901:                }
902:            }
903:
904:            /**
905:             * Give private access to dictionary to ease copying.
906:             * 
907:             * @param dictionary
908:             *            dictionary part of the stream
909:             * 
910:             * @throws IllegalArgumentException
911:             *             if the stream is indirect
912:             */
913:            private void setDict(COSDictionary dictionary) {
914:                if (dictionary.isIndirect()) {
915:                    throw new IllegalArgumentException(
916:                            "stream dictionary cannot be indirect"); //$NON-NLS-1$
917:                }
918:                dict = dictionary;
919:                dict.addContainer(this );
920:            }
921:
922:            /**
923:             * Set the stream physical content.
924:             * 
925:             * @param newBytes
926:             *            the physical content for the stream
927:             */
928:            public void setEncodedBytes(byte[] newBytes) {
929:                willChange(this );
930:                basicSetEncodedBytes(newBytes);
931:                int length = (encodedBytes == null) ? 0 : encodedBytes.length;
932:                getDict().basicPutSilent(DK_Length, COSInteger.create(length));
933:                if (objectListeners != null) {
934:                    triggerChanged(SLOT_BYTES, null, null);
935:                }
936:            }
937:
938:            /**
939:             * Clear length
940:             * 
941:             */
942:            private void clearLength() {
943:                getDict().remove(DK_Length);
944:            }
945:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.