KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdmodel > interactive > form > PDAcroForm


1 /**
2  * Copyright (c) 2003-2006, 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.interactive.form;
32
33 import org.pdfbox.cos.COSArray;
34 import org.pdfbox.cos.COSBase;
35 import org.pdfbox.cos.COSDictionary;
36 import org.pdfbox.cos.COSName;
37 import org.pdfbox.cos.COSString;
38
39 import org.pdfbox.pdmodel.PDDocument;
40 import org.pdfbox.pdmodel.PDResources;
41
42 import org.pdfbox.pdmodel.common.COSArrayList;
43 import org.pdfbox.pdmodel.common.COSObjectable;
44 import org.pdfbox.pdmodel.fdf.FDFDictionary;
45 import org.pdfbox.pdmodel.fdf.FDFDocument;
46 import org.pdfbox.pdmodel.fdf.FDFCatalog;
47 import org.pdfbox.pdmodel.fdf.FDFField;
48
49 import java.io.IOException JavaDoc;
50
51 import java.util.ArrayList JavaDoc;
52 import java.util.HashMap JavaDoc;
53 import java.util.Iterator JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.Map JavaDoc;
56
57 /**
58  * This class represents the acroform of a PDF document.
59  *
60  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
61  * @version $Revision: 1.14 $
62  */

63 public class PDAcroForm implements COSObjectable
64 {
65     private COSDictionary acroForm;
66     private PDDocument document;
67
68     private Map JavaDoc fieldCache;
69
70     /**
71      * Constructor.
72      *
73      * @param doc The document that this form is part of.
74      */

75     public PDAcroForm( PDDocument doc )
76     {
77         document = doc;
78         acroForm = new COSDictionary();
79         COSArray fields = new COSArray();
80         acroForm.setItem( COSName.getPDFName( "Fields" ), fields );
81     }
82
83     /**
84      * Constructor.
85      *
86      * @param doc The document that this form is part of.
87      * @param form The existing acroForm.
88      */

89     public PDAcroForm( PDDocument doc, COSDictionary form )
90     {
91         document = doc;
92         acroForm = form;
93     }
94
95     /**
96      * This will get the document associated with this form.
97      *
98      * @return The PDF document.
99      */

100     public PDDocument getDocument()
101     {
102         return document;
103     }
104
105     /**
106      * This will get the dictionary that this form wraps.
107      *
108      * @return The dictionary for this form.
109      */

110     public COSDictionary getDictionary()
111     {
112         return acroForm;
113     }
114
115     /**
116      * This method will import an entire FDF document into the PDF document
117      * that this acroform is part of.
118      *
119      * @param fdf The FDF document to import.
120      *
121      * @throws IOException If there is an error doing the import.
122      */

123     public void importFDF( FDFDocument fdf ) throws IOException JavaDoc
124     {
125         List fields = fdf.getCatalog().getFDF().getFields();
126         if( fields != null )
127         {
128             for( int i=0; i<fields.size(); i++ )
129             {
130                 FDFField fdfField = (FDFField)fields.get( i );
131                 PDField docField = getField( fdfField.getPartialFieldName() );
132                 if( docField != null )
133                 {
134                     docField.importFDF( fdfField );
135                 }
136             }
137         }
138     }
139     
140     /**
141      * This will export all FDF form data.
142      *
143      * @return An FDF document used to export the document.
144      * @throws IOException If there is an error when exporting the document.
145      */

146     public FDFDocument exportFDF() throws IOException JavaDoc
147     {
148         FDFDocument fdf = new FDFDocument();
149         FDFCatalog catalog = fdf.getCatalog();
150         FDFDictionary fdfDict = new FDFDictionary();
151         catalog.setFDF( fdfDict );
152         
153         List fdfFields = new ArrayList();
154         List fields = getFields();
155         Iterator JavaDoc fieldIter = fields.iterator();
156         while( fieldIter.hasNext() )
157         {
158             PDField docField = (PDField)fieldIter.next();
159             addFieldAndChildren( docField, fdfFields );
160         }
161         fdfDict.setID( document.getDocument().getDocumentID() );
162         if( fdfFields.size() > 0 )
163         {
164             fdfDict.setFields( fdfFields );
165         }
166         return fdf;
167     }
168     
169     private void addFieldAndChildren( PDField docField, List fdfFields ) throws IOException JavaDoc
170     {
171         Object JavaDoc fieldValue = docField.getValue();
172         FDFField fdfField = new FDFField();
173         fdfField.setPartialFieldName( docField.getPartialName() );
174         fdfField.setValue( fieldValue );
175         List kids = docField.getKids();
176         List childFDFFields = new ArrayList();
177         if( kids != null )
178         {
179             
180             for( int i=0; i<kids.size(); i++ )
181             {
182                 addFieldAndChildren( (PDField)kids.get( i ), childFDFFields );
183             }
184             if( childFDFFields.size() > 0 )
185             {
186                 fdfField.setKids( childFDFFields );
187             }
188         }
189         if( fieldValue != null || childFDFFields.size() > 0 )
190         {
191             fdfFields.add( fdfField );
192         }
193     }
194
195     /**
196      * This will return all of the fields in the document. The type
197      * will be a org.pdfbox.pdmodel.field.PDField.
198      *
199      * @return A list of all the fields.
200      * @throws IOException If there is an error while getting the list of fields.
201      */

202     public List getFields() throws IOException JavaDoc
203     {
204         List retval = null;
205         COSArray fields =
206             (COSArray) acroForm.getDictionaryObject(
207                 COSName.getPDFName("Fields"));
208         
209         if( fields != null )
210         {
211             List actuals = new ArrayList();
212             for (int i = 0; i < fields.size(); i++)
213             {
214                 COSDictionary element = (COSDictionary) fields.getObject(i);
215                 if (element != null)
216                 {
217                     PDField field = PDFieldFactory.createField( this, element );
218                     if( field != null )
219                     {
220                         actuals.add(field);
221                     }
222                 }
223             }
224             retval = new COSArrayList( actuals, fields );
225         }
226         return retval;
227     }
228     
229     /**
230      * Set the fields that are part of this AcroForm.
231      *
232      * @param fields The fields that are part of this form.
233      */

234     public void setFields( List fields )
235     {
236         acroForm.setItem( "Fields", COSArrayList.converterToCOSArray( fields ));
237     }
238
239     /**
240      * This will tell this form to cache the fields into a Map structure
241      * for fast access via the getField method. The default is false. You would
242      * want this to be false if you were changing the COSDictionary behind the scenes,
243      * otherwise setting this to true is acceptable.
244      *
245      * @param cache A boolean telling if we should cache the fields.
246      * @throws IOException If there is an error while caching the fields.
247      */

248     public void setCacheFields( boolean cache ) throws IOException JavaDoc
249     {
250         if( cache )
251         {
252             fieldCache = new HashMap JavaDoc();
253             List fields = getFields();
254             Iterator JavaDoc fieldIter = fields.iterator();
255             while( fieldIter.hasNext() )
256             {
257                 PDField next = (PDField)fieldIter.next();
258                 fieldCache.put( next.getFullyQualifiedName(), next );
259             }
260         }
261         else
262         {
263             fieldCache = null;
264         }
265     }
266
267     /**
268      * This will tell if this acro form is caching the fields.
269      *
270      * @return true if the fields are being cached.
271      */

272     public boolean isCachingFields()
273     {
274         return fieldCache != null;
275     }
276
277     /**
278      * This will get a field by name, possibly using the cache if setCache is true.
279      *
280      * @param name The name of the field to get.
281      *
282      * @return The field with that name of null if one was not found.
283      *
284      * @throws IOException If there is an error getting the field type.
285      */

286     public PDField getField( String JavaDoc name ) throws IOException JavaDoc
287     {
288         PDField retval = null;
289         if( fieldCache != null )
290         {
291             retval = (PDField)fieldCache.get( name );
292         }
293         else
294         {
295             String JavaDoc[] nameSubSection = name.split( "\\." );
296             COSArray fields =
297                 (COSArray) acroForm.getDictionaryObject(
298                     COSName.getPDFName("Fields"));
299
300             for (int i = 0; i < fields.size() && retval == null; i++)
301             {
302                 COSDictionary element = (COSDictionary) fields.getObject(i);
303                 if( element != null )
304                 {
305                     COSString fieldName =
306                         (COSString)element.getDictionaryObject( COSName.getPDFName( "T" ) );
307                     if( fieldName.getString().equals( name ) ||
308                         fieldName.getString().equals( nameSubSection[0] ) )
309                     {
310                         PDField root = PDFieldFactory.createField( this, element );
311                         
312                         if( nameSubSection.length > 1 )
313                         {
314                             PDField kid = root.findKid( nameSubSection, 1 );
315                             if( kid != null )
316                             {
317                                 retval = kid;
318                             }
319                             else
320                             {
321                                 retval = root;
322                             }
323                         }
324                         else
325                         {
326                             retval = root;
327                         }
328                     }
329                 }
330             }
331         }
332         return retval;
333     }
334
335     /**
336      * This will get the default resources for the acro form.
337      *
338      * @return The default resources.
339      */

340     public PDResources getDefaultResources()
341     {
342         PDResources retval = null;
343         COSDictionary dr = (COSDictionary)acroForm.getDictionaryObject( COSName.getPDFName( "DR" ) );
344         if( dr != null )
345         {
346             retval = new PDResources( dr );
347         }
348         return retval;
349     }
350
351     /**
352      * This will set the default resources for the acroform.
353      *
354      * @param dr The new default resources.
355      */

356     public void setDefaultResources( PDResources dr )
357     {
358         COSDictionary drDict = null;
359         if( dr != null )
360         {
361             drDict = dr.getCOSDictionary();
362         }
363         acroForm.setItem( COSName.getPDFName( "DR" ), drDict );
364     }
365     
366     /**
367      * {@inheritDoc}
368      */

369     public COSBase getCOSObject()
370     {
371         return acroForm;
372     }
373     
374     /**
375      * Get the XFA resource, the XFA resource is only used for PDF 1.5+ forms.
376      *
377      * @return The xfa resource or null if it does not exist.
378      */

379     public PDXFA getXFA()
380     {
381         PDXFA xfa = null;
382         COSBase base = acroForm.getDictionaryObject( "XFA" );
383         if( base != null )
384         {
385             xfa = new PDXFA( base );
386         }
387         return xfa;
388     }
389     
390     /**
391      * Set the XFA resource, this is only used for PDF 1.5+ forms.
392      *
393      * @param xfa The xfa resource.
394      */

395     public void setXFA( PDXFA xfa )
396     {
397         acroForm.setItem( "XFA", xfa );
398     }
399 }
Popular Tags