Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdfviewer » [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.pdfviewer;
   18   
   19   /**
   20    * A tree model that uses a cos document.
   21    *
   22    *
   23    * @author  wurtz
   24    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   25    * @version $Revision: 1.9 $
   26    */
   27   import javax.swing.tree.TreePath;
   28   import javax.swing.tree.TreeModel;
   29   
   30   //import java.awt.event.*;
   31   import javax.swing.event.TreeModelListener;
   32   
   33   import org.apache.pdfbox.cos.COSArray;
   34   import org.apache.pdfbox.cos.COSBase;
   35   import org.apache.pdfbox.cos.COSDictionary;
   36   import org.apache.pdfbox.cos.COSDocument;
   37   import org.apache.pdfbox.cos.COSName;
   38   import org.apache.pdfbox.cos.COSObject;
   39   
   40   import org.apache.pdfbox.pdmodel.PDDocument;
   41   
   42   import java.util.ArrayList;
   43   import java.util.Collections;
   44   import java.util.List;
   45   
   46   /**
   47    * A class to model a PDF document as a tree structure.
   48    *
   49    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   50    * @version $Revision: 1.9 $
   51    */
   52   public class PDFTreeModel implements TreeModel
   53   {
   54       private PDDocument document;
   55   
   56       /**
   57        * constructor.
   58        */
   59       public PDFTreeModel()
   60       {
   61           //default constructor
   62       }
   63   
   64       /**
   65        * Constructor to take a document.
   66        *
   67        * @param doc The document to display in the tree.
   68        */
   69       public PDFTreeModel(PDDocument doc)
   70       {
   71            setDocument(doc);
   72       }
   73   
   74       /**
   75        * Set the document to display in the tree.
   76        *
   77        * @param doc The document to display in the tree.
   78        */
   79       public void setDocument(PDDocument doc)
   80       {
   81           document = doc;
   82       }
   83       /**
   84        * Adds a listener for the <code>TreeModelEvent</code>
   85        * posted after the tree changes.
   86        *
   87        * @param   l       the listener to add
   88        * @see     #removeTreeModelListener
   89        *
   90        */
   91       public void addTreeModelListener(TreeModelListener l)
   92       {
   93           //required for interface
   94       }
   95   
   96       /**
   97        * Returns the child of <code>parent</code> at index <code>index</code>
   98        * in the parent's
   99        * child array.  <code>parent</code> must be a node previously obtained
  100        * from this data source. This should not return <code>null</code>
  101        * if <code>index</code>
  102        * is a valid index for <code>parent</code> (that is <code>index >= 0 &&
  103        * index < getChildCount(parent</code>)).
  104        *
  105        * @param   parent  a node in the tree, obtained from this data source
  106        * @param index The index into the parent object to location the child object.
  107        * @return  the child of <code>parent</code> at index <code>index</code>
  108        *
  109        */
  110       public Object getChild(Object parent, int index)
  111       {
  112           Object retval = null;
  113           if( parent instanceof COSArray )
  114           {
  115               ArrayEntry entry = new ArrayEntry();
  116               entry.setIndex( index );
  117               entry.setValue( ((COSArray)parent).getObject( index ) );
  118               retval = entry;
  119           }
  120           else if( parent instanceof COSDictionary )
  121           {
  122               COSDictionary dict = ((COSDictionary)parent);
  123               List<COSName> keys = new ArrayList<COSName>(dict.keySet());
  124               Collections.sort( keys );
  125               Object key = keys.get( index );
  126               Object value = dict.getDictionaryObject( (COSName)key );
  127               MapEntry entry = new MapEntry();
  128               entry.setKey( key );
  129               entry.setValue( value );
  130               retval = entry;
  131           }
  132           else if( parent instanceof MapEntry )
  133           {
  134               retval = getChild( ((MapEntry)parent).getValue(), index );
  135           }
  136           else if( parent instanceof ArrayEntry )
  137           {
  138               retval = getChild( ((ArrayEntry)parent).getValue(), index );
  139           }
  140           else if( parent instanceof COSDocument )
  141           {
  142               retval = ((COSDocument)parent).getObjects().get( index );
  143           }
  144           else if( parent instanceof COSObject )
  145           {
  146               retval = ((COSObject)parent).getObject();
  147           }
  148           else
  149           {
  150               throw new RuntimeException( "Unknown COS type " + parent.getClass().getName() );
  151           }
  152           return retval;
  153       }
  154   
  155       /** Returns the number of children of <code>parent</code>.
  156        * Returns 0 if the node
  157        * is a leaf or if it has no children.  <code>parent</code> must be a node
  158        * previously obtained from this data source.
  159        *
  160        * @param   parent  a node in the tree, obtained from this data source
  161        * @return  the number of children of the node <code>parent</code>
  162        *
  163        */
  164       public int getChildCount(Object parent)
  165       {
  166           int retval = 0;
  167           if( parent instanceof COSArray )
  168           {
  169               retval = ((COSArray)parent).size();
  170           }
  171           else if( parent instanceof COSDictionary )
  172           {
  173               retval = ((COSDictionary)parent).size();
  174           }
  175           else if( parent instanceof MapEntry )
  176           {
  177               retval = getChildCount( ((MapEntry)parent).getValue() );
  178           }
  179           else if( parent instanceof ArrayEntry )
  180           {
  181               retval = getChildCount( ((ArrayEntry)parent).getValue() );
  182           }
  183           else if( parent instanceof COSDocument )
  184           {
  185               retval = ((COSDocument)parent).getObjects().size();
  186           }
  187           else if( parent instanceof COSObject )
  188           {
  189               retval = 1;
  190           }
  191           return retval;
  192       }
  193   
  194       /** Returns the index of child in parent.  If <code>parent</code>
  195        * is <code>null</code> or <code>child</code> is <code>null</code>,
  196        * returns -1.
  197        *
  198        * @param parent a note in the tree, obtained from this data source
  199        * @param child the node we are interested in
  200        * @return the index of the child in the parent, or -1 if either
  201        *    <code>child</code> or <code>parent</code> are <code>null</code>
  202        *
  203        */
  204       public int getIndexOfChild(Object parent, Object child)
  205       {
  206           int retval = -1;
  207           if( parent != null && child != null )
  208           {
  209               if( parent instanceof COSArray )
  210               {
  211                   COSArray array = (COSArray)parent;
  212                   if( child instanceof ArrayEntry )
  213                   {
  214                       ArrayEntry arrayEntry = (ArrayEntry)child;
  215                       retval = arrayEntry.getIndex();
  216                   }
  217                   else
  218                   {
  219                       retval = array.indexOf( (COSBase)child );
  220                   }
  221               }
  222               else if( parent instanceof COSDictionary )
  223               {
  224                   MapEntry entry = (MapEntry)child;
  225                   COSDictionary dict = (COSDictionary)parent;
  226                   List<COSName> keys = new ArrayList<COSName>(dict.keySet());
  227                   Collections.sort( keys );
  228                   for( int i=0; retval == -1 && i<keys.size(); i++ )
  229                   {
  230                       if( keys.get( i ).equals( entry.getKey() ) )
  231                       {
  232                           retval = i;
  233                       }
  234                   }
  235               }
  236               else if( parent instanceof MapEntry )
  237               {
  238                   retval = getIndexOfChild( ((MapEntry)parent).getValue(), child );
  239               }
  240               else if( parent instanceof ArrayEntry )
  241               {
  242                   retval = getIndexOfChild( ((ArrayEntry)parent).getValue(), child );
  243               }
  244               else if( parent instanceof COSDocument )
  245               {
  246                   retval = ((COSDocument)parent).getObjects().indexOf( child );
  247               }
  248               else if( parent instanceof COSObject )
  249               {
  250                   retval = 0;
  251               }
  252               else
  253               {
  254                   throw new RuntimeException( "Unknown COS type " + parent.getClass().getName() );
  255               }
  256           }
  257           return retval;
  258       }
  259   
  260       /** Returns the root of the tree.  Returns <code>null</code>
  261        * only if the tree has no nodes.
  262        *
  263        * @return  the root of the tree
  264        *
  265        */
  266       public Object getRoot()
  267       {
  268           return document.getDocument().getTrailer();
  269       }
  270   
  271       /** Returns <code>true</code> if <code>node</code> is a leaf.
  272        * It is possible for this method to return <code>false</code>
  273        * even if <code>node</code> has no children.
  274        * A directory in a filesystem, for example,
  275        * may contain no files; the node representing
  276        * the directory is not a leaf, but it also has no children.
  277        *
  278        * @param   node  a node in the tree, obtained from this data source
  279        * @return  true if <code>node</code> is a leaf
  280        *
  281        */
  282       public boolean isLeaf(Object node)
  283       {
  284           boolean isLeaf = !(node instanceof COSDictionary ||
  285                    node instanceof COSArray ||
  286                    node instanceof COSDocument ||
  287                    node instanceof COSObject ||
  288                    (node instanceof MapEntry && !isLeaf(((MapEntry)node).getValue()) ) ||
  289                    (node instanceof ArrayEntry && !isLeaf(((ArrayEntry)node).getValue()) ));
  290           return isLeaf;
  291       }
  292   
  293       /** Removes a listener previously added with
  294        * <code>addTreeModelListener</code>.
  295        *
  296        * @see     #addTreeModelListener
  297        * @param   l       the listener to remove
  298        *
  299        */
  300   
  301       public void removeTreeModelListener(TreeModelListener l)
  302       {
  303           //required for interface
  304       }
  305   
  306       /** Messaged when the user has altered the value for the item identified
  307        * by <code>path</code> to <code>newValue</code>.
  308        * If <code>newValue</code> signifies a truly new value
  309        * the model should post a <code>treeNodesChanged</code> event.
  310        *
  311        * @param path path to the node that the user has altered
  312        * @param newValue the new value from the TreeCellEditor
  313        *
  314        */
  315       public void valueForPathChanged(TreePath path, Object newValue)
  316       {
  317           //required for interface
  318       }
  319   }

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