private void addFieldString(PDField field) throws SAXException { // Pick partial name to present in content and altName for attribute // Ignoring FullyQualifiedName for now String partName = field.getPartialName(); String altName = field.getAlternateFieldName(); StringBuilder sb = new StringBuilder(); AttributesImpl attrs = new AttributesImpl(); if (partName != null) { sb.append(partName).append(": "); } if (altName != null) { attrs.addAttribute("", "altName", "altName", "CDATA", altName); } // return early if PDSignature field if (field instanceof PDSignatureField) { handleSignature(attrs, (PDSignatureField) field); return; } String value = field.getValueAsString(); if (value != null && !value.equals("null")) { sb.append(value); } if (attrs.getLength() > 0 || sb.length() > 0) { xhtml.startElement("li", attrs); xhtml.characters(sb.toString()); xhtml.endElement("li"); } }
/** * This method creates a COSField subclass from the given field. The field is a PDF Dictionary * object that must represent a field element. - othewise null is returned * * @param acroForm The form that the field will be part of. * @param field The dictionary representing a field element * @return a subclass to COSField according to the kind of field passed to createField * @throws IOException If there is an error determining the field type. */ public static PDField createField(PDAcroForm acroForm, COSDictionary field) throws IOException { PDField pdField = new PDUnknownField(acroForm, field); if (isButton(pdField)) { int flags = pdField.getFieldFlags(); // BJL, I have found that the radio flag bit is not always set // and that sometimes there is just a kids dictionary. // so, if there is a kids dictionary then it must be a radio button // group. COSArray kids = (COSArray) field.getDictionaryObject(COSName.getPDFName("Kids")); if (kids != null || isRadio(flags)) { pdField = new PDRadioCollection(acroForm, field); } else if (isPushButton(flags)) { pdField = new PDPushButton(acroForm, field); } else { pdField = new PDCheckbox(acroForm, field); } } else if (isChoiceField(pdField)) { pdField = new PDChoiceField(acroForm, field); } else if (isTextbox(pdField)) { pdField = new PDTextbox(acroForm, field); } else if (isSignature(pdField)) { pdField = new PDSignatureField(acroForm, field); } else { // do nothing and return an unknown field type. } return pdField; }
@Override FDFField exportFDF() throws IOException { FDFField fdfField = new FDFField(); fdfField.setPartialFieldName(getPartialName()); fdfField.setValue(getValue()); List<PDField> children = getChildren(); List<FDFField> fdfChildren = new ArrayList<FDFField>(); for (PDField child : children) { fdfChildren.add(child.exportFDF()); } fdfField.setKids(fdfChildren); return fdfField; }
/** * This will find one of the child elements. The name array are the components of the name to * search down the tree of names. The nameIndex is where to start in that array. This method is * called recursively until it finds the end point based on the name array. * * @param name An array that picks the path to the field. * @param nameIndex The index into the array. * @return The field at the endpoint or null if none is found. */ PDField findKid(String[] name, int nameIndex) { PDField retval = null; COSArray kids = (COSArray) dictionary.getDictionaryObject(COSName.KIDS); if (kids != null) { for (int i = 0; retval == null && i < kids.size(); i++) { COSDictionary kidDictionary = (COSDictionary) kids.getObject(i); if (name[nameIndex].equals(kidDictionary.getString(COSName.T))) { retval = PDField.fromDictionary(acroForm, kidDictionary, (PDNonTerminalField) this); if (retval != null && name.length > nameIndex + 1) { retval = retval.findKid(name, nameIndex + 1); } } } } return retval; }
@Override void importFDF(FDFField fdfField) throws IOException { super.importFDF(fdfField); List<FDFField> fdfKids = fdfField.getKids(); List<PDField> children = getChildren(); for (int i = 0; fdfKids != null && i < fdfKids.size(); i++) { for (COSObjectable pdKid : children) { if (pdKid instanceof PDField) { PDField pdChild = (PDField) pdKid; FDFField fdfChild = fdfKids.get(i); String fdfName = fdfChild.getPartialFieldName(); if (fdfName != null && fdfName.equals(pdChild.getPartialName())) { pdChild.importFDF(fdfChild); } } } } }
public static PDRectangle getPDRectangleForField(PDField field) { COSBase rectArray = field.getDictionary().getDictionaryObject("Rect"); PDRectangle pdrect = new PDRectangle(0, 0); if (rectArray instanceof COSArray) { pdrect = new PDRectangle((COSArray) rectArray); } else if (rectArray != null && rectArray.getCOSObject() instanceof COSArray) { pdrect = new PDRectangle((COSArray) rectArray.getCOSObject()); } return pdrect; }
/** * This method determines if the given field is a button. * * @param field the field to determine * @return the result of the determination * @throws IOException If there is an error determining the field type. */ private static boolean isButton(PDField field) throws IOException { String ft = field.findFieldType(); boolean retval = FIELD_TYPE_BTN.equals(ft); List kids = field.getKids(); if (ft == null && kids != null && kids.size() > 0) { // sometimes if it is a button the type is only defined by one // of the kids entries Object obj = kids.get(0); COSDictionary kidDict = null; if (obj instanceof PDField) { kidDict = ((PDField) obj).getDictionary(); } else if (obj instanceof PDAnnotationWidget) { kidDict = ((PDAnnotationWidget) obj).getDictionary(); } else { throw new IOException("Error:Unexpected type of kids field:" + obj); } retval = isButton(new PDUnknownField(field.getAcroForm(), kidDict)); } return retval; }
/** * Returns this field's children. These may be either terminal or non-terminal fields. * * @return he list of child fields. */ public List<PDField> getChildren() { List<PDField> children = new ArrayList<PDField>(); COSArray kids = (COSArray) getCOSObject().getDictionaryObject(COSName.KIDS); for (int i = 0; i < kids.size(); i++) { PDField field = PDField.fromDictionary(getAcroForm(), (COSDictionary) kids.getObject(i), this); if (field != null) { children.add(field); } } return children; }
public static PDSignatureField swapTextWithSignature(PDField box, List<PDField> fields) { PDSignatureField sig = null; try { PDAcroForm acroForm; acroForm = box.getAcroForm(); acroForm.getDictionary().setDirect(true); PDSignature sigobj = new PDSignature(); sig = new PDSignatureField(acroForm); sig.getDictionary().setDirect(true); sig.setSignature(sigobj); sig.getWidget().setPage(box.getWidget().getPage()); sig.setPartialName(box.getPartialName()); sig.setAlternateFieldName(box.getAlternateFieldName()); sig.getDictionary().setItem(COSName.RECT, box.getDictionary().getItem(COSName.RECT)); sig.getDictionary().setNeedToBeUpdate(true); acroForm.getDictionary().setInt(COSName.SIG_FLAGS, 3); acroForm.getDictionary().setNeedToBeUpdate(true); fields.remove(box); fields.add(sig); } catch (IOException ioe) { } return sig; }
/** * This method determines if the given field is a Textbox. * * @param field the field to determine * @return the result of the determination */ private static boolean isTextbox(PDField field) throws IOException { return FIELD_TYPE_TX.equals(field.findFieldType()); }
/** * This method determines if the given field is a signature. * * @param field the field to determine * @return the result of the determination */ private static boolean isSignature(PDField field) throws IOException { return FIELD_TYPE_SIG.equals(field.findFieldType()); }
/** * This method determines if the given field is a choicefield Choicefields are either listboxes or * comboboxes. * * @param field the field to determine * @return the result of the determination */ private static boolean isChoiceField(PDField field) throws IOException { return FIELD_TYPE_CH.equals(field.findFieldType()); }