001: /*
002: * Copyright 2003 by Paulo Soares.
003: *
004: * The contents of this file are subject to the Mozilla Public License Version 1.1
005: * (the "License"); you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the License.
011: *
012: * The Original Code is 'iText, a free JAVA-PDF library'.
013: *
014: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
015: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
016: * All Rights Reserved.
017: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
018: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
019: *
020: * Contributor(s): all the names of the contributors are added in the source code
021: * where applicable.
022: *
023: * Alternatively, the contents of this file may be used under the terms of the
024: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
025: * provisions of LGPL are applicable instead of those above. If you wish to
026: * allow use of your version of this file only under the terms of the LGPL
027: * License and not to allow others to use your version of this file under
028: * the MPL, indicate your decision by deleting the provisions above and
029: * replace them with the notice and other provisions required by the LGPL.
030: * If you do not delete the provisions above, a recipient may use your version
031: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
032: *
033: * This library is free software; you can redistribute it and/or modify it
034: * under the terms of the MPL as stated above or under the terms of the GNU
035: * Library General Public License as published by the Free Software Foundation;
036: * either version 2 of the License, or any later version.
037: *
038: * This library is distributed in the hope that it will be useful, but WITHOUT
039: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
040: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
041: * details.
042: *
043: * If you didn't download this code from the following link, you should check if
044: * you aren't using an obsolete version:
045: * http://www.lowagie.com/iText/
046: */
047: package com.lowagie.text.pdf;
048:
049: import java.io.IOException;
050: import java.io.InputStream;
051: import java.net.URL;
052: import java.util.ArrayList;
053: import java.util.HashMap;
054:
055: /** Reads an FDF form and makes the fields available
056: * @author Paulo Soares (psoares@consiste.pt)
057: */
058: public class FdfReader extends PdfReader {
059:
060: HashMap fields;
061: String fileSpec;
062: PdfName encoding;
063:
064: /** Reads an FDF form.
065: * @param filename the file name of the form
066: * @throws IOException on error
067: */
068: public FdfReader(String filename) throws IOException {
069: super (filename);
070: }
071:
072: /** Reads an FDF form.
073: * @param pdfIn the byte array with the form
074: * @throws IOException on error
075: */
076: public FdfReader(byte pdfIn[]) throws IOException {
077: super (pdfIn);
078: }
079:
080: /** Reads an FDF form.
081: * @param url the URL of the document
082: * @throws IOException on error
083: */
084: public FdfReader(URL url) throws IOException {
085: super (url);
086: }
087:
088: /** Reads an FDF form.
089: * @param is the <CODE>InputStream</CODE> containing the document. The stream is read to the
090: * end but is not closed
091: * @throws IOException on error
092: */
093: public FdfReader(InputStream is) throws IOException {
094: super (is);
095: }
096:
097: protected void readPdf() throws IOException {
098: fields = new HashMap();
099: try {
100: tokens.checkFdfHeader();
101: rebuildXref();
102: readDocObj();
103: } finally {
104: try {
105: tokens.close();
106: } catch (Exception e) {
107: // empty on purpose
108: }
109: }
110: readFields();
111: }
112:
113: protected void kidNode(PdfDictionary merged, String name) {
114: PdfArray kids = (PdfArray) getPdfObject(merged
115: .get(PdfName.KIDS));
116: if (kids == null || kids.getArrayList().size() == 0) {
117: if (name.length() > 0)
118: name = name.substring(1);
119: fields.put(name, merged);
120: } else {
121: merged.remove(PdfName.KIDS);
122: ArrayList ar = kids.getArrayList();
123: for (int k = 0; k < ar.size(); ++k) {
124: PdfDictionary dic = new PdfDictionary();
125: dic.merge(merged);
126: PdfDictionary newDic = (PdfDictionary) getPdfObject((PdfObject) ar
127: .get(k));
128: PdfString t = (PdfString) getPdfObject(newDic
129: .get(PdfName.T));
130: String newName = name;
131: if (t != null)
132: newName += "." + t.toUnicodeString();
133: dic.merge(newDic);
134: dic.remove(PdfName.T);
135: kidNode(dic, newName);
136: }
137: }
138: }
139:
140: protected void readFields() {
141: catalog = (PdfDictionary) getPdfObject(trailer
142: .get(PdfName.ROOT));
143: PdfDictionary fdf = (PdfDictionary) getPdfObject(catalog
144: .get(PdfName.FDF));
145: if (fdf == null)
146: return;
147: PdfString fs = (PdfString) getPdfObject(fdf.get(PdfName.F));
148: if (fs != null)
149: fileSpec = fs.toUnicodeString();
150: PdfArray fld = (PdfArray) getPdfObject(fdf.get(PdfName.FIELDS));
151: if (fld == null)
152: return;
153: encoding = (PdfName) getPdfObject(fdf.get(PdfName.ENCODING));
154: PdfDictionary merged = new PdfDictionary();
155: merged.put(PdfName.KIDS, fld);
156: kidNode(merged, "");
157: }
158:
159: /** Gets all the fields. The map is keyed by the fully qualified
160: * field name and the value is a merged <CODE>PdfDictionary</CODE>
161: * with the field content.
162: * @return all the fields
163: */
164: public HashMap getFields() {
165: return fields;
166: }
167:
168: /** Gets the field dictionary.
169: * @param name the fully qualified field name
170: * @return the field dictionary
171: */
172: public PdfDictionary getField(String name) {
173: return (PdfDictionary) fields.get(name);
174: }
175:
176: /** Gets the field value or <CODE>null</CODE> if the field does not
177: * exist or has no value defined.
178: * @param name the fully qualified field name
179: * @return the field value or <CODE>null</CODE>
180: */
181: public String getFieldValue(String name) {
182: PdfDictionary field = (PdfDictionary) fields.get(name);
183: if (field == null)
184: return null;
185: PdfObject v = getPdfObject(field.get(PdfName.V));
186: if (v == null)
187: return null;
188: if (v.isName())
189: return PdfName.decodeName(((PdfName) v).toString());
190: else if (v.isString()) {
191: PdfString vs = (PdfString) v;
192: if (encoding == null || vs.getEncoding() != null)
193: return vs.toUnicodeString();
194: byte b[] = vs.getBytes();
195: if (b.length >= 2 && b[0] == (byte) 254
196: && b[1] == (byte) 255)
197: return vs.toUnicodeString();
198: try {
199: if (encoding.equals(PdfName.SHIFT_JIS))
200: return new String(b, "SJIS");
201: else if (encoding.equals(PdfName.UHC))
202: return new String(b, "MS949");
203: else if (encoding.equals(PdfName.GBK))
204: return new String(b, "GBK");
205: else if (encoding.equals(PdfName.BIGFIVE))
206: return new String(b, "Big5");
207: } catch (Exception e) {
208: }
209: return vs.toUnicodeString();
210: }
211: return null;
212: }
213:
214: /** Gets the PDF file specification contained in the FDF.
215: * @return the PDF file specification contained in the FDF
216: */
217: public String getFileSpec() {
218: return fileSpec;
219: }
220: }
|