XfdfReader.java

1
/*
2
 *
3
 * Copyright 2004 by Leonard Rosenthol.
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version 1.1
6
 * (the "License"); you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
8
 *
9
 * Software distributed under the License is distributed on an "AS IS" basis,
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
 * for the specific language governing rights and limitations under the License.
12
 *
13
 * The Original Code is 'iText, a free JAVA-PDF library'.
14
 *
15
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
16
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
17
 * All Rights Reserved.
18
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
19
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
20
 *
21
 * Contributor(s): all the names of the contributors are added in the source code
22
 * where applicable.
23
 *
24
 * Alternatively, the contents of this file may be used under the terms of the
25
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
26
 * provisions of LGPL are applicable instead of those above.  If you wish to
27
 * allow use of your version of this file only under the terms of the LGPL
28
 * License and not to allow others to use your version of this file under
29
 * the MPL, indicate your decision by deleting the provisions above and
30
 * replace them with the notice and other provisions required by the LGPL.
31
 * If you do not delete the provisions above, a recipient may use your version
32
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
33
 *
34
 * This library is free software; you can redistribute it and/or modify it
35
 * under the terms of the MPL as stated above or under the terms of the GNU
36
 * Library General Public License as published by the Free Software Foundation;
37
 * either version 2 of the License, or any later version.
38
 *
39
 * This library is distributed in the hope that it will be useful, but WITHOUT
40
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
41
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
42
 * details.
43
 *
44
 * If you didn't download this code from the following link, you should check if
45
 * you aren't using an obsolete version:
46
 * http://www.lowagie.com/iText/
47
 */
48
49
package com.lowagie.text.pdf;
50
51
import com.lowagie.text.error_messages.MessageLocalization;
52
import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler;
53
import com.lowagie.text.xml.simpleparser.SimpleXMLParser;
54
55
import java.io.ByteArrayInputStream;
56
import java.io.FileInputStream;
57
import java.io.IOException;
58
import java.util.*;
59
60
/**
61
 * Reads a XFDF.
62
 *
63
 * @author Leonard Rosenthol (leonardr@pdfsages.com)
64
 */
