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 15:57:54 UTC
svn commit: r1150371 [2/8] - in /pdfbox/trunk/xmpbox: ./ 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/xmpbox/
src/main/java/org/apache/padaf/xmpbox/parser/ src...
Added: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java?rev=1150371&view=auto
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java (added)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java Sun Jul 24 13:57:39 2011
@@ -0,0 +1,198 @@
+/*****************************************************************************
+ *
+ * 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.xmpbox.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.apache.commons.io.IOUtils;
+import org.apache.padaf.xmpbox.BuildPDFAExtensionSchemaDescriptionException;
+import org.apache.padaf.xmpbox.schema.XMPSchema;
+import org.apache.padaf.xmpbox.type.PropertyDescription;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * Manage XML property description file Allow user to create XML property
+ * description description file or retrieve List of PropertyDescription from an
+ * XML File If file data are specified in class schema representation, building
+ * of Description schema (which must included in PDF/A Extension) will use these
+ * information.
+ *
+ * @author a183132
+ *
+ */
+public class XMLPropertiesDescriptionManager {
+
+ protected List<PropertyDescription> propDescs;
+ protected XStream xstream;
+
+ /**
+ * Create new XMLPropertiesDescriptionManager
+ */
+ public XMLPropertiesDescriptionManager() {
+ propDescs = new ArrayList<PropertyDescription>();
+ xstream = new XStream(new DomDriver());
+ xstream.alias("PropertiesDescriptions", List.class);
+ xstream.alias("PropertyDescription", PropertyDescription.class);
+ }
+
+ /**
+ * Add a description for the named property
+ *
+ * @param name
+ * Name of property
+ * @param description
+ * Description which will be used
+ */
+ public void addPropertyDescription(String name, String description) {
+ propDescs.add(new PropertyDescription(name, description));
+ }
+
+ /**
+ * Save as XML data, all information defined before to the OutputStream
+ *
+ * @param os
+ * The stream where write data
+ */
+ public void toXML(OutputStream os) {
+ xstream.toXML(propDescs, os);
+ }
+
+ /**
+ * Load Properties Description from a well-formed XML File
+ *
+ * @param classSchem
+ * Description Schema where properties description are used
+ * @param path
+ * Relative Path (file loading search in same class Schema
+ * representation folder)
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When problems to get or treat data in XML description file
+ */
+ public void loadListFromXML(Class<? extends XMPSchema> classSchem,
+ String path) throws BuildPDFAExtensionSchemaDescriptionException {
+ InputStream fis = classSchem.getResourceAsStream(path);
+ if (fis == null) {
+ // resource not found
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to find specified XML properties descriptions resource");
+ }
+ loadListFromXML(fis);
+
+ }
+
+ /**
+ * Load Properties Description from XML Stream
+ *
+ * @param is
+ * Stream where read data
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When problems to get or treat data in XML description file
+ */
+ public void loadListFromXML(InputStream is)
+ throws BuildPDFAExtensionSchemaDescriptionException {
+ try {
+ Object o = xstream.fromXML(is);
+ if (o instanceof List<?>) {
+ if (((List<?>) o).get(0) != null) {
+ if (((List<?>) o).get(0) instanceof PropertyDescription) {
+ propDescs = (List<PropertyDescription>) o;
+ } else {
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to get correct properties descriptions from specified XML stream");
+ }
+ } else {
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to find a properties description into the specified XML stream");
+ }
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to get correct properties descriptions from specified XML stream",
+ e.getCause());
+ } finally {
+ IOUtils.closeQuietly(is);
+ }
+ }
+
+ /**
+ * Get all Properties Descriptions defined
+ *
+ * @return List of PropertyDescription
+ */
+ public List<PropertyDescription> getPropertiesDescriptionList() {
+ return propDescs;
+ }
+
+ /**
+ * Sample of using to write/read information
+ *
+ * @param args
+ * Not used
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When errors during building/reading xml file
+ */
+ public static void main(String[] args)
+ throws BuildPDFAExtensionSchemaDescriptionException {
+ XMLPropertiesDescriptionManager ptMaker = new XMLPropertiesDescriptionManager();
+
+ // add Descriptions
+ for (int i = 0; i < 3; i++) {
+ ptMaker.addPropertyDescription("name" + i, "description" + i);
+
+ }
+
+ // Display XML conversion
+ System.out.println("Display XML Result:");
+ ptMaker.toXML(System.out);
+
+ // Sample to show how to build object from XML file
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ptMaker.toXML(bos);
+ IOUtils.closeQuietly(bos);
+
+ // emulate a new reading
+ InputStream is = new ByteArrayInputStream(bos.toByteArray());
+ ptMaker = new XMLPropertiesDescriptionManager();
+ ptMaker.loadListFromXML(is);
+ List<PropertyDescription> result = ptMaker
+ .getPropertiesDescriptionList();
+ System.out.println();
+ System.out.println();
+ System.out.println("Result of XML Loading :");
+ for (PropertyDescription propertyDescription : result) {
+ System.out.println(propertyDescription.getPropertyName() + " :"
+ + propertyDescription.getDescription());
+ }
+ }
+
+}
Propchange: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java?rev=1150371&view=auto
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java (added)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java Sun Jul 24 13:57:39 2011
@@ -0,0 +1,407 @@
+/*****************************************************************************
+ *
+ * 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.xmpbox.parser;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+import org.apache.padaf.xmpbox.type.Elementable;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+
+/**
+ * This class with handle some simple XML operations.
+ *
+ * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
+ * @author <a href="mailto:chris@oezbek.net">Christopher Oezbek</a>
+ *
+ * @version $Revision: 1.2 $
+ */
+public final class XMLUtil {
+ /**
+ * Utility class, should not be instantiated.
+ *
+ */
+ private XMLUtil() {
+ }
+
+ /**
+ * This will parse an XML stream and create a DOM document.
+ *
+ * @param is
+ * The stream to get the XML from.
+ * @return The DOM document.
+ * @throws IOException
+ * It there is an error creating the dom.
+ */
+ public static Document parse(InputStream is) throws IOException {
+ try {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ return builder.parse(is);
+ } catch (Exception e) {
+ IOException thrown = new IOException(e.getMessage());
+ throw thrown;
+ }
+ }
+
+ /**
+ * This will parse an InputSource and create a DOM document.
+ *
+ * @param is
+ * The stream to get the XML from.
+ * @return The DOM document.
+ * @throws IOException
+ * It there is an error creating the dom.
+ */
+ public static Document parse(InputSource is) throws IOException {
+ try {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ return builder.parse(is);
+ } catch (Exception e) {
+ IOException thrown = new IOException(e.getMessage());
+ throw thrown;
+ }
+ }
+
+ /**
+ * This will parse an XML stream and create a DOM document.
+ *
+ * @param fileName
+ * The file to get the XML from.
+ * @return The DOM document.
+ * @throws IOException
+ * It there is an error creating the dom.
+ */
+ public static Document parse(String fileName) throws IOException {
+ try {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ return builder.parse(fileName);
+ } catch (Exception e) {
+ IOException thrown = new IOException(e.getMessage());
+ throw thrown;
+ }
+ }
+
+ /**
+ * Create a new blank XML document.
+ *
+ * @return The new blank XML document.
+ *
+ * @throws IOException
+ * If there is an error creating the XML document.
+ */
+ public static Document newDocument() throws IOException {
+ try {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ return builder.newDocument();
+ } catch (Exception e) {
+ IOException thrown = new IOException(e.getMessage());
+ throw thrown;
+ }
+ }
+
+ /**
+ * Get the first instance of an element by name.
+ *
+ * @param parent
+ * The parent to get the element from.
+ * @param elementName
+ * The name of the element to look for.
+ * @return The element or null if it is not found.
+ */
+ public static Element getElement(Element parent, String elementName) {
+ Element retval = null;
+ NodeList children = parent.getElementsByTagName(elementName);
+ if (children.getLength() > 0) {
+ retval = (Element) children.item(0);
+ }
+ return retval;
+ }
+
+ /**
+ * Get the integer value of a subnode.
+ *
+ * @param parent
+ * The parent element that holds the values.
+ * @param nodeName
+ * The name of the node that holds the integer value.
+ *
+ * @return The integer value of the node.
+ */
+ public static Integer getIntValue(Element parent, String nodeName) {
+ String intVal = XMLUtil.getStringValue(XMLUtil.getElement(parent,
+ nodeName));
+ Integer retval = null;
+ if (intVal != null) {
+ retval = new Integer(intVal);
+ }
+ return retval;
+ }
+
+ /**
+ * Set the integer value of an element.
+ *
+ * @param parent
+ * The parent element that will hold this subelement.
+ * @param nodeName
+ * The name of the subelement.
+ * @param intValue
+ * The value to set.
+ */
+ public static void setIntValue(Element parent, String nodeName,
+ Integer intValue) {
+ Element currentValue = getElement(parent, nodeName);
+ if (intValue == null) {
+ if (currentValue != null) {
+ parent.removeChild(currentValue);
+ } // else it doesn't exist so we don't need to remove it.
+ } else {
+ if (currentValue == null) {
+ currentValue = parent.getOwnerDocument()
+ .createElement(nodeName);
+ parent.appendChild(currentValue);
+ }
+ XMLUtil.setStringValue(currentValue, intValue.toString());
+ }
+ }
+
+ /**
+ * Get the value of a subnode.
+ *
+ * @param parent
+ * The parent element that holds the values.
+ * @param nodeName
+ * The name of the node that holds the value.
+ *
+ * @return The value of the sub node.
+ */
+ public static String getStringValue(Element parent, String nodeName) {
+ return XMLUtil.getStringValue(XMLUtil.getElement(parent, nodeName));
+ }
+
+ /**
+ * Set the value of an element.
+ *
+ * @param parent
+ * The parent element that will hold this subelement.
+ * @param nodeName
+ * The name of the subelement.
+ * @param nodeValue
+ * The value to set.
+ */
+ public static void setStringValue(Element parent, String nodeName,
+ String nodeValue) {
+ Element currentValue = getElement(parent, nodeName);
+ if (nodeValue == null) {
+ if (currentValue != null) {
+ parent.removeChild(currentValue);
+ } // else it doesn't exist so we don't need to remove it.
+ } else {
+ if (currentValue == null) {
+ currentValue = parent.getOwnerDocument()
+ .createElement(nodeName);
+ parent.appendChild(currentValue);
+ }
+ XMLUtil.setStringValue(currentValue, nodeValue);
+ }
+ }
+
+ /**
+ * This will get the text value of an element.
+ *
+ * @param node
+ * The node to get the text value for.
+ * @return The text of the node.
+ */
+ public static String getStringValue(Element node) {
+ String retval = "";
+ NodeList children = node.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node next = children.item(i);
+ if (next instanceof Text) {
+ retval = next.getNodeValue();
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the text value of an element.
+ *
+ * @param node
+ * The node to get the text value for.
+ * @param value
+ * The new value to set the node to.
+ */
+ public static void setStringValue(Element node, String value) {
+ NodeList children = node.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node next = children.item(i);
+ if (next instanceof Text) {
+ node.removeChild(next);
+ }
+ }
+ node.appendChild(node.getOwnerDocument().createTextNode(value));
+ }
+
+ /**
+ * Set an XML element document.
+ *
+ * @param parent
+ * The parent document to set the value in.
+ * @param name
+ * The name of the XML element to set.
+ * @param node
+ * The node to set or clear.
+ */
+ public static void setElementableValue(Element parent, String name,
+ Elementable node) {
+ NodeList nodes = parent.getElementsByTagName(name);
+ if (node == null) {
+ for (int i = 0; i < nodes.getLength(); i++) {
+ parent.removeChild(nodes.item(i));
+ }
+ } else {
+ if (nodes.getLength() == 0) {
+ if (parent.hasChildNodes()) {
+ Node firstChild = parent.getChildNodes().item(0);
+ parent.insertBefore(node.getElement(), firstChild);
+ } else {
+ parent.appendChild(node.getElement());
+ }
+ } else {
+ Node oldNode = nodes.item(0);
+ parent.replaceChild(node.getElement(), oldNode);
+ }
+ }
+ }
+
+ /**
+ * Save the XML document to a file.
+ *
+ * @param doc
+ * The XML document to save.
+ * @param file
+ * The file to save the document to.
+ * @param encoding
+ * The encoding to save the file as.
+ *
+ * @throws TransformerException
+ * If there is an error while saving the XML.
+ */
+ public static void save(Document doc, String file, String encoding)
+ throws TransformerException {
+ Transformer transformer = TransformerFactory.newInstance()
+ .newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
+ "yes");
+ // initialize StreamResult with File object to save to file
+
+ Result result = new StreamResult(new File(file));
+ DOMSource source = new DOMSource(doc);
+ transformer.transform(source, result);
+ }
+
+ /**
+ * Save the XML document to an output stream.
+ *
+ * @param doc
+ * The XML document to save.
+ * @param outStream
+ * The stream to save the document to.
+ * @param encoding
+ * The encoding to save the file as.
+ *
+ * @throws TransformerException
+ * If there is an error while saving the XML.
+ */
+ public static void save(Node doc, OutputStream outStream, String encoding)
+ throws TransformerException {
+ Transformer transformer = TransformerFactory.newInstance()
+ .newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
+ "yes");
+
+ // initialize StreamResult with File object to save to file
+ Result result = new StreamResult(outStream);
+ DOMSource source = new DOMSource(doc);
+ transformer.transform(source, result);
+ }
+
+ /**
+ * Convert the document to an array of bytes.
+ *
+ * @param doc
+ * The XML document.
+ * @param encoding
+ * The encoding of the output data.
+ *
+ * @return The XML document as an array of bytes.
+ *
+ * @throws TransformerException
+ * If there is an error transforming to text.
+ */
+ public static byte[] asByteArray(Document doc, String encoding)
+ throws TransformerException {
+ Transformer transformer = TransformerFactory.newInstance()
+ .newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+
+ StringWriter writer = new StringWriter();
+ Result result = new StreamResult(writer);
+ DOMSource source = new DOMSource(doc);
+ transformer.transform(source, result);
+ return writer.getBuffer().toString().getBytes();
+ }
+}
Propchange: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java?rev=1150371&view=auto
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java (added)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java Sun Jul 24 13:57:39 2011
@@ -0,0 +1,244 @@
+/*****************************************************************************
+ *
+ * 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.xmpbox.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+import org.apache.commons.io.IOUtils;
+import org.apache.padaf.xmpbox.BuildPDFAExtensionSchemaDescriptionException;
+import org.apache.padaf.xmpbox.schema.XMPSchema;
+import org.apache.padaf.xmpbox.type.FieldDescription;
+import org.apache.padaf.xmpbox.type.ValueTypeDescription;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * Manage XML valuetype description file Allow user to create XML valuetype
+ * description file or retrieve List of ValueTypeDescription from an XML File
+ *
+ * If file data are specified in class schema representation, building of
+ * Description schema (which must included in PDF/A Extension) will use these
+ * information.
+ *
+ * @author a183132
+ *
+ */
+public class XMLValueTypeDescriptionManager {
+
+ protected List<ValueTypeDescription> vTypes;
+ protected XStream xstream;
+
+ /**
+ * Create a new XMLValueTypeDescriptionManager
+ */
+ public XMLValueTypeDescriptionManager() {
+ vTypes = new ArrayList<ValueTypeDescription>();
+ xstream = new XStream(new DomDriver());
+ xstream.alias("ValueTypesDescriptions", List.class);
+ xstream.alias("ValueTypeDescription", ValueTypeDescription.class);
+ xstream.alias("FieldDescription", FieldDescription.class);
+ }
+
+ /**
+ * Add a new Value Type description without any fields
+ *
+ * @param type
+ * Type of the Value Type
+ * @param nsURI
+ * namespace URI of the Value Type
+ * @param prefix
+ * prefix of the Value Type
+ * @param description
+ * Description of the Value Type
+ */
+ public void addValueTypeDescription(String type, String nsURI,
+ String prefix, String description) {
+ vTypes.add(new ValueTypeDescription(type, nsURI, prefix, description));
+ }
+
+ /**
+ * /** Add a new Value Type description with fields
+ *
+ * @param type
+ * Type of the Value Type
+ * @param nsURI
+ * namespace URI of the Value Type
+ * @param prefix
+ * prefix of the Value Type
+ * @param description
+ * Description of the Value Type
+ * @param fields
+ * List of FieldDescription
+ */
+ public void addValueTypeDescription(String type, String nsURI,
+ String prefix, String description, List<FieldDescription> fields) {
+ vTypes.add(new ValueTypeDescription(type, nsURI, prefix, description,
+ fields));
+ }
+
+ /**
+ * Save as XML data, all information defined before to the OutputStream
+ *
+ * @param os
+ * The stream where write data
+ */
+ public void toXML(OutputStream os) {
+ xstream.toXML(vTypes, os);
+ }
+
+ /**
+ * Load Value Types Descriptions from a well-formed XML File
+ *
+ * @param classSchem
+ * Description Schema where properties description are used
+ * @param path
+ * Relative Path (file loading search in same class Schema
+ * representation folder)
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When problems to get or treat data in XML description file
+ */
+ public void loadListFromXML(Class<? extends XMPSchema> classSchem,
+ String path) throws BuildPDFAExtensionSchemaDescriptionException {
+ InputStream fis = classSchem.getResourceAsStream(path);
+ if (fis == null) {
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to find specified XML valuetypes descriptions File");
+ }
+ loadListFromXML(fis);
+ }
+
+ /**
+ * Get all Value Types Descriptions defined
+ *
+ * @return List of ValueTypeDescription
+ */
+ public List<ValueTypeDescription> getValueTypesDescriptionList() {
+ return vTypes;
+ }
+
+ /**
+ * Load Value Types Descriptions from XML Stream
+ *
+ * @param is
+ * Stream where read data
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When problems to get or treat data in XML description file
+ */
+ public void loadListFromXML(InputStream is)
+ throws BuildPDFAExtensionSchemaDescriptionException {
+ try {
+ Object o = xstream.fromXML(is);
+ if (o instanceof List<?>) {
+ if (((List<?>) o).get(0) != null) {
+ if (((List<?>) o).get(0) instanceof ValueTypeDescription) {
+ vTypes = (List<ValueTypeDescription>) o;
+ } else {
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to get correct valuetypes descriptions from specified XML stream");
+ }
+ } else {
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to find a valuetype description into the specified XML stream");
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new BuildPDFAExtensionSchemaDescriptionException(
+ "Failed to get correct valuetypes descriptions from specified XML stream",
+ e.getCause());
+ } finally {
+ IOUtils.closeQuietly(is);
+ }
+ }
+
+ /**
+ * Sample of using to write/read information
+ *
+ * @param args
+ * not used
+ * @throws BuildPDFAExtensionSchemaDescriptionException
+ * When errors during building/reading xml file
+ */
+ public static void main(String[] args)
+ throws BuildPDFAExtensionSchemaDescriptionException {
+ XMLValueTypeDescriptionManager vtMaker = new XMLValueTypeDescriptionManager();
+
+ // add Descriptions
+ for (int i = 0; i < 3; i++) {
+ vtMaker.addValueTypeDescription("testType" + i, "nsURI" + i,
+ "prefix" + i, "description" + i);
+
+ }
+ List<FieldDescription> fieldSample = new ArrayList<FieldDescription>();
+ for (int i = 0; i < 2; i++) {
+ fieldSample.add(new FieldDescription("fieldName" + i, "valueType"
+ + i, "description" + i));
+ }
+ vtMaker.addValueTypeDescription("testTypeField",
+ "http://test.withfield.com/vt/", "prefTest",
+ " value type description", fieldSample);
+
+ // Display XML conversion
+ System.out.println("Display XML Result:");
+ vtMaker.toXML(System.out);
+
+ // Sample to show how to build object from XML file
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ vtMaker.toXML(bos);
+ IOUtils.closeQuietly(bos);
+
+ // emulate a new reading
+ InputStream is = new ByteArrayInputStream(bos.toByteArray());
+ vtMaker = new XMLValueTypeDescriptionManager();
+ vtMaker.loadListFromXML(is);
+ List<ValueTypeDescription> result = vtMaker
+ .getValueTypesDescriptionList();
+ System.out.println();
+ System.out.println();
+ System.out.println("Result of XML Loading :");
+ for (ValueTypeDescription propertyDescription : result) {
+ System.out.println(propertyDescription.getType() + " :"
+ + propertyDescription.getDescription());
+ if (propertyDescription.getFields() != null) {
+ Iterator<FieldDescription> fit = propertyDescription
+ .getFields().iterator();
+ FieldDescription field;
+ while (fit.hasNext()) {
+ field = fit.next();
+ System.out.println("Field " + field.getName() + " :"
+ + field.getValueType());
+ }
+ }
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java?rev=1150371&view=auto
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java (added)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java Sun Jul 24 13:57:39 2011
@@ -0,0 +1,1465 @@
+/*****************************************************************************
+ *
+ * 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.xmpbox.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.padaf.xmpbox.CreateXMPMetadataException;
+import org.apache.padaf.xmpbox.XMPMetadata;
+import org.apache.padaf.xmpbox.schema.PDFAExtensionSchema;
+import org.apache.padaf.xmpbox.schema.PDFAFieldDescription;
+import org.apache.padaf.xmpbox.schema.SchemaDescription;
+import org.apache.padaf.xmpbox.schema.XMPSchema;
+import org.apache.padaf.xmpbox.type.AbstractSimpleProperty;
+import org.apache.padaf.xmpbox.type.Attribute;
+import org.apache.padaf.xmpbox.type.BadFieldValueException;
+import org.apache.padaf.xmpbox.type.BooleanType;
+import org.apache.padaf.xmpbox.type.ComplexProperty;
+import org.apache.padaf.xmpbox.type.ComplexPropertyContainer;
+import org.apache.padaf.xmpbox.type.DateType;
+import org.apache.padaf.xmpbox.type.IntegerType;
+import org.apache.padaf.xmpbox.type.RealType;
+import org.apache.padaf.xmpbox.type.TextType;
+import org.apache.padaf.xmpbox.type.ThumbnailType;
+
+
+/**
+ * Parse serialized XMP (in XML/RDF Format) to the XmpBox representation.
+ *
+ * @author a183132
+ *
+ */
+public class XMPDocumentBuilder {
+ protected NSMapping nsMap;
+
+ protected ThreadLocal<XMLStreamReader> reader = new ThreadLocal<XMLStreamReader>();
+
+ /**
+ * Constructor of a XMPDocumentBuilder
+ *
+ * @throws XmpSchemaException
+ * When instancing schema object failed or in PDF/A Extension
+ * case, if its namespace miss
+ */
+ public XMPDocumentBuilder() throws XmpSchemaException {
+ nsMap = new NSMapping();
+ }
+
+ /**
+ * Parsing method. Return a XMPMetadata object with all elements read
+ *
+ * @param xmp
+ * serialized XMP
+ * @return Metadata with all information read
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XmpSchemaException
+ * When instancing schema object failed or in PDF/A Extension
+ * case, if its namespace miss
+ * @throws XmpUnknownValueTypeException
+ * When ValueType found not correspond to basic type and not has
+ * been declared in current schema
+ * @throws XmpExpectedRdfAboutAttribute
+ * When rdf:Description not contains rdf:about attribute
+ * @throws XmpXpacketEndException
+ * When xpacket end Processing Instruction is missing or is
+ * incorrect
+ * @throws BadFieldValueException
+ * When treat a Schema associed to a schema Description in PDF/A
+ * Extension schema
+ */
+
+ public XMPMetadata parse(byte[] xmp) throws XmpParsingException,
+ XmpSchemaException, XmpUnknownValueTypeException,
+ XmpExpectedRdfAboutAttribute, XmpXpacketEndException,
+ BadFieldValueException {
+ return parse(new ByteArrayInputStream(xmp));
+ }
+
+ /**
+ * Parsing method using serialized xmp read from a stream
+ *
+ * @param is
+ * The stream to read
+ * @return Metadata with all information read
+ * @throws XmpParsingException
+ * When element expected not found When element expected not
+ * found
+ * @throws XmpSchemaException
+ * When instancing schema object failed or in PDF/A Extension
+ * case, if its namespace miss
+ * @throws XmpUnknownValueTypeException
+ * When ValueType found not correspond to basic type and not has
+ * been declared in current schema
+ * @throws XmpExpectedRdfAboutAttribute
+ * When rdf:Description not contains rdf:about attribute
+ * @throws XmpXpacketEndException
+ * When xpacket end Processing Instruction is missing or is
+ * incorrect
+ * @throws BadFieldValueException
+ * When treat a Schema associed to a schema Description in PDF/A
+ * Extension schema
+ */
+ public XMPMetadata parse(InputStream is) throws XmpParsingException,
+ XmpSchemaException, XmpUnknownValueTypeException,
+ XmpExpectedRdfAboutAttribute, XmpXpacketEndException,
+ BadFieldValueException {
+
+ try {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ reader.set(factory.createXMLStreamReader(is));
+
+ // expect xpacket processing instruction
+ expectNext(XMLStreamReader.PROCESSING_INSTRUCTION,
+ "Did not find initial xpacket processing instruction");
+ XMPMetadata metadata = parseInitialXpacket(reader.get().getPIData());
+
+ // expect x:xmpmeta
+ expectNextTag(XMLStreamReader.START_ELEMENT,
+ "Did not find initial x:xmpmeta");
+ expectName("adobe:ns:meta/", "xmpmeta");
+
+ // expect rdf:RDF
+ expectNextTag(XMLStreamReader.START_ELEMENT,
+ "Did not find initial rdf:RDF");
+ expectName("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "RDF");
+
+ nsMap.resetComplexBasicTypesDeclarationInEntireXMPLevel();
+ // add all namespaces which could declare nsURI of a basicValueType
+ // all others declarations are ignored
+ int nsCount = reader.get().getNamespaceCount();
+ for (int i = 0; i < nsCount; i++) {
+ if (nsMap.isComplexBasicTypes(reader.get().getNamespaceURI(i))) {
+ System.out.println("in method parse: prefix:"
+ + reader.get().getAttributeLocalName(i)
+ + "; nsURI:" + reader.get().getAttributeValue(i));
+ nsMap.setComplexBasicTypesDeclarationForLevelXMP(reader
+ .get().getNamespaceURI(i), reader.get()
+ .getNamespacePrefix(i));
+ }
+ }
+ // now work on each rdf:Description
+ int type = reader.get().nextTag();
+ while (type == XMLStreamReader.START_ELEMENT) {
+ parseDescription(metadata);
+ type = reader.get().nextTag();
+ }
+
+ // all description are finished
+ // expect end of rdf:RDF
+ expectType(XMLStreamReader.END_ELEMENT,
+ "Expected end of descriptions");
+ expectName("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "RDF");
+
+ // expect ending xmpmeta
+ expectNextTag(XMLStreamReader.END_ELEMENT,
+ "Did not find initial x:xmpmeta");
+ expectName("adobe:ns:meta/", "xmpmeta");
+
+ // expect final processing instruction
+ expectNext(XMLStreamReader.PROCESSING_INSTRUCTION,
+ "Did not find final xpacket processing instruction");
+ // treats xpacket end
+ if (!reader.get().getPITarget().equals("xpacket")) {
+ throw new XmpXpacketEndException("Excepted PI xpacket");
+ }
+ String xpackData = reader.get().getPIData();
+ // end attribute must be present and placed in first
+ // xmp spec says Other unrecognized attributes can follow, but
+ // should be ignored
+ if (xpackData.startsWith("end=")) {
+ // check value (5 for end='X')
+ if (xpackData.charAt(5)!='r' && xpackData.charAt(5)!='w') {
+ throw new XmpXpacketEndException(
+ "Excepted xpacket 'end' attribute with value 'r' or 'w' ");
+ }
+ } else {
+ // should find end='r/w'
+ throw new XmpXpacketEndException(
+ "Excepted xpacket 'end' attribute (must be present and placed in first)");
+ }
+
+ metadata.setEndXPacket(xpackData);
+ // return constructed object
+ return metadata;
+ } catch (XMLStreamException e) {
+ throw new XmpParsingException(
+ "An error has occured when processing the underlying XMP source",
+ e);
+ } finally {
+ reader.remove();
+ }
+ }
+
+ /**
+ * Check InitialXPacket and build metadata object with these information
+ *
+ * @param data
+ * data corresponding to Initial XPacket Processing Instruction
+ * Processing Information corresponding to Inital XPacket data
+ * @return Metadata with specified information
+ * @throws XmpInitialXPacketParsingException
+ * When Initial XPacket missing or is incorrect
+ * @throws CreateXMPMetadataException
+ * If DOM Document associated could not be created
+ */
+ protected XMPMetadata parseInitialXpacket(String data)
+ throws XmpInitialXPacketParsingException,
+ CreateXMPMetadataException {
+ StringTokenizer tokens = new StringTokenizer(data, " ");
+ String id = null;
+ String begin = null;
+ String bytes = null;
+ String encoding = null;
+ while (tokens.hasMoreTokens()) {
+ String token = tokens.nextToken();
+ if (!token.endsWith("\"") && !token.endsWith("\'")) {
+ throw new XmpInitialXPacketParsingException(
+ "Cannot understand PI data part : '" + token + "'");
+ }
+ String quote = token.substring(token.length()-1);
+ int pos = token.indexOf("="+quote);
+ if (pos <= 0) {
+ throw new XmpInitialXPacketParsingException(
+ "Cannot understand PI data part : '" + token + "'");
+ }
+ String name = token.substring(0, pos);
+ String value = token.substring(pos + 2, token.length() - 1);
+ if ("id".equals(name)) {
+ id = value;
+ } else if ("begin".equals(name)) {
+ begin = value;
+ } else if ("bytes".equals(name)) {
+ bytes = value;
+ } else if ("encoding".equals(name)) {
+ encoding = value;
+ } else {
+ throw new XmpInitialXPacketParsingException(
+ "Unknown attribute in xpacket PI : '" + token + "'");
+ }
+ }
+ return new XMPMetadata(begin, id, bytes, encoding);
+ }
+
+ /**
+ * Check the next element type. all comments are ignored.
+ *
+ * @param expectType
+ * Type of xml element expected
+ * @param message
+ * Error message if problems occur
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected When DOM Element type
+ * found unexpected
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream When error
+ * during reading the rest of xmp stream
+ */
+ private void expectNext(int expectType, String message)
+ throws XmpParsingException, XmpUnexpectedTypeException,
+ XMLStreamException {
+ try {
+ int type = reader.get().next();
+ while (type == XMLStreamReader.COMMENT || type == XMLStreamReader.SPACE) {
+ type = reader.get().next();
+ }
+ if (type != expectType) {
+ throw new XmpUnexpectedTypeException(message);
+ }
+ } catch (NoSuchElementException e) {
+ // unexpected end of stream
+ throw new XmpParsingException(
+ "XMP Stream did not end in a good way, invalid content");
+ }
+ }
+
+ /**
+ * Check the next element type. White spaces , Comments and Processing
+ * Instructions are ignored.
+ *
+ * @param type
+ * Type of xml element expected
+ * @param message
+ * Error message if problems occur
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ */
+ private void expectNextTag(int type, String message)
+ throws XmpParsingException, XmpUnexpectedTypeException,
+ XMLStreamException {
+ try {
+ if (!(reader.get().nextTag() == type)) {
+ throw new XmpUnexpectedTypeException(message);
+ }
+ } catch (NoSuchElementException e) {
+ // unexpected end of stream
+ throw new XmpParsingException(
+ "XMP Stream did not end in a good way, invalid content");
+ }
+ }
+
+ /**
+ * check if qualified name of current element is what is expected
+ *
+ * @param namespace
+ * namespace URI
+ * @param name
+ * current element name
+ * @throws XmpUnexpectedElementQualifiedNameException
+ * When a qualifiedName found and is not that expected
+ *
+ */
+ private void expectName(String namespace, String name)
+ throws XmpUnexpectedElementQualifiedNameException {
+ if (!reader.get().getNamespaceURI().equals(namespace)) {
+ throw new XmpUnexpectedElementQualifiedNameException("Expected '"
+ + namespace + "' and found '"
+ + reader.get().getNamespaceURI() + "'");
+ }
+ if (!reader.get().getLocalName().equals(name)) {
+ throw new XmpUnexpectedElementQualifiedNameException("Expected '"
+ + name + "' and found '" + reader.get().getLocalName()
+ + "'");
+ }
+ }
+
+ /**
+ * Check the current element type.
+ *
+ * @param type
+ * XML element type expected
+ * @param message
+ * Error Message if problems occur
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ */
+ private void expectType(int type, String message)
+ throws XmpUnexpectedTypeException {
+ if (!(type == reader.get().getEventType())) {
+ throw new XmpUnexpectedTypeException("Expected type " + type
+ + " and found " + reader.get().getEventType() + " : "
+ + message);
+ }
+ }
+
+ /**
+ * Check if rdf:about attribute is declared for rdf description and add all
+ * attributes to the schema
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param schema
+ * Schema corresponding to the rdf:Description use
+ * @throws XmpExpectedRdfAboutAttribute
+ * When rdf:Description not contains rdf:about attribute
+ */
+ private void treatDescriptionAttributes(XMPMetadata metadata,
+ XMPSchema schema) throws XmpExpectedRdfAboutAttribute {
+ int cptAtt = reader.get().getAttributeCount();
+ if (cptAtt < 1) {
+ System.out.println(reader.get().getLocalName());
+ throw new XmpExpectedRdfAboutAttribute(
+ "Expected rdf:about attribute not found");
+
+ } else {
+ int i = 0;
+ boolean rdfAboutFound = false;
+ String prefix;
+ while (i < cptAtt) {
+ // rdf:about attribute must be here and can be presented by
+ // rdf:about and about
+ // according to
+ // http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/#basic
+ // (2.2. Basic RDF Syntax)
+ if (reader.get().getAttributeLocalName(i).equals("about")) {
+ prefix = reader.get().getAttributePrefix(i);
+ if (prefix != null) {
+ if (!prefix.equals("") && !prefix.equals("rdf")) {
+ // System.out.println("prefix de l'attribut "+reader.get().getAttributeLocalName(i)+": "+prefix);
+ throw new XmpExpectedRdfAboutAttribute(
+ "An about attribute is present but have an invalid prefix (it must be 'rdf')");
+ }
+ }
+ rdfAboutFound = true;
+ }
+ schema.setAttribute(new Attribute(null, reader.get()
+ .getAttributePrefix(i), reader.get()
+ .getAttributeLocalName(i), reader.get()
+ .getAttributeValue(i)));
+
+ i++;
+ }
+ if (!rdfAboutFound) {
+ System.out.println(reader.get().getLocalName());
+ throw new XmpExpectedRdfAboutAttribute(
+ "Expected rdf:about attribute not found");
+ }
+ }
+ }
+
+ /**
+ * Treat each rdf:Description (which must represent a schema), instanciate
+ * class representation of this schema and add it to metadata
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpSchemaException
+ * When instancing schema object failed or in PDF/A Extension
+ * case, if its namespace miss
+ * @throws XmpUnknownValueTypeException
+ * When ValueType found not correspond to basic type and not has
+ * been declared in current schema
+ * @throws XmpExpectedRdfAboutAttribute
+ * When rdf:Description not contains rdf:about attribute
+ * @throws BadFieldValueException
+ * When a bad value found in Schema description content
+ */
+ protected void parseDescription(XMPMetadata metadata)
+ throws XmpParsingException, XMLStreamException, XmpSchemaException,
+ XmpUnknownValueTypeException, XmpExpectedRdfAboutAttribute,
+ BadFieldValueException {
+ nsMap.resetComplexBasicTypesDeclarationInSchemaLevel();
+ int cptNS = reader.get().getNamespaceCount();
+ HashMap<String, String> namespaces = new HashMap<String, String>();
+ for (int i = 0; i < cptNS; i++) {
+ namespaces.put(reader.get().getNamespacePrefix(i), reader.get()
+ .getNamespaceURI(i));
+ if (nsMap.isComplexBasicTypes(reader.get().getNamespaceURI(i))) {
+ // System.out.println("in parseDesc method: prefix:"+reader.get().getNamespacePrefix(i)+", nsURI:"+reader.get().getNamespaceURI(i));
+ nsMap.setComplexBasicTypesDeclarationForLevelSchema(reader
+ .get().getNamespaceURI(i), reader.get()
+ .getNamespacePrefix(i));
+ }
+ }
+ // Different treatment for PDF/A Extension schema
+ // System.out.println(PDFAExtensionSchema.PDFAEXTENSION+";"+PDFAExtensionSchema.PDFAPROPERTY+";"+PDFAExtensionSchema.PDFASCHEMA);
+ if (namespaces.containsKey(PDFAExtensionSchema.PDFAEXTENSION)) {
+ if (namespaces.containsKey(PDFAExtensionSchema.PDFAPROPERTY)
+ && namespaces.containsKey(PDFAExtensionSchema.PDFASCHEMA)) {
+ if (namespaces
+ .containsValue(PDFAExtensionSchema.PDFAEXTENSIONURI)
+ && namespaces
+ .containsValue(PDFAExtensionSchema.PDFAPROPERTYURI)
+ && namespaces
+ .containsValue(PDFAExtensionSchema.PDFASCHEMAURI)) {
+ PDFAExtensionSchema schema = metadata
+ .createAndAddPDFAExtensionSchemaWithNS(namespaces);
+ treatDescriptionAttributes(metadata, schema);
+ parseExtensionSchema(schema, metadata);
+
+ } else {
+ throw new XmpUnexpectedNamespaceURIException(
+ "Unexpected namespaceURI in PDFA Extension Schema encountered");
+ }
+ } else {
+ throw new XmpUnexpectedNamespacePrefixException(
+ "Unexpected namespace Prefix in PDFA Extension Schema");
+ }
+
+ } else {
+ // TODO Considering first namespace is that corresponding to the
+ // schema (see if it must be changed)
+ String namespaceUri = reader.get().getNamespaceURI(0);
+ String namespacePrefix = reader.get().getNamespacePrefix(0);
+ XMPSchema schema = nsMap.getAssociatedSchemaObject(metadata, namespaceUri, namespacePrefix);
+ if (schema != null) {
+ namespaces.remove(namespacePrefix);
+ } else {
+ schema = metadata.createAndAddDefaultSchema(namespacePrefix,namespaceUri);
+ }
+ for (int i = 1; i < cptNS; i++) {
+ schema.setAttribute(new Attribute(XMPSchema.NS_NAMESPACE,
+ "xmlns", reader.get().getNamespacePrefix(i), reader.get().getNamespaceURI(i)));
+ }
+ treatDescriptionAttributes(metadata, schema);
+ while (reader.get().nextTag() == XMLStreamReader.START_ELEMENT) {
+ parseProperty(schema, metadata);
+ }
+ }
+
+ }
+
+ /**
+ * Check the next element type and its expected value
+ *
+ * @param type
+ * expected type of xml element
+ * @param localNameExpected
+ * The property name (local) expected
+ * @param message
+ * Error message if problems occur
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ */
+ private void expectNextSpecificTag(int type, String localNameExpected,
+ String message) throws XmpUnexpectedTypeException,
+ XmpParsingException, XMLStreamException {
+ expectNextTag(type, message);
+ expectCurrentLocalName(localNameExpected);
+ }
+
+ /**
+ * check that the current local name is that expected
+ *
+ * @param localNameExpected
+ * The name expected
+ * @throws XmpUnexpectedElementException
+ * When Element is not that expected
+ */
+ private void expectCurrentLocalName(String localNameExpected)
+ throws XmpUnexpectedElementException {
+ if (!reader.get().getLocalName().equals(localNameExpected)) {
+ throw new XmpUnexpectedElementException("'" + localNameExpected
+ + "' expected and '" + reader.get().getLocalName()
+ + "' found");
+ }
+ }
+
+ /**
+ * Treat a PDFAExtension schema
+ *
+ * @param schema
+ * PDFA/Extension schema where save information found
+ * @param metadata
+ * Metadata to attach new elements
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownValueTypeException
+ * When ValueType found not correspond to basic type and not has
+ * been declared in current schema
+ * @throws BadFieldValueException
+ * When one of a field property include to describe a property
+ * in Schema Description contain an incorrect value
+ */
+ private void parseExtensionSchema(PDFAExtensionSchema schema,
+ XMPMetadata metadata) throws XmpParsingException,
+ XMLStreamException, XmpUnknownValueTypeException,
+ BadFieldValueException {
+ // <pdfaExtension:schemas>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "schemas",
+ "Cannot find container declaration of schemas descriptions ");
+ // <rdf:Bag>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Bag",
+ "Cannot find bag declaration for container of schemas descriptions");
+ // now work on each rdf:li corresponding to each schema description
+ int type = reader.get().nextTag();
+ while (type == XMLStreamReader.START_ELEMENT) {
+ parseSchemaDescription(schema, metadata);
+ type = reader.get().nextTag();
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, "schemas",
+ "Cannot find end of container declaration in schemas descriptions ");
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, "Description",
+ "Cannot find end of PDF/A Extension definition ");
+
+ }
+
+ /**
+ * Treat one Schema description defined in the extension Schema found
+ *
+ * @param schema
+ * PDFA/Extension schema where save information found
+ * @param metadata
+ * Metadata to attach new elements
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XmpUnknownValueTypeException
+ * When ValueType found not correspond to basic type and not has
+ * been declared in current schema
+ * @throws BadFieldValueException
+ * When one of a field property contain an incorrect value
+ */
+ private void parseSchemaDescription(PDFAExtensionSchema schema,
+ XMPMetadata metadata) throws XMLStreamException,
+ XmpParsingException, XmpUnknownValueTypeException,
+ BadFieldValueException {
+ expectCurrentLocalName("li");
+ SchemaDescription desc = schema.createSchemaDescription();
+ int type = reader.get().nextTag();
+ while (type == XMLStreamReader.START_ELEMENT) {
+ if (reader.get().getLocalName().equals("schema")
+ || reader.get().getLocalName().equals("namespaceURI")
+ || reader.get().getLocalName().equals("prefix")) {
+ try {
+ // System.out.println(reader.get().getPrefix()+";"+reader.get().getLocalName()+";"+reader.get().getElementText());
+ desc.addProperty(new TextType(metadata, reader.get()
+ .getPrefix(), reader.get().getLocalName(), reader
+ .get().getElementText()));
+ } catch (IllegalArgumentException e) {
+ throw new XmpPropertyFormatException(
+ "Unexpected value for '"
+ + reader.get().getLocalName()
+ + "' property");
+ }
+ } else if (reader.get().getLocalName().equals("property")) {
+ parsePropertyDefinition(desc);
+ } else if (reader.get().getLocalName().equals("valueType")) {
+ parseValueTypeDefinition(desc, metadata);
+
+ } else {
+ throw new XmpUnexpectedElementException(
+ "Unexpected property definition in one of PDF/A Extension schemas description");
+ }
+ type = reader.get().nextTag();
+ }
+ schema.addSchemaDescription(desc);
+ nsMap.setNamespaceDefinition(desc);
+
+ }
+
+ /**
+ * Treat value type definition for a specific Schema Description
+ *
+ * @param desc
+ * the current Schema Description analyzed
+ * @param metadata
+ * Metadata to attach new elements
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ */
+ private void parseValueTypeDefinition(SchemaDescription desc,
+ XMPMetadata metadata) throws XmpParsingException,
+ XMLStreamException {
+ // <rdf:Seq>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Seq",
+ "Expected Seq Declaration");
+ int elmtType = reader.get().nextTag();
+ String type, namespaceURI, prefix, description;
+ List<PDFAFieldDescription> fields;
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ type = null;
+ namespaceURI = null;
+ prefix = null;
+ description = null;
+ fields = null;
+ expectCurrentLocalName("li");
+ elmtType = reader.get().nextTag();
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ if (reader.get().getLocalName().equals("type")) {
+ type = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("namespaceURI")) {
+ namespaceURI = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("prefix")) {
+ prefix = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("description")) {
+ description = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("field")) {
+ fields = parseFieldDescription(metadata);
+
+ } else {
+ throw new XmpUnexpectedElementException(
+ "Unexpected property definition in one of ValueType Descriptions of PDF/A Extension schemas description");
+ }
+ elmtType = reader.get().nextTag();
+ }
+ if ((type != null) && (namespaceURI != null) && (prefix != null)
+ && (description != null)) {
+ desc.addValueType(type, namespaceURI, prefix, description,
+ fields);
+ } else {
+ throw new XmpRequiredPropertyException(
+ "one property declaration in PDF/A Extension is not complete");
+ }
+ elmtType = reader.get().nextTag();
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, "valueType",
+ "Expected End of ValueType Declaration");
+
+ }
+
+ /**
+ * Treat field description on the current analyzed value type description
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @return A list of parsed fields
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpParsingException
+ * When element expected not found
+ */
+ private List<PDFAFieldDescription> parseFieldDescription(
+ XMPMetadata metadata) throws XmpParsingException,
+ XMLStreamException {
+ List<PDFAFieldDescription> fields = new ArrayList<PDFAFieldDescription>();
+ // <rdf:Seq>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Seq",
+ "Expected Seq Declaration");
+ int elmtType = reader.get().nextTag();
+ String name, type, description;
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ expectCurrentLocalName("li");
+ elmtType = reader.get().nextTag();
+ name = null;
+ type = null;
+ description = null;
+
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ if (reader.get().getLocalName().equals("name")) {
+ name = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("valueType")) {
+ type = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("description")) {
+ description = reader.get().getElementText();
+ } else {
+ throw new XmpUnexpectedElementException(
+ "Unexpected property definition in one of ValueType Field Descriptions of PDF/A Extension schemas description");
+ }
+ elmtType = reader.get().nextTag();
+ }
+ if ((name != null) && (type != null) && (description != null)) {
+ PDFAFieldDescription tmp = new PDFAFieldDescription(metadata);
+ tmp.setNameValue(name);
+ tmp.setValueTypeValue(type);
+ tmp.setDescriptionValue(description);
+ fields.add(tmp);
+ } else {
+ throw new XmpRequiredPropertyException(
+ "One valuetype field declaration in PDF/A Extension is not complete");
+ }
+ // expectNextTag(XMLStreamReader.END_ELEMENT,"Expected element end");
+ elmtType = reader.get().nextTag();
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, "field",
+ "Expected End of Properties Declaration");
+ if (fields.size() != 0) {
+ return fields;
+ }
+ return null;
+ }
+
+ /**
+ * Treat a property definition for a specific Schema Description
+ *
+ * @param desc
+ * the current Schema Description analyzed
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws BadFieldValueException
+ * When one of a field property contain an incorrect value
+ */
+ private void parsePropertyDefinition(SchemaDescription desc)
+ throws XmpParsingException, XMLStreamException,
+ BadFieldValueException {
+ // <rdf:Seq>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Seq",
+ "Expected Seq Declaration");
+ // Each property definition
+ int elmtType = reader.get().nextTag();
+ String name, type, category, description;
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ expectCurrentLocalName("li");
+ elmtType = reader.get().nextTag();
+ name = null;
+ type = null;
+ category = null;
+ description = null;
+
+ while (elmtType == XMLStreamReader.START_ELEMENT) {
+ if (reader.get().getLocalName().equals("name")) {
+ name = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("valueType")) {
+ type = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("category")) {
+ category = reader.get().getElementText();
+ } else if (reader.get().getLocalName().equals("description")) {
+ description = reader.get().getElementText();
+ } else {
+ throw new XmpUnexpectedElementException(
+ "Unexpected property definition in one of Properties Descriptions of PDF/A Extension schemas description");
+ }
+ elmtType = reader.get().nextTag();
+ }
+ if ((name != null) && (type != null) && (category != null)
+ && (description != null)) {
+ desc.addProperty(name, type, category, description);
+ } else {
+ throw new XmpRequiredPropertyException(
+ "one property declaration in PDF/A Extension is not complete");
+ }
+ // expectNextTag(XMLStreamReader.END_ELEMENT,"Expected element end");
+ elmtType = reader.get().nextTag();
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, "property",
+ "Expected End of Properties Declaration");
+ }
+
+ /**
+ * Check for all namespaces declared for the specified schema if the
+ * property searched exists and return its type or null
+ *
+ * @param schema
+ * The Schema to analyze
+ * @param prop
+ * The property Qualified Name
+ * @return The property value type or null if not found in schema
+ * @throws XmpParsingException
+ * When element expected not found
+ */
+ private String getPropertyDeclarationInNamespaces(XMPSchema schema,
+ QName prop) throws XmpParsingException {
+
+ Iterator<Attribute> it = schema.getAllAttributes().iterator();
+ Attribute tmp;
+ ArrayList<Attribute> list = new ArrayList<Attribute>();
+ while (it.hasNext()) {
+ tmp = it.next();
+ if (tmp.getPrefix() != null) {
+ if (tmp.getPrefix().equals("xmlns")) {
+ list.add(tmp);
+ }
+ }
+ }
+ it = list.iterator();
+ String type;
+ StringBuffer unknownNS = new StringBuffer();
+ while (it.hasNext()) {
+ String namespace = it.next().getValue();
+ if (!nsMap.isContainedNamespace(namespace)) {
+ unknownNS.append(" '").append(namespace).append("' ");
+ continue;
+ }
+ type = nsMap.getSpecifiedPropertyType(namespace, prop);
+ if (type != null) {
+ return type;
+ }
+ }
+ String uns = unknownNS.toString().trim();
+ if ((uns == null) || "".equals(uns)) {
+ throw new XmpUnknownPropertyException(
+ "Cannot find a description for '" + prop.getLocalPart()
+ + "' property");
+ } else {
+ throw new XmpUnknownSchemaException(
+ "Cannot find a definition for the namespace " + uns + " ");
+ }
+
+ }
+
+ /**
+ * Build a property with the specific type defined in schema or complex
+ * property and add it to the object representation
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param propertyName
+ * The fully qualified name of the property
+ * @param stype
+ * Type of the property
+ * @param container
+ * the entity where place the property representation
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ */
+ protected void parseXmpSimpleProperty(XMPMetadata metadata,
+ QName propertyName, XmpPropertyType stype,
+ ComplexPropertyContainer container)
+ throws XmpUnknownPropertyTypeException, XmpPropertyFormatException,
+ XMLStreamException {
+ try {
+ AbstractSimpleProperty prop = null;
+ ArrayList<Attribute> attributes = new ArrayList<Attribute>();
+ int cpt = reader.get().getAttributeCount();
+ for (int i = 0; i < cpt; i++) {
+ attributes.add(new Attribute(null, reader.get()
+ .getAttributePrefix(i), reader.get()
+ .getAttributeLocalName(i), reader.get()
+ .getAttributeValue(i)));
+ }
+ if (stype == XmpPropertyType.Text) {
+ prop = new TextType(metadata, propertyName.getPrefix(),
+ propertyName.getLocalPart(), reader.get()
+ .getElementText());
+ } else if (stype == XmpPropertyType.Integer) {
+ prop = new IntegerType(metadata, propertyName.getPrefix(),
+ propertyName.getLocalPart(), reader.get()
+ .getElementText());
+ } else if (stype == XmpPropertyType.Date) {
+ prop = new DateType(metadata, propertyName.getPrefix(),
+ propertyName.getLocalPart(), reader.get()
+ .getElementText());
+ } else if (stype == XmpPropertyType.Boolean) {
+ prop = new BooleanType(metadata, propertyName.getPrefix(),
+ propertyName.getLocalPart(), reader.get()
+ .getElementText());
+ } else if (stype == XmpPropertyType.Real) {
+ prop = new RealType(metadata, propertyName.getPrefix(),
+ propertyName.getLocalPart(), reader.get()
+ .getElementText());
+ }
+ if (prop != null) {
+ container.addProperty(prop);
+ // ADD ATTRIBUTES
+ for (Attribute att : attributes) {
+ prop.setAttribute(att);
+ }
+ } else {
+ throw new XmpUnknownPropertyTypeException(
+ "Unknown simple type found");
+ }
+ } catch (IllegalArgumentException e) {
+ throw new XmpPropertyFormatException(
+ "Unexpected type found for the property '"
+ + propertyName.getLocalPart() + "'", e);
+ }
+ }
+
+ /**
+ * Parse a bag property (unordered array) with the specific type defined in
+ * schema or complex property and add it to the object representation
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param bagName
+ * name of bag property
+ * @param stype
+ * type of values contained in this bag
+ * @param container
+ * the entity where place the property representation
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ protected void parseBagProperty(XMPMetadata metadata, QName bagName,
+ XmpPropertyType stype, ComplexPropertyContainer container)
+ throws XmpUnexpectedTypeException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException,
+ XmpPropertyFormatException {
+ ComplexProperty bag = new ComplexProperty(metadata,
+ bagName.getPrefix(), bagName.getLocalPart(),
+ ComplexProperty.UNORDERED_ARRAY);
+ container.addProperty(bag);
+ // <rdf:Bag>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Bag",
+ "Expected Seq Declaration");
+ // Each property definition
+ int elmtType = reader.get().nextTag();
+ while ((elmtType != XMLStreamReader.END_ELEMENT)
+ && !reader.get().getName().getLocalPart().equals("Bag")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(), stype, bag
+ .getContainer());
+ elmtType = reader.get().nextTag();
+
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, bagName
+ .getLocalPart(), "Expected end of Bag property");
+
+ }
+
+ /**
+ * Parse a seq property (ordered array) with the specific type defined in
+ * schema or complex property and add it to the object representation
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param seqName
+ * name of the seq
+ * @param stype
+ * type of values contained in this bag
+ * @param container
+ * the entity where place the property representation
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ protected void parseSeqProperty(XMPMetadata metadata, QName seqName,
+ XmpPropertyType stype, ComplexPropertyContainer container)
+ throws XmpUnexpectedTypeException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException,
+ XmpPropertyFormatException {
+ ComplexProperty seq = new ComplexProperty(metadata,
+ seqName.getPrefix(), seqName.getLocalPart(),
+ ComplexProperty.ORDERED_ARRAY);
+ container.addProperty(seq);
+ // <rdf:Bag>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Seq",
+ "Expected Seq Declaration");
+ // Each property definition
+ int elmtType = reader.get().nextTag();
+ while ((elmtType != XMLStreamReader.END_ELEMENT)
+ && !reader.get().getName().getLocalPart().equals("Seq")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(), stype, seq
+ .getContainer());
+ elmtType = reader.get().nextTag();
+
+ }
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, seqName
+ .getLocalPart(), "Expected end of Seq property");
+ }
+
+ /**
+ * Parse Alt property (Alternative language property) with the specific type
+ * defined in schema or complex property and add it to the object
+ * representation
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param altName
+ * name of Alt property
+ * @param stype
+ * type of values contained in this bag
+ * @param container
+ * the entity where place the property representation
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ protected void parseAltProperty(XMPMetadata metadata, QName altName,
+ XmpPropertyType stype, ComplexPropertyContainer container)
+ throws XmpUnexpectedTypeException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException,
+ XmpPropertyFormatException {
+ ComplexProperty alt = new ComplexProperty(metadata,
+ altName.getPrefix(), altName.getLocalPart(),
+ ComplexProperty.ALTERNATIVE_ARRAY);
+ container.addProperty(alt);
+ // <rdf:Alt>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Alt",
+ "Expected Alt Declaration");
+ int elmtType = reader.get().nextTag();
+ while (!((elmtType == XMLStreamReader.END_ELEMENT) && reader.get()
+ .getName().getLocalPart().equals("Alt"))) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(), stype, alt
+ .getContainer());
+ elmtType = reader.get().nextTag();
+
+ }
+ // <dc:description><rdf:Alt><rdf:li>sujet</rdf:li></rdf:Alt></dc:description>
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, altName
+ .getLocalPart(), "Expected end of alt property");
+
+ }
+
+ /**
+ * Create a property in a specified container (complexproperty or schema)
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param type
+ * type of value contained in the property
+ * @param container
+ * the entity where place the property representation
+ * @return True if property has been treated (according to its type)
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ */
+ private boolean createAndAddPropertyToContainer(XMPMetadata metadata,
+ String type, ComplexPropertyContainer container)
+ throws XmpParsingException, XmpUnexpectedTypeException,
+ XmpUnknownPropertyTypeException, XmpPropertyFormatException,
+ XMLStreamException {
+ if (type.equals("Text")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("Integer")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Integer, container);
+
+ } else if (type.equals("Boolean")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Boolean, container);
+
+ } else if (type.equals("Real")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Real, container);
+ } else if (type.equals("Date")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Date, container);
+
+ } else if (type.equals("URI")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+
+ } else if (type.equals("URL")) {
+ parseXmpSimpleProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+
+ } else if (type.equals("bag Text")) {
+ parseBagProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("bag ProperName")) {
+ parseBagProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("bag Job")) {
+ parseBagProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("bag Xpath")) {
+ parseBagProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("seq Text")) {
+ parseSeqProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("seq Field")) {
+ parseSeqProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else if (type.equals("seq Date")) {
+ parseSeqProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Date, container);
+ } else if (type.equals("Lang Alt")) {
+ parseAltProperty(metadata, reader.get().getName(),
+ XmpPropertyType.Text, container);
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Parse a specific field
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param propertyName
+ * the full qualified name of this property
+ * @param schema
+ * The schema where save this property
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ protected void parseFieldProperty(XMPMetadata metadata, QName propertyName,
+ XMPSchema schema) throws XmpUnexpectedTypeException,
+ XmpPropertyFormatException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException {
+ ComplexPropertyContainer field = new ComplexPropertyContainer(metadata,
+ propertyName.getPrefix(), propertyName.getLocalPart());
+ schema.addProperty(field);
+ field.setAttribute(new Attribute(null, "rdf", "parseType", "Resource"));
+ String type;
+ int elmtType = reader.get().nextTag();
+ while ((elmtType != XMLStreamReader.END_ELEMENT)
+ && !reader.get().getName().getLocalPart().equals("Seq")) {
+
+ type = getPropertyDeclarationInNamespaces(schema, reader.get()
+ .getName());
+ if (!createAndAddPropertyToContainer(metadata, type, field)) {
+ if (type.equals("Field")) {
+ String stype = getPropertyDeclarationInNamespaces(schema,
+ reader.get().getName());
+ createAndAddPropertyToContainer(metadata, stype, field);
+ } else {
+ throw new XmpUnknownPropertyTypeException("Unknown type : "
+ + type);
+ }
+ }
+ elmtType = reader.get().nextTag();
+ }
+ expectCurrentLocalName(propertyName.getLocalPart());
+
+ // expectNextSpecificTag(XMLStreamReader.END_ELEMENT,
+ // propertyName.getLocalPart(), "Expected end of field declaration");
+
+ }
+
+ /**
+ * analyze one property in the stream, retrieve its type according to the
+ * schema information and call its object representation building
+ *
+ * @param schema
+ * The schema where find information
+ * @param metadata
+ * Metadata to attach new elements
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMPUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ protected void parseProperty(XMPSchema schema, XMPMetadata metadata)
+ throws XmpParsingException, XmpPropertyFormatException,
+ XmpUnexpectedTypeException, XMLStreamException,
+ XmpUnknownPropertyTypeException {
+ QName propertyName = reader.get().getName();
+ nsMap.resetComplexBasicTypesDeclarationInPropertyLevel();
+ int cptNs = reader.get().getNamespaceCount();
+ for (int i = 0; i < cptNs; i++) {
+ if (nsMap.isComplexBasicTypes(reader.get().getNamespaceURI(i))) {
+ nsMap.setComplexBasicTypesDeclarationForLevelSchema(reader
+ .get().getNamespaceURI(i), reader.get()
+ .getNamespacePrefix(i));
+ }
+ }
+ String type = getPropertyDeclarationInNamespaces(schema, propertyName);
+ if (type.equals("Unmanaged")) {
+ // do not parse the property, no validation, no reserialization
+ boolean cont = true;
+ while (cont) {
+ int t = reader.get().next();
+ if (t==XMLStreamReader.END_ELEMENT) {
+ if (propertyName.equals(reader.get().getName())) {
+ cont = false;
+ }
+ }
+ }
+ } else if (type.equals("Text")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Text, schema.getContent());
+ } else if (type.equals("Integer")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Integer, schema.getContent());
+
+ } else if (type.equals("Boolean")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Boolean, schema.getContent());
+
+ } else if (type.equals("Real")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Real, schema.getContent());
+ } else if (type.equals("Date")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Date, schema.getContent());
+
+ } else if (type.equals("URI")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Text, schema.getContent());
+
+ } else if (type.equals("URL")) {
+ parseXmpSimpleProperty(metadata, propertyName,
+ XmpPropertyType.Text, schema.getContent());
+
+ } else if (type.equals("bag Text")) {
+ parseBagProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("bag ProperName")) {
+ parseBagProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("bag Job")) {
+ parseBagProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("bag Xpath")) {
+ parseBagProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("seq Text")) {
+ parseSeqProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("seq Date")) {
+ parseSeqProperty(metadata, propertyName, XmpPropertyType.Date,
+ schema.getContent());
+ } else if (type.equals("Lang Alt")) {
+ parseAltProperty(metadata, propertyName, XmpPropertyType.Text,
+ schema.getContent());
+ } else if (type.equals("Field")) {
+ parseFieldProperty(metadata, propertyName, schema);
+ } else if (type.equals("Thumbnail")) {
+ parseThumbnailProperty(metadata, propertyName, schema.getContent());
+ } else if (type.equals("Alt Thumbnail")) {
+ parseAltThumbnailProperty(metadata, propertyName, schema
+ .getContent());
+ } else {
+ System.out.println(reader.get().getName().getLocalPart()
+ + " de type " + type);
+ throw new XmpUnknownPropertyTypeException("Unknown type : " + type);
+ }
+
+ }
+
+ /**
+ * Treat Alternative Thumbnails property
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param altName
+ * name of thumbnails alternative property
+ * @param container
+ * the container where record this representation
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ private void parseAltThumbnailProperty(XMPMetadata metadata, QName altName,
+ ComplexPropertyContainer container)
+ throws XmpUnexpectedTypeException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException,
+ XmpPropertyFormatException {
+ ComplexProperty alt = new ComplexProperty(metadata,
+ altName.getPrefix(), altName.getLocalPart(),
+ ComplexProperty.ALTERNATIVE_ARRAY);
+ container.addProperty(alt);
+ // <rdf:Alt>
+ expectNextSpecificTag(XMLStreamReader.START_ELEMENT, "Alt",
+ "Expected Alt Declaration");
+ int elmtType = reader.get().nextTag();
+ while (!((elmtType == XMLStreamReader.END_ELEMENT) && reader.get()
+ .getName().getLocalPart().equals("Alt"))) {
+ parseThumbnailProperty(metadata, reader.get().getName(), alt
+ .getContainer());
+ elmtType = reader.get().nextTag();
+ }
+
+ // <dc:description><rdf:Alt><rdf:li>sujet</rdf:li></rdf:Alt></dc:description>
+ expectNextSpecificTag(XMLStreamReader.END_ELEMENT, altName
+ .getLocalPart(), "Expected end of alt property");
+ }
+
+ /**
+ * * Treat a thumbnail property
+ *
+ * @param metadata
+ * Metadata to attach new elements
+ * @param altName
+ * name of thumbnail property
+ * @param container
+ * The container where save property representation
+ * @throws XmpUnexpectedTypeException
+ * When DOM Element type found unexpected
+ * @throws XmpParsingException
+ * When element expected not found
+ * @throws XMLStreamException
+ * When error during reading the rest of xmp stream
+ * @throws XmpUnknownPropertyTypeException
+ * Value Type property is incorrect or the basic value type
+ * can't be treat at the moment
+ * @throws XmpPropertyFormatException
+ * Unexpected type found (IllegalArgumentException)
+ */
+ private void parseThumbnailProperty(XMPMetadata metadata, QName altName,
+ ComplexPropertyContainer container)
+ throws XmpUnexpectedTypeException, XmpParsingException,
+ XMLStreamException, XmpUnknownPropertyTypeException,
+ XmpPropertyFormatException {
+ expectCurrentLocalName("li");
+ ThumbnailType thumbnail = new ThumbnailType(metadata, altName
+ .getPrefix(), altName.getLocalPart());
+ int elmtType = reader.get().nextTag();
+ QName eltName;
+ String eltContent;
+ while (!((elmtType == XMLStreamReader.END_ELEMENT) && reader.get()
+ .getName().getLocalPart().equals("li"))) {
+ eltName = reader.get().getName();
+ eltContent = reader.get().getElementText();
+ if (eltName.getLocalPart().equals("height")) {
+ thumbnail.setHeight(eltName.getPrefix(),
+ eltName.getLocalPart(), Integer.valueOf(eltContent));
+ } else if (eltName.getLocalPart().equals("width")) {
+ thumbnail.setWidth(eltName.getPrefix(), eltName.getLocalPart(),
+ Integer.valueOf(eltContent));
+ } else if (eltName.getLocalPart().equals("image")) {
+ thumbnail.setImg(eltName.getPrefix(), eltName.getLocalPart(),
+ eltContent);
+ } else if (eltName.getLocalPart().equals("format")) {
+ thumbnail.setFormat(eltName.getPrefix(),
+ eltName.getLocalPart(), eltContent);
+ } else {
+ throw new XmpParsingException(
+ "Unknown property name for a thumbnail element : "
+ + eltName.getLocalPart());
+ }
+ elmtType = reader.get().nextTag();
+ }
+ container.addProperty(thumbnail);
+ }
+
+}
Propchange: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native