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/07/24 16:02:33 UTC

svn commit: r1150373 [9/12] - in /pdfbox/trunk/preflight: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/padaf/ src/main/java/org/apache/padaf/preflight/ src/main/java/org/apache/padaf/preflight/a...

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/FontValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/FontValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/FontValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/FontValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.font.FontValidator;
+import org.apache.padaf.preflight.font.FontValidatorFactory;
+import org.apache.padaf.preflight.font.Type3FontValidator;
+import org.apache.padaf.preflight.font.AbstractFontContainer.State;
+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.cos.COSObject;
+import org.apache.pdfbox.pdmodel.PDDocument;
+
+/**
+ * This Validation helper validates font objects contained by the PDF File. This
+ * class stores all validated fonts in the DocumentHandler to allow some
+ * validation like ContentStream.
+ * 
+ * So FontValidationHelper must be one of the first validation helper to be
+ * called.
+ */
+public class FontValidationHelper extends AbstractValidationHelper {
+	protected FontValidatorFactory fontValidationFactory = null; 
+
+	public FontValidationHelper(ValidatorConfig cfg) throws ValidationException {
+		super(cfg);
+		initFontValidatorFactory();
+	}
+
+	/**
+	 * instantiate the FontValidatorFactory used by the FontValidationHelper
+	 */
+	protected void initFontValidatorFactory () {
+		this.fontValidationFactory = new FontValidatorFactory();	
+	}
+	
+	@Override
+	public List<ValidationError> innerValidate(DocumentHandler handler)
+	throws ValidationException {
+		List<ValidationError> result = new ArrayList<ValidationError>(0);
+		PDDocument pdfDoc = handler.getDocument();
+		COSDocument cDoc = pdfDoc.getDocument();
+
+		List<?> lCOSObj = cDoc.getObjects();
+
+		List<FontValidator> lType3 = new ArrayList<FontValidator>();
+
+		for (Object o : lCOSObj) {
+			COSObject cObj = (COSObject) o;
+
+			// If this object represents a Stream, the Dictionary must contain the
+			// Length key
+			COSBase cBase = cObj.getObject();
+			if (cBase instanceof COSDictionary) {
+				COSDictionary dic = (COSDictionary) cBase;
+				String type = dic.getNameAsString(COSName
+						.getPDFName(DICTIONARY_KEY_TYPE));
+				if (type != null && FONT_DICTIONARY_VALUE_FONT.equals(type)) {
+					FontValidator fontVal = fontValidationFactory.getFontValidator(cObj,
+							handler);
+					if (fontVal instanceof Type3FontValidator) {
+						lType3.add(fontVal);
+					} else {
+						validateFont(handler, fontVal, result);
+					}
+				}
+			}
+		}
+
+		// ---- Type 3 can contain other font, so type 3 are validated at the end.
+		for (FontValidator t3FontVal : lType3) {
+			validateFont(handler, t3FontVal, result);
+		}
+
+		return result;
+	}
+
+	public void validateFont(DocumentHandler handler, FontValidator fontVal,
+			List<ValidationError> result) throws ValidationException {
+		if (fontVal != null) {
+			fontVal.validate(); 
+			if (fontVal.getState() == State.INVALID) {
+				result.addAll(fontVal.getValdiationErrors());
+				// If State is MAYBE, the Error must be checked when the font is used.
+			}
+		}
+	}
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/FontValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/GraphicsValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/GraphicsValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/GraphicsValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/GraphicsValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.graphics.ShadingPattern;
+import org.apache.padaf.preflight.graphics.TilingPattern;
+import org.apache.padaf.preflight.graphics.XObjFormValidator;
+import org.apache.padaf.preflight.graphics.XObjImageValidator;
+import org.apache.padaf.preflight.graphics.XObjPostscriptValidator;
+import org.apache.padaf.preflight.graphics.XObjectValidator;
+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.cos.COSObject;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDDocument;
+
+/**
+ * @author eric
+ * 
+ */
+public class GraphicsValidationHelper extends AbstractValidationHelper {
+
+  public GraphicsValidationHelper(ValidatorConfig cfg)
+  throws ValidationException {
+		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);
+    PDDocument pdfDoc = handler.getDocument();
+
+    // ---- Checks all XObjects
+    COSDocument cDoc = pdfDoc.getDocument();
+    List<?> lCOSObj = cDoc.getObjects();
+    for (Object o : lCOSObj) {
+      COSObject cObj = (COSObject) o;
+      COSBase cBase = cObj.getObject();
+      if (cBase instanceof COSDictionary) {
+        COSDictionary dic = (COSDictionary) cBase;
+        String type = dic.getNameAsString(COSName
+            .getPDFName(DICTIONARY_KEY_TYPE));
+        if (type != null && DICTIONARY_KEY_XOBJECT.equals(type)) {
+          result.addAll(validateXObject(handler, cObj));
+        } else if (type != null && DICTIONARY_KEY_PATTERN.equals(type)) {
+          result.addAll(validatePattern(handler, cObj));
+        }
+      }
+    }
+    return result;
+  }
+
+  public List<ValidationError> validatePattern(DocumentHandler handler,
+      COSObject cObj) throws ValidationException {
+    COSDictionary cosPattern = (COSDictionary) cObj.getObject();
+    int ptype = cosPattern.getInt(DICTIONARY_KEY_PATTERN_TYPE);
+
+    XObjectValidator validator = null;
+
+    switch (ptype) {
+    case DICTIONARY_PATTERN_TILING:
+      validator = new TilingPattern(handler, (COSStream) cosPattern);
+      break;
+    case DICTIONARY_PATTERN_SHADING:
+      validator = new ShadingPattern(handler, cosPattern);
+      break;
+    default:
+      throw new ValidationException("Unkown pattern type : " + ptype);
+    }
+
+    return validator.validate();
+  }
+
+  public List<ValidationError> validateXObject(DocumentHandler handler,
+      COSObject cObj) throws ValidationException {
+    XObjectValidator xObjVal = null;
+
+    // ---- According to the XObject subtype, the validation isn't processed by
+    // the same Validator
+    COSStream dic = (COSStream) cObj.getObject();
+    String subtype = dic.getNameAsString(COSName
+        .getPDFName(DICTIONARY_KEY_SUBTYPE));
+
+    if (XOBJECT_DICTIONARY_VALUE_SUBTYPE_IMG.equals(subtype)) {
+      xObjVal = new XObjImageValidator(handler, dic);
+    } else if (XOBJECT_DICTIONARY_VALUE_SUBTYPE_FORM.equals(subtype)) {
+      xObjVal = new XObjFormValidator(handler, dic);
+    } else if (XOBJECT_DICTIONARY_VALUE_SUBTYPE_POSTSCRIPT.equals(subtype)) {
+      xObjVal = new XObjPostscriptValidator(handler, dic);
+    } else {
+      throw new ValidationException("Invalid XObject subtype");
+    }
+
+    return xObjVal.validate();
+  }
+
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/GraphicsValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/MetadataValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/MetadataValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/MetadataValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/MetadataValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,248 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.commons.io.IOUtils;
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.utils.COSUtils;
+import org.apache.padaf.preflight.xmp.PDFAIdentificationValidation;
+import org.apache.padaf.preflight.xmp.RDFAboutAttributeConcordanceValidation;
+import org.apache.padaf.preflight.xmp.SynchronizedMetaDataValidation;
+import org.apache.padaf.preflight.xmp.XpacketParsingException;
+import org.apache.padaf.preflight.xmp.RDFAboutAttributeConcordanceValidation.DifferentRDFAboutException;
+import org.apache.padaf.xmpbox.XMPMetadata;
+import org.apache.padaf.xmpbox.parser.XMPDocumentBuilder;
+import org.apache.padaf.xmpbox.parser.XmpExpectedRdfAboutAttribute;
+import org.apache.padaf.xmpbox.parser.XmpParsingException;
+import org.apache.padaf.xmpbox.parser.XmpPropertyFormatException;
+import org.apache.padaf.xmpbox.parser.XmpRequiredPropertyException;
+import org.apache.padaf.xmpbox.parser.XmpSchemaException;
+import org.apache.padaf.xmpbox.parser.XmpUnexpectedNamespacePrefixException;
+import org.apache.padaf.xmpbox.parser.XmpUnexpectedNamespaceURIException;
+import org.apache.padaf.xmpbox.parser.XmpUnknownPropertyException;
+import org.apache.padaf.xmpbox.parser.XmpUnknownSchemaException;
+import org.apache.padaf.xmpbox.parser.XmpUnknownValueTypeException;
+import org.apache.padaf.xmpbox.parser.XmpXpacketEndException;
+import org.apache.padaf.xmpbox.type.BadFieldValueException;
+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.cos.COSObject;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+
+public class MetadataValidationHelper extends AbstractValidationHelper {
+
+  public MetadataValidationHelper(ValidatorConfig cfg)
+  throws ValidationException {
+	super(cfg);
+  }
+
+  /**
+   * Return the xpacket from the dictionary's stream
+   */
+  public static byte[] getXpacket(COSDocument cdocument) throws IOException,
+      XpacketParsingException {
+    COSObject catalog = cdocument.getCatalog();
+    COSBase cb = catalog.getDictionaryObject(COSName.METADATA);
+    if (cb == null) {
+      // missing Metadata Key in catalog
+      ValidationError error = new ValidationError(
+          ValidationConstants.ERROR_METADATA_FORMAT,
+          "Missing Metadata Key in catalog");
+      throw new XpacketParsingException("Failed while retrieving xpacket",
+          error);
+    }
+    // no filter key
+    COSDictionary metadataDictionnary = COSUtils.getAsDictionary(cb, cdocument);
+    if (metadataDictionnary.getItem(COSName.FILTER) != null) {
+      // should not be defined
+      ValidationError error = new ValidationError(
+          ValidationConstants.ERROR_SYNTAX_STREAM_INVALID_FILTER,
+          "Filter specified in metadata dictionnary");
+      throw new XpacketParsingException("Failed while retrieving xpacket",
+          error);
+    }
+
+    PDStream stream = PDStream.createFromCOS(metadataDictionnary);
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    InputStream is = stream.createInputStream();
+    IOUtils.copy(is, bos);
+    is.close();
+    bos.close();
+    return bos.toByteArray();
+  }
+
+  public List<ValidationError> innerValidate(DocumentHandler handler)
+      throws ValidationException {
+    try {
+      PDDocument document = handler.getDocument();
+
+      byte[] tmp = getXpacket(document.getDocument());
+      XMPDocumentBuilder builder;
+	  try {
+		builder = new XMPDocumentBuilder();
+	  } catch (XmpSchemaException e1) {
+	    throw new ValidationException(e1.getMessage(), e1);
+	  }
+      XMPMetadata metadata;
+      try {
+        metadata = builder.parse(tmp);
+        handler.setMetadata(metadata);
+      } catch (XmpSchemaException e) {
+        throw new ValidationException(
+            "Parser: Internal Problem (failed to instanciate Schema object)", e);
+      } catch (XmpXpacketEndException e) {
+        throw new ValidationException("Unable to parse font metadata due to : "
+            + e.getMessage(), e);
+      }
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+
+      // 6.7.5 no deprecated attribute in xpacket processing instruction
+      if (metadata.getXpacketBytes() != null) {
+        lve.add(new ValidationError(
+            ValidationConstants.ERROR_METADATA_XPACKET_DEPRECATED,
+            "bytes attribute is forbidden"));
+      }
+      if (metadata.getXpacketEncoding() != null) {
+        lve.add(new ValidationError(
+            ValidationConstants.ERROR_METADATA_XPACKET_DEPRECATED,
+            "encoding attribute is forbidden"));
+      }
+
+      // Call metadata synchronization checking
+      lve.addAll(new SynchronizedMetaDataValidation()
+          .validateMetadataSynchronization(document, metadata));
+
+      // Call PDF/A Identifier checking
+      lve.addAll(new PDFAIdentificationValidation()
+          .validatePDFAIdentifer(metadata));
+
+      // Call rdf:about checking
+      try {
+        new RDFAboutAttributeConcordanceValidation()
+            .validateRDFAboutAttributes(metadata);
+      } catch (DifferentRDFAboutException e) {
+        lve.add(new ValidationError(
+            ValidationConstants.ERROR_METADATA_RDF_ABOUT_ATTRIBUTE_INEQUAL_VALUE, e
+                .getMessage()));
+      }
+
+      return lve;
+    } catch (XpacketParsingException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      if (e.getError() != null) {
+        lve.add(e.getError());
+      } else {
+        lve.add(new ValidationError(ValidationConstants.ERROR_METADATA_MAIN,
+            "Unexpected error"));
+      }
+      return lve;
+    } catch (XmpPropertyFormatException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_PROPERTY_FORMAT, e.getMessage()));
+      return lve;
+    } catch (BadFieldValueException e) {
+		List<ValidationError> lve = new ArrayList<ValidationError>();
+		lve.add(new ValidationError(ValidationConstants.ERROR_METADATA_CATEGORY_PROPERTY_INVALID ,e.getMessage()));
+		return lve;
+	}
+	catch (XmpExpectedRdfAboutAttribute e) {
+		List<ValidationError> lve = new ArrayList<ValidationError>();
+		lve.add(new ValidationError(ValidationConstants.ERROR_METADATA_RDF_ABOUT_ATTRIBUTE_MISSING ,e.getMessage()));
+		return lve;
+    } catch (XmpUnknownPropertyException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_PROPERTY_UNKNOWN, e.getMessage()));
+      return lve;
+    } catch (XmpUnknownSchemaException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_ABSENT_DESCRIPTION_SCHEMA, e
+              .getMessage()));
+      return lve;
+    } catch (XmpUnexpectedNamespaceURIException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_WRONG_NS_URI, e.getMessage()));
+      return lve;
+    } catch (XmpUnexpectedNamespacePrefixException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_ABSENT_DESCRIPTION_SCHEMA, e
+              .getMessage()));
+      return lve;
+    } catch (XmpRequiredPropertyException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(
+          ValidationConstants.ERROR_METADATA_PROPERTY_MISSING, e.getMessage()));
+      return lve;
+    } catch (XmpUnknownValueTypeException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve
+          .add(new ValidationError(
+              ValidationConstants.ERROR_METADATA_UNKNOWN_VALUETYPE, e
+                  .getMessage()));
+      return lve;
+    } catch (XmpParsingException e) {
+      List<ValidationError> lve = new ArrayList<ValidationError>();
+      lve.add(new ValidationError(ValidationConstants.ERROR_METADATA_FORMAT, e
+          .getMessage()));
+      return lve;
+    }
+
+    catch (IOException e) {
+      throw new ValidationException("Failed while validating", e);
+    }
+  }
+
+  /**
+   * Check if metadata dictionary has no stream filter
+   * 
+   * @param doc
+   * @return
+   */
+  protected List<ValidationError> checkStreamFilterUsage(PDDocument doc) {
+    List<ValidationError> ve = new ArrayList<ValidationError>();
+    List<?> filters = doc.getDocumentCatalog().getMetadata().getFilters();
+    if (filters != null && !filters.isEmpty()) {
+      ve.add(new ValidationError(ValidationConstants.ERROR_METADATA_MAIN,
+          "Using stream filter on metadata dictionary is forbidden"));
+    }
+    return ve;
+  }
+
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/MetadataValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/PagesValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/PagesValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/PagesValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/PagesValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,235 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationException;
+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.annotation.AnnotationValidator;
+import org.apache.padaf.preflight.contentstream.ContentStreamWrapper;
+import org.apache.padaf.preflight.graphics.ExtGStateContainer;
+import org.apache.padaf.preflight.graphics.ShadingPattern;
+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.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+
+
+public class PagesValidationHelper extends AbstractValidationHelper {
+ 
+  public PagesValidationHelper(ValidatorConfig cfg)
+  throws ValidationException {
+	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) {
+
+      // ---- PDFBox provides a method which returns all pages in a List.
+      // Currently, it is useless to explore the Pages hierarchy.
+      List<?> pages = catalog.getAllPages();
+      for (int i = 0; i < pages.size(); ++i) {
+        if (!validatePage((PDPage) pages.get(i), handler, result)) {
+          return result;
+        }
+      }
+    } else {
+      throw new ValidationException(
+          "There are no Catalog entry in the Document.");
+    }
+
+    return result;
+  }
+
+  /**
+   * This method checks the given page. Only a part of element contained by the
+   * page will be checked, like :
+   * <UL>
+   * <li>Presence of mandatory elements
+   * <li>The page content when it is possible (ex : text area)
+   * <li>The Additional Actions are authorized
+   * <li>etc...
+   * </UL>
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   */
+  protected boolean validatePage(PDPage page, DocumentHandler handler,
+      List<ValidationError> result) throws ValidationException {
+    boolean isValid = validateActions(page, handler, result);
+    isValid = isValid && validateAnnotation(page, handler, result);
+    isValid = isValid && validateTransparency(page, handler, result);
+    isValid = isValid && validateContent(page, handler, result);
+    isValid = isValid && validateShadingPattern(page, handler, result);
+    return isValid;
+  }
+
+  /**
+   * This method checks additional actions contained in the given Page object.
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   * @throws ValidationException
+   */
+  protected boolean validateActions(PDPage page, DocumentHandler handler,
+      List<ValidationError> result) throws ValidationException {
+    // ---- get AA (additional actions) entry if it is present
+    List<AbstractActionManager> lActions = this.actionFact.getActions(page
+        .getCOSDictionary(), handler.getDocument().getDocument());
+    for (AbstractActionManager action : lActions) {
+      if (!action.valid(true, result)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * This method check the ExtGState entry of the resource dictionary.
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   * @throws ValidationException
+   */
+  protected boolean validateTransparency(PDPage page, DocumentHandler handler,
+      List<ValidationError> result) throws ValidationException {
+    PDResources resources = page.getResources();
+    COSDocument cDoc = handler.getDocument().getDocument();
+    ExtGStateContainer extGStates = new ExtGStateContainer(resources
+        .getCOSDictionary(), cDoc);
+    return extGStates.validateTransparencyRules(result);
+    // ---- Even if a Group entry is possible in the Page dictionary, No
+    // restrictions are defined by PDF/A
+  }
+
+  /**
+   * This method check the Shading entry of the resource dictionary if exists.
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   * @throws ValidationException
+   */
+  protected boolean validateShadingPattern(PDPage page,
+      DocumentHandler handler, List<ValidationError> result)
+      throws ValidationException {
+    PDResources resources = page.getResources();
+    COSDictionary shadings = (COSDictionary) resources.getCOSDictionary()
+        .getDictionaryObject(PATTERN_KEY_SHADING);
+    boolean res = true;
+    if (shadings != null) {
+      for (Object key : shadings.keySet()) {
+        COSDictionary aShading = (COSDictionary) shadings
+            .getDictionaryObject((COSName) key);
+        ShadingPattern sp = new ShadingPattern(handler, aShading);
+        List<ValidationError> lErrors = sp.validate();
+        if (lErrors != null && !lErrors.isEmpty()) {
+          result.addAll(lErrors);
+          res = false;
+        }
+      }
+    }
+    return res;
+  }
+
+  /**
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   * @throws ValidationException
+   */
+  protected boolean validateContent(PDPage page, DocumentHandler handler,
+      List<ValidationError> result) throws ValidationException {
+
+    ContentStreamWrapper csWrapper = new ContentStreamWrapper(handler);
+    List<ValidationError> csParseErrors = csWrapper.validPageContentStream(page);
+    if (csParseErrors == null || csParseErrors.isEmpty()) {
+      return true;
+    }
+
+    result.addAll(csParseErrors);
+    return false;
+  }
+
+  /**
+   * 
+   * @param page
+   * @param handler
+   * @param result
+   * @return
+   * @throws ValidationException
+   */
+  protected boolean validateAnnotation(PDPage page, DocumentHandler handler,
+      List<ValidationError> result) throws ValidationException {
+    try {
+      List<?> lAnnots = page.getAnnotations();
+      for (Object object : lAnnots) {
+        if (object instanceof PDAnnotation) {
+
+          COSDictionary cosAnnot = ((PDAnnotation) object).getDictionary();
+          AnnotationValidator validator = this.annotFact.getAnnotationValidator(cosAnnot, handler, result);
+          if (validator != null) {
+            return validator.validate(result);
+          }
+
+        }
+      }
+
+    } catch (IOException e) {
+      throw new ValidationException("Unable to access Annotation", e);
+    }
+    // --- No annotations, validation OK
+    return true;
+  }
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/PagesValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/StreamValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/StreamValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/StreamValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/StreamValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,360 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.commons.io.IOUtils;
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.utils.COSUtils;
+import org.apache.padaf.preflight.utils.FilterHelper;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDocument;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.persistence.util.COSObjectKey;
+
+/**
+ * @author eric
+ * 
+ */
+public class StreamValidationHelper extends AbstractValidationHelper {
+
+	public StreamValidationHelper(ValidatorConfig cfg)
+	throws ValidationException {
+	  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);
+		PDDocument pdfDoc = handler.getDocument();
+		COSDocument cDoc = pdfDoc.getDocument();
+
+		List<?> lCOSObj = cDoc.getObjects();
+		for (Object o : lCOSObj) {
+			COSObject cObj = (COSObject) o;
+
+			// If this object represents a Stream, the Dictionary must contain the
+			// Length key
+			COSBase cBase = cObj.getObject();
+			if (cBase instanceof COSStream) {
+				// it is a stream
+				result.addAll(validateStreamObject(handler, cObj));
+			}
+		}
+		return result;
+	}
+
+	public List<ValidationError> validateStreamObject(DocumentHandler handler,
+			COSObject cObj) throws ValidationException {
+		List<ValidationError> result = new ArrayList<ValidationError>(0);
+		COSStream streamObj = (COSStream) cObj.getObject();
+
+		// ---- Check dictionary entries
+		// ---- Only the Length entry is mandatory
+		// ---- In a PDF/A file, F, FFilter and FDecodeParms are forbidden
+		checkDictionaryEntries(streamObj, result);
+		// ---- check stream length
+		checkStreamLength(handler, cObj, result);
+		// ---- Check the Filter value(s)
+		checkFilters(streamObj, handler, result);
+
+		return result;
+	}
+
+	/**
+	 * This method checks if one of declared Filter is LZWdecode. If LZW is found,
+	 * the result list is updated with an error code.
+	 * 
+	 * @param stream
+	 * @param handler
+	 * @param result
+	 */
+	protected void checkFilters(COSStream stream, DocumentHandler handler,
+			List<ValidationError> result) {
+		COSDocument cDoc = handler.getDocument().getDocument();
+		COSBase bFilter = stream.getItem(COSName
+				.getPDFName(STREAM_DICTIONARY_KEY_FILTER));
+		if (bFilter != null) {
+			if (COSUtils.isArray(bFilter, cDoc)) {
+				COSArray afName = (COSArray) bFilter;
+				for (int i = 0; i < afName.size(); ++i) {
+					if (!FilterHelper.isAuthorizedFilter(afName.getString(i), result)) {
+						return;
+					}
+				}
+			} else if (bFilter instanceof COSName) {
+				String fName = ((COSName) bFilter).getName();
+				if (!FilterHelper.isAuthorizedFilter(fName, result)) {
+					return;
+				}
+			} else {
+				// ---- The filter type is invalid
+				result.add(new ValidationError(ERROR_SYNTAX_STREAM_INVALID_FILTER,
+				"Filter should be a Name or an Array"));
+			}
+		} 
+		//  else Filter entry is optional
+	}
+
+	private boolean readUntilStream(InputStream ra) throws IOException {
+		boolean search = true;
+		//    String stream = "";
+		boolean maybe = false;
+		int lastChar = -1;
+		do {
+			int c = ra.read();
+			switch (c) {
+			case 's':
+				//      stream = "s";
+				maybe = true;
+				lastChar = c;
+				break;
+			case 't':
+				//      if (maybe && stream.endsWith("s")) {
+				if (maybe && lastChar == 's') {
+					//          stream = stream + "t";
+					lastChar = c;
+				} else {
+					maybe = false;
+					lastChar = -1;
+				}
+				break;
+			case 'r':
+				// if (maybe && stream.endsWith("t")) {
+				if (maybe && lastChar == 't') {
+					//        stream = stream + "r";
+					lastChar = c;
+				} else {
+					maybe = false;
+					lastChar = -1;
+				}
+				break;
+			case 'e':
+				//      if (maybe && stream.endsWith("r")) {
+				if (maybe && lastChar == 'r') {
+					lastChar = c;
+					//        stream = stream + "e";
+				} else {
+					maybe = false;
+				}
+				break;
+			case 'a':
+				//        if (maybe && stream.endsWith("e")) {
+				if (maybe && lastChar == 'e') {
+					lastChar = c;
+					//        stream = stream + "a";
+				} else {
+					maybe = false;
+				}
+				break;
+			case 'm':
+				//        if (maybe && stream.endsWith("a")) {
+				if (maybe && lastChar == 'a') {
+					return true;
+				} else {
+					maybe = false;
+				}
+				break;
+			case -1:
+				search = false;
+				break;
+			default:
+				maybe = false;
+			break;
+			}
+		} while (search);
+		return false;
+	}
+
+	protected void checkStreamLength(DocumentHandler handler, COSObject cObj,
+			List<ValidationError> result) throws ValidationException {
+		COSStream streamObj = (COSStream) cObj.getObject();
+		int length = streamObj.getInt(COSName
+				.getPDFName(STREAM_DICTIONARY_KEY_LENGHT));
+		InputStream ra = null;
+		try {
+			ra = handler.getSource().getInputStream();
+			Integer offset = (Integer) handler.getDocument().getDocument()
+			.getXrefTable().get(new COSObjectKey(cObj));
+
+			// ---- go to the beginning of the object
+			long skipped = 0;
+			while (skipped != offset) {
+				long curSkip = ra.skip(offset - skipped);
+				if (curSkip < 0) {
+					throw new ValidationException(
+							"Unable to skip bytes in the PDFFile to check stream length");
+				}
+				skipped += curSkip;
+			}
+
+			// ---- go to the stream key word
+			if (readUntilStream(ra)) {
+				int c = ra.read();
+				if (c == '\r') {
+					ra.read();
+				} // else c is '\n' no more character to read
+
+
+				// ---- Here is the true beginning of the Stream Content.
+				// ---- Read the given length of bytes and check the 10 next bytes
+				// ---- to see if there are endstream.
+				byte[] buffer = new byte[1024];
+				int nbBytesToRead = length;
+
+				do {
+					int cr = 0;
+					if (nbBytesToRead > 1024) {
+						cr = ra.read(buffer, 0, 1024);
+					} else {
+						cr = ra.read(buffer, 0, nbBytesToRead);
+					}
+					if (cr == -1) {
+						result.add(new ValidationResult.ValidationError(
+								ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+								"Stream length is invalide"));
+						return;
+					} else {
+						nbBytesToRead = nbBytesToRead - cr;
+					}
+				} while (nbBytesToRead > 0);
+
+				int len = "endstream".length() + 2;
+				byte[] buffer2 = new byte[len];
+				for (int i = 0; i < len; ++i) {
+					buffer2[i] = (byte) ra.read();
+				}
+
+				// ---- check the content of 10 last characters
+				String endStream = new String(buffer2);
+				if (buffer2[0] == '\r' && buffer2[1] == '\n') {
+					if (!endStream.contains("endstream")) {
+						result.add(new ValidationResult.ValidationError(
+								ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+								"Stream length is invalide"));
+					}
+				} else if (buffer2[0] == '\r' && buffer2[1] == 'e') {
+					if (!endStream.contains("endstream")) {
+						result.add(new ValidationResult.ValidationError(
+								ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+								"Stream length is invalide"));
+					}
+				} else if (buffer2[0] == '\n' && buffer2[1] == 'e') {
+					if (!endStream.contains("endstream")) {
+						result.add(new ValidationResult.ValidationError(
+								ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+								"Stream length is invalide"));
+					}
+				} else {
+					result.add(new ValidationResult.ValidationError(
+							ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+							"Stream length is invalide"));
+				}
+
+			} else {
+				result.add(new ValidationResult.ValidationError(
+						ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_INVALID,
+						"Stream length is invalide"));
+			}
+		} catch (IOException e) {
+			throw new ValidationException(
+					"Unable to read a stream to validate it due to : " + e.getMessage(),
+					e);
+		} finally {
+			if ( ra != null) {
+				IOUtils.closeQuietly(ra);
+			}
+		}
+	}
+
+	/**
+	 * Check dictionary entries. Only the Length entry is mandatory. In a PDF/A
+	 * file, F, FFilter and FDecodeParms are forbidden
+	 * 
+	 * @param streamObj
+	 * @param result
+	 */
+	protected void checkDictionaryEntries(COSStream streamObj,
+			List<ValidationError> result) {
+		boolean len = false;
+		boolean f = false;
+		boolean ffilter = false;
+		boolean fdecParams = false;
+
+		for (Object key : streamObj.keyList()) {
+			if (!(key instanceof COSName)) {
+				result.add(new ValidationResult.ValidationError(
+						ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+						"Invalid key in The Stream dictionary"));
+				return;
+			}
+			COSName cosName = (COSName) key;
+			if (cosName.getName().equals(STREAM_DICTIONARY_KEY_LENGHT)) {
+				len = true;
+			}
+			if (cosName.getName().equals(STREAM_DICTIONARY_KEY_F)) {
+				f = true;
+			}
+			if (cosName.getName().equals(STREAM_DICTIONARY_KEY_FFILTER)) {
+				ffilter = true;
+			}
+			if (cosName.getName().equals(STREAM_DICTIONARY_KEY_FDECODEPARAMS)) {
+				fdecParams = true;
+			}
+		}
+
+		if (!len) {
+			result.add(new ValidationResult.ValidationError(
+					ValidationConstants.ERROR_SYNTAX_STREAM_LENGTH_MISSING,
+					"Stream length is missing"));
+		}
+
+		if (f || ffilter || fdecParams) {
+			result
+			.add(new ValidationResult.ValidationError(
+					ValidationConstants.ERROR_SYNTAX_STREAM_FX_KEYS,
+					"F, FFilter or FDecodeParms keys are present in the stream dictionary"));
+		}
+	}
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/StreamValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/TrailerValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/TrailerValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/TrailerValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/TrailerValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,376 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidationResult;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.padaf.preflight.utils.COSUtils;
+import org.apache.padaf.preflight.utils.PdfElementParser;
+import org.apache.pdfbox.cos.COSArray;
+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.cos.COSObject;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdmodel.PDDocument;
+
+/**
+ * @author eric
+ * 
+ */
+public class TrailerValidationHelper extends AbstractValidationHelper {
+
+  public TrailerValidationHelper(ValidatorConfig cfg)
+  throws ValidationException {
+	super(cfg);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * net.awl.edoc.pdfa.validation.helpers.AbstractValidationHelper#validate(
+   * net.awl.edoc.pdfa.validation.DocumentHandler)
+   */
+  @Override
+  public List<ValidationError> innerValidate(DocumentHandler handler)
+      throws ValidationException {
+
+    List<ValidationError> result = new ArrayList<ValidationError>(0);
+    PDDocument pdfDoc = handler.getDocument();
+
+    COSDictionary linearizedDict = isLinearizedPdf(pdfDoc);
+    if (linearizedDict != null) {
+      // it is a linearized PDF, check the linearized dictionary
+      checkLinearizedDictionnary(linearizedDict, result);
+
+      // if the pdf is a linearized pdf. the first trailer must be checked
+      // and it must have the same ID than the last trailer.
+      List<String> lTrailers = handler.getPdfExtractor().getAllTrailers();
+      String firstTrailer = lTrailers.get(0);
+      String lastTrailer = lTrailers.get(lTrailers.size() - 1);
+
+      COSDictionary first = null;
+      COSDictionary last = null;
+      COSDocument cd = null;
+      try {
+        cd = new COSDocument();
+        PdfElementParser parser1 = new PdfElementParser(cd, firstTrailer
+            .getBytes());
+        first = parser1.parseAsDictionary();
+        PdfElementParser parser2 = new PdfElementParser(cd, lastTrailer
+            .getBytes());
+        last = parser2.parseAsDictionary();
+
+        checkMainTrailer(pdfDoc.getDocument(), first, result);
+        if (!compareIds(first, last, pdfDoc.getDocument())) {
+          result.add(new ValidationResult.ValidationError(
+              ValidationConstants.ERROR_SYNTAX_TRAILER_ID_CONSISTENCY,
+              "ID is different in the first and the last trailer"));
+        }
+
+      } catch (IOException e) {
+        result.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_TRAILER,
+            "Unable to parse trailers of the linearized PDF"));
+      } finally {
+        COSUtils.closeDocumentQuietly(cd);
+      }
+
+    } else {
+      // If the PDF isn't a linearized one, only the last trailer must be
+      // checked
+      List<String> lTrailers = handler.getPdfExtractor().getAllTrailers();
+      String lastTrailer = lTrailers.get(lTrailers.size() - 1);
+
+      COSDocument cd = null;
+      try {
+        cd = new COSDocument();
+        PdfElementParser parser = new PdfElementParser(cd, lastTrailer
+            .getBytes());
+        COSDictionary trailer = parser.parseAsDictionary();
+        checkMainTrailer(pdfDoc.getDocument(), trailer, result);
+      } catch (IOException e) {
+        result.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_TRAILER,
+            "The trailer dictionary is missing"));
+      } finally {
+        try {
+          cd.close();
+        } catch (IOException e) {
+          COSUtils.closeDocumentQuietly(cd);
+        }
+      }
+
+    }
+    return result;
+  }
+
+  /**
+   * Return true if the ID of the first dictionary is the same as the id of the
+   * last dictionary Return false otherwise.
+   * 
+   * @param first
+   * @param last
+   * @return
+   */
+  protected boolean compareIds(COSDictionary first, COSDictionary last,
+      COSDocument doc) {
+    COSBase idFirst = first.getItem(COSName
+        .getPDFName(TRAILER_DICTIONARY_KEY_ID));
+    COSBase idLast = last
+        .getItem(COSName.getPDFName(TRAILER_DICTIONARY_KEY_ID));
+
+    if (idFirst == null || idLast == null) {
+      return false;
+    }
+
+    // ---- cast two COSBase to COSArray.
+    COSArray af = COSUtils.getAsArray(idFirst, doc);
+    COSArray al = COSUtils.getAsArray(idLast, doc);
+
+    // ---- if one COSArray is null, the PDF/A isn't valid
+    if ((af == null) || (al == null)) {
+      return false;
+    }
+
+    // ---- compare both arrays
+    boolean isEqual = true;
+    for (Object of : af.toList()) {
+      boolean oneIsEquals = false;
+      for (Object ol : al.toList()) {
+        // ---- according to PDF Reference 1-4, ID is an array containing two
+        // strings
+        if (!oneIsEquals)
+          oneIsEquals = ((COSString) ol).getString().equals(
+              ((COSString) of).getString());
+      }
+      isEqual = isEqual && oneIsEquals;
+    }
+    return isEqual;
+  }
+
+  /**
+   * check if all keys are authorized in a trailer dictionary and if the type is
+   * valid.
+   * 
+   * @param trailer
+   * @param lErrors
+   */
+  protected void checkMainTrailer(COSDocument doc, COSDictionary trailer,
+      List<ValidationError> lErrors) {
+    boolean id = false;
+    boolean root = false;
+    boolean size = false;
+    boolean prev = false;
+    boolean info = false;
+    boolean encrypt = false;
+
+    for (Object key : trailer.keySet()) {
+      if (!(key instanceof COSName)) {
+        lErrors.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+            "Invalid key in The trailer dictionary"));
+        return;
+      }
+
+      String cosName = ((COSName) key).getName();
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_ENCRYPT)) {
+        encrypt = true;
+      }
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_SIZE)) {
+        size = true;
+      }
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_PREV)) {
+        prev = true;
+      }
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_ROOT)) {
+        root = true;
+      }
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_INFO)) {
+        info = true;
+      }
+      if (cosName.equals(TRAILER_DICTIONARY_KEY_ID)) {
+        id = true;
+      }
+    }
+
+    // ---- PDF/A Trailer dictionary must contain the ID key
+    if (!id) {
+      lErrors.add(new ValidationResult.ValidationError(
+          ValidationConstants.ERROR_SYNTAX_TRAILER_MISSING_ID,
+          "The trailer dictionary doesn't contain ID"));
+    } else {
+      COSBase trailerId = trailer.getItem(COSName
+          .getPDFName(TRAILER_DICTIONARY_KEY_ID));
+      if (!COSUtils.isArray(trailerId, doc)) {
+        lErrors.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_TRAILER_TYPE_INVALID,
+            "The trailer dictionary contains an id but it isn't an array"));
+      }
+    }
+    // ---- PDF/A Trailer dictionary mustn't contain the Encrypt key
+    if (encrypt) {
+      lErrors.add(new ValidationResult.ValidationError(
+          ValidationConstants.ERROR_SYNTAX_TRAILER_ENCRYPT,
+          "The trailer dictionary contains Encrypt"));
+    }
+    // ---- PDF Trailer dictionary must contain the Size key
+    if (!size) {
+      lErrors.add(new ValidationResult.ValidationError(
+          ValidationConstants.ERROR_SYNTAX_TRAILER_MISSING_SIZE,
+          "The trailer dictionary doesn't contain Size"));
+    } else {
+      COSBase trailerSize = trailer.getItem(COSName
+          .getPDFName(TRAILER_DICTIONARY_KEY_SIZE));
+      if (!COSUtils.isInteger(trailerSize, doc)) {
+        lErrors.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_TRAILER_TYPE_INVALID,
+            "The trailer dictionary contains a size but it isn't an integer"));
+      }
+    }
+
+    // ---- PDF Trailer dictionary must contain the Root key
+    if (!root) {
+      lErrors.add(new ValidationResult.ValidationError(
+          ValidationConstants.ERROR_SYNTAX_TRAILER_MISSING_ROOT,
+          "The trailer dictionary doesn't contain Root"));
+    } else {
+      COSBase trailerRoot = trailer.getItem(COSName
+          .getPDFName(TRAILER_DICTIONARY_KEY_ROOT));
+      if (!COSUtils.isDictionary(trailerRoot, doc)) {
+        lErrors
+            .add(new ValidationResult.ValidationError(
+                ValidationConstants.ERROR_SYNTAX_TRAILER_TYPE_INVALID,
+                "The trailer dictionary contains a root but it isn't a dictionary"));
+      }
+    }
+    // ---- PDF Trailer dictionary may contain the Prev key
+    if (prev) {
+      COSBase trailerPrev = trailer.getItem(COSName
+          .getPDFName(TRAILER_DICTIONARY_KEY_PREV));
+      if (!COSUtils.isInteger(trailerPrev, doc)) {
+        lErrors.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_TRAILER_TYPE_INVALID,
+            "The trailer dictionary contains a prev but it isn't an integer"));
+      }
+    }
+    // ---- PDF Trailer dictionary may contain the Info key
+    if (info) {
+      COSBase trailerInfo = trailer.getItem(COSName
+          .getPDFName(TRAILER_DICTIONARY_KEY_INFO));
+      if (!COSUtils.isDictionary(trailerInfo, doc)) {
+        lErrors
+            .add(new ValidationResult.ValidationError(
+                ValidationConstants.ERROR_SYNTAX_TRAILER_TYPE_INVALID,
+                "The trailer dictionary contains an info but it isn't a dictionary"));
+      }
+    }
+  }
+
+  /**
+   * According to the PDF Reference, A linearized PDF contain a dictionary as
+   * first object (linearized dictionary) and only this one in the first
+   * section.
+   * 
+   * @param document
+   * @return
+   */
+  protected COSDictionary isLinearizedPdf(PDDocument document) {
+    // ---- Get Ref to obj
+    COSDocument cDoc = document.getDocument();
+    List<?> lObj = cDoc.getObjects();
+    for (Object object : lObj) {
+      COSBase curObj = ((COSObject) object).getObject();
+      if (curObj instanceof COSDictionary
+          && ((COSDictionary) curObj).keySet().contains(
+              COSName.getPDFName(DICTIONARY_KEY_LINEARIZED))) {
+        return (COSDictionary) curObj;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check if mandatory keys of linearized dictionary are present.
+   * 
+   * @param lErrors
+   */
+  protected void checkLinearizedDictionnary(COSDictionary linearizedDict,
+      List<ValidationError> lErrors) {
+    // ---- check if all keys are authorized in a linearized dictionary
+    // ---- Linearized dictionary must contain the lhoent keys
+    boolean l = false;
+    boolean h = false;
+    boolean o = false;
+    boolean e = false;
+    boolean n = false;
+    boolean t = false;
+
+    for (Object key : linearizedDict.keySet()) {
+      if (!(key instanceof COSName)) {
+        lErrors.add(new ValidationResult.ValidationError(
+            ValidationConstants.ERROR_SYNTAX_DICTIONARY_KEY_INVALID,
+            "Invalid key in The Linearized dictionary"));
+        return;
+      }
+
+      String cosName = ((COSName) key).getName();
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_L)) {
+        l = true;
+      }
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_H)) {
+        h = true;
+      }
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_O)) {
+        o = true;
+      }
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_E)) {
+        e = true;
+      }
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_N)) {
+        n = true;
+      }
+      if (cosName.equals(DICTIONARY_KEY_LINEARIZED_T)) {
+        t = true;
+      }
+    }
+
+    if (!(l && h && o && e && t && n)) {
+      lErrors.add(new ValidationResult.ValidationError(
+          ValidationConstants.ERROR_SYNTAX_DICT_INVALID,
+          "Invalid key in The Linearized dictionary"));
+    }
+
+    return;
+  }
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/TrailerValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/XRefValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/XRefValidationHelper.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/XRefValidationHelper.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/XRefValidationHelper.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.padaf.preflight.DocumentHandler;
+import org.apache.padaf.preflight.ValidationConstants;
+import org.apache.padaf.preflight.ValidationException;
+import org.apache.padaf.preflight.ValidatorConfig;
+import org.apache.padaf.preflight.ValidationResult.ValidationError;
+import org.apache.pdfbox.cos.COSDocument;
+
+/**
+ * Check if the number of inderect objects is less great than ValidationConstant.MAX_INDIRECT_OBJ.
+ */
+public class XRefValidationHelper extends AbstractValidationHelper {
+
+	/**
+	 * @param cfg
+	 * @throws ValidationException
+	 */
+	public XRefValidationHelper(ValidatorConfig cfg) throws ValidationException {
+		super(cfg);
+	}
+
+	/* (non-Javadoc)
+	 * @see net.padaf.preflight.helpers.AbstractValidationHelper#innerValidate(net.padaf.preflight.DocumentHandler)
+	 */
+	@Override
+	public List<ValidationError> innerValidate(DocumentHandler handler)
+	throws ValidationException {
+		List<ValidationError> errors = new ArrayList<ValidationError>();
+		COSDocument document = handler.getDocument().getDocument();
+		if ( document.getObjects().size() > ValidationConstants.MAX_INDIRECT_OBJ ) {
+			errors.add(new ValidationError(ERROR_SYNTAX_INDIRECT_OBJ_RANGE, "Too many indirect objects"));
+		}
+		return errors;
+	}
+
+}
+ 
\ No newline at end of file

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/XRefValidationHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/utils/COSUtils.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/utils/COSUtils.java?rev=1150373&view=auto
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/utils/COSUtils.java (added)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/utils/COSUtils.java Sun Jul 24 14:02:12 2011
@@ -0,0 +1,399 @@
+/*****************************************************************************
+ * 
+ * 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.padaf.preflight.utils;
+
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSDocument;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.persistence.util.COSObjectKey;
+
+public class COSUtils {
+
+  public static final Logger logger = Logger.getLogger(COSUtils.class);
+
+  /**
+   * return true if the elt is a COSDictionary or a reference to a COSDictionary
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isDictionary(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && obj.getObject() instanceof COSDictionary);
+      } catch (IOException e) {
+        return false;
+      }
+    }
+    return (elt instanceof COSDictionary);
+  }
+
+  /**
+   * return true if the elt is a COSString or a reference to a COSString
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isString(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && (obj.getObject() instanceof COSString || obj
+            .getObject() instanceof COSName));
+      } catch (IOException e) {
+        return false;
+      }
+    }
+
+    return (elt instanceof COSString || elt instanceof COSName);
+  }
+
+  /**
+   * return true if the elt is a COSStream or a reference to a COSStream
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isStream(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && obj.getObject() instanceof COSStream);
+      } catch (IOException e) {
+        return false;
+      }
+    }
+
+    return (elt instanceof COSStream);
+  }
+
+  /**
+   * return true if the elt is a COSInteger or a reference to a COSInteger
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isInteger(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && obj.getObject() instanceof COSInteger);
+      } catch (IOException e) {
+        return false;
+      }
+    }
+
+    return (elt instanceof COSInteger);
+  }
+
+  /**
+   * return true if elt is COSInteger or COSFloat
+   *
+   * @param elt
+   * @param doc
+   * @return boolean
+   */
+  public static boolean isNumeric (COSBase elt, COSDocument doc) {
+	  return isInteger(elt, doc) || isFloat(elt, doc);
+  }
+  
+  /**
+   * return true if the elt is a COSInteger or a reference to a COSInteger
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isFloat(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && obj.getObject() instanceof COSFloat);
+      } catch (IOException e) {
+        return false;
+      }
+    }
+
+    return (elt instanceof COSFloat);
+  }
+
+  /**
+   * return true if the elt is a COSArray or a reference to a COSArray
+   * 
+   * @param elt
+   * @param doc
+   * @return
+   */
+  public static boolean isArray(COSBase elt, COSDocument doc) {
+    if (elt instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) elt);
+        COSObject obj = doc.getObjectFromPool(key);
+        return (obj != null && obj.getObject() instanceof COSArray);
+      } catch (IOException e) {
+        return false;
+      }
+    }
+
+    return (elt instanceof COSArray);
+  }
+
+  /**
+   * Return the COSBase object as COSArray if the COSBase object is an instance
+   * of COSArray or a reference to a COSArray object. In other cases, this
+   * method returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static COSArray getAsArray(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj != null && obj.getObject() instanceof COSArray) {
+          return (COSArray) obj.getObject();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSArray) {
+      return (COSArray) cbase;
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Return the COSBase object as COSString if the COSBase object is an instance
+   * of COSString or a reference to a COSString object. In other cases, this
+   * method returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static String getAsString(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj != null && obj.getObject() instanceof COSString) {
+         return ((COSString) obj.getObject()).getString();
+        } else if (obj != null && obj.getObject() instanceof COSName) {
+          return ((COSName) obj.getObject()).getName();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSString) {
+      return ((COSString) cbase).getString();
+    } else if (cbase instanceof COSName) {
+      return ((COSName) cbase).getName();
+    } else { 
+      return null;
+    }
+  }
+
+  /**
+   * Return the COSBase object as COSDictionary if the COSBase object is an
+   * instance of COSDictionary or a reference to a COSDictionary object. In
+   * other cases, this method returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static COSDictionary getAsDictionary(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj != null && obj.getObject() instanceof COSDictionary) {
+          return (COSDictionary) obj.getObject();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSDictionary) {
+      return (COSDictionary) cbase;
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Return the COSBase object as COSStream if the COSBase object is an instance
+   * of COSStream or a reference to a COSStream object. In other cases, this
+   * method returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static COSStream getAsStream(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj != null && obj.getObject() instanceof COSStream) {
+          return (COSStream) obj.getObject();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSStream) {
+      return (COSStream) cbase;
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Return the COSBase object as Float if the COSBase object is an instance of
+   * COSFloat or a reference to a COSFloat object. In other cases, this method
+   * returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static Float getAsFloat(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj ==null) {
+        	return null;
+        } else if (obj.getObject() instanceof COSFloat) {
+          return ((COSFloat) obj.getObject()).floatValue();
+        } else if (obj.getObject() instanceof COSInteger) {
+        	return (float)((COSInteger)obj.getObject()).intValue();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSFloat) {
+      return ((COSFloat) cbase).floatValue();
+    } else if (cbase instanceof COSInteger) {
+        return (float)((COSInteger) cbase).intValue();
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Return the COSBase object as Integer if the COSBase object is an instance
+   * of COSInteger or a reference to a COSInteger object. In other cases, this
+   * method returns null;
+   * 
+   * @param cbase
+   * @param cDoc
+   * @return
+   */
+  public static Integer getAsInteger(COSBase cbase, COSDocument cDoc) {
+    if (cbase instanceof COSObject) {
+      try {
+        COSObjectKey key = new COSObjectKey((COSObject) cbase);
+        COSObject obj = cDoc.getObjectFromPool(key);
+        if (obj == null) {
+        	return null;
+        } else if (obj.getObject() instanceof COSInteger) {
+          return ((COSInteger) obj.getObject()).intValue();
+        } else if (obj.getObject() instanceof COSFloat) {
+          return ((COSFloat) obj.getObject()).intValue();
+        } else {
+          return null;
+        }
+      } catch (IOException e) {
+        return null;
+      }
+    } else if (cbase instanceof COSInteger) {
+      return ((COSInteger) cbase).intValue();
+    } else if (cbase instanceof COSFloat) {
+      return ((COSFloat) cbase).intValue();
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Close the given Document. If the close method of the document throws an
+   * exception, it is logged using a log4j logger (Level : WARN)
+   * 
+   * @param document
+   */
+  public static void closeDocumentQuietly(COSDocument document) {
+    try {
+      if (document != null) {
+        document.close();
+      }
+    } catch (IOException e) {
+      logger.warn("Error occured during the close of a COSDocument : "
+          + e.getMessage());
+    }
+  }
+
+  /**
+   * Close the given Document. If the close method of the document throws an
+   * exception, it is logged using a log4j logger (Level : WARN)
+   * 
+   * @param document
+   */
+  public static void closeDocumentQuietly(PDDocument document) {
+    if (document != null) {
+      closeDocumentQuietly(document.getDocument());
+    }
+  }
+}

Propchange: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/utils/COSUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native