65
public class XfdfReader implements SimpleXMLDocHandler, FieldReader {
66
67
    // stuff used during parsing to handle state
68
    private boolean foundRoot = false;
69
    private Stack<String> fieldNames = new Stack<>();
70
    private Stack<String> fieldValues = new Stack<>();
71
72
    // storage for the field list and their values
73
    private Map<String, String> fields;
74
    /**
75
     * Storage for field values if there's more than one value for a field.
76
     *
77
     * @since 2.1.4
78
     */
79
    private Map<String, List<String>> listFields;
80
81
    // storage for the path to referenced PDF, if any
82
    private String fileSpec;
83
84
    /**
85
     * Reads an XFDF form.
86
     *
87
     * @param filename the file name of the form
88
     * @throws IOException on error
89
     */
90
    public XfdfReader(String filename) throws IOException {
91
        try (FileInputStream fin = new FileInputStream(filename)) {
92 1 1. : removed call to com/lowagie/text/xml/simpleparser/SimpleXMLParser::parse → NO_COVERAGE
            SimpleXMLParser.parse(this, fin);
93
        }
94
    }
95
96
    /**
97
     * Reads an XFDF form.
98
     *
99
     * @param xfdfIn the byte array with the form
100
     * @throws IOException on error
101
     */
102
    public XfdfReader(byte[] xfdfIn) throws IOException {
103 1 1. : removed call to com/lowagie/text/xml/simpleparser/SimpleXMLParser::parse → NO_COVERAGE
        SimpleXMLParser.parse(this, new ByteArrayInputStream(xfdfIn));
104
    }
105
106
    /**
107
     * Gets all the fields. The map is keyed by the fully qualified field name and the value is a merged
108
     * <CODE>PdfDictionary</CODE> with the
109
     * field content.
110
     *
111
     * @return all the fields
112
     */
113
    public Map<String, String> getFields() {
114
        return fields;
115
    }
116
117
    /**
118
     * Gets the field value.
119
     *
120
     * @param name the fully qualified field name
121
     * @return the field's value
122
     */
123
    public String getField(String name) {
124 1 1. getField : mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getField to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return fields.get(name);
125
    }
126
127
    /**
128
     * Gets the field value or <CODE>null</CODE> if the field does not exist or has no value defined.
129
     *
130
     * @param name the fully qualified field name
131
     * @return the field value or <CODE>null</CODE>
132
     */
133
    public String getFieldValue(String name) {
134 1 1. getFieldValue : mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getFieldValue to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return fields.get(name);
135
    }
136
137
    /**
138
     * Gets the field values for a list or <CODE>null</CODE> if the field does not exist or has no value defined.
139
     *
140
     * @param name the fully qualified field name
141
     * @return the field values or <CODE>null</CODE>
142
     * @since 2.1.4
143
     */
144
    public List<String> getListValues(String name) {
145 1 1. getListValues : mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getListValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return listFields.get(name);
146
    }
147
148
    /**
149
     * Gets the PDF file specification contained in the FDF.
150
     *
151
     * @return the PDF file specification contained in the FDF
152
     */
153
    public String getFileSpec() {
154
        return fileSpec;
155
    }
156
157
    /**
158
     * Called when a start tag is found.
159
     *
160
     * @param tag the tag name
161
     * @param h   the tag's attributes
162
     */
163
    public void startElement(String tag, Map<String, String> h) {
164 1 1. startElement : negated conditional → NO_COVERAGE
        if (!foundRoot) {
165 1 1. startElement : negated conditional → NO_COVERAGE
            if (!tag.equals("xfdf")) {
166
                throw new RuntimeException(MessageLocalization.getComposedMessage("root.element.is.not.xfdf.1", tag));
167
            } else {
168
                foundRoot = true;
169
            }
170
        }
171
172
        switch (tag) {
173
            case "xfdf":
174
                // intentionally left blank
175
                break;
176
            case "f":
177
                fileSpec = h.get("href");
178
                break;
179
            case "fields":
180
                fields = new HashMap<>();    // init it!
181
182
                listFields = new HashMap<>();
183
                break;
184
            case "field":
185
                String fName = h.get("name");
186
                fieldNames.push(fName);
187
                break;
188
            case "value":
189
                fieldValues.push("");
190
                break;
191
        }
192
    }
193
194
    /**
195
     * Called when an end tag is found.
196
     *
197
     * @param tag the tag name
198
     */
199
    public void endElement(String tag) {
200 1 1. endElement : negated conditional → NO_COVERAGE
        if (tag.equals("value")) {
201
            StringBuilder fName = new StringBuilder();
202 2 1. endElement : changed conditional boundary → NO_COVERAGE
2. endElement : negated conditional → NO_COVERAGE
            for (int k = 0; k < fieldNames.size(); ++k) {
203
                fName.append(".").append(fieldNames.elementAt(k));
204
            }
205 1 1. endElement : negated conditional → NO_COVERAGE
            if (fName.toString().startsWith(".")) {
206
                fName = new StringBuilder(fName.substring(1));
207
            }
208
            String fVal = fieldValues.pop();
209
            String old = fields.put(fName.toString(), fVal);
210 1 1. endElement : negated conditional → NO_COVERAGE
            if (old != null) {
211
                List<String> l = listFields.get(fName.toString());
212 1 1. endElement : negated conditional → NO_COVERAGE
                if (l == null) {
213
                    l = new ArrayList<>();
214
                    l.add(old);
215
                }
216
                l.add(fVal);
217
                listFields.put(fName.toString(), l);
218
            }
219 1 1. endElement : negated conditional → NO_COVERAGE
        } else if (tag.equals("field")) {
220 1 1. endElement : negated conditional → NO_COVERAGE
            if (!fieldNames.isEmpty()) {
221
                fieldNames.pop();
222
            }
223
        }
224
    }
225
226
    /**
227
     * Called when the document starts to be parsed.
228
     */
229
    public void startDocument() {
230
        fileSpec = "";
231
    }
232
233
    /**
234
     * Called after the document is parsed.
235
     */
236
    public void endDocument() {
237
238
    }
239
240
    /**
241
     * Called when a text element is found.
242
     *
243
     * @param str the text element, probably a fragment.
244
     */
245
    public void text(String str) {
246 2 1. text : negated conditional → NO_COVERAGE
2. text : negated conditional → NO_COVERAGE
        if (fieldNames.isEmpty() || fieldValues.isEmpty()) {
247
            return;
248
        }
249
250
        String val = fieldValues.pop();
251
        val += str;
252
        fieldValues.push(val);
253
    }
254
}

Mutations

92

1.1
Location :
Killed by : none
removed call to com/lowagie/text/xml/simpleparser/SimpleXMLParser::parse → NO_COVERAGE

103

1.1
Location :
Killed by : none
removed call to com/lowagie/text/xml/simpleparser/SimpleXMLParser::parse → NO_COVERAGE

124

1.1
Location : getField
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getField to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

134

1.1
Location : getFieldValue
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getFieldValue to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

145

1.1
Location : getListValues
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/XfdfReader::getListValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

164

1.1
Location : startElement
Killed by : none
negated conditional → NO_COVERAGE

165

1.1
Location : startElement
Killed by : none
negated conditional → NO_COVERAGE

200

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

202

1.1
Location : endElement
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

205

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

210

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

212

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

219

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

220

1.1
Location : endElement
Killed by : none
negated conditional → NO_COVERAGE

246

1.1
Location : text
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : text
Killed by : none
negated conditional → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.4.2