org.verapdf.pd.form.PDFormField Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parser Show documentation
Show all versions of parser Show documentation
veraPDF tools for parsing, modifying and creating PDF documents.
/**
* This file is part of veraPDF Parser, a module of the veraPDF project.
* Copyright (c) 2015, veraPDF Consortium
* All rights reserved.
*
* veraPDF Parser is free software: you can redistribute it and/or modify
* it under the terms of either:
*
* The GNU General public license GPLv3+.
* You should have received a copy of the GNU General Public License
* along with veraPDF Parser as the LICENSE.GPL file in the root of the source
* tree. If not, see http://www.gnu.org/licenses/ or
* https://www.gnu.org/licenses/gpl-3.0.en.html.
*
* The Mozilla Public License MPLv2+.
* You should have received a copy of the Mozilla Public License along with
* veraPDF Parser as the LICENSE.MPL file in the root of the source tree.
* If a copy of the MPL was not distributed with this file, you can obtain one at
* http://mozilla.org/MPL/2.0/.
*/
package org.verapdf.pd.form;
import org.verapdf.as.ASAtom;
import org.verapdf.cos.COSArray;
import org.verapdf.cos.COSKey;
import org.verapdf.cos.COSObjType;
import org.verapdf.cos.COSObject;
import org.verapdf.exceptions.LoopedException;
import org.verapdf.pd.PDObject;
import org.verapdf.pd.actions.PDFormFieldActions;
import java.util.*;
/**
* @author Maksim Bezrukov
*/
public class PDFormField extends PDObject {
private Set parents = null;
protected PDFormField(COSObject obj, Set parents) {
super(obj);
COSKey objectKey = obj.getObjectKey();
this.parents = new HashSet<>(parents);
if (objectKey != null) {
if (this.parents.contains(objectKey)) {
throw new LoopedException("Loop form field tree");
} else {
this.parents.add(objectKey);
}
}
}
public static PDFormField createTypedFormField(COSObject obj) {
return createTypedFormField(obj, new HashSet());
}
private static PDFormField createTypedFormField(COSObject obj, Set parents) {
if (obj == null) {
throw new IllegalStateException("Argument object can not be null");
}
if (parents == null) {
throw new IllegalStateException("Argument parents can not be null");
}
ASAtom fieldType = getFieldTypeCOSObject(obj);
if (fieldType == ASAtom.SIG) {
return new PDSignatureField(obj, parents);
}
return new PDFormField(obj, parents);
}
public ASAtom getFT() {
COSObject object = getInheritedObject(ASAtom.FT);
return object == null || object.getType() != COSObjType.COS_NAME ? null : object.getName();
}
public COSObject getV() {
return getInheritedObject(ASAtom.V);
}
private COSObject getInheritedObject(ASAtom key) {
COSObject currObject = getObject();
Set checkedObjects = new HashSet<>();
while (currObject != null) {
COSObject currVal = currObject.getKey(key);
if (currVal != null && !currVal.empty()) {
return currVal;
}
COSKey currKey = currObject.getKey();
if (currKey != null) {
checkedObjects.add(currKey);
}
COSObject parent = currObject.getKey(ASAtom.PARENT);
if (parent != null
&& parent.getType().isDictionaryBased()
&& !checkedObjects.contains(parent.getKey())) {
currObject = parent;
} else {
currObject = null;
}
}
return null;
}
public String getFullyQualifiedName() {
List parts = new ArrayList<>();
COSObject currObject = getObject();
Set checkedObjects = new HashSet<>();
while (currObject != null && !currObject.empty()) {
String partial = getStringKey(ASAtom.T);
if (partial != null) {
parts.add(partial);
}
COSKey currKey = currObject.getKey();
if (currKey != null) {
checkedObjects.add(currKey);
}
COSObject parent = currObject.getKey(ASAtom.PARENT);
if (parent != null
&& parent.getType().isDictionaryBased()
&& !checkedObjects.contains(parent.getKey())) {
currObject = parent;
} else {
currObject = null;
}
}
if (!parts.isEmpty()) {
StringBuilder builder = new StringBuilder();
for (int i = parts.size() - 1; i > 0; --i) {
builder.append(parts.get(i)).append(".");
}
builder.append(parts.get(0));
return builder.toString();
}
return null;
}
public PDFormFieldActions getActions() {
COSObject object = getKey(ASAtom.AA);
if (object != null && object.getType().isDictionaryBased()) {
return new PDFormFieldActions(object);
}
return null;
}
public List getChildFormFields() {
if (isNonTerminalField()) {
List res = new ArrayList<>();
for (COSObject elem : (COSArray) getKey(ASAtom.KIDS).getDirectBase()) {
res.add(createTypedFormField(elem, this.parents));
}
return Collections.unmodifiableList(res);
}
return Collections.emptyList();
}
private boolean isNonTerminalField() {
COSObject kids = getKey(ASAtom.KIDS);
if (kids != null && kids.getType() == COSObjType.COS_ARRAY) {
for (COSObject elem : (COSArray) kids.getDirectBase()) {
if (elem == null
|| !elem.getType().isDictionaryBased()
|| ASAtom.ANNOT.equals(elem.getNameKey(ASAtom.TYPE))) {
return false;
}
}
return true;
}
return false;
}
private static ASAtom getFieldTypeCOSObject(COSObject field) {
ASAtom res = field.getNameKey(ASAtom.FT);
if (res != null) {
return res;
}
COSObject parent = field.getKey(ASAtom.PARENT);
if (parent != null) {
return getFieldTypeCOSObject(parent);
}
return null;
}
}