Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.interactive.form » [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.interactive.form;
   18   
   19   import org.apache.pdfbox.cos.COSArray;
   20   import org.apache.pdfbox.cos.COSBase;
   21   import org.apache.pdfbox.cos.COSDictionary;
   22   import org.apache.pdfbox.cos.COSName;
   23   import org.apache.pdfbox.cos.COSString;
   24   
   25   import org.apache.pdfbox.pdmodel.PDDocument;
   26   import org.apache.pdfbox.pdmodel.PDResources;
   27   
   28   import org.apache.pdfbox.pdmodel.common.COSArrayList;
   29   import org.apache.pdfbox.pdmodel.common.COSObjectable;
   30   import org.apache.pdfbox.pdmodel.fdf.FDFDictionary;
   31   import org.apache.pdfbox.pdmodel.fdf.FDFDocument;
   32   import org.apache.pdfbox.pdmodel.fdf.FDFCatalog;
   33   import org.apache.pdfbox.pdmodel.fdf.FDFField;
   34   
   35   import java.io.IOException;
   36   
   37   import java.util.ArrayList;
   38   import java.util.HashMap;
   39   import java.util.Iterator;
   40   import java.util.List;
   41   import java.util.Map;
   42   
   43   /**
   44    * This class represents the acroform of a PDF document.
   45    *
   46    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   47    * @version $Revision: 1.14 $
   48    */
   49   public class PDAcroForm implements COSObjectable
   50   {
   51       private COSDictionary acroForm;
   52       private PDDocument document;
   53   
   54       private Map fieldCache;
   55   
   56       /**
   57        * Constructor.
   58        *
   59        * @param doc The document that this form is part of.
   60        */
   61       public PDAcroForm( PDDocument doc )
   62       {
   63           document = doc;
   64           acroForm = new COSDictionary();
   65           COSArray fields = new COSArray();
   66           acroForm.setItem( COSName.getPDFName( "Fields" ), fields );
   67       }
   68   
   69       /**
   70        * Constructor.
   71        *
   72        * @param doc The document that this form is part of.
   73        * @param form The existing acroForm.
   74        */
   75       public PDAcroForm( PDDocument doc, COSDictionary form )
   76       {
   77           document = doc;
   78           acroForm = form;
   79       }
   80   
   81       /**
   82        * This will get the document associated with this form.
   83        *
   84        * @return The PDF document.
   85        */
   86       public PDDocument getDocument()
   87       {
   88           return document;
   89       }
   90   
   91       /**
   92        * This will get the dictionary that this form wraps.
   93        *
   94        * @return The dictionary for this form.
   95        */
   96       public COSDictionary getDictionary()
   97       {
   98           return acroForm;
   99       }
  100   
  101       /**
  102        * This method will import an entire FDF document into the PDF document
  103        * that this acroform is part of.
  104        *
  105        * @param fdf The FDF document to import.
  106        *
  107        * @throws IOException If there is an error doing the import.
  108        */
  109       public void importFDF( FDFDocument fdf ) throws IOException
  110       {
  111           List fields = fdf.getCatalog().getFDF().getFields();
  112           if( fields != null )
  113           {
  114               for( int i=0; i<fields.size(); i++ )
  115               {
  116                   FDFField fdfField = (FDFField)fields.get( i );
  117                   PDField docField = getField( fdfField.getPartialFieldName() );
  118                   if( docField != null )
  119                   {
  120                       docField.importFDF( fdfField );
  121                   }
  122               }
  123           }
  124       }
  125   
  126       /**
  127        * This will export all FDF form data.
  128        *
  129        * @return An FDF document used to export the document.
  130        * @throws IOException If there is an error when exporting the document.
  131        */
  132       public FDFDocument exportFDF() throws IOException
  133       {
  134           FDFDocument fdf = new FDFDocument();
  135           FDFCatalog catalog = fdf.getCatalog();
  136           FDFDictionary fdfDict = new FDFDictionary();
  137           catalog.setFDF( fdfDict );
  138   
  139           List fdfFields = new ArrayList();
  140           List fields = getFields();
  141           Iterator fieldIter = fields.iterator();
  142           while( fieldIter.hasNext() )
  143           {
  144               PDField docField = (PDField)fieldIter.next();
  145               addFieldAndChildren( docField, fdfFields );
  146           }
  147           fdfDict.setID( document.getDocument().getDocumentID() );
  148           if( fdfFields.size() > 0 )
  149           {
  150               fdfDict.setFields( fdfFields );
  151           }
  152           return fdf;
  153       }
  154   
  155       private void addFieldAndChildren( PDField docField, List fdfFields ) throws IOException
  156       {
  157           Object fieldValue = docField.getValue();
  158           FDFField fdfField = new FDFField();
  159           fdfField.setPartialFieldName( docField.getPartialName() );
  160           fdfField.setValue( fieldValue );
  161           List kids = docField.getKids();
  162           List childFDFFields = new ArrayList();
  163           if( kids != null )
  164           {
  165   
  166               for( int i=0; i<kids.size(); i++ )
  167               {
  168                   addFieldAndChildren( (PDField)kids.get( i ), childFDFFields );
  169               }
  170               if( childFDFFields.size() > 0 )
  171               {
  172                   fdfField.setKids( childFDFFields );
  173               }
  174           }
  175           if( fieldValue != null || childFDFFields.size() > 0 )
  176           {
  177               fdfFields.add( fdfField );
  178           }
  179       }
  180   
  181       /**
  182        * This will return all of the fields in the document.  The type
  183        * will be a org.apache.pdfbox.pdmodel.field.PDField.
  184        *
  185        * @return A list of all the fields.
  186        * @throws IOException If there is an error while getting the list of fields.
  187        */
  188       public List getFields() throws IOException
  189       {
  190           List retval = null;
  191           COSArray fields =
  192               (COSArray) acroForm.getDictionaryObject(
  193                   COSName.getPDFName("Fields"));
  194   
  195           if( fields != null )
  196           {
  197               List actuals = new ArrayList();
  198               for (int i = 0; i < fields.size(); i++)
  199               {
  200                   COSDictionary element = (COSDictionary) fields.getObject(i);
  201                   if (element != null)
  202                   {
  203                       PDField field = PDFieldFactory.createField( this, element );
  204                       if( field != null )
  205                       {
  206                           actuals.add(field);
  207                       }
  208                   }
  209               }
  210               retval = new COSArrayList( actuals, fields );
  211           }
  212           return retval;
  213       }
  214   
  215       /**
  216        * Set the fields that are part of this AcroForm.
  217        *
  218        * @param fields The fields that are part of this form.
  219        */
  220       public void setFields( List fields )
  221       {
  222           acroForm.setItem( "Fields", COSArrayList.converterToCOSArray( fields ));
  223       }
  224   
  225       /**
  226        * This will tell this form to cache the fields into a Map structure
  227        * for fast access via the getField method.  The default is false.  You would
  228        * want this to be false if you were changing the COSDictionary behind the scenes,
  229        * otherwise setting this to true is acceptable.
  230        *
  231        * @param cache A boolean telling if we should cache the fields.
  232        * @throws IOException If there is an error while caching the fields.
  233        */
  234       public void setCacheFields( boolean cache ) throws IOException
  235       {
  236           if( cache )
  237           {
  238               fieldCache = new HashMap();
  239               List fields = getFields();
  240               Iterator fieldIter = fields.iterator();
  241               while( fieldIter.hasNext() )
  242               {
  243                   PDField next = (PDField)fieldIter.next();
  244                   fieldCache.put( next.getFullyQualifiedName(), next );
  245               }
  246           }
  247           else
  248           {
  249               fieldCache = null;
  250           }
  251       }
  252   
  253       /**
  254        * This will tell if this acro form is caching the fields.
  255        *
  256        * @return true if the fields are being cached.
  257        */
  258       public boolean isCachingFields()
  259       {
  260           return fieldCache != null;
  261       }
  262   
  263       /**
  264        * This will get a field by name, possibly using the cache if setCache is true.
  265        *
  266        * @param name The name of the field to get.
  267        *
  268        * @return The field with that name of null if one was not found.
  269        *
  270        * @throws IOException If there is an error getting the field type.
  271        */
  272       public PDField getField( String name ) throws IOException
  273       {
  274           PDField retval = null;
  275           if( fieldCache != null )
  276           {
  277               retval = (PDField)fieldCache.get( name );
  278           }
  279           else
  280           {
  281               String[] nameSubSection = name.split( "\\." );
  282               COSArray fields =
  283                   (COSArray) acroForm.getDictionaryObject(
  284                       COSName.getPDFName("Fields"));
  285   
  286               for (int i = 0; i < fields.size() && retval == null; i++)
  287               {
  288                   COSDictionary element = (COSDictionary) fields.getObject(i);
  289                   if( element != null )
  290                   {
  291                       COSString fieldName =
  292                           (COSString)element.getDictionaryObject( COSName.getPDFName( "T" ) );
  293                       if( fieldName.getString().equals( name ) ||
  294                           fieldName.getString().equals( nameSubSection[0] ) )
  295                       {
  296                           PDField root = PDFieldFactory.createField( this, element );
  297   
  298                           if( nameSubSection.length > 1 )
  299                           {
  300                               PDField kid = root.findKid( nameSubSection, 1 );
  301                               if( kid != null )
  302                               {
  303                                   retval = kid;
  304                               }
  305                               else
  306                               {
  307                                   retval = root;
  308                               }
  309                           }
  310                           else
  311                           {
  312                               retval = root;
  313                           }
  314                       }
  315                   }
  316               }
  317           }
  318           return retval;
  319       }
  320   
  321       /**
  322        * This will get the default resources for the acro form.
  323        *
  324        * @return The default resources.
  325        */
  326       public PDResources getDefaultResources()
  327       {
  328           PDResources retval = null;
  329           COSDictionary dr = (COSDictionary)acroForm.getDictionaryObject( COSName.getPDFName( "DR" ) );
  330           if( dr != null )
  331           {
  332               retval = new PDResources( dr );
  333           }
  334           return retval;
  335       }
  336   
  337       /**
  338        * This will set the default resources for the acroform.
  339        *
  340        * @param dr The new default resources.
  341        */
  342       public void setDefaultResources( PDResources dr )
  343       {
  344           COSDictionary drDict = null;
  345           if( dr != null )
  346           {
  347               drDict = dr.getCOSDictionary();
  348           }
  349           acroForm.setItem( COSName.getPDFName( "DR" ), drDict );
  350       }
  351   
  352       /**
  353        * {@inheritDoc}
  354        */
  355       public COSBase getCOSObject()
  356       {
  357           return acroForm;
  358       }
  359   
  360       /**
  361        * Get the XFA resource, the XFA resource is only used for PDF 1.5+ forms.
  362        *
  363        * @return The xfa resource or null if it does not exist.
  364        */
  365       public PDXFA getXFA()
  366       {
  367           PDXFA xfa = null;
  368           COSBase base = acroForm.getDictionaryObject( "XFA" );
  369           if( base != null )
  370           {
  371               xfa = new PDXFA( base );
  372           }
  373           return xfa;
  374       }
  375   
  376       /**
  377        * Set the XFA resource, this is only used for PDF 1.5+ forms.
  378        *
  379        * @param xfa The xfa resource.
  380        */
  381       public void setXFA( PDXFA xfa )
  382       {
  383           acroForm.setItem( "XFA", xfa );
  384       }
  385   }

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