Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.common » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.pdfbox.pdmodel.common;
   18   
   19   import java.io.IOException;
   20   import java.lang.reflect.Constructor;
   21   import java.util.ArrayList;
   22   import java.util.Collections;
   23   import java.util.HashMap;
   24   import java.util.List;
   25   import java.util.Map;
   26   
   27   import org.apache.pdfbox.cos.COSArray;
   28   import org.apache.pdfbox.cos.COSBase;
   29   import org.apache.pdfbox.cos.COSDictionary;
   30   import org.apache.pdfbox.cos.COSInteger;
   31   import org.apache.pdfbox.cos.COSName;
   32   
   33   /**
   34    * This class represents a PDF Number tree. See the PDF Reference 1.7 section
   35    * 7.9.7 for more details.
   36    * 
   37    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>,
   38    *         <a href="igor.podolskiy@ievvwi.uni-stuttgart.de">Igor Podolskiy</a>
   39    * @version $Revision: 1.4 $
   40    */
   41   public class PDNumberTreeNode implements COSObjectable
   42   {
   43       private COSDictionary node;
   44       private Class valueType = null;
   45   
   46       /**
   47        * Constructor.
   48        *
   49        * @param valueClass The PD Model type of object that is the value.
   50        */
   51       public PDNumberTreeNode( Class valueClass )
   52       {
   53           node = new COSDictionary();
   54           valueType = valueClass;
   55       }
   56   
   57       /**
   58        * Constructor.
   59        *
   60        * @param dict The dictionary that holds the name information.
   61        * @param valueClass The PD Model type of object that is the value.
   62        */
   63       public PDNumberTreeNode( COSDictionary dict, Class valueClass )
   64       {
   65           node = dict;
   66           valueType = valueClass;
   67       }
   68   
   69       /**
   70        * Convert this standard java object to a COS object.
   71        *
   72        * @return The cos object that matches this Java object.
   73        */
   74       public COSBase getCOSObject()
   75       {
   76           return node;
   77       }
   78   
   79       /**
   80        * Convert this standard java object to a COS object.
   81        *
   82        * @return The cos object that matches this Java object.
   83        */
   84       public COSDictionary getCOSDictionary()
   85       {
   86           return node;
   87       }
   88   
   89       /**
   90        * Return the children of this node.  This list will contain PDNumberTreeNode objects.
   91        *
   92        * @return The list of children or null if there are no children.
   93        */
   94       public List getKids()
   95       {
   96   
   97           List retval = null;
   98           COSArray kids = (COSArray)node.getDictionaryObject( COSName.KIDS );
   99           if( kids != null )
  100           {
  101               List pdObjects = new ArrayList();
  102               for( int i=0; i<kids.size(); i++ )
  103               {
  104                   pdObjects.add( createChildNode( (COSDictionary)kids.getObject(i) ) );
  105               }
  106               retval = new COSArrayList(pdObjects,kids);
  107           }
  108   
  109           return retval;
  110       }
  111   
  112       /**
  113        * Set the children of this number tree.
  114        *
  115        * @param kids The children of this number tree.
  116        */
  117       public void setKids( List kids )
  118       {
  119           node.setItem( "Kids", COSArrayList.converterToCOSArray( kids ) );
  120       }
  121   
  122       /**
  123        * Returns the value corresponding to an index in the number tree.
  124        *
  125        * @param index The index in the number tree.
  126        *
  127        * @return The value corresponding to the index.
  128        * 
  129        * @throws IOException If there is a problem creating the values.
  130        */
  131       public Object getValue( Integer index ) throws IOException
  132       {
  133           Object retval = null;
  134           Map names = getNumbers();
  135           if( names != null )
  136           {
  137               retval = names.get( index );
  138           }
  139           else
  140           {
  141               List kids = getKids();
  142               for( int i=0; i<kids.size() && retval == null; i++ )
  143               {
  144                   PDNumberTreeNode childNode = (PDNumberTreeNode)kids.get( i );
  145                   if( childNode.getLowerLimit().compareTo( index ) <= 0 &&
  146                           childNode.getUpperLimit().compareTo( index ) >= 0 )
  147                   {
  148                       retval = childNode.getValue( index );
  149                   }
  150               }
  151           }
  152           return retval;
  153       }
  154   
  155   
  156       /**
  157        * This will return a map of numbers.  The key will be a java.lang.Integer, the value will
  158        * depend on where this class is being used.
  159        *
  160        * @return A map of COS objects.
  161        * 
  162        * @throws IOException If there is a problem creating the values.
  163        */
  164       public Map getNumbers()  throws IOException
  165       {
  166           Map indices = null;
  167           COSArray namesArray = (COSArray)node.getDictionaryObject( COSName.NUMS );
  168           if( namesArray != null )
  169           {
  170               indices = new HashMap();
  171               for( int i=0; i<namesArray.size(); i+=2 )
  172               {
  173                   COSInteger key = (COSInteger)namesArray.getObject(i);
  174                   COSBase cosValue = namesArray.getObject( i+1 );
  175                   Object pdValue = convertCOSToPD( cosValue );
  176   
  177                   indices.put( Integer.valueOf(key.intValue()), pdValue );
  178               }
  179               indices = Collections.unmodifiableMap(indices);
  180           }
  181   
  182           return indices;
  183       }
  184   
  185       /**
  186        * Method to convert the COS value in the name tree to the PD Model object.  The
  187        * default implementation will simply use reflection to create the correct object
  188        * type.  Subclasses can do whatever they want.
  189        *
  190        * @param base The COS object to convert.
  191        * @return The converted PD Model object.
  192        * @throws IOException If there is an error during creation.
  193        */
  194       protected Object convertCOSToPD( COSBase base ) throws IOException
  195       {
  196           Object retval = null;
  197           try
  198           {
  199               Constructor ctor = valueType.getConstructor( new Class[] { base.getClass() } );
  200               retval = ctor.newInstance( new Object[] { base } );
  201           }
  202           catch( Throwable t )
  203           {
  204               throw new IOException( "Error while trying to create value in number tree:" + t.getMessage());
  205   
  206           }
  207           return retval;
  208       }
  209   
  210       /**
  211        * Create a child node object.
  212        *
  213        * @param dic The dictionary for the child node object to refer to.
  214        * @return The new child node object.
  215        */
  216       protected PDNumberTreeNode createChildNode( COSDictionary dic )
  217       {
  218           return new PDNumberTreeNode(dic,valueType);
  219       }
  220   
  221       /**
  222        * Set the names of for this node.  The keys should be java.lang.String and the
  223        * values must be a COSObjectable.  This method will set the appropriate upper and lower
  224        * limits based on the keys in the map.
  225        *
  226        * @param numbers The map of names to objects.
  227        */
  228       public void setNumbers( Map numbers )
  229       {
  230           if( numbers == null )
  231           {
  232               node.setItem( COSName.NUMS, (COSObjectable)null );
  233               node.setItem( "Limits", (COSObjectable)null);
  234           }
  235           else
  236           {
  237               List keys = new ArrayList( numbers.keySet() );
  238               Collections.sort( keys );
  239               COSArray array = new COSArray();
  240               for( int i=0; i<keys.size(); i++ )
  241               {
  242                   Integer key = (Integer)keys.get(i);
  243                   array.add( COSInteger.get( key ) );
  244                   COSObjectable obj = (COSObjectable)numbers.get( key );
  245                   array.add( obj );
  246               }
  247               Integer lower = null;
  248               Integer upper = null;
  249               if( keys.size() > 0 )
  250               {
  251                   lower = (Integer)keys.get( 0 );
  252                   upper = (Integer)keys.get( keys.size()-1 );
  253               }
  254               setUpperLimit( upper );
  255               setLowerLimit( lower );
  256               node.setItem( "Names", array );
  257           }
  258       }
  259   
  260       /**
  261        * Get the highest value for a key in the name map.
  262        *
  263        * @return The highest value for a key in the map.
  264        */
  265       public Integer getUpperLimit()
  266       {
  267           Integer retval = null;
  268           COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
  269           if( arr != null )
  270           {
  271               retval = Integer.valueOf(arr.getInt( 1 ));
  272           }
  273           return retval;
  274       }
  275   
  276       /**
  277        * Set the highest value for the key in the map.
  278        *
  279        * @param upper The new highest value for a key in the map.
  280        */
  281       private void setUpperLimit( Integer upper )
  282       {
  283           COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
  284           if( arr == null )
  285           {
  286               arr = new COSArray();
  287               arr.add( null );
  288               arr.add( null );
  289           }
  290           arr.setInt( 1, upper.intValue() );
  291       }
  292   
  293       /**
  294        * Get the lowest value for a key in the name map.
  295        *
  296        * @return The lowest value for a key in the map.
  297        */
  298       public Integer getLowerLimit()
  299       {
  300           Integer retval = null;
  301           COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
  302           if( arr != null )
  303           {
  304               retval = Integer.valueOf(arr.getInt( 0 ));
  305           }
  306           return retval;
  307       }
  308   
  309       /**
  310        * Set the lowest value for the key in the map.
  311        *
  312        * @param lower The new lowest value for a key in the map.
  313        */
  314       private void setLowerLimit( Integer lower )
  315       {
  316           COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
  317           if( arr == null )
  318           {
  319               arr = new COSArray();
  320               arr.add( null );
  321               arr.add( null );
  322           }
  323           arr.setInt( 0, lower.intValue() );
  324       }
  325   }

Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.common » [javadoc | source]