org.apache.pdfbox.pdmodel.fdf.FDFDictionary Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox Show documentation
Show all versions of pdfbox Show documentation
The Apache PDFBox library is an open source Java tool for working with PDF documents.
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.pdmodel.fdf;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
import org.apache.pdfbox.pdmodel.common.COSArrayList;
import org.apache.pdfbox.pdmodel.common.filespecification.PDFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDSimpleFileSpecification;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This represents an FDF dictionary that is part of the FDF document.
*
* @author Ben Litchfield
*/
public class FDFDictionary implements COSObjectable
{
private static final Log LOG = LogFactory.getLog(FDFDictionary.class);
private final COSDictionary fdf;
/**
* Default constructor.
*/
public FDFDictionary()
{
fdf = new COSDictionary();
}
/**
* Constructor.
*
* @param fdfDictionary The FDF documents catalog.
*/
public FDFDictionary(COSDictionary fdfDictionary)
{
fdf = fdfDictionary;
}
/**
* This will create an FDF dictionary from an XFDF XML document.
*
* @param fdfXML The XML document that contains the XFDF data.
*/
public FDFDictionary(Element fdfXML)
{
this();
NodeList nodeList = fdfXML.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node instanceof Element)
{
Element child = (Element) node;
switch (child.getTagName())
{
case "f":
PDSimpleFileSpecification fs = new PDSimpleFileSpecification();
fs.setFile(child.getAttribute("href"));
setFile(fs);
break;
case "ids":
COSArray ids = new COSArray();
String original = child.getAttribute("original");
String modified = child.getAttribute("modified");
try
{
ids.add(COSString.parseHex(original));
}
catch (IOException e)
{
LOG.warn("Error parsing ID entry for attribute 'original' [" + original +
"]. ID entry ignored.", e);
}
try
{
ids.add(COSString.parseHex(modified));
}
catch (IOException e)
{
LOG.warn("Error parsing ID entry for attribute 'modified' [" + modified +
"]. ID entry ignored.", e);
}
setID(ids);
break;
case "fields":
NodeList fields = child.getChildNodes();
List fieldList = new ArrayList<>();
for (int f = 0; f < fields.getLength(); f++)
{
Node currentNode = fields.item(f);
if (currentNode instanceof Element
&& ((Element) currentNode).getTagName().equals("field"))
{
try
{
fieldList.add(new FDFField((Element) fields.item(f)));
}
catch (IOException e)
{
LOG.warn("Error parsing field entry [" + currentNode.getNodeValue() +
"]. Field ignored.", e);
}
}
}
setFields(fieldList);
break;
case "annots":
NodeList annots = child.getChildNodes();
List annotList = new ArrayList<>();
for (int j = 0; j < annots.getLength(); j++)
{
Node annotNode = annots.item(j);
if (annotNode instanceof Element)
{
// the node name defines the annotation type
Element annot = (Element) annotNode;
String annotationName = annot.getNodeName();
try
{
switch (annotationName)
{
case "text":
annotList.add(new FDFAnnotationText(annot));
break;
case "caret":
annotList.add(new FDFAnnotationCaret(annot));
break;
case "freetext":
annotList.add(new FDFAnnotationFreeText(annot));
break;
case "fileattachment":
annotList.add(new FDFAnnotationFileAttachment(annot));
break;
case "highlight":
annotList.add(new FDFAnnotationHighlight(annot));
break;
case "ink":
annotList.add(new FDFAnnotationInk(annot));
break;
case "line":
annotList.add(new FDFAnnotationLine(annot));
break;
case "link":
annotList.add(new FDFAnnotationLink(annot));
break;
case "circle":
annotList.add(new FDFAnnotationCircle(annot));
break;
case "square":
annotList.add(new FDFAnnotationSquare(annot));
break;
case "polygon":
annotList.add(new FDFAnnotationPolygon(annot));
break;
case "polyline":
annotList.add(new FDFAnnotationPolyline(annot));
break;
case "sound":
annotList.add(new FDFAnnotationSound(annot));
break;
case "squiggly":
annotList.add(new FDFAnnotationSquiggly(annot));
break;
case "stamp":
annotList.add(new FDFAnnotationStamp(annot));
break;
case "strikeout":
annotList.add(new FDFAnnotationStrikeOut(annot));
break;
case "underline":
annotList.add(new FDFAnnotationUnderline(annot));
break;
default:
LOG.warn("Unknown or unsupported annotation type '" +
annotationName + "'");
break;
}
}
catch (IOException e)
{
LOG.warn("Error parsing annotation information [" +
annot.getNodeValue() + "]. Annotation ignored", e);
}
}
}
setAnnotations(annotList);
break;
default:
break;
}
}
}
}
/**
* This will write this element as an XML document.
*
* @param output The stream to write the xml to.
*
* @throws IOException If there is an error writing the XML.
*/
public void writeXML(Writer output) throws IOException
{
PDFileSpecification fs = this.getFile();
if (fs != null)
{
output.write(" \n");
}
COSArray ids = this.getID();
if (ids != null)
{
COSString original = (COSString) ids.getObject(0);
COSString modified = (COSString) ids.getObject(1);
output.write(" \n");
}
List fields = getFields();
if (fields != null && fields.size() > 0)
{
output.write("\n");
for (FDFField field : fields)
{
field.writeXML(output);
}
output.write(" \n");
}
}
/**
* Convert this standard java object to a COS object.
*
* @return The cos object that matches this Java object.
*/
@Override
public COSDictionary getCOSObject()
{
return fdf;
}
/**
* The source file or target file: the PDF document file that this FDF file was exported from or is intended to be
* imported into.
*
* @return The F entry of the FDF dictionary.
*
* @throws IOException If there is an error creating the file spec.
*/
public PDFileSpecification getFile() throws IOException
{
return PDFileSpecification.createFS(fdf.getDictionaryObject(COSName.F));
}
/**
* This will set the file specification.
*
* @param fs The file specification.
*/
public final void setFile(PDFileSpecification fs)
{
fdf.setItem(COSName.F, fs);
}
/**
* This is the FDF id.
*
* @return The FDF ID.
*/
public COSArray getID()
{
return fdf.getCOSArray(COSName.ID);
}
/**
* This will set the FDF id.
*
* @param id The new id for the FDF.
*/
public final void setID(COSArray id)
{
fdf.setItem(COSName.ID, id);
}
/**
* This will get the list of FDF Fields. This will return a list of FDFField objects.
*
* @return A list of FDF fields.
*/
public List getFields()
{
List retval = null;
COSArray fieldArray = fdf.getCOSArray(COSName.FIELDS);
if (fieldArray != null)
{
List fields = new ArrayList<>();
for (int i = 0; i < fieldArray.size(); i++)
{
fields.add(new FDFField((COSDictionary) fieldArray.getObject(i)));
}
retval = new COSArrayList<>(fields, fieldArray);
}
return retval;
}
/**
* This will set the list of fields. This should be a list of FDFField objects.
*
* @param fields The list of fields.
*/
public final void setFields(List fields)
{
fdf.setItem(COSName.FIELDS, new COSArray(fields));
}
/**
* This will get the status string to be displayed as the result of an action.
*
* @return The status.
*/
public String getStatus()
{
return fdf.getString(COSName.STATUS);
}
/**
* This will set the status string.
*
* @param status The new status string.
*/
public void setStatus(String status)
{
fdf.setString(COSName.STATUS, status);
}
/**
* This will get the list of FDF Pages. This will return a list of FDFPage objects.
*
* @return A list of FDF pages.
*/
public List getPages()
{
List retval = null;
COSArray pageArray = fdf.getCOSArray(COSName.PAGES);
if (pageArray != null)
{
List pages = new ArrayList<>();
for (int i = 0; i < pageArray.size(); i++)
{
pages.add(new FDFPage((COSDictionary) pageArray.get(i)));
}
retval = new COSArrayList<>(pages, pageArray);
}
return retval;
}
/**
* This will set the list of pages. This should be a list of FDFPage objects.
*
*
* @param pages The list of pages.
*/
public void setPages(List pages)
{
fdf.setItem(COSName.PAGES, new COSArray(pages));
}
/**
* The encoding to be used for a FDF field. The default is PDFDocEncoding and this method will never return null.
*
* @return The encoding value.
*/
public String getEncoding()
{
String encoding = fdf.getNameAsString(COSName.ENCODING);
if (encoding == null)
{
encoding = "PDFDocEncoding";
}
return encoding;
}
/**
* This will set the encoding.
*
* @param encoding The new encoding.
*/
public void setEncoding(String encoding)
{
fdf.setName(COSName.ENCODING, encoding);
}
/**
* This will get the list of FDF Annotations. This will return a list of FDFAnnotation objects or null if the entry
* is not set.
*
* @return A list of FDF annotations.
*
* @throws IOException If there is an error creating the annotation list.
*/
public List getAnnotations() throws IOException
{
List retval = null;
COSArray annotArray = fdf.getCOSArray(COSName.ANNOTS);
if (annotArray != null)
{
List annots = new ArrayList<>();
for (int i = 0; i < annotArray.size(); i++)
{
annots.add(FDFAnnotation.create((COSDictionary) annotArray.getObject(i)));
}
retval = new COSArrayList<>(annots, annotArray);
}
return retval;
}
/**
* This will set the list of annotations. This should be a list of FDFAnnotation objects.
*
*
* @param annots The list of annotations.
*/
public final void setAnnotations(List annots)
{
fdf.setItem(COSName.ANNOTS, new COSArray(annots));
}
/**
* This will get the incremental updates since the PDF was last opened.
*
* @return The differences entry of the FDF dictionary.
*/
public COSStream getDifferences()
{
return fdf.getCOSStream(COSName.DIFFERENCES);
}
/**
* This will set the differences stream.
*
* @param diff The new differences stream.
*/
public void setDifferences(COSStream diff)
{
fdf.setItem(COSName.DIFFERENCES, diff);
}
/**
* This will get the target frame in the browser to open this document.
*
* @return The target frame.
*/
public String getTarget()
{
return fdf.getString(COSName.TARGET);
}
/**
* This will set the target frame in the browser to open this document.
*
* @param target The new target frame.
*/
public void setTarget(String target)
{
fdf.setString(COSName.TARGET, target);
}
/**
* This will get the list of embedded FDF entries, or null if the entry is null. This will return a list of
* PDFileSpecification objects.
*
* @return A list of embedded FDF files.
*
* @throws IOException If there is an error creating the file spec.
*/
public List getEmbeddedFDFs() throws IOException
{
List retval = null;
COSArray embeddedArray = fdf.getCOSArray(COSName.EMBEDDED_FDFS);
if (embeddedArray != null)
{
List embedded = new ArrayList<>();
for (int i = 0; i < embeddedArray.size(); i++)
{
embedded.add(PDFileSpecification.createFS(embeddedArray.get(i)));
}
retval = new COSArrayList<>(embedded, embeddedArray);
}
return retval;
}
/**
* This will set the list of embedded FDFs. This should be a list of PDFileSpecification objects.
*
*
* @param embedded The list of embedded FDFs.
*/
public void setEmbeddedFDFs(List embedded)
{
fdf.setItem(COSName.EMBEDDED_FDFS, new COSArray(embedded));
}
/**
* This will get the java script entry.
*
* @return The java script entry describing javascript commands.
*/
public FDFJavaScript getJavaScript()
{
COSDictionary dic = fdf.getCOSDictionary(COSName.JAVA_SCRIPT);
return dic != null ? new FDFJavaScript(dic) : null;
}
/**
* This will set the JavaScript entry.
*
* @param js The javascript entries.
*/
public void setJavaScript(FDFJavaScript js)
{
fdf.setItem(COSName.JAVA_SCRIPT, js);
}
}