Source Code Cross Referenced for IndirectObjects.java in  » PDF » PDFClown-0.0.5 » it » stefanochizzolini » clown » files » 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 » PDFClown 0.0.5 » it.stefanochizzolini.clown.files 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          Copyright © 2006,2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004:          Contributors:
005:         * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006:              contributed code is Copyright © 2006,2007 by Stefano Chizzolini.
007:
008:          This file should be part of the source code distribution of "PDF Clown library"
009:          (the Program): see the accompanying README files for more info.
010:
011:          This Program is free software; you can redistribute it and/or modify it under
012:          the terms of the GNU General Public License as published by the Free Software
013:          Foundation; either version 2 of the License, or (at your option) any later version.
014:
015:          This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016:          WARRANTY, either expressed or implied; without even the implied warranty of
017:          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019:          You should have received a copy of the GNU General Public License along with this
020:          Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022:          Redistribution and use, with or without modification, are permitted provided that such
023:          redistributions retain the above copyright notice, license and disclaimer, along with
024:          this list of conditions.
025:         */
026:
027:        package it.stefanochizzolini.clown.files;
028:
029:        import it.stefanochizzolini.clown.objects.PdfDataObject;
030:        import it.stefanochizzolini.clown.objects.PdfIndirectObject;
031:        import it.stefanochizzolini.clown.tokens.XRefEntry;
032:        import it.stefanochizzolini.clown.tokens.XRefEntryUsageEnum;
033:        import it.stefanochizzolini.clown.util.NotImplementedException;
034:
035:        import java.util.ArrayList;
036:        import java.util.Collection;
037:        import java.util.Hashtable;
038:        import java.util.Iterator;
039:        import java.util.List;
040:        import java.util.ListIterator;
041:        import java.util.NoSuchElementException;
042:        import java.util.TreeMap;
043:
044:        /**
045:         Collection of the <b>alive indirect objects</b> available inside the file.
046:         <h3>Remarks</h3>
047:         <p>According to the PDF spec, <i>indirect object entries may be free
048:         (no data object associated) or in-use (data object associated)</i>.</p>
049:         <p>We can effectively subdivide indirect objects in two possibly-overriding
050:         collections: the <b>original indirect objects</b> (coming from the associated
051:         preexisting file) and the <b>newly-registered indirect objects</b> (coming
052:         from new data objects or original indirect objects manipulated during the
053:         current session).</p>
054:         <p><i>To ensure that the modifications applied to an original indirect object
055:         are committed to being persistent</i> is critical that the modified original
056:         indirect object is newly-registered (practically overriding the original
057:         indirect object).</p>
058:         <p><b>Alive indirect objects</b> encompass all the newly-registered ones plus
059:         not-overridden original ones.</p>
060:         @version 0.0.5
061:         @since 0.0.0
062:         */
063:        public class IndirectObjects implements  List<PdfIndirectObject> {
064:            // <class>
065:            // <dynamic>
066:            // <fields>
067:            /**
068:              Associated file.
069:             */
070:            private File file;
071:
072:            /**
073:              Map of matching references of imported indirect objects.
074:              <h3>Remarks</h3>
075:              <p>This collection is used to prevent duplications among imported indirect
076:              objects.</p>
077:              <p><code>Key</code> is the external indirect object hashcode, <code>Value</code> is the
078:              matching internal indirect object.</p>
079:             */
080:            private Hashtable<Integer, PdfIndirectObject> importedObjects = new Hashtable<Integer, PdfIndirectObject>();
081:            /**
082:              Collection of newly-registered indirect objects.
083:             */
084:            private TreeMap<Integer, PdfIndirectObject> modifiedObjects = new TreeMap<Integer, PdfIndirectObject>();
085:            /**
086:              Collection of instantiated original indirect objects.
087:              <h3>Remarks</h3>
088:              <p>This collection is useful as a cache to avoid unconsistent parsing duplications.</p>
089:             */
090:            private TreeMap<Integer, PdfIndirectObject> wokenObjects = new TreeMap<Integer, PdfIndirectObject>();
091:
092:            /**
093:              Object counter.
094:             */
095:            private int lastObjectNumber = -1; // Empty.
096:            /**
097:              Offsets of the original indirect objects inside the associated file (to say:
098:              implicit collection of the original indirect objects).
099:              <h3>Remarks
100:              <p>This information is vital to randomly retrieve the indirect-object persistent
101:              representation inside the associated file.</p>
102:             */
103:            private XRefEntry[] xrefEntries;
104:
105:            private UpdateModeEnum updateMode = UpdateModeEnum.Manual;
106:
107:            // </fields>
108:
109:            // <constructors>
110:            IndirectObjects(File file, XRefEntry[] xrefEntries) {
111:                this .file = file;
112:                this .xrefEntries = xrefEntries;
113:                // Are there original indirect objects?
114:                if (this .xrefEntries == null) {
115:                    /*
116:                    [PDF:1.6:3.4.3] Mandatory head of the linked list of free objects
117:                    at object number 0.
118:                     */
119:                    // Register the leading free-object!
120:                    lastObjectNumber++;
121:                    modifiedObjects.put(lastObjectNumber,
122:                            new PdfIndirectObject(this .file, null,
123:                                    new XRefEntry(lastObjectNumber, 65535, 0,
124:                                            XRefEntryUsageEnum.Free)));
125:                } else {
126:                    // Adjust the object counter!
127:                    lastObjectNumber = xrefEntries.length - 1;
128:                }
129:            }
130:
131:            // </constructors>
132:
133:            // <interface>
134:            // <public>
135:            public File getFile() {
136:                return file;
137:            }
138:
139:            /**
140:              Register an <b>internal data object</b>.
141:              <h3>Remarks</h3>
142:              <p>Alternatives:<ul>
143:              <li>To register a modified internal indirect object, use
144:              {@link #set(int,PdfIndirectObject) set(int,PdfIndirectObject)}.</li>
145:              <li>To register an external indirect object, use
146:              {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
147:              </ul></p>
148:             */
149:            public PdfIndirectObject add(PdfDataObject object) {
150:                // Wrap the data object inside a new indirect object!
151:                lastObjectNumber++;
152:                PdfIndirectObject indirectObject = new PdfIndirectObject(file,
153:                        object, new XRefEntry(lastObjectNumber, 0, 0,
154:                                XRefEntryUsageEnum.InUse));
155:                // Register the object!
156:                modifiedObjects.put(lastObjectNumber, indirectObject);
157:
158:                return indirectObject;
159:            }
160:
161:            /**
162:              Registers and gets an <b>external indirect object</b>.
163:              <h3>Remarks</h3>
164:              <p>External indirect objects come from alien PDF files. <i>This is a powerful
165:              way to import the content of one file into another</i>.</p>
166:              <p>Alternatives:<ul>
167:              <li>To register a modified internal indirect object, use
168:              {@link #set(int,PdfIndirectObject) set(int,PdfIndirectObject)}.</li>
169:              <li>To register an internal data object, use
170:              {@link #add(PdfDataObject) add(PdfDataObject)}.</li></ul></p>
171:             */
172:            public PdfIndirectObject addExternal(PdfIndirectObject object) {
173:                PdfIndirectObject indirectObject = importedObjects.get(object
174:                        .hashCode());
175:                // Hasn't the external indirect object been imported yet?
176:                if (indirectObject == null) {
177:                    // Register the clone of the data object corresponding to the external indirect object!
178:                    indirectObject = add((PdfDataObject) object.getDataObject()
179:                            .clone(file));
180:                    // Keep track of the imported indirect object!
181:                    importedObjects.put(object.hashCode(), indirectObject);
182:                }
183:
184:                return indirectObject;
185:            }
186:
187:            public Collection<? extends PdfIndirectObject> addAllExternal(
188:                    Collection<? extends PdfIndirectObject> objects) {
189:                ArrayList<PdfIndirectObject> addedObjects = new ArrayList<PdfIndirectObject>(
190:                        objects.size());
191:                for (PdfIndirectObject object : objects) {
192:                    addedObjects.add((PdfIndirectObject) addExternal(object));
193:                }
194:
195:                return addedObjects;
196:            }
197:
198:            // <List>
199:            public void add(int index, PdfIndirectObject object) {
200:                throw new UnsupportedOperationException();
201:            }
202:
203:            public boolean addAll(int index,
204:                    Collection<? extends PdfIndirectObject> objects) {
205:                throw new UnsupportedOperationException();
206:            }
207:
208:            /**
209:              Gets an indirect object with the specified object number.
210:              @param index Object number of the indirect object to get.
211:              @return Indirect object corresponding to the specified object number.
212:             */
213:            public PdfIndirectObject get(int index) {
214:                // Try among the new objects!
215:                PdfIndirectObject object = modifiedObjects.get(index);
216:                // Is it among the original objects?
217:                if (object == null) {
218:                    // Try among the woken original objects!
219:                    object = wokenObjects.get(index);
220:                    // Is it among the sleeping original objects?
221:                    if (object == null) {
222:                        try {
223:                            object = new PdfIndirectObject(file, null,
224:                                    xrefEntries[index]);
225:                        } catch (Exception e) {
226:                            throw new RuntimeException(e);
227:                        }
228:
229:                        // Now it's awake!
230:                        /*
231:                        NOTE: This operation allows to keep a consistant state across the whole session,
232:                        avoiding multiple incoherent instantiations of the same original indirect object.
233:                         */
234:                        wokenObjects.put(index, object);
235:
236:                        // Early registration?
237:                        if (updateMode == UpdateModeEnum.Automatic) {
238:                            update(object); /* Force early registration. */
239:                        }
240:                    }
241:                }
242:
243:                return object;
244:            }
245:
246:            public int indexOf(Object object) {
247:                // Is this indirect object associated to this file?
248:                if (((PdfIndirectObject) object).getFile() != file)
249:                    return -1;
250:
251:                return ((PdfIndirectObject) object).getReference()
252:                        .getObjectNumber();
253:            }
254:
255:            public int lastIndexOf(Object object) {
256:                /*
257:                  NOTE: By definition, there's a bijective relation between indirect objects
258:                  and their indices.
259:                 */
260:                return indexOf(object);
261:            }
262:
263:            public ListIterator<PdfIndirectObject> listIterator() {
264:                throw new NotImplementedException();
265:            }
266:
267:            public ListIterator<PdfIndirectObject> listIterator(int index) {
268:                throw new NotImplementedException();
269:            }
270:
271:            public PdfIndirectObject remove(int index) {
272:                /*
273:                  NOTE: Acrobat 6.0 and later (PDF 1.5+) DO NOT use the free list to recycle object numbers;
274:                  new objects are assigned new numbers [PDF:1.6:H.3:16].
275:                  According to such an implementation note, we simply mark the removed object as 'not-reusable'
276:                  newly-freed entry (generation 65535), neglecting both to add it to the linked list of free
277:                  entries and to increment by 1 its generation number.
278:                 */
279:                return update(new PdfIndirectObject(file, null, new XRefEntry(
280:                        index, 65535, // Not reusable.
281:                        0, XRefEntryUsageEnum.Free)));
282:            }
283:
284:            /**
285:              Sets an indirect object with the specified object number.
286:              <h3>Contract</h3>
287:              <ul>
288:                <li>Preconditions:
289:                  <ol>
290:                    <li><code>index</code> value MUST be between 1 and (size() - 1); index 0
291:                    is reserved to the mandatory head of the linked list of free objects [PDF:1.6:3.4.3].</li>
292:                  </ol>
293:                </li>
294:                <li>Postconditions:<ol><li>(none).</li></ol></li>
295:                <li>Invariants:<ol><li>(none).</li></ol></li>
296:                <li>Side-effects:<ol><li>(none).</li></ol></li>
297:              </ul>
298:              <h3>Remarks</h3>
299:              <p>This method is currently limited to <b>internal indirect
300:              objects</b>: <i>use it to register modified internal indirect objects only</i>.
301:              If you need to register alternative-type objects, consider the following
302:              methods:</p>
303:              <ul>
304:                <li>to register an <b>external indirect object</b>, use
305:                {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
306:                <li>to register an <b>internal data object</b>, use
307:                {@link #add(PdfDataObject) add(PdfDataObject)}.</li>
308:              </ul>
309:              @param index Object number of the indirect object to set.
310:              @param object Indirect object to set.
311:              @return Replaced indirect object.
312:             */
313:            public PdfIndirectObject set(int index, PdfIndirectObject object) {
314:                throw new UnsupportedOperationException();
315:            }
316:
317:            public List<PdfIndirectObject> subList(int fromIndex, int toIndex) {
318:                throw new NotImplementedException();
319:            }
320:
321:            // <Collection>
322:            /**
323:              Registers an <b>external indirect object</b>.
324:              <h3>Remarks</h3>
325:              <p>External indirect objects come from alien PDF files. <i>This is a powerful
326:              way to import the content of one file into another</i>.</p>
327:              <p>Alternatives:<ul>
328:              <li>To register and get an external indirect object, use
329:              {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
330:              </ul></p>
331:             */
332:            public boolean add(PdfIndirectObject object) {
333:                boolean changed = (addExternal(object) != null);
334:
335:                return changed;
336:            }
337:
338:            /**
339:              Registers <b>external indirect objects</b>.
340:              <h3>Remarks</h3>
341:              <p>External indirect objects come from alien PDF files. <i>This is a powerful
342:              way to import the content of one file into another</i>.</p>
343:              <p>Alternatives:<ul>
344:              <li>To register and get external indirect object, use
345:              {@link #addAllExternal(PdfIndirectObject) addAllExternal(Collection<? extends PdfIndirectObject>)}.</li>
346:              </ul></p>
347:             */
348:            public boolean addAll(
349:                    Collection<? extends PdfIndirectObject> objects) {
350:                boolean changed = false;
351:                for (PdfIndirectObject object : objects) {
352:                    changed |= (addExternal(object) != null);
353:                }
354:
355:                return changed;
356:            }
357:
358:            public void clear() {
359:                throw new UnsupportedOperationException();
360:            }
361:
362:            public boolean contains(Object object) {
363:                throw new NotImplementedException();
364:            }
365:
366:            public boolean containsAll(Collection<?> objects) {
367:                throw new NotImplementedException();
368:            }
369:
370:            public boolean equals(Object object) {
371:                throw new NotImplementedException();
372:            }
373:
374:            public int hashCode() {
375:                throw new NotImplementedException();
376:            }
377:
378:            public boolean isEmpty() {
379:                /*
380:                NOTE: Semantics of the indirect objects collection imply that the collection is considered
381:                empty in any case no in-use object is available.
382:                 */
383:                for (PdfIndirectObject object : this ) {
384:                    if (object.isInUse())
385:                        return false;
386:                }
387:
388:                return true;
389:            }
390:
391:            /**
392:              @version 0.0.5
393:              @since 0.0.0
394:             */
395:            public boolean remove(Object object) {
396:                return (remove(((PdfIndirectObject) object).getReference()
397:                        .getObjectNumber()) != null);
398:            }
399:
400:            public boolean removeAll(Collection<?> objects) {
401:                throw new NotImplementedException();
402:            }
403:
404:            public boolean retainAll(Collection<?> objects) {
405:                throw new UnsupportedOperationException();
406:            }
407:
408:            /**
409:              Gets the number of entries available (both in-use and free) in the
410:              collection.
411:              @return The number of entries available in the collection.
412:             */
413:            public int size() {
414:                return (lastObjectNumber + 1);
415:            }
416:
417:            public PdfIndirectObject[] toArray() {
418:                throw new NotImplementedException();
419:            }
420:
421:            public <PdfIndirectObject> PdfIndirectObject[] toArray(
422:                    PdfIndirectObject[] objects) {
423:                throw new NotImplementedException();
424:            }
425:
426:            // <Iterable>
427:            public Iterator<PdfIndirectObject> iterator() {
428:                return new Iterator<PdfIndirectObject>() {
429:                    // <class>
430:                    // <dynamic>
431:                    // <fields>
432:                    /** Index of the next item. */
433:                    private int index = 0;
434:
435:                    // </fields>
436:
437:                    // <interface>
438:                    // <public>
439:                    // <Iterator>
440:                    public boolean hasNext() {
441:                        return (index < size());
442:                    }
443:
444:                    public PdfIndirectObject next() {
445:                        if (!hasNext())
446:                            throw new NoSuchElementException();
447:
448:                        return get(index++);
449:                    }
450:
451:                    public void remove() {
452:                        throw new UnsupportedOperationException();
453:                    }
454:                    // </Iterator>
455:                    // </public>
456:                    // </interface>
457:                    // </dynamic>
458:                    // </class>
459:                };
460:            }
461:
462:            // </Iterable>
463:            // </Collection>
464:            // </List>
465:            // </public>
466:
467:            // <internal>
468:            /**
469:              <h3>Remarks</h3>
470:              <p>For internal use only.</p>
471:             */
472:            public TreeMap<Integer, PdfIndirectObject> getModifiedObjects() {
473:                return modifiedObjects;
474:            }
475:
476:            /**
477:              <h3>Remarks</h3>
478:              <p>For internal use only.</p>
479:             */
480:            public PdfIndirectObject update(PdfIndirectObject object) {
481:                int index = object.getReference().getObjectNumber();
482:
483:                // Get the old indirect object to be replaced!
484:                PdfIndirectObject old = get(index);
485:                if (old != object) {
486:                    old.dropFile(); /* Disconnect the old indirect object. */
487:                }
488:
489:                // Insert the new indirect object into the modified objects collection!
490:                modifiedObjects.put(index, object);
491:                // Remove old indirect object from cache!
492:                wokenObjects.remove(index);
493:                // Mark the new indirect object as modified!
494:                object.dropOriginal();
495:
496:                return old;
497:            }
498:            // </internal>
499:            // </interface>
500:            // </dynamic>
501:            // </class>
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.