1 | /* | |
2 | * $Id: PRAcroForm.java 3735 2009-02-26 01:44:03Z xlv $ | |
3 | * | |
4 | * Copyright 2001, 2002 by Paulo Soares. | |
5 | * | |
6 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
7 | * (the "License"); you may not use this file except in compliance with the License. | |
8 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
9 | * | |
10 | * Software distributed under the License is distributed on an "AS IS" basis, | |
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 | * for the specific language governing rights and limitations under the License. | |
13 | * | |
14 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
15 | * | |
16 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
17 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
18 | * All Rights Reserved. | |
19 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
20 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
21 | * | |
22 | * This class written by Mark Thompson, Copyright (C) 2002 by Mark Thompson. | |
23 | * | |
24 | * Contributor(s): all the names of the contributors are added in the source code | |
25 | * where applicable. | |
26 | * | |
27 | * Alternatively, the contents of this file may be used under the terms of the | |
28 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
29 | * provisions of LGPL are applicable instead of those above. If you wish to | |
30 | * allow use of your version of this file only under the terms of the LGPL | |
31 | * License and not to allow others to use your version of this file under | |
32 | * the MPL, indicate your decision by deleting the provisions above and | |
33 | * replace them with the notice and other provisions required by the LGPL. | |
34 | * If you do not delete the provisions above, a recipient may use your version | |
35 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
36 | * | |
37 | * This library is free software; you can redistribute it and/or modify it | |
38 | * under the terms of the MPL as stated above or under the terms of the GNU | |
39 | * Library General Public License as published by the Free Software Foundation; | |
40 | * either version 2 of the License, or any later version. | |
41 | * | |
42 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
43 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
44 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
45 | * details. | |
46 | * | |
47 | * If you didn't download this code from the following link, you should check if | |
48 | * you aren't using an obsolete version: | |
49 | * http://www.lowagie.com/iText/ | |
50 | */ | |
51 | ||
52 | package com.lowagie.text.pdf; | |
53 | ||
54 | import java.util.ArrayList; | |
55 | import java.util.HashMap; | |
56 | import java.util.Iterator; | |
57 | ||
58 | /** | |
59 | * This class captures an AcroForm on input. Basically, it extends Dictionary | |
60 | * by indexing the fields of an AcroForm | |
61 | * @author Mark Thompson | |
62 | */ | |
63 | ||
64 | public class PRAcroForm extends PdfDictionary { | |
65 | | |
66 | /** | |
67 | * This class holds the information for a single field | |
68 | */ | |
69 | public static class FieldInformation { | |
70 | String name; | |
71 | PdfDictionary info; | |
72 | PRIndirectReference ref; | |
73 | | |
74 | FieldInformation(String name, PdfDictionary info, PRIndirectReference ref) { | |
75 | this.name = name; this.info = info; this.ref = ref; | |
76 | } | |
77 | public String getName() { return name; } | |
78 | public PdfDictionary getInfo() { return info; } | |
79 | public PRIndirectReference getRef() { return ref; } | |
80 | } | |
81 | ||
82 | ArrayList fields; | |
83 | ArrayList stack; | |
84 | HashMap fieldByName; | |
85 | PdfReader reader; | |
86 | | |
87 | /** | |
88 | * Constructor | |
89 | * @param reader reader of the input file | |
90 | */ | |
91 | public PRAcroForm(PdfReader reader) { | |
92 | this.reader = reader; | |
93 | fields = new ArrayList(); | |
94 | fieldByName = new HashMap(); | |
95 | stack = new ArrayList(); | |
96 | } | |
97 | /** | |
98 | * Number of fields found | |
99 | * @return size | |
100 | */ | |
101 | public int size() { | |
102 | return fields.size(); | |
103 | } | |
104 | | |
105 | public ArrayList getFields() { | |
106 | return fields; | |
107 | } | |
108 | | |
109 | public FieldInformation getField(String name) { | |
110 |
1
1. getField : mutated return of Object value for com/lowagie/text/pdf/PRAcroForm::getField to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return (FieldInformation)fieldByName.get(name); |
111 | } | |
112 | | |
113 | /** | |
114 | * Given the title (/T) of a reference, return the associated reference | |
115 | * @param name a string containing the path | |
116 | * @return a reference to the field, or null | |
117 | */ | |
118 | public PRIndirectReference getRefByName(String name) { | |
119 | FieldInformation fi = (FieldInformation)fieldByName.get(name); | |
120 |
2
1. getRefByName : negated conditional → NO_COVERAGE 2. getRefByName : mutated return of Object value for com/lowagie/text/pdf/PRAcroForm::getRefByName to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
if (fi == null) return null; |
121 |
1
1. getRefByName : mutated return of Object value for com/lowagie/text/pdf/PRAcroForm::getRefByName to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return fi.getRef(); |
122 | } | |
123 | /** | |
124 | * Read, and comprehend the acroform | |
125 | * @param root the document root | |
126 | */ | |
127 | public void readAcroForm(PdfDictionary root) { | |
128 |
1
1. readAcroForm : negated conditional → NO_COVERAGE |
if (root == null) |
129 | return; | |
130 | hashMap = root.hashMap; | |
131 |
1
1. readAcroForm : removed call to com/lowagie/text/pdf/PRAcroForm::pushAttrib → NO_COVERAGE |
pushAttrib(root); |
132 | PdfArray fieldlist = (PdfArray)PdfReader.getPdfObjectRelease(root.get(PdfName.FIELDS)); | |
133 |
1
1. readAcroForm : removed call to com/lowagie/text/pdf/PRAcroForm::iterateFields → NO_COVERAGE |
iterateFields(fieldlist, null, null); |
134 | } | |
135 | | |
136 | /** | |
137 | * After reading, we index all of the fields. Recursive. | |
138 | * @param fieldlist An array of fields | |
139 | * @param fieldDict the last field dictionary we encountered (recursively) | |
140 | * @param title the pathname of the field, up to this point or null | |
141 | */ | |
142 | protected void iterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String title) { | |
143 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
for (Iterator it = fieldlist.listIterator(); it.hasNext();) { |
144 | PRIndirectReference ref = (PRIndirectReference)it.next(); | |
145 | PdfDictionary dict = (PdfDictionary) PdfReader.getPdfObjectRelease(ref); | |
146 | | |
147 | // if we are not a field dictionary, pass our parent's values | |
148 | PRIndirectReference myFieldDict = fieldDict; | |
149 | String myTitle = title; | |
150 | PdfString tField = (PdfString)dict.get(PdfName.T); | |
151 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
boolean isFieldDict = tField != null; |
152 | | |
153 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
if (isFieldDict) { |
154 | myFieldDict = ref; | |
155 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
if (title == null) myTitle = tField.toString(); |
156 | else myTitle = title + '.' + tField.toString(); | |
157 | } | |
158 | | |
159 | PdfArray kids = (PdfArray)dict.get(PdfName.KIDS); | |
160 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
if (kids != null) { |
161 |
1
1. iterateFields : removed call to com/lowagie/text/pdf/PRAcroForm::pushAttrib → NO_COVERAGE |
pushAttrib(dict); |
162 |
1
1. iterateFields : removed call to com/lowagie/text/pdf/PRAcroForm::iterateFields → NO_COVERAGE |
iterateFields(kids, myFieldDict, myTitle); |
163 |
1
1. iterateFields : Replaced integer subtraction with addition → NO_COVERAGE |
stack.remove(stack.size() - 1); // pop |
164 | } | |
165 | else { // leaf node | |
166 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
if (myFieldDict != null) { |
167 |
1
1. iterateFields : Replaced integer subtraction with addition → NO_COVERAGE |
PdfDictionary mergedDict = (PdfDictionary)stack.get(stack.size() - 1); |
168 |
1
1. iterateFields : negated conditional → NO_COVERAGE |
if (isFieldDict) |
169 | mergedDict = mergeAttrib(mergedDict, dict); | |
170 | | |
171 |
1
1. iterateFields : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
mergedDict.put(PdfName.T, new PdfString(myTitle)); |
172 | FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict); | |
173 | fields.add(fi); | |
174 | fieldByName.put(myTitle, fi); | |
175 | } | |
176 | } | |
177 | } | |
178 | } | |
179 | /** | |
180 | * merge field attributes from two dictionaries | |
181 | * @param parent one dictionary | |
182 | * @param child the other dictionary | |
183 | * @return a merged dictionary | |
184 | */ | |
185 | protected PdfDictionary mergeAttrib(PdfDictionary parent, PdfDictionary child) { | |
186 | PdfDictionary targ = new PdfDictionary(); | |
187 |
2
1. mergeAttrib : negated conditional → NO_COVERAGE 2. mergeAttrib : removed call to com/lowagie/text/pdf/PdfDictionary::putAll → NO_COVERAGE |
if (parent != null) targ.putAll(parent); |
188 | ||
189 | for (PdfName key : child.getKeys()) { | |
190 |
2
1. mergeAttrib : negated conditional → NO_COVERAGE 2. mergeAttrib : negated conditional → NO_COVERAGE |
if (key.equals(PdfName.DR) || key.equals(PdfName.DA) || |
191 |
2
1. mergeAttrib : negated conditional → NO_COVERAGE 2. mergeAttrib : negated conditional → NO_COVERAGE |
key.equals(PdfName.Q) || key.equals(PdfName.FF) || |
192 |
2
1. mergeAttrib : negated conditional → NO_COVERAGE 2. mergeAttrib : negated conditional → NO_COVERAGE |
key.equals(PdfName.DV) || key.equals(PdfName.V) |
193 |
1
1. mergeAttrib : negated conditional → NO_COVERAGE |
|| key.equals(PdfName.FT) |
194 |
1
1. mergeAttrib : negated conditional → NO_COVERAGE |
|| key.equals(PdfName.F)) { |
195 |
1
1. mergeAttrib : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
targ.put(key, child.get(key)); |
196 | } | |
197 | } | |
198 |
1
1. mergeAttrib : mutated return of Object value for com/lowagie/text/pdf/PRAcroForm::mergeAttrib to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return targ; |
199 | } | |
200 | /** | |
201 | * stack a level of dictionary. Merge in a dictionary from this level | |
202 | */ | |
203 | protected void pushAttrib(PdfDictionary dict) { | |
204 | PdfDictionary dic = null; | |
205 |
1
1. pushAttrib : negated conditional → NO_COVERAGE |
if (!stack.isEmpty()) { |
206 |
1
1. pushAttrib : Replaced integer subtraction with addition → NO_COVERAGE |
dic = (PdfDictionary)stack.get(stack.size() - 1); |
207 | } | |
208 | dic = mergeAttrib(dic, dict); | |
209 | stack.add(dic); | |
210 | } | |
211 | } | |
Mutations | ||
110 |
1.1 |
|
120 |
1.1 2.2 |
|
121 |
1.1 |
|
128 |
1.1 |
|
131 |
1.1 |
|
133 |
1.1 |
|
143 |
1.1 |
|
151 |
1.1 |
|
153 |
1.1 |
|
155 |
1.1 |
|
160 |
1.1 |
|
161 |
1.1 |
|
162 |
1.1 |
|
163 |
1.1 |
|
166 |
1.1 |
|
167 |
1.1 |
|
168 |
1.1 |
|
171 |
1.1 |
|
187 |
1.1 2.2 |
|
190 |
1.1 2.2 |
|
191 |
1.1 2.2 |
|
192 |
1.1 2.2 |
|
193 |
1.1 |
|
194 |
1.1 |
|
195 |
1.1 |
|
198 |
1.1 |
|
205 |
1.1 |
|
206 |
1.1 |