KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdmodel > common > PDNameTreeNode


1 /**
2  * Copyright (c) 2004-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.pdmodel.common;
32
33 import java.io.IOException JavaDoc;
34 import java.lang.reflect.Constructor JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Collections JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.Map JavaDoc;
40
41 import org.pdfbox.cos.COSArray;
42 import org.pdfbox.cos.COSBase;
43 import org.pdfbox.cos.COSDictionary;
44 import org.pdfbox.cos.COSString;
45
46 /**
47  * This class represends a PDF Name tree. See the PDF Reference 1.5 section 3.8.5
48  * for more details.
49  *
50  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
51  * @version $Revision: 1.4 $
52  */

53 public class PDNameTreeNode implements COSObjectable
54 {
55     private COSDictionary node;
56     private Class JavaDoc valueType = null;
57
58     /**
59      * Constructor.
60      *
61      * @param valueClass The PD Model type of object that is the value.
62      */

63     public PDNameTreeNode( Class JavaDoc valueClass )
64     {
65         node = new COSDictionary();
66         valueType = valueClass;
67     }
68
69     /**
70      * Constructor.
71      *
72      * @param dict The dictionary that holds the name information.
73      * @param valueClass The PD Model type of object that is the value.
74      */

75     public PDNameTreeNode( COSDictionary dict, Class JavaDoc valueClass )
76     {
77         node = dict;
78         valueType = valueClass;
79     }
80
81     /**
82      * Convert this standard java object to a COS object.
83      *
84      * @return The cos object that matches this Java object.
85      */

86     public COSBase getCOSObject()
87     {
88         return node;
89     }
90
91     /**
92      * Convert this standard java object to a COS object.
93      *
94      * @return The cos object that matches this Java object.
95      */

96     public COSDictionary getCOSDictionary()
97     {
98         return node;
99     }
100     
101     /**
102      * Return the children of this node. This list will contain PDNameTreeNode objects.
103      *
104      * @return The list of children or null if there are no children.
105      */

106     public List JavaDoc getKids()
107     {
108         
109         List JavaDoc retval = null;
110         COSArray kids = (COSArray)node.getDictionaryObject( "Kids" );
111         if( kids != null )
112         {
113             List JavaDoc pdObjects = new ArrayList JavaDoc();
114             for( int i=0; i<kids.size(); i++ )
115             {
116                 pdObjects.add( createChildNode( (COSDictionary)kids.getObject(i) ) );
117             }
118             retval = new COSArrayList(pdObjects,kids);
119         }
120         
121         return retval;
122     }
123     
124     /**
125      * Set the children of this named tree.
126      *
127      * @param kids The children of this named tree.
128      */

129     public void setKids( List JavaDoc kids )
130     {
131         node.setItem( "Kids", COSArrayList.converterToCOSArray( kids ) );
132     }
133     
134     /**
135      * The name to retrieve.
136      *
137      * @param name The name in the tree.
138      *
139      * @return The value of the name in the tree.
140      *
141      * @throws IOException If an there is a problem creating the destinations.
142      */

143     public Object JavaDoc getValue( String JavaDoc name ) throws IOException JavaDoc
144     {
145         Object JavaDoc retval = null;
146         Map JavaDoc names = getNames();
147         if( names != null )
148         {
149             retval = names.get( name );
150         }
151         else
152         {
153             List JavaDoc kids = getKids();
154             for( int i=0; i<kids.size() && retval == null; i++ )
155             {
156                 PDNameTreeNode childNode = (PDNameTreeNode)kids.get( i );
157                 if( childNode.getLowerLimit().compareTo( name ) <= 0 &&
158                         childNode.getUpperLimit().compareTo( name ) >= 0 )
159                 {
160                     retval = childNode.getValue( name );
161                 }
162             }
163         }
164         return retval;
165     }
166     
167     
168     /**
169      * This will return a map of names. The key will be a java.lang.String the value will
170      * depend on where this class is being used.
171      *
172      * @return A map of cos objects.
173      *
174      * @throws IOException If there is an error while creating the sub types.
175      */

176     public Map JavaDoc getNames() throws IOException JavaDoc
177     {
178         Map JavaDoc names = null;
179         COSArray namesArray = (COSArray)node.getDictionaryObject( "Names" );
180         if( namesArray != null )
181         {
182             names = new HashMap JavaDoc();
183             for( int i=0; i<namesArray.size(); i+=2 )
184             {
185                 COSString key = (COSString)namesArray.getObject(i);
186                 COSBase cosValue = namesArray.getObject( i+1 );
187                 Object JavaDoc pdValue = convertCOSToPD( cosValue );
188                 
189                 names.put( key.getString(), pdValue );
190             }
191             names = Collections.unmodifiableMap(names);
192         }
193         
194         return names;
195     }
196     
197     /**
198      * Method to convert the COS value in the name tree to the PD Model object. The
199      * default implementation will simply use reflection to create the correct object
200      * type. Subclasses can do whatever they want.
201      *
202      * @param base The COS object to convert.
203      * @return The converted PD Model object.
204      * @throws IOException If there is an error during creation.
205      */

206     protected Object JavaDoc convertCOSToPD( COSBase base ) throws IOException JavaDoc
207     {
208         Object JavaDoc retval = null;
209         try
210         {
211             Constructor JavaDoc ctor = valueType.getConstructor( new Class JavaDoc[] { base.getClass() } );
212             retval = ctor.newInstance( new Object JavaDoc[] { base } );
213         }
214         catch( Throwable JavaDoc t )
215         {
216             throw new IOException JavaDoc( "Error while trying to create value in named tree:" + t.getMessage());
217             
218         }
219         return retval;
220     }
221     
222     /**
223      * Create a child node object.
224      *
225      * @param dic The dictionary for the child node object to refer to.
226      * @return The new child node object.
227      */

228     protected PDNameTreeNode createChildNode( COSDictionary dic )
229     {
230         return new PDNameTreeNode(dic,valueType);
231     }
232     
233     /**
234      * Set the names of for this node. The keys should be java.lang.String and the
235      * values must be a COSObjectable. This method will set the appropriate upper and lower
236      * limits based on the keys in the map.
237      *
238      * @param names The map of names to objects.
239      */

240     public void setNames( Map JavaDoc names )
241     {
242         if( names == null )
243         {
244             node.setItem( "Names", (COSObjectable)null );
245             node.setItem( "Limits", (COSObjectable)null);
246         }
247         else
248         {
249             List JavaDoc keys = new ArrayList JavaDoc( names.keySet() );
250             Collections.sort( keys );
251             COSArray array = new COSArray();
252             for( int i=0; i<keys.size(); i++ )
253             {
254                 String JavaDoc key = (String JavaDoc)keys.get(i);
255                 array.add( new COSString( key ) );
256                 COSObjectable obj = (COSObjectable)names.get( key );
257                 array.add( obj );
258             }
259             String JavaDoc lower = null;
260             String JavaDoc upper = null;
261             if( keys.size() > 0 )
262             {
263                 lower = (String JavaDoc)keys.get( 0 );
264                 upper = (String JavaDoc)keys.get( keys.size()-1 );
265             }
266             setUpperLimit( upper );
267             setLowerLimit( lower );
268             node.setItem( "Names", array );
269         }
270     }
271     
272     /**
273      * Get the highest value for a key in the name map.
274      *
275      * @return The highest value for a key in the map.
276      */

277     public String JavaDoc getUpperLimit()
278     {
279         String JavaDoc retval = null;
280         COSArray arr = (COSArray)node.getDictionaryObject( "Limits" );
281         if( arr != null )
282         {
283             retval = arr.getString( 1 );
284         }
285         return retval;
286     }
287     
288     /**
289      * Set the highest value for the key in the map.
290      *
291      * @param upper The new highest value for a key in the map.
292      */

293     private void setUpperLimit( String JavaDoc upper )
294     {
295         COSArray arr = (COSArray)node.getDictionaryObject( "Limits" );
296         if( arr == null )
297         {
298             arr = new COSArray();
299             arr.add( null );
300             arr.add( null );
301         }
302         arr.setString( 1, upper );
303     }
304     
305     /**
306      * Get the lowest value for a key in the name map.
307      *
308      * @return The lowest value for a key in the map.
309      */

310     public String JavaDoc getLowerLimit()
311     {
312         String JavaDoc retval = null;
313         COSArray arr = (COSArray)node.getDictionaryObject( "Limits" );
314         if( arr != null )
315         {
316             retval = arr.getString( 0 );
317         }
318         return retval;
319     }
320     
321     /**
322      * Set the lowest value for the key in the map.
323      *
324      * @param lower The new lowest value for a key in the map.
325      */

326     private void setLowerLimit( String JavaDoc lower )
327     {
328         COSArray arr = (COSArray)node.getDictionaryObject( "Limits" );
329         if( arr == null )
330         {
331             arr = new COSArray();
332             arr.add( null );
333             arr.add( null );
334         }
335         arr.setString( 0, lower );
336     }
337 }
Popular Tags