KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdfviewer > PDFTreeModel


1 /**
2  * Copyright (c) 2003-2005, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.pdfviewer;
32
33 /**
34  * A tree model that uses a cos document.
35  *
36  *
37  * @author wurtz
38  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
39  * @version $Revision: 1.9 $
40  */

41 import javax.swing.tree.TreePath JavaDoc;
42 import javax.swing.tree.TreeModel JavaDoc;
43
44 //import java.awt.event.*;
45
import javax.swing.event.TreeModelListener JavaDoc;
46
47 import org.pdfbox.cos.COSArray;
48 import org.pdfbox.cos.COSBase;
49 import org.pdfbox.cos.COSDictionary;
50 import org.pdfbox.cos.COSDocument;
51 import org.pdfbox.cos.COSName;
52 import org.pdfbox.cos.COSObject;
53
54 import org.pdfbox.pdmodel.PDDocument;
55
56 import java.util.Collections JavaDoc;
57 import java.util.List JavaDoc;
58
59 /**
60  * A class to model a PDF document as a tree structure.
61  *
62  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
63  * @version $Revision: 1.9 $
64  */

65 public class PDFTreeModel implements TreeModel JavaDoc
66 {
67     private PDDocument document;
68
69     /**
70      * constructor.
71      */

72     public PDFTreeModel()
73     {
74         //default constructor
75
}
76
77     /**
78      * Constructor to take a document.
79      *
80      * @param doc The document to display in the tree.
81      */

82     public PDFTreeModel(PDDocument doc)
83     {
84          setDocument(doc);
85     }
86
87     /**
88      * Set the document to display in the tree.
89      *
90      * @param doc The document to display in the tree.
91      */

92     public void setDocument(PDDocument doc)
93     {
94         document = doc;
95     }
96     /**
97      * Adds a listener for the <code>TreeModelEvent</code>
98      * posted after the tree changes.
99      *
100      * @param l the listener to add
101      * @see #removeTreeModelListener
102      *
103      */

104     public void addTreeModelListener(TreeModelListener JavaDoc l)
105     {
106         //required for interface
107
}
108
109     /**
110      * Returns the child of <code>parent</code> at index <code>index</code>
111      * in the parent's
112      * child array. <code>parent</code> must be a node previously obtained
113      * from this data source. This should not return <code>null</code>
114      * if <code>index</code>
115      * is a valid index for <code>parent</code> (that is <code>index >= 0 &&
116      * index < getChildCount(parent</code>)).
117      *
118      * @param parent a node in the tree, obtained from this data source
119      * @param index The index into the parent object to location the child object.
120      * @return the child of <code>parent</code> at index <code>index</code>
121      *
122      */

123     public Object JavaDoc getChild(Object JavaDoc parent, int index)
124     {
125         Object JavaDoc retval = null;
126         if( parent instanceof COSArray )
127         {
128             ArrayEntry entry = new ArrayEntry();
129             entry.setIndex( index );
130             entry.setValue( ((COSArray)parent).getObject( index ) );
131             retval = entry;
132         }
133         else if( parent instanceof COSDictionary )
134         {
135             COSDictionary dict = ((COSDictionary)parent);
136             List JavaDoc keys = dict.keyList();
137             Collections.sort( keys );
138             Object JavaDoc key = keys.get( index );
139             Object JavaDoc value = dict.getDictionaryObject( (COSName)key );
140             MapEntry entry = new MapEntry();
141             entry.setKey( key );
142             entry.setValue( value );
143             retval = entry;
144         }
145         else if( parent instanceof MapEntry )
146         {
147             retval = getChild( ((MapEntry)parent).getValue(), index );
148         }
149         else if( parent instanceof ArrayEntry )
150         {
151             retval = getChild( ((ArrayEntry)parent).getValue(), index );
152         }
153         else if( parent instanceof COSDocument )
154         {
155             retval = ((COSDocument)parent).getObjects().get( index );
156         }
157         else if( parent instanceof COSObject )
158         {
159             retval = ((COSObject)parent).getObject();
160         }
161         else
162         {
163             throw new RuntimeException JavaDoc( "Unknown COS type " + parent.getClass().getName() );
164         }
165         return retval;
166     }
167
168     /** Returns the number of children of <code>parent</code>.
169      * Returns 0 if the node
170      * is a leaf or if it has no children. <code>parent</code> must be a node
171      * previously obtained from this data source.
172      *
173      * @param parent a node in the tree, obtained from this data source
174      * @return the number of children of the node <code>parent</code>
175      *
176      */

177     public int getChildCount(Object JavaDoc parent)
178     {
179         int retval = 0;
180         if( parent instanceof COSArray )
181         {
182             retval = ((COSArray)parent).size();
183         }
184         else if( parent instanceof COSDictionary )
185         {
186             retval = ((COSDictionary)parent).size();
187         }
188         else if( parent instanceof MapEntry )
189         {
190             retval = getChildCount( ((MapEntry)parent).getValue() );
191         }
192         else if( parent instanceof ArrayEntry )
193         {
194             retval = getChildCount( ((ArrayEntry)parent).getValue() );
195         }
196         else if( parent instanceof COSDocument )
197         {
198             retval = ((COSDocument)parent).getObjects().size();
199         }
200         else if( parent instanceof COSObject )
201         {
202             retval = 1;
203         }
204         return retval;
205     }
206
207     /** Returns the index of child in parent. If <code>parent</code>
208      * is <code>null</code> or <code>child</code> is <code>null</code>,
209      * returns -1.
210      *
211      * @param parent a note in the tree, obtained from this data source
212      * @param child the node we are interested in
213      * @return the index of the child in the parent, or -1 if either
214      * <code>child</code> or <code>parent</code> are <code>null</code>
215      *
216      */

217     public int getIndexOfChild(Object JavaDoc parent, Object JavaDoc child)
218     {
219         int retval = -1;
220         if( parent != null && child != null )
221         {
222             if( parent instanceof COSArray )
223             {
224                 COSArray array = (COSArray)parent;
225                 if( child instanceof ArrayEntry )
226                 {
227                     ArrayEntry arrayEntry = (ArrayEntry)child;
228                     retval = arrayEntry.getIndex();
229                 }
230                 else
231                 {
232                     retval = array.indexOf( (COSBase)child );
233                 }
234             }
235             else if( parent instanceof COSDictionary )
236             {
237                 MapEntry entry = (MapEntry)child;
238                 COSDictionary dict = (COSDictionary)parent;
239                 List JavaDoc keys = dict.keyList();
240                 Collections.sort( keys );
241                 for( int i=0; retval == -1 && i<keys.size(); i++ )
242                 {
243                     if( keys.get( i ).equals( entry.getKey() ) )
244                     {
245                         retval = i;
246                     }
247                 }
248             }
249             else if( parent instanceof MapEntry )
250             {
251                 retval = getIndexOfChild( ((MapEntry)parent).getValue(), child );
252             }
253             else if( parent instanceof ArrayEntry )
254             {
255                 retval = getIndexOfChild( ((ArrayEntry)parent).getValue(), child );
256             }
257             else if( parent instanceof COSDocument )
258             {
259                 retval = ((COSDocument)parent).getObjects().indexOf( child );
260             }
261             else if( parent instanceof COSObject )
262             {
263                 retval = 0;
264             }
265             else
266             {
267                 throw new RuntimeException JavaDoc( "Unknown COS type " + parent.getClass().getName() );
268             }
269         }
270         return retval;
271     }
272
273     /** Returns the root of the tree. Returns <code>null</code>
274      * only if the tree has no nodes.
275      *
276      * @return the root of the tree
277      *
278      */

279     public Object JavaDoc getRoot()
280     {
281         return document.getDocument().getTrailer();
282     }
283
284     /** Returns <code>true</code> if <code>node</code> is a leaf.
285      * It is possible for this method to return <code>false</code>
286      * even if <code>node</code> has no children.
287      * A directory in a filesystem, for example,
288      * may contain no files; the node representing
289      * the directory is not a leaf, but it also has no children.
290      *
291      * @param node a node in the tree, obtained from this data source
292      * @return true if <code>node</code> is a leaf
293      *
294      */

295     public boolean isLeaf(Object JavaDoc node)
296     {
297         boolean isLeaf = !(node instanceof COSDictionary ||
298                  node instanceof COSArray ||
299                  node instanceof COSDocument ||
300                  node instanceof COSObject ||
301                  (node instanceof MapEntry && !isLeaf(((MapEntry)node).getValue()) ) ||
302                  (node instanceof ArrayEntry && !isLeaf(((ArrayEntry)node).getValue()) ));
303         return isLeaf;
304     }
305
306     /** Removes a listener previously added with
307      * <code>addTreeModelListener</code>.
308      *
309      * @see #addTreeModelListener
310      * @param l the listener to remove
311      *
312      */

313
314     public void removeTreeModelListener(TreeModelListener JavaDoc l)
315     {
316         //required for interface
317
}
318
319     /** Messaged when the user has altered the value for the item identified
320      * by <code>path</code> to <code>newValue</code>.
321      * If <code>newValue</code> signifies a truly new value
322      * the model should post a <code>treeNodesChanged</code> event.
323      *
324      * @param path path to the node that the user has altered
325      * @param newValue the new value from the TreeCellEditor
326      *
327      */

328     public void valueForPathChanged(TreePath JavaDoc path, Object JavaDoc newValue)
329     {
330         //required for interface
331
}
332 }
Popular Tags