Open Source Repository

Home /itextpdf/itextpdf-5.1.2 | Repository Home



com/itextpdf/text/pdf/XfdfReader.java
/*
 * $Id: XfdfReader.java 4784 2011-03-15 08:33:00Z blowagie $
 *
 * This file is part of the iText (R) project.
 * Copyright (c) 1998-2011 1T3XT BVBA
 * Authors: Bruno Lowagie, Paulo Soares, et al.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation with the addition of the
 * following permission added to Section 15 as permitted in Section 7(a):
 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT,
 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA, 02110-1301 USA, or download the license from the following URL:
 * http://itextpdf.com/terms-of-use/
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License,
 * a covered work must retain the producer line in every PDF that is created
 * or manipulated using iText.
 *
 * You can be released from the requirements of the license by purchasing
 * a commercial license. Buying such a license is mandatory as soon as you
 * develop commercial activities involving the iText software without
 * disclosing the source code of your own applications.
 * These activities include: offering paid services to customers as an ASP,
 * serving PDFs on the fly in a web application, shipping iText with a closed
 * source product.
 *
 * For more information, please contact iText Software Corp. at this
 * address: [email protected]
 */
package com.itextpdf.text.pdf;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import com.itextpdf.text.error_messages.MessageLocalization;
import com.itextpdf.text.xml.simpleparser.SimpleXMLDocHandler;
import com.itextpdf.text.xml.simpleparser.SimpleXMLParser;

/**
 * Reads a XFDF.
 @author Leonard Rosenthol ([email protected])
 */
public class XfdfReader implements SimpleXMLDocHandler {
  // stuff used during parsing to handle state
  private boolean foundRoot = false;
    private final Stack<String> fieldNames = new Stack<String>();
    private final Stack<String> fieldValues = new Stack<String>();

    // storage for the field list and their values
  HashMap<String, String>  fields;
  /**
   * Storage for field values if there's more than one value for a field.
   @since  2.1.4
   */
  protected HashMap<String, List<String>> listFields;

  // storage for the path to referenced PDF, if any
  String  fileSpec;

   /**
    * Reads an XFDF form.
     @param filename the file name of the form
     @throws IOException on error
     */
    public XfdfReader(String filenamethrows IOException {
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(filename);
            SimpleXMLParser.parse(this, fin);
        }
        finally {
            try{if (fin != null) {fin.close();}}catch(Exception e){}
        }
    }

    /**
     * Reads an XFDF form.
     @param xfdfIn the byte array with the form
     @throws IOException on error
     */
    public XfdfReader(byte xfdfIn[]) throws IOException {
        this(new ByteArrayInputStream(xfdfIn));
   }

    /**
     * Reads an XFDF form.
     @param is an InputStream to read the form
     @throws IOException on error
     @since 5.0.1
     */
    public XfdfReader(InputStream isthrows IOException {
        SimpleXMLParser.parsethis, is);
   }

    /** Gets all the fields. The map is keyed by the fully qualified
     * field name and the value is a merged <CODE>PdfDictionary</CODE>
     * with the field content.
     @return all the fields
     */
    public HashMap<String, String> getFields() {
        return fields;
    }

    /** Gets the field value.
     @param name the fully qualified field name
     @return the field's value
     */
    public String getField(String name) {
        return fields.get(name);
    }

    /** Gets the field value or <CODE>null</CODE> if the field does not
     * exist or has no value defined.
     @param name the fully qualified field name
     @return the field value or <CODE>null</CODE>
     */
    public String getFieldValue(String name) {
        String field = fields.get(name);
        if (field == null)
            return null;
        else
          return field;
    }

    /**
     * Gets the field values for a list or <CODE>null</CODE> if the field does not
     * exist or has no value defined.
     @param name the fully qualified field name
     @return the field values or <CODE>null</CODE>
     @since  2.1.4
     */
    public List<String> getListValues(String name) {
        return listFields.get(name);
    }

    /** Gets the PDF file specification contained in the FDF.
     @return the PDF file specification contained in the FDF
     */
    public String getFileSpec() {
        return fileSpec;
    }

    /**
     * Called when a start tag is found.
     @param tag the tag name
     @param h the tag's attributes
     */
    public void startElement(String tag, Map<String, String> h)
    {
        if !foundRoot ) {
            if (!tag.equals("xfdf"))
                throw new RuntimeException(MessageLocalization.getComposedMessage("root.element.is.not.xfdf.1", tag));
            else
              foundRoot = true;
        }

        if tag.equals("xfdf") ){

      else if tag.equals("f") ) {
        fileSpec = h.get"href" );
      else if tag.equals("fields") ) {
            fields = new HashMap<String, String>();    // init it!
            listFields = new HashMap<String, List<String>>();
      else if tag.equals("field") ) {
        String  fName = h.get"name" );
        fieldNames.pushfName );
      else if tag.equals("value") ) {
        fieldValues.push"" );
      }
    }
    /**
     * Called when an end tag is found.
     @param tag the tag name
     */
    public void endElement(String tag) {
        if tag.equals("value") ) {
            String  fName = "";
            for (int k = 0; k < fieldNames.size(); ++k) {
                fName += "." + fieldNames.elementAt(k);
            }
            if (fName.startsWith("."))
                fName = fName.substring(1);
            String fVal = fieldValues.pop();
            String old = fields.putfName, fVal );
            if (old != null) {
              List<String> l = listFields.get(fName);
              if (l == null) {
                l = new ArrayList<String>();
                l.add(old);
              }
              l.add(fVal);
              listFields.put(fName, l);
            }
        }
        else if (tag.equals("field") ) {
            if (!fieldNames.isEmpty())
                fieldNames.pop();
        }
    }

    /**
     * Called when the document starts to be parsed.
     */
    public void startDocument()
    {
        fileSpec = "";
    }
    /**
     * Called after the document is parsed.
     */
    public void endDocument()
  {

  }
    /**
     * Called when a text element is found.
     @param str the text element, probably a fragment.
     */
    public void text(String str)
    {
        if (fieldNames.isEmpty() || fieldValues.isEmpty())
            return;

        String val = fieldValues.pop();
        val += str;
        fieldValues.push(val);
    }
}