You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2011/08/30 22:58:50 UTC
svn commit: r1163376 -
/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java
Author: leleueri
Date: Tue Aug 30 20:58:49 2011
New Revision: 1163376
URL: http://svn.apache.org/viewvc?rev=1163376&view=rev
Log:
[PDFBOX-1112] Fix outline hierarchy control
Modified:
pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java?rev=1163376&r1=1163375&r2=1163376&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/BookmarkValidationHelper.java Tue Aug 30 20:58:49 2011
@@ -30,8 +30,10 @@ import org.apache.padaf.preflight.Valida
import org.apache.padaf.preflight.ValidatorConfig;
import org.apache.padaf.preflight.ValidationResult.ValidationError;
import org.apache.padaf.preflight.actions.AbstractActionManager;
+import org.apache.padaf.preflight.utils.COSUtils;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
@@ -51,137 +53,141 @@ public class BookmarkValidationHelper ex
super(cfg);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * net.awl.edoc.pdfa.validation.helpers.AbstractValidationHelper#innerValidate
- * (net.awl.edoc.pdfa.validation.DocumentHandler)
- */
- @Override
- public List<ValidationError> innerValidate(DocumentHandler handler)
- throws ValidationException {
- List<ValidationError> result = new ArrayList<ValidationError>(0);
-
- PDDocumentCatalog catalog = handler.getDocument().getDocumentCatalog();
- if (catalog != null) {
- PDDocumentOutline outlineHierarchy = catalog.getDocumentOutline();
- if (outlineHierarchy != null) {
- if (outlineHierarchy.getFirstChild() == null
- || outlineHierarchy.getLastChild() == null) {
- result.add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
- "Outline Hierarchy doesn't have First and/or Last entry(ies)"));
- } else {
- // ---- Count entry is mandatory if there are childrens
- if (!isCountEntryPresent(outlineHierarchy.getCOSDictionary())) {
- result.add(new ValidationError(
- ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
- "Outline Hierarchy doesn't have Count entry"));
- } else {
- exploreOutlineLevel(outlineHierarchy.getFirstChild(), handler,
- result);
- }
- }
- }
- } else {
- throw new ValidationException(
- "There are no Catalog entry in the Document.");
- }
- return result;
- }
-
- /**
- * Return true if the Count entry is present in the given dictionary.
- *
- * @param outline
- * @return
- */
- private boolean isCountEntryPresent(COSDictionary outline) {
- return outline.getItem(COSName.getPDFName("Count")) != null;
- }
-
- /**
- * This method explores the Outline Item Level and call a validation method on
- * each Outline Item. If an invalid outline item is found, the result list is
- * updated.
- *
- * @param inputItem
- * The first outline item of the level
- * @param handler
- * The document handler which provides useful data for the level
- * exploration (ex : access to the PDDocument)
- * @param result
- * @return true if all items are valid in this level.
- * @throws ValidationException
- */
- protected boolean exploreOutlineLevel(PDOutlineItem inputItem,
- DocumentHandler handler, List<ValidationError> result)
- throws ValidationException {
- PDOutlineItem currentItem = inputItem;
- int oiValided = 0;
- while (currentItem != null) {
- if (!validateItem(currentItem, handler, result)) {
- return false;
- }
- oiValided++;
- currentItem = currentItem.getNextSibling();
- }
- return true;
- }
-
- /**
- * This method checks the inputItem dictionary and call the
- * exploreOutlineLevel method on the first child if it is not null.
- *
- * @param inputItem
- * outline item to validate
- * @param handler
- * The document handler which provides useful data for the level
- * exploration (ex : access to the PDDocument)
- * @param result
- * @return
- * @throws ValidationException
- */
- protected boolean validateItem(PDOutlineItem inputItem,
- DocumentHandler handler, List<ValidationError> result)
- throws ValidationException {
- boolean isValid = true;
- // ---- Dest entry isn't permitted if the A entry is present
- // A entry isn't permitted if the Dest entry is present
- // If the A enntry is present, the referenced actions is validated
- COSDictionary dictionary = inputItem.getCOSDictionary();
- COSBase dest = dictionary.getItem(COSName
- .getPDFName(DICTIONARY_KEY_DESTINATION));
- COSBase action = dictionary.getItem(COSName
- .getPDFName(DICTIONARY_KEY_ACTION));
-
- if (action != null && dest != null) {
- result.add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
- "Dest entry isn't permitted if the A entry is present"));
- return false;
- } else if (action != null) {
- List<AbstractActionManager> actions = this.actionFact.getActions(dictionary, handler
- .getDocument().getDocument());
- for (AbstractActionManager act : actions) {
- isValid = isValid && act.valid(result);
- }
- } // else no specific validation
-
- // ---- check children
- PDOutlineItem fChild = inputItem.getFirstChild();
- if (fChild != null) {
- if (!isCountEntryPresent(inputItem.getCOSDictionary())) {
- result
- .add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
- "Outline item doesn't have Count entry but has at least one descendant."));
- isValid = false;
- } else {
- // ---- there are some descendants, so dictionary must have a Count
- // entry
- isValid = isValid && exploreOutlineLevel(fChild, handler, result);
- }
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.awl.edoc.pdfa.validation.helpers.AbstractValidationHelper#innerValidate
+ * (net.awl.edoc.pdfa.validation.DocumentHandler)
+ */
+ @Override
+ public List<ValidationError> innerValidate(DocumentHandler handler)
+ throws ValidationException {
+ List<ValidationError> result = new ArrayList<ValidationError>(0);
+
+ PDDocumentCatalog catalog = handler.getDocument().getDocumentCatalog();
+ if (catalog != null) {
+ PDDocumentOutline outlineHierarchy = catalog.getDocumentOutline();
+ if (outlineHierarchy != null) {
+ // ---- Count entry is mandatory if there are childrens
+ if (!isCountEntryPresent(outlineHierarchy.getCOSDictionary()) && (outlineHierarchy.getFirstChild() != null || outlineHierarchy.getLastChild() != null) ) {
+ result.add(new ValidationError(
+ ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
+ "Outline Hierarchy doesn't have Count entry"));
+ } else if (isCountEntryPositive(outlineHierarchy.getCOSDictionary(), handler.getDocument().getDocument())
+ && (outlineHierarchy.getFirstChild() == null || outlineHierarchy.getLastChild() == null)) {
+ result.add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
+ "Outline Hierarchy doesn't have First and/or Last entry(ies)"));
+ } else {
+ exploreOutlineLevel(outlineHierarchy.getFirstChild(), handler, result);
+ }
+ }
+ } else {
+ throw new ValidationException(
+ "There are no Catalog entry in the Document.");
+ }
+ return result;
+ }
+
+ /**
+ * Return true if the Count entry is present in the given dictionary.
+ *
+ * @param outline
+ * @return
+ */
+ private boolean isCountEntryPresent(COSDictionary outline) {
+ return outline.getItem(COSName.getPDFName("Count")) != null;
+ }
+ /**
+ * return true if Count entry > 0
+ * @param outline
+ * @param doc
+ * @return
+ */
+ private boolean isCountEntryPositive(COSDictionary outline, COSDocument doc) {
+ COSBase countBase = outline.getItem(COSName.getPDFName("Count"));
+ return COSUtils.isInteger(countBase, doc) && (COSUtils.getAsInteger(countBase, doc)>0);
+ }
+ /**
+ * This method explores the Outline Item Level and call a validation method on
+ * each Outline Item. If an invalid outline item is found, the result list is
+ * updated.
+ *
+ * @param inputItem
+ * The first outline item of the level
+ * @param handler
+ * The document handler which provides useful data for the level
+ * exploration (ex : access to the PDDocument)
+ * @param result
+ * @return true if all items are valid in this level.
+ * @throws ValidationException
+ */
+ protected boolean exploreOutlineLevel(PDOutlineItem inputItem,
+ DocumentHandler handler, List<ValidationError> result)
+ throws ValidationException {
+ PDOutlineItem currentItem = inputItem;
+ while (currentItem != null) {
+ if (!validateItem(currentItem, handler, result)) {
+ return false;
+ }
+ currentItem = currentItem.getNextSibling();
+ }
+ return true;
+ }
- return isValid;
- }
+ /**
+ * This method checks the inputItem dictionary and call the
+ * exploreOutlineLevel method on the first child if it is not null.
+ *
+ * @param inputItem
+ * outline item to validate
+ * @param handler
+ * The document handler which provides useful data for the level
+ * exploration (ex : access to the PDDocument)
+ * @param result
+ * @return
+ * @throws ValidationException
+ */
+ protected boolean validateItem(PDOutlineItem inputItem,
+ DocumentHandler handler, List<ValidationError> result)
+ throws ValidationException {
+ boolean isValid = true;
+ // ---- Dest entry isn't permitted if the A entry is present
+ // A entry isn't permitted if the Dest entry is present
+ // If the A enntry is present, the referenced actions is validated
+ COSDictionary dictionary = inputItem.getCOSDictionary();
+ COSBase dest = dictionary.getItem(COSName
+ .getPDFName(DICTIONARY_KEY_DESTINATION));
+ COSBase action = dictionary.getItem(COSName
+ .getPDFName(DICTIONARY_KEY_ACTION));
+
+ if (action != null && dest != null) {
+ result.add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
+ "Dest entry isn't permitted if the A entry is present"));
+ return false;
+ } else if (action != null) {
+ List<AbstractActionManager> actions = this.actionFact.getActions(dictionary, handler
+ .getDocument().getDocument());
+ for (AbstractActionManager act : actions) {
+ isValid = isValid && act.valid(result);
+ }
+ } // else no specific validation
+
+ // ---- check children
+ PDOutlineItem fChild = inputItem.getFirstChild();
+ if (fChild != null) {
+ if (!isCountEntryPresent(inputItem.getCOSDictionary())) {
+ result
+ .add(new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
+ "Outline item doesn't have Count entry but has at least one descendant."));
+ isValid = false;
+ } else {
+ // ---- there are some descendants, so dictionary must have a Count
+ // entry
+ isValid = isValid && exploreOutlineLevel(fChild, handler, result);
+ }
+ }
+
+ return isValid;
+ }
}