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

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


001:        package com.etymon.pjx.util;
002:
003:        import java.io.*;
004:        import java.util.*;
005:        import com.etymon.pjx.*;
006:
007:        /**
008:         Provides methods for retrieving and modifying the field tree of a
009:         PDF document.  This class is synchronized.
010:         @author Nassib Nassar
011:         */
012:        public class PdfFieldTree {
013:
014:            /**
015:               A stack for holding nested levels of field nodes.
016:             */
017:            protected Stack _nested;
018:
019:            /**
020:               The manager associated with this document.
021:             */
022:            protected PdfManager _m;
023:
024:            /**
025:               The catalog associated with this document.
026:             */
027:            protected PdfCatalog _catalog;
028:
029:            /**
030:               Defines the set of inheritable field attributes.
031:             */
032:            protected static Set _inheritable;
033:
034:            /**
035:               Defines the set of field attributes that are inheritable
036:               from the AcroForm.
037:             */
038:            protected static Set _inheritableAcroForm;
039:
040:            protected static final PdfName PDFNAME_ACROFORM = new PdfName(
041:                    "AcroForm");
042:            protected static final PdfName PDFNAME_KIDS = new PdfName("Kids");
043:            protected static final PdfName PDFNAME_FIELDS = new PdfName(
044:                    "Fields");
045:            protected static final PdfName PDFNAME_PARENT = new PdfName(
046:                    "Parent");
047:            protected static final PdfName PDFNAME_T = new PdfName("T");
048:            protected static final PdfName PDFNAME_TYPE = new PdfName("Type");
049:
050:            /**
051:               Constructs a <code>PdfFieldTree</code> instance based on a
052:               specified <code>PdfManager</code>.
053:             */
054:            public PdfFieldTree(PdfManager manager) {
055:
056:                _m = manager;
057:                _catalog = new PdfCatalog(manager);
058:
059:                _inheritable = new HashSet(13);
060:                _inheritable.add(new PdfName("FT"));
061:                _inheritable.add(new PdfName("Ff"));
062:                _inheritable.add(new PdfName("V"));
063:                _inheritable.add(new PdfName("DV"));
064:                _inheritable.add(new PdfName("DR"));
065:                _inheritable.add(new PdfName("DA"));
066:                _inheritable.add(new PdfName("Q"));
067:                _inheritable.add(new PdfName("Opt"));
068:                _inheritable.add(new PdfName("MaxLen"));
069:                _inheritable.add(new PdfName("TI"));
070:                _inheritable.add(new PdfName("I"));
071:                _inheritable.add(new PdfName("Filter"));
072:                _inheritable.add(new PdfName("Flags"));
073:
074:                _inheritableAcroForm = new HashSet(3);
075:                _inheritableAcroForm.add(new PdfName("DR"));
076:                _inheritableAcroForm.add(new PdfName("DA"));
077:                _inheritableAcroForm.add(new PdfName("Q"));
078:
079:            }
080:
081:            // the following should be made public once the API is stable
082:            /**
083:               Returns the interactive form dictionary of the document.
084:               This method returns a <code>PdfDictionary</code> (the
085:               AcroForm dictionary), a <code>PdfReference</code> (an
086:               indirect reference to the AcroForm dictionary), or
087:               <code>null</code> if there is no AcroForm dictionary
088:               present.
089:               @return the AcroForm dictionary (direct object or indirect
090:               reference) or <code>null</code>.
091:               @throws IOException
092:               @throws PdfFormatException
093:             */
094:            protected PdfObject getAcroForm() throws IOException,
095:                    PdfFormatException {
096:                synchronized (this ) {
097:                    synchronized (_m) {
098:
099:                        Object obj = _m
100:                                .getObjectIndirect(_catalog.getCatalog());
101:                        if (!(obj instanceof  PdfDictionary)) {
102:                            throw new PdfFormatException(
103:                                    "Catalog is not a dictionary.");
104:                        }
105:                        PdfDictionary catalog = (PdfDictionary) obj;
106:
107:                        obj = catalog.getMap().get(PDFNAME_ACROFORM);
108:                        if (obj == null) {
109:                            return null;
110:                        }
111:                        if ((!(obj instanceof  PdfReference))
112:                                && (!(obj instanceof  PdfDictionary))) {
113:                            throw new PdfFormatException(
114:                                    "AcroForm is not a dictionary or indirect reference.");
115:                        }
116:                        return (PdfObject) obj;
117:
118:                    }
119:                }
120:            }
121:
122:            /**
123:               Determines the fully qualified field name of a specified
124:               field.
125:               @param field the field dictionary.
126:               @return the fully qualified field name.
127:               @throws IOException
128:               @throws PdfFormatException
129:             */
130:            public String getFullyQualifiedName(PdfDictionary field)
131:                    throws IOException, PdfFormatException {
132:                synchronized (this ) {
133:                    synchronized (_m) {
134:
135:                        // keep track of the approximate
136:                        // length of the fully qualified field
137:                        // name to use later when constructing
138:                        // the StringBuffer
139:                        int approxStringLength = 0;
140:
141:                        // the partial names will be stored in
142:                        // a list
143:                        ArrayList names = new ArrayList();
144:
145:                        // the first node we examine is the
146:                        // specified dictionary
147:                        PdfDictionary fieldNode = field;
148:
149:                        boolean done = false;
150:                        do {
151:
152:                            Map fieldMap = fieldNode.getMap();
153:
154:                            // get the node's partial field name
155:                            Object obj = fieldMap.get(PDFNAME_T);
156:                            if (PdfNull.isNull(obj) == false) {
157:                                if (!(obj instanceof  PdfObject)) {
158:                                    throw new PdfFormatException(
159:                                            "Field name (T) is not a PDF object.");
160:                                }
161:                                obj = _m.getObjectIndirect((PdfObject) obj);
162:                                if (PdfNull.isNull(obj) == false) {
163:                                    if (!(obj instanceof  PdfString)) {
164:                                        throw new PdfFormatException(
165:                                                "Field name (T) is not a string.");
166:                                    }
167:                                    // add name to
168:                                    // running list
169:                                    String fieldName = ((PdfString) obj)
170:                                            .getString();
171:                                    if (fieldName.length() > 0) {
172:                                        names.add(fieldName);
173:                                        approxStringLength += fieldName
174:                                                .length() + 1;
175:                                    }
176:                                }
177:                            }
178:
179:                            // ascend to the parent node
180:                            obj = fieldMap.get(PDFNAME_PARENT);
181:                            if (PdfNull.isNull(obj) == true) {
182:                                done = true;
183:                            } else {
184:                                if (!(obj instanceof  PdfObject)) {
185:                                    throw new PdfFormatException(
186:                                            "Field parent is not a PDF object.");
187:                                }
188:                                obj = _m.getObjectIndirect((PdfObject) obj);
189:                                if (PdfNull.isNull(obj) == true) {
190:                                    done = true;
191:                                } else {
192:                                    if (!(obj instanceof  PdfDictionary)) {
193:                                        throw new PdfFormatException(
194:                                                "Field parent is not a dictionary.");
195:                                    }
196:                                    fieldNode = (PdfDictionary) obj;
197:                                }
198:                            }
199:
200:                        } while (!done);
201:
202:                        // now string the partial names together
203:                        StringBuffer sb = new StringBuffer(approxStringLength);
204:                        boolean first = true;
205:                        int namesSize = names.size();
206:                        for (int x = namesSize - 1; x >= 0; x--) {
207:                            String name = (String) names.get(x);
208:                            // append the name
209:                            if (first) {
210:                                first = false;
211:                            } else {
212:                                sb.append('.');
213:                            }
214:                            sb.append(name);
215:                        }
216:
217:                        return sb.toString();
218:
219:                    }
220:                }
221:            }
222:
223:            /**
224:               Adds inherited attributes to a specified field dictionary
225:               object.  The field object is cloned and the inherited
226:               attributes are made explicit in the cloned object's
227:               dictionary.  The inherited attributes are retrieved by
228:               ascending the field tree and looking for inheritable
229:               attributes (if any) that are missing from the specified
230:               field dictionary.  The interactive form dictionary is also
231:               checked (if necessary) for document-wide default values.
232:               @param field the field dictionary to be filled in with
233:               inherited attributes.
234:               @return a clone of the specified field dictionary, with all
235:               inherited attributes filled in.
236:               @throws IOException
237:               @throws PdfFormatException
238:             */
239:            public PdfDictionary inheritAttributes(PdfDictionary field)
240:                    throws IOException, PdfFormatException {
241:                synchronized (this ) {
242:                    synchronized (_m) {
243:
244:                        Map fieldM = field.getMap();
245:
246:                        // define new dictionary map
247:                        Map newMap = new HashMap(field.getMap());
248:
249:                        // start out looking for all inheritable attributes
250:                        // that are not present in this field
251:                        Set unused = new HashSet(_inheritable.size());
252:                        for (Iterator t = _inheritable.iterator(); t.hasNext();) {
253:
254:                            PdfName attr = (PdfName) t.next();
255:                            Object obj = fieldM.get(attr);
256:
257:                            if ((obj == null) || (obj instanceof  PdfNull)) {
258:                                unused.add(attr);
259:                            }
260:
261:                        }
262:
263:                        boolean done = false;
264:
265:                        do {
266:
267:                            // if all the inheritable attributes have been
268:                            // filled, there is no need to continue
269:                            // ascending the tree
270:                            if (unused.isEmpty()) {
271:                                done = true;
272:                                break;
273:                            }
274:
275:                            // get the Parent node
276:                            Object obj = fieldM.get(PDFNAME_PARENT);
277:                            if (obj == null) {
278:                                // we are done, but we
279:                                // need to do one more
280:                                // round of
281:                                // inheritance from
282:                                // the AcroForm
283:                                done = true;
284:                                obj = getAcroForm();
285:                                if (obj == null) {
286:                                    break;
287:                                }
288:                                // remove all elements
289:                                // from the unused set
290:                                // except for
291:                                // AcroForm-inheritable fields
292:                                unused.retainAll(_inheritableAcroForm);
293:                                if (unused.isEmpty()) {
294:                                    break;
295:                                }
296:                            }
297:                            if (!(obj instanceof  PdfObject)) {
298:                                throw new PdfFormatException(
299:                                        "Parent object is not a PDF object.");
300:                            }
301:                            obj = _m.getObjectIndirect((PdfObject) obj);
302:                            if (!(obj instanceof  PdfDictionary)) {
303:                                throw new PdfFormatException(
304:                                        "Parent object is not a dictionary.");
305:                            }
306:                            fieldM = ((PdfDictionary) obj).getMap();
307:
308:                            // now examine the parent node
309:                            for (Iterator t = unused.iterator(); t.hasNext();) {
310:
311:                                PdfName attr = (PdfName) t.next();
312:
313:                                // check if the attribute is present
314:                                obj = fieldM.get(attr);
315:                                if ((obj != null)
316:                                        && (!(obj instanceof  PdfNull))) {
317:                                    t.remove();
318:                                    newMap.put(attr, obj);
319:                                }
320:
321:                            }
322:
323:                        } while (!done);
324:
325:                        return new PdfDictionary(newMap);
326:
327:                    }
328:                }
329:            }
330:
331:            /**
332:               Returns an iterator over the terminal field objects in this
333:               document's field tree.  Note that terminal field objects do
334:               not include inherited attributes; {@link
335:               #inheritAttributes(PdfDictionary)
336:               inheritAttributes(PdfDictionary)} should be used to obtain
337:               inherited attributes.
338:               @return the iterator over the terminal field objects.
339:               @throws IOException
340:               @throws PdfFormatException
341:             */
342:            public PdfFieldTreeIterator getIterator() throws IOException,
343:                    PdfFormatException {
344:                return new FieldTreeIterator(this , _m);
345:            }
346:
347:            /**
348:               An iterator over the tree of field dictionaries in a PDF document.
349:               @author Nassib Nassar
350:             */
351:            protected class FieldTreeIterator implements  PdfFieldTreeIterator {
352:
353:                /**
354:                   The manager associated with this iterator.
355:                 */
356:                protected PdfManager _m;
357:
358:                /**
359:                   The field tree associated with this iterator.
360:                 */
361:                protected PdfFieldTree _ft;
362:
363:                /**
364:                   Constructs an iterator over a field tree.
365:                   @param ft the field tree to iterate over.
366:                   @param m the associated document manager.
367:                   @throws IOException
368:                   @throws PdfFormatException
369:                 */
370:                public FieldTreeIterator(PdfFieldTree ft, PdfManager m)
371:                        throws IOException, PdfFormatException {
372:
373:                    _ft = ft;
374:                    _m = m;
375:                    _nested = new Stack();
376:
377:                    // get the AcroForm
378:                    Object obj = m.getObjectIndirect(getAcroForm());
379:
380:                    if (obj != null) {
381:
382:                        if (!(obj instanceof  PdfDictionary)) {
383:                            throw new PdfFormatException(
384:                                    "AcroForm is not a dictionary.");
385:                        }
386:                        PdfDictionary acroForm = (PdfDictionary) obj;
387:
388:                        // get the Fields array from the AcroForm
389:                        obj = acroForm.getMap().get(PDFNAME_FIELDS);
390:                        if (!(obj instanceof  PdfObject)) {
391:                            throw new PdfFormatException(
392:                                    "Fields array is not a PDF object.");
393:                        }
394:                        obj = m.getObjectIndirect((PdfObject) obj);
395:                        if (!(obj instanceof  PdfArray)) {
396:                            throw new PdfFormatException(
397:                                    "Fields array is not an array.");
398:                        }
399:                        List fields = ((PdfArray) obj).getList();
400:
401:                        _nested.push(newList(fields));
402:
403:                    }
404:
405:                }
406:
407:                protected List newList(List list) {
408:                    return new ArrayList(list);
409:                }
410:
411:                /**
412:                   Descends the left-edge of the tree until reaching a
413:                   terminal node and returns its reference.  As the
414:                   tree is descended, this method pushes field lists
415:                   onto the stack.
416:                   @return an indirect reference to the terminal node
417:                   @throws IOException
418:                   @throws PdfFormatException
419:                 */
420:                protected PdfReference descendTree() throws IOException,
421:                        PdfFormatException {
422:
423:                    List kidsM;
424:                    PdfReference node;
425:
426:                    do {
427:
428:                        // get the first element of the field
429:                        // list in the top element of the
430:                        // stack; this assumes there is a
431:                        // field list on the stack, and that
432:                        // the field list contains at least
433:                        // one element
434:                        List fieldsM = (List) _nested.peek();
435:                        node = (PdfReference) fieldsM.get(0);
436:
437:                        // remove the element
438:                        fieldsM.remove(0);
439:
440:                        // retrieve the referenced node
441:                        Object obj = _m.getObjectIndirect(node);
442:                        if (!(obj instanceof  PdfDictionary)) {
443:                            throw new PdfFormatException(
444:                                    "Field node is not a dictionary.");
445:                        }
446:                        Map fieldNode = ((PdfDictionary) obj).getMap();
447:
448:                        // determine if there are any children
449:
450:                        obj = fieldNode.get(PDFNAME_KIDS);
451:
452:                        if (obj == null) {
453:
454:                            kidsM = null;
455:
456:                        } else {
457:
458:                            if (!(obj instanceof  PdfObject)) {
459:                                throw new PdfFormatException(
460:                                        "Kids array is not a PDF object.");
461:                            }
462:                            obj = _m.getObjectIndirect((PdfObject) obj);
463:                            if (!(obj instanceof  PdfArray)) {
464:                                throw new PdfFormatException(
465:                                        "Kids array is not an array object.");
466:                            }
467:                            List kidsL = ((PdfArray) obj).getList();
468:                            if (kidsL.isEmpty()) {
469:                                throw new PdfFormatException(
470:                                        "Kids array is empty.");
471:                            }
472:
473:                            kidsM = newList(kidsL);
474:
475:                        }
476:                        // now kidsM contains a modifiable
477:                        // version of the kids array, or it
478:                        // equals null if there is no kids
479:                        // array
480:
481:                        // push the kids onto the stack and
482:                        // continue to the next level of
483:                        // descent
484:                        if (kidsM != null) {
485:                            _nested.push(kidsM);
486:                        }
487:
488:                    } while (kidsM != null);
489:                    // at this point, kidsM == null, which means
490:                    // that fieldNode is a terminal node
491:
492:                    return node;
493:
494:                }
495:
496:                /**
497:                   Removes any empty lists from the top of the stack.
498:                 */
499:                protected void cleanUp() {
500:
501:                    while ((_nested.empty() == false)
502:                            && (((List) _nested.peek()).isEmpty())) {
503:
504:                        _nested.pop();
505:
506:                    }
507:
508:                }
509:
510:                // Clean-up, Check Null Stack
511:                public boolean hasNext() throws PdfFormatException {
512:                    synchronized (_m) {
513:                        synchronized (_ft) {
514:
515:                            cleanUp();
516:
517:                            return !(_nested.empty());
518:
519:                        }
520:                    }
521:                }
522:
523:                /**
524:                   @throws IOException
525:                   @throws PdfFormatException
526:                 */
527:                public PdfReference next() throws NoSuchElementException,
528:                        IOException, PdfFormatException {
529:                    synchronized (_m) {
530:                        synchronized (_ft) {
531:
532:                            // throw an exception if there
533:                            // are no more elements
534:                            if (!hasNext()) {
535:                                throw new NoSuchElementException();
536:                            }
537:
538:                            // descend the tree to a
539:                            // terminal node
540:                            return descendTree();
541:
542:                        }
543:                    }
544:                }
545:
546:            }
547:
548:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.