Author: gbailleul Date: Sat Jul 28 08:36:32 2012 New Revision: 1366609 URL: http://svn.apache.org/viewvc?rev=1366609&view=rev Log: PDFBOX-1343 : add missing structured types and create missing field in namespaces
Added: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java - copied, changed from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/SchemaMapping.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/AbstractStructuredType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ComplexProperty.java - copied, changed from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ComplexProperty.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ComplexPropertyContainer.java - copied, changed from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ComplexPropertyContainer.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/FieldDescription.java - copied, changed from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/FieldDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/RenditionClassType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/TypeDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/TypeMapping.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ValueTypeDescription.java - copied, changed from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ValueTypeDescription.java Removed: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/JobParser.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XmpPropertyType.java Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/PDFAExtentionSchemaPreprocessor.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/StructuredPropertyParser.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/AdobePDFSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/DublinCoreSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAExtensionSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAFieldDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAIdentificationSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAPropertyDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAValueTypeDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PhotoshopSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/SchemaDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPBasicJobTicketSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPBasicSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPMediaManagementSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPRightsManagementSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPSchema.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/AbstractField.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/AbstractSimpleProperty.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/BooleanType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/DateType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/Elementable.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/IntegerType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/JobType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/LayerType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/PropertyDescription.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/RealType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ResourceEventType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ResourceRefType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/TextType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/ThumbnailType.java pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/VersionType.java Copied: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java (from r1355678, pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java) URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java?p2=pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java&p1=pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java&r1=1355678&r2=1366609&rev=1366609&view=diff ============================================================================== --- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java (original) +++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java Sat Jul 28 08:36:32 2012 @@ -21,8 +21,6 @@ package org.apache.padaf.xmpbox.parser; -import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,22 +29,13 @@ import java.util.Map.Entry; import javax.xml.namespace.QName; import org.apache.padaf.xmpbox.XMPMetadata; -import org.apache.padaf.xmpbox.schema.AdobePDFSchema; -import org.apache.padaf.xmpbox.schema.DublinCoreSchema; -import org.apache.padaf.xmpbox.schema.PDFAExtensionSchema; import org.apache.padaf.xmpbox.schema.PDFAFieldDescription; -import org.apache.padaf.xmpbox.schema.PDFAIdentificationSchema; import org.apache.padaf.xmpbox.schema.PDFAPropertyDescription; import org.apache.padaf.xmpbox.schema.PDFAValueTypeDescription; -import org.apache.padaf.xmpbox.schema.PhotoshopSchema; -import org.apache.padaf.xmpbox.schema.PropertyAttributesAnnotation; -import org.apache.padaf.xmpbox.schema.PropertyType; import org.apache.padaf.xmpbox.schema.SchemaDescription; -import org.apache.padaf.xmpbox.schema.XMPBasicJobTicketSchema; -import org.apache.padaf.xmpbox.schema.XMPBasicSchema; -import org.apache.padaf.xmpbox.schema.XMPMediaManagementSchema; -import org.apache.padaf.xmpbox.schema.XMPRightsManagementSchema; +import org.apache.padaf.xmpbox.schema.SchemaMapping; import org.apache.padaf.xmpbox.schema.XMPSchema; +import org.apache.padaf.xmpbox.type.TypeMapping; /** @@ -57,462 +46,324 @@ import org.apache.padaf.xmpbox.schema.XM */ public class NSMapping { - public static final List<String> BASIC_TYPES; - public static final Map<String, String> COMPLEX_BASIC_TYPES; + private Map<String, XMPSchemaFactory> definedNamespaces; - static { - BASIC_TYPES = new ArrayList<String>(); - BASIC_TYPES.add("Text"); - BASIC_TYPES.add("ProperName"); - BASIC_TYPES.add("Integer"); - BASIC_TYPES.add("Boolean"); - BASIC_TYPES.add("Date"); - BASIC_TYPES.add("URI"); - BASIC_TYPES.add("URL"); - BASIC_TYPES.add("bag Text"); - BASIC_TYPES.add("bag ProperName"); - BASIC_TYPES.add("bag Xpath"); - BASIC_TYPES.add("seq Text"); - BASIC_TYPES.add("seq Field"); - BASIC_TYPES.add("seq Date"); - BASIC_TYPES.add("Lang Alt"); - - COMPLEX_BASIC_TYPES = new HashMap<String, String>(); - COMPLEX_BASIC_TYPES.put("http://ns.adobe.com/xap/1.0/g/img/", - "Thumbnail"); - COMPLEX_BASIC_TYPES.put(PhotoshopSchema.PHOTOSHOPURI, - "TextLayers"); - COMPLEX_BASIC_TYPES.put(XMPBasicJobTicketSchema.JOB_TICKET_URI, "Job"); - } - - protected Map<String, XMPSchemaFactory> nsMaps; - protected Map<String, String> complexBasicTypesDeclarationEntireXMPLevel; - protected Map<String, String> complexBasicTypesDeclarationSchemaLevel; - protected Map<String, String> complexBasicTypesDeclarationPropertyLevel; - - /** - * Constructor of the NameSpace mapping - * - * @throws XmpSchemaException - * When could not read a property data in a Schema Class given - */ - public NSMapping() throws XmpSchemaException { - nsMaps = new HashMap<String, XMPSchemaFactory>(); - complexBasicTypesDeclarationEntireXMPLevel = new HashMap<String, String>(); - complexBasicTypesDeclarationSchemaLevel = new HashMap<String, String>(); - complexBasicTypesDeclarationPropertyLevel = new HashMap<String, String>(); - // Add mapping of common schemas - addNameSpace("http://ns.adobe.com/xap/1.0/", XMPBasicSchema.class); - addNameSpace("http://purl.org/dc/elements/1.1/", DublinCoreSchema.class); - addNameSpace("http://www.aiim.org/pdfa/ns/extension/", PDFAExtensionSchema.class); - addNameSpace("http://ns.adobe.com/xap/1.0/mm/", XMPMediaManagementSchema.class); - addNameSpace("http://ns.adobe.com/pdf/1.3/", AdobePDFSchema.class); - addNameSpace("http://www.aiim.org/pdfa/ns/id/", PDFAIdentificationSchema.class); - addNameSpace("http://ns.adobe.com/xap/1.0/rights/", XMPRightsManagementSchema.class); - addNameSpace(PhotoshopSchema.PHOTOSHOPURI, PhotoshopSchema.class); - addNameSpace(XMPBasicJobTicketSchema.JOB_TICKET_URI,XMPBasicJobTicketSchema.class); - - - } - - - /** - * Import an NSMapping content. - * @param imp - */ - public void importNSMapping(NSMapping imp) throws XmpSchemaException { - mergeNSMap(imp.nsMaps); - mergeComplexBasicTypesDeclarationEntireXMPLevel(imp.complexBasicTypesDeclarationEntireXMPLevel); - mergeComplexBasicTypesDeclarationSchemaLevel(imp.complexBasicTypesDeclarationSchemaLevel); - mergeComplexBasicTypesDeclarationPropertyLevel(imp.complexBasicTypesDeclarationPropertyLevel); - } - - protected void mergeNSMap(Map<String, XMPSchemaFactory> map) throws XmpSchemaException { - for (Entry<String, XMPSchemaFactory> entry : map.entrySet() ) { - if (this.nsMaps.containsKey(entry.getKey())) { - this.nsMaps.get(entry.getKey()).importXMPSchemaFactory(entry.getValue()); - } else { - this.nsMaps.put(entry.getKey(), entry.getValue()); - } - } - } - - private void mergeComplexBasicTypesDeclarationEntireXMPLevel(Map<String, String> external) { - for (Entry<String, String> entry : external.entrySet()) { - if(!complexBasicTypesDeclarationEntireXMPLevel.containsKey(entry.getKey())) { - complexBasicTypesDeclarationEntireXMPLevel.put(entry.getKey(), entry.getValue()); - } - } - } - - private void mergeComplexBasicTypesDeclarationSchemaLevel(Map<String, String> external) { - for (Entry<String, String> entry : external.entrySet()) { - if(!complexBasicTypesDeclarationSchemaLevel.containsKey(entry.getKey())) { - complexBasicTypesDeclarationSchemaLevel.put(entry.getKey(), entry.getValue()); - } - } - } - - private void mergeComplexBasicTypesDeclarationPropertyLevel(Map<String, String> external) { - for (Entry<String, String> entry : external.entrySet()) { - if(!complexBasicTypesDeclarationPropertyLevel.containsKey(entry.getKey())) { - complexBasicTypesDeclarationPropertyLevel.put(entry.getKey(), entry.getValue()); - } - } - } - - /** - * Add a namespace declaration and Schema factory associated - * - * @param ns - * the Namespace URI - * @param classSchem - * The class representation of the schema linked to the namespace - * @throws XmpSchemaException - * When could not read property name in Schema Class given - */ - private void addNameSpace(String ns, Class<? extends XMPSchema> classSchem) - throws XmpSchemaException { - nsMaps.put(ns, new XMPSchemaFactory(ns, classSchem, initializePropMapping(ns, classSchem))); - } - - /** - * Initialize the Property Mapping for a given schema - * - * @param ns - * Namespace URI - * @param classSchem - * The class representation of the schema linked to the namespace - * @return Construct expected properties types representation - * @throws XmpSchemaException - * When could not read property name in field with properties - * annotations - */ - private PropMapping initializePropMapping(String ns, - Class<? extends XMPSchema> classSchem) throws XmpSchemaException { - PropertyType propType; - PropertyAttributesAnnotation propAtt; - Field[] fields; - PropMapping propMap = new PropMapping(ns); - fields = classSchem.getFields(); - String propName = null; - for (Field field : fields) { - if (field.isAnnotationPresent(PropertyType.class)) { - try { - propName = (String) field.get(propName); - } catch (Exception e) { - throw new XmpSchemaException( - "couldn't read one type declaration, please check accessibility and declaration of fields annoted in " - + classSchem.getName(), e); - } - // System.out.println("nameField:"+propName); - propType = field.getAnnotation(PropertyType.class); - // System.out.println("Type '"+propInfo.propertyType()+"' defined for "+propName); - if (!field - .isAnnotationPresent(PropertyAttributesAnnotation.class)) { - propMap.addNewProperty(propName, propType.propertyType(), - null); - } else { - // TODO Case where a special annotation is used to specify - // attributes - // NOT IMPLEMENTED YET, JUST TO GIVE A CLUE TO MAKE THIS - propAtt = field - .getAnnotation(PropertyAttributesAnnotation.class); - List<String> attributes = new ArrayList<String>(); - for (String att : propAtt.expectedAttributes()) { - attributes.add(att); - } - propMap.addNewProperty(propName, propType.propertyType(), - attributes); - } - } - } - return propMap; - } - - /** - * see if a specific type is known as a basic XMP type - * - * @param type - * Type to check - * @return True if type is a simple basic type - */ - private boolean isBasicType(String type) { - return BASIC_TYPES.contains(type); - - } - - /** - * Say if a specific namespace is known - * - * @param namespace - * The namespace URI checked - * @return True if namespace URI is known - */ - public boolean isContainedNamespace(String namespace) { - return nsMaps.containsKey(namespace); - } - - /** - * Give type of specified property in specified schema (given by its - * namespaceURI) - * - * @param namespace - * The namespaceURI to explore - * @param prop - * the property Qualified Name - * @return Property type declared for namespace specified, null if unknown - */ - public String getSpecifiedPropertyType(String namespace, QName prop) { - if (nsMaps.containsKey(namespace)) { - return nsMaps.get(namespace).getPropertyType(prop.getLocalPart()); - } - // check if its a complexbasicValueType and if it's has been declared - return getComplexBasicValueTypeEffectiveType(prop.getPrefix()); - - } - - /** - * Check if a non basic value type used is describes in the schema which - * inlude a property with a such type - * - * @param desc - * The schema description associated to the schema which declare - * a property with specific value type - * @param definedValueType - * The value type name to find in value types descriptions - * @return The description of this specific value type - * @throws XmpUnknownValueTypeException - * If no declaration found - */ - private PDFAValueTypeDescription findValueTypeDescription( - SchemaDescription desc, String definedValueType) - throws XmpUnknownValueTypeException { - List<PDFAValueTypeDescription> values = desc.getValueTypes(); - for (PDFAValueTypeDescription val : values) { - if (definedValueType.equals(val.getTypeNameValue())) { - return val; - } - } - throw new XmpUnknownValueTypeException("ValueType '" + definedValueType - + "' is unknown. no declaration found in this schema"); - } - - /** - * Check if valueType used for a specified property description is known (in - * case where it's a normal value type or if a value type which has been - * defined in PDF/A Extension schema) - * - * @param desc - * The schema description associated to the schema which declare - * a property with specific value type - * @param definedValueType - * The value type name to find in value types descriptions - * @return value type equivalence (value type which can be treat (orginal - * basic value type or specific value type decomposed to find basic - * types) - * @throws XmpUnknownValueTypeException - * When Value Type is unknown - * - */ - private String getValueTypeEquivalence(SchemaDescription desc, - String definedValueType) throws XmpUnknownValueTypeException { - if (isBasicType(definedValueType)) { - return definedValueType; - } - PDFAValueTypeDescription val = findValueTypeDescription(desc, - definedValueType); - if (val.getFields().isEmpty()) { - // if fields value are note defined we suppose the property is a - // Text type - return "Text"; - } - return "Field"; - } - - /** - * . For a specific valuetype declared in this schema. This method decompose - * it if field are present. and add types expected - * - * @param desc - * The schema description associated to the schema which declare - * a property with specific value type - * @param valueType - * valueType to analyze - * @param prop - * Expected properties types representation - * @throws XmpUnknownValueTypeException - * When a Value Type associated is unknown - */ - private void declareAssociatedFieldType(SchemaDescription desc, - String valueType, PropMapping prop) - throws XmpUnknownValueTypeException { - - PDFAValueTypeDescription val = findValueTypeDescription(desc, valueType); - for (PDFAFieldDescription field : val.getFields()) { - // TODO case where a field call another nspace property ??? - String fieldType = getValueTypeEquivalence(desc, field - .getValueTypeValue()); - if (fieldType.equals("Field")) { - throw new XmpUnknownValueTypeException( - "ValueType Field reference a valuetype unknown"); - } - prop.addNewProperty(field.getNameValue(), fieldType, null); - - } - } - - /** - * Add a new namespace Mapping for specific schema declared in PDF/A - * Extension schema - * - * @param desc - * The schemaDescription associated to the schema - * @throws XmpUnknownValueTypeException - * When a Value Type associated is unknown - */ - public void setNamespaceDefinition(SchemaDescription desc) - throws XmpUnknownValueTypeException { - PropMapping propMap = new PropMapping(desc.getNameSpaceURI()); - List<PDFAPropertyDescription> props = desc.getProperties(); - for (int i = 0; i < props.size(); i++) { - String type = getValueTypeEquivalence(desc, props.get(i).getValueTypeValue()); - propMap.addNewProperty(props.get(i).getNameValue(), type, null); - if (type.equals("Field")) { - declareAssociatedFieldType(desc, props.get(i).getValueTypeValue(), propMap); - } - } - String nsName = desc.getPrefix(); - String ns = desc.getNameSpaceURI(); - nsMaps.put(ns, new XMPSchemaFactory(nsName, ns, XMPSchema.class, propMap)); - } - - /** - * Return the specialized schema class representation if it's known (create - * and add it to metadata). In other cases, return null - * - * @param metadata - * Metadata to link the new schema - * @param namespace - * The namespace URI - * @return Schema representation - * @throws XmpSchemaException - * When Instancing specified Object Schema failed - */ - public XMPSchema getAssociatedSchemaObject(XMPMetadata metadata, String namespace, String prefix) throws XmpSchemaException { - if (!nsMaps.containsKey(namespace)) { - return null; - } - XMPSchemaFactory factory = nsMaps.get(namespace); - return factory.createXMPSchema(metadata, prefix); - } - - /** - * Check if a namespace used reference a complex basic types (like - * Thumbnails) - * - * @param namespace - * The namespace URI to check - * @return True if namespace URI is a reference for a complex basic type - */ - public boolean isComplexBasicTypes(String namespace) { - return COMPLEX_BASIC_TYPES.containsKey(namespace); - } - - /** - * Check if a namespace declaration for a complex basic type has been found - * and if its valid for the entire XMP stream - * - * @param namespace - * the namespace URI - * @param prefix - * the prefix associated to this namespace - */ - public void setComplexBasicTypesDeclarationForLevelXMP(String namespace, - String prefix) { - if (isComplexBasicTypes(namespace)) { - complexBasicTypesDeclarationEntireXMPLevel.put(prefix, namespace); - } - } - - /** - * Check if a namespace declaration for a complex basic type has been found - * and if its valid for the current schema description (at level of - * rdf:Description) - * - * @param namespace - * the namespace URI - * @param prefix - * the prefix associated to this namespace - */ - public void setComplexBasicTypesDeclarationForLevelSchema(String namespace, - String prefix) { - if (isComplexBasicTypes(namespace)) { - complexBasicTypesDeclarationSchemaLevel.put(prefix, namespace); - } - - } - - /** - * Check if a namespace declaration for a complex basic type has been found - * and if its valid for the current property description - * - * @param namespace - * the namespace URI - * @param prefix - * the prefix associated to this namespace - */ - public void setComplexBasicTypesDeclarationForLevelProperty( - String namespace, String prefix) { - if (isComplexBasicTypes(namespace)) { - complexBasicTypesDeclarationPropertyLevel.put(prefix, namespace); - } - } - - /** - * Check for all XMP level if a complexBasicValueType prefix has been - * declared - * - * @param prefix - * The prefix which may design the namespace URI of the complex - * basic type - * @return The type if it is known, else null. - */ - public String getComplexBasicValueTypeEffectiveType(String prefix) { - if (complexBasicTypesDeclarationPropertyLevel.containsKey(prefix)) { - return COMPLEX_BASIC_TYPES - .get(complexBasicTypesDeclarationPropertyLevel.get(prefix)); - } - if (complexBasicTypesDeclarationSchemaLevel.containsKey(prefix)) { - return COMPLEX_BASIC_TYPES - .get(complexBasicTypesDeclarationSchemaLevel.get(prefix)); - } - if (complexBasicTypesDeclarationEntireXMPLevel.containsKey(prefix)) { - return COMPLEX_BASIC_TYPES - .get(complexBasicTypesDeclarationEntireXMPLevel.get(prefix)); - } - return null; - } - - /** - * Reset complex Basic types declaration for property level - */ - public void resetComplexBasicTypesDeclarationInPropertyLevel() { - complexBasicTypesDeclarationPropertyLevel.clear(); - } - - /** - * Reset complex Basic types declaration for schema level - */ - public void resetComplexBasicTypesDeclarationInSchemaLevel() { - complexBasicTypesDeclarationSchemaLevel.clear(); - } - - /** - * Reset complex Basic types declaration for Entire XMP level - */ - public void resetComplexBasicTypesDeclarationInEntireXMPLevel() { - complexBasicTypesDeclarationEntireXMPLevel.clear(); - } + private Map<String, String> complexBasicTypesDeclarationEntireXMPLevel; + + private Map<String, String> complexBasicTypesDeclarationSchemaLevel; + + private Map<String, String> complexBasicTypesDeclarationPropertyLevel; + + /** + * Constructor of the NameSpace mapping + * + * @throws XmpSchemaException + * When could not read a property data in a Schema Class given + */ + public NSMapping() throws XmpSchemaException { + complexBasicTypesDeclarationEntireXMPLevel = new HashMap<String, String>(); + complexBasicTypesDeclarationSchemaLevel = new HashMap<String, String>(); + complexBasicTypesDeclarationPropertyLevel = new HashMap<String, String>(); + definedNamespaces = new HashMap<String, XMPSchemaFactory>(); + } + + + /** + * Import an NSMapping content. + * @param imp + */ + public void importNSMapping(NSMapping imp) throws XmpSchemaException { + // merge name sapce maps + for (Entry<String, XMPSchemaFactory> entry : imp.definedNamespaces.entrySet() ) { + if (this.definedNamespaces.containsKey(entry.getKey())) { + this.definedNamespaces.get(entry.getKey()).importXMPSchemaFactory(entry.getValue()); + } else { + this.definedNamespaces.put(entry.getKey(), entry.getValue()); + } + } + // merge complex basic types declaration entire xmp level + for (Entry<String, String> entry : imp.complexBasicTypesDeclarationEntireXMPLevel.entrySet()) { + if(!complexBasicTypesDeclarationEntireXMPLevel.containsKey(entry.getKey())) { + complexBasicTypesDeclarationEntireXMPLevel.put(entry.getKey(), entry.getValue()); + } + } + // merge complex basic types declaration schema level + for (Entry<String, String> entry : imp.complexBasicTypesDeclarationSchemaLevel.entrySet()) { + if(!complexBasicTypesDeclarationSchemaLevel.containsKey(entry.getKey())) { + complexBasicTypesDeclarationSchemaLevel.put(entry.getKey(), entry.getValue()); + } + } + // merger complex basic types declaration property level + for (Entry<String, String> entry : imp.complexBasicTypesDeclarationPropertyLevel.entrySet()) { + if(!complexBasicTypesDeclarationPropertyLevel.containsKey(entry.getKey())) { + complexBasicTypesDeclarationPropertyLevel.put(entry.getKey(), entry.getValue()); + } + } + } + + + + /** + * Say if a specific namespace is known + * + * @param namespace + * The namespace URI checked + * @return True if namespace URI is known + */ + public boolean isContainedNamespace(String namespace) { + boolean found = SchemaMapping.isContainedNamespace(namespace); + if (!found) { + found = definedNamespaces.containsKey(namespace); + } + return found; + } + + /** + * Give type of specified property in specified schema (given by its + * namespaceURI) + * + * @param namespace + * The namespaceURI to explore + * @param prop + * the property Qualified Name + * @return Property type declared for namespace specified, null if unknown + */ + public String getSpecifiedPropertyType(String namespace, QName prop) { + XMPSchemaFactory factory = SchemaMapping.getSchemaFactory(namespace); + if (factory==null) { + factory = definedNamespaces.get(namespace); + } + if (factory!=null) { + return factory.getPropertyType(prop.getLocalPart()); + } else { + // check if its a complexbasicValueType and if it's has been declared + return getComplexBasicValueTypeEffectiveType(prop.getPrefix()); + } + } + + /** + * Check if a non basic value type used is describes in the schema which + * inlude a property with a such type + * + * @param desc + * The schema description associated to the schema which declare + * a property with specific value type + * @param definedValueType + * The value type name to find in value types descriptions + * @return The description of this specific value type + * @throws XmpUnknownValueTypeException + * If no declaration found + */ + private PDFAValueTypeDescription findValueTypeDescription( + SchemaDescription desc, String definedValueType) + throws XmpUnknownValueTypeException { + List<PDFAValueTypeDescription> values = desc.getValueTypes(); + for (PDFAValueTypeDescription val : values) { + if (definedValueType.equals(val.getTypeNameValue())) { + return val; + } + } + throw new XmpUnknownValueTypeException("ValueType '" + definedValueType + + "' is unknown. no declaration found in this schema"); + } + + /** + * Check if valueType used for a specified property description is known (in + * case where it's a normal value type or if a value type which has been + * defined in PDF/A Extension schema) + * + * @param desc + * The schema description associated to the schema which declare + * a property with specific value type + * @param definedValueType + * The value type name to find in value types descriptions + * @return value type equivalence (value type which can be treat (orginal + * basic value type or specific value type decomposed to find basic + * types) + * @throws XmpUnknownValueTypeException + * When Value Type is unknown + * + */ + private String getValueTypeEquivalence(SchemaDescription desc, + String definedValueType) throws XmpUnknownValueTypeException { + if (TypeMapping.isSimpleType(definedValueType) || TypeMapping.isArrayOfSimpleType(definedValueType)) { + return definedValueType; + } + PDFAValueTypeDescription val = findValueTypeDescription(desc, + definedValueType); + if (val.getFields().isEmpty()) { + // if fields value are note defined we suppose the property is a + // Text type + return "Text"; + } + return "Field"; + } + + + /** + * Add a new namespace Mapping for specific schema declared in PDF/A + * Extension schema + * + * @param desc + * The schemaDescription associated to the schema + * @throws XmpUnknownValueTypeException + * When a Value Type associated is unknown + */ + public void setNamespaceDefinition(SchemaDescription desc) + throws XmpUnknownValueTypeException { + PropMapping propMap = new PropMapping(desc.getNameSpaceURI()); + List<PDFAPropertyDescription> props = desc.getProperties(); + for (int i = 0; i < props.size(); i++) { + String type = getValueTypeEquivalence(desc, props.get(i).getValueTypeValue()); + propMap.addNewProperty(props.get(i).getNameValue(), type, null); + if (type.equals("Field")) { + String valueType = props.get(i).getValueTypeValue(); + PDFAValueTypeDescription val = findValueTypeDescription(desc, valueType); + for (PDFAFieldDescription field : val.getFields()) { + // XXX case where a field call another nspace property ??? + String fieldType = getValueTypeEquivalence(desc, field + .getValueTypeValue()); + if (fieldType.equals("Field")) { + throw new XmpUnknownValueTypeException( + "ValueType Field reference a valuetype unknown"); + } + propMap.addNewProperty(field.getNameValue(), fieldType, null); + + } + + + } + } + String nsName = desc.getPrefix(); + String ns = desc.getNameSpaceURI(); + definedNamespaces.put(ns, new XMPSchemaFactory(nsName, ns, XMPSchema.class, propMap)); + } + + /** + * Check if a namespace declaration for a complex basic type has been found + * and if its valid for the entire XMP stream + * + * @param namespace + * the namespace URI + * @param prefix + * the prefix associated to this namespace + */ + public void setComplexBasicTypesDeclarationForLevelXMP(String namespace, + String prefix) { + if (TypeMapping.isStructuredTypeNamespace(namespace)) { + complexBasicTypesDeclarationEntireXMPLevel.put(prefix, namespace); + } + } + + /** + * Check if a namespace declaration for a complex basic type has been found + * and if its valid for the current schema description (at level of + * rdf:Description) + * + * @param namespace + * the namespace URI + * @param prefix + * the prefix associated to this namespace + */ + public void setComplexBasicTypesDeclarationForLevelSchema(String namespace, + String prefix) { + if (TypeMapping.isStructuredTypeNamespace(namespace)) { + complexBasicTypesDeclarationSchemaLevel.put(prefix, namespace); + } + + } + + /** + * Check if a namespace declaration for a complex basic type has been found + * and if its valid for the current property description + * + * @param namespace + * the namespace URI + * @param prefix + * the prefix associated to this namespace + */ + public void setComplexBasicTypesDeclarationForLevelProperty( + String namespace, String prefix) { + if (TypeMapping.isStructuredTypeNamespace(namespace)) { + complexBasicTypesDeclarationPropertyLevel.put(prefix, namespace); + } + } + + + /** + * Reset complex Basic types declaration for property level + */ + public void resetComplexBasicTypesDeclarationInPropertyLevel() { + complexBasicTypesDeclarationPropertyLevel.clear(); + } + + /** + * Reset complex Basic types declaration for schema level + */ + public void resetComplexBasicTypesDeclarationInSchemaLevel() { + complexBasicTypesDeclarationSchemaLevel.clear(); + } + + /** + * Reset complex Basic types declaration for Entire XMP level + */ + public void resetComplexBasicTypesDeclarationInEntireXMPLevel() { + complexBasicTypesDeclarationEntireXMPLevel.clear(); + } + + /** + * Check for all XMP level if a complexBasicValueType prefix has been + * declared + * + * @param prefix + * The prefix which may design the namespace URI of the complex + * basic type + * @return The type if it is known, else null. + */ + public String getComplexBasicValueTypeEffectiveType(String prefix) { + // stop when found in first map + String tmp = complexBasicTypesDeclarationPropertyLevel.get(prefix); + if (tmp==null) { + tmp = complexBasicTypesDeclarationSchemaLevel.get(prefix); + } + if (tmp ==null) { + tmp = complexBasicTypesDeclarationEntireXMPLevel.get(prefix); + } + // return complex basic type + if (tmp!=null) { + return TypeMapping.getStructuredTypeName(tmp).getType(); + } else { + // + return null; + } + } + + /** + * Return the specialized schema class representation if it's known (create + * and add it to metadata). In other cases, return null + * + * @param metadata + * Metadata to link the new schema + * @param namespace + * The namespace URI + * @return Schema representation + * @throws XmpSchemaException + * When Instancing specified Object Schema failed + */ + public XMPSchema getAssociatedSchemaObject(XMPMetadata metadata, String namespace, String prefix) throws XmpSchemaException { + XMPSchema found = SchemaMapping.getAssociatedSchemaObject(metadata, namespace, prefix); + if (found!=null) { + return found; + } else { + // look in local + if (!definedNamespaces.containsKey(namespace)) { + return null; + } + XMPSchemaFactory factory = definedNamespaces.get(namespace); + return factory.createXMPSchema(metadata, prefix); + } + } + + } Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/PDFAExtentionSchemaPreprocessor.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/PDFAExtentionSchemaPreprocessor.java?rev=1366609&r1=1366608&r2=1366609&view=diff ============================================================================== --- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/PDFAExtentionSchemaPreprocessor.java (original) +++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/PDFAExtentionSchemaPreprocessor.java Sat Jul 28 08:36:32 2012 @@ -29,6 +29,7 @@ import javax.xml.stream.XMLStreamReader; import org.apache.padaf.xmpbox.XMPMetadata; import org.apache.padaf.xmpbox.schema.PDFAExtensionSchema; import org.apache.padaf.xmpbox.type.BadFieldValueException; +import org.apache.padaf.xmpbox.type.TypeMapping; public class PDFAExtentionSchemaPreprocessor extends XMPDocumentBuilder implements XMPDocumentPreprocessor { @@ -39,7 +40,7 @@ public class PDFAExtentionSchemaPreproce public NSMapping process(byte[] xmp) throws XmpParsingException, XmpSchemaException, XmpUnknownValueTypeException, XmpExpectedRdfAboutAttribute, XmpXpacketEndException, BadFieldValueException { parse(xmp); - return this.nsMap; + return this.getNsMap(); } protected void parseDescription(XMPMetadata metadata) @@ -47,15 +48,16 @@ public class PDFAExtentionSchemaPreproce XmpUnknownValueTypeException, XmpExpectedRdfAboutAttribute, BadFieldValueException { + NSMapping nsMap = getNsMap(); + XMLStreamReader reader = getReader(); nsMap.resetComplexBasicTypesDeclarationInSchemaLevel(); - int cptNS = reader.get().getNamespaceCount(); + int cptNS = reader.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))) { + namespaces.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i)); + if (TypeMapping.isStructuredTypeNamespace(reader.getNamespaceURI(i))) { nsMap.setComplexBasicTypesDeclarationForLevelSchema(reader - .get().getNamespaceURI(i), reader.get() - .getNamespacePrefix(i)); + .getNamespaceURI(i), reader.getNamespacePrefix(i)); } } @@ -81,10 +83,10 @@ public class PDFAExtentionSchemaPreproce } else { int openedTag = 0; - while (reader.get().nextTag() == XMLStreamReader.START_ELEMENT) { + while (reader.nextTag() == XMLStreamReader.START_ELEMENT) { openedTag=1; do { - int tag = reader.get().next(); + int tag = reader.next(); if (tag == XMLStreamReader.START_ELEMENT) { openedTag++; } else if (tag == XMLStreamReader.END_ELEMENT) { Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/StructuredPropertyParser.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/StructuredPropertyParser.java?rev=1366609&r1=1366608&r2=1366609&view=diff ============================================================================== --- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/StructuredPropertyParser.java (original) +++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/StructuredPropertyParser.java Sat Jul 28 08:36:32 2012 @@ -21,25 +21,218 @@ package org.apache.padaf.xmpbox.parser; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; import org.apache.padaf.xmpbox.XMPMetadata; +import org.apache.padaf.xmpbox.schema.PropertyType; +import org.apache.padaf.xmpbox.type.AbstractField; +import org.apache.padaf.xmpbox.type.AbstractSimpleProperty; +import org.apache.padaf.xmpbox.type.AbstractStructuredType; import org.apache.padaf.xmpbox.type.ComplexPropertyContainer; +import org.apache.padaf.xmpbox.type.TypeDescription; +import org.apache.padaf.xmpbox.type.TypeMapping; + +public class StructuredPropertyParser { -public abstract class StructuredPropertyParser { + private XMPDocumentBuilder builder = null; + + private Class<? extends AbstractStructuredType> typeClass = null; + + private Constructor<? extends AbstractStructuredType> typeConstructor = null; + + private Map<String,PropertyDescription> propDesc = null; + +// private static Class<?> [] propertyConstructorParams = new Class [] {XMPMetadata.class,String.class}; + private static Class<?> [] propertyConstructorParams = new Class [] {XMPMetadata.class}; + + public StructuredPropertyParser(XMPDocumentBuilder builder,Class<? extends AbstractStructuredType> propertyTypeClass) + throws XmpPropertyFormatException + { + this.builder = builder; + this.typeClass = propertyTypeClass; + this.propDesc = new HashMap<String, PropertyDescription>(); + // retrieve xmp properties + Field [] fields = typeClass.getFields(); + for (Field field : fields) { + if (field.getAnnotation(PropertyType.class)!=null) { + PropertyDescription pd = new PropertyDescription(); + pd.propertyType = field.getAnnotation(PropertyType.class); +// pd.fieldName = field.getName(); + try { + pd.propertyName = field.get(null).toString(); + } catch (IllegalArgumentException e1) { + throw new XmpPropertyFormatException("Failed to parse structured type : "+typeClass.getName(),e1); + } catch (IllegalAccessException e1) { + throw new XmpPropertyFormatException("Failed to parse structured type : "+typeClass.getName(),e1); + } + propDesc.put(pd.propertyName, pd); + } + } + // retrieve constructor + try { + typeConstructor = typeClass.getConstructor(propertyConstructorParams); + } catch (SecurityException e) { + throw new XmpPropertyFormatException("Failed to initialize structured type parser : "+typeClass.getName(),e); + } catch (NoSuchMethodException e) { + throw new XmpPropertyFormatException("Failed to initialize structured type parser : "+typeClass.getName(),e); + } + + } + + private AbstractStructuredType instanciateProperty (XMPMetadata metadata) throws XmpParsingException { + try { +// return typeConstructor.newInstance(metadata,prefix); + return typeConstructor.newInstance(metadata); + } catch (IllegalArgumentException e) { + throw new XmpParsingException("Failed to instanciate structured type : "+typeClass.getName(),e); + } catch (InstantiationException e) { + throw new XmpParsingException("Failed to instanciate structured type : "+typeClass.getName(),e); + } catch (IllegalAccessException e) { + throw new XmpParsingException("Failed to instanciate structured type : "+typeClass.getName(),e); + } catch (InvocationTargetException e) { + throw new XmpParsingException("Failed to instanciate structured type : "+typeClass.getName(),e); + } + } + + +// private String retrieveNamespacePrefix (XMLStreamReader reader, String namespace) { +// int na = reader.getNamespaceCount(); +// for (int i=0; i < na; i++) { +// if (reader.getNamespaceURI(i).equals(namespace)) { +// return reader.getNamespacePrefix(i); +// } +// } +// // no namespace for prefix +// return null; +// } +// +// private String getStructuredClassNamespace (Class<? extends AbstractStructuredType> clz) throws XmpUnexpectedTypeException { +// try { +// return (String)typeClass.getField("ELEMENT_NS").get(null); +// } catch (IllegalArgumentException e) { +// throw new XmpUnexpectedTypeException("Failed to find Structured type namespace ("+clz.getName()+")",e); +// } catch (SecurityException e) { +// throw new XmpUnexpectedTypeException("Failed to find Structured type namespace ("+clz.getName()+")",e); +// } catch (IllegalAccessException e) { +// throw new XmpUnexpectedTypeException("Failed to find Structured type namespace ("+clz.getName()+")",e); +// } catch (NoSuchFieldException e) { +// throw new XmpUnexpectedTypeException("Failed to find Structured type namespace ("+clz.getName()+")",e); +// } +// +// } + + + public void parse(XMPMetadata metadata, QName altName, + ComplexPropertyContainer container) + throws XmpUnexpectedTypeException, XmpParsingException, + XMLStreamException, XmpUnknownPropertyTypeException, + XmpPropertyFormatException { + builder.expectCurrentLocalName("li"); + // create property +// String fieldPrefix = retrieveNamespacePrefix( +// builder.reader.get(), +// getStructuredClassNamespace(typeClass)); +// ComplexPropertyContainer property = instanciateProperty(metadata, fieldPrefix ); + ComplexPropertyContainer property = instanciateProperty(metadata); + XMLStreamReader reader = builder.getReader(); + int elmtType = reader.nextTag(); + QName eltName; + while (!((elmtType == XMLStreamReader.END_ELEMENT) && reader.getName().getLocalPart().equals("li"))) { + // read element name, then text content + eltName = reader.getName(); + String eltContent = reader.getElementText(); + // check if property is expected + String localPart = eltName.getLocalPart(); + if (propDesc.containsKey(localPart)) { + PropertyDescription description = propDesc.get(localPart); + + AbstractField a = instanciateSimple( + description.propertyType.propertyType(), + metadata, + eltName.getPrefix(), + localPart, + eltContent); + + property.addProperty(a); + } else { + // expect only defined properties are accepted + // XXX : really the good choice ? + // XXX : should we create text properties for unknown types ? + throw new XmpParsingException( + "Unknown property name for a job element : " + + eltName.getLocalPart()); + } + elmtType = reader.nextTag(); + } + container.addProperty(property); + + } + + + + + private AbstractSimpleProperty instanciateSimple ( + String type, + XMPMetadata metadata, + String prefix, + String propertyName, + String valueAsString) + throws XmpParsingException { + TypeDescription description = TypeMapping.getTypeDescription(type); + Object value = null; + switch (description.getBasic()) { + case Boolean : + value = Boolean.parseBoolean(valueAsString); + break; + case Date : + try { + value = DateConverter.toCalendar(valueAsString); + } catch (IOException e) { + throw new XmpParsingException("Failed to parse date property",e); + } + break; + case Integer : + try { + value = Integer.parseInt(valueAsString); + } catch (NumberFormatException e) { + throw new XmpParsingException("Failed to parse integer property",e); + } + break; + case Real : + try { + value = Float.parseFloat(valueAsString); + } catch (NumberFormatException e) { + throw new XmpParsingException("Failed to parse real type property",e); + } + break; + case Text : + value = valueAsString; + } + + return TypeMapping.instanciateSimpleProperty(metadata, null, prefix, propertyName, value, type); + } + + + + protected class PropertyDescription { + +// private String fieldName; +// + private String propertyName; + private PropertyType propertyType; - protected XMPDocumentBuilder builder = null; + } - public StructuredPropertyParser (XMPDocumentBuilder builder) { - this.builder = builder; - }; - public abstract void parse(XMPMetadata metadata, QName altName, - ComplexPropertyContainer container) - throws XmpUnexpectedTypeException, XmpParsingException, - XMLStreamException, XmpUnknownPropertyTypeException, - XmpPropertyFormatException; } Modified: 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=1366609&r1=1366608&r2=1366609&view=diff ============================================================================== --- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java (original) +++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java Sat Jul 28 08:36:32 2012 @@ -46,8 +46,9 @@ import com.thoughtworks.xstream.io.xml.D */ public class XMLPropertiesDescriptionManager { - protected List<PropertyDescription> propDescs; - protected XStream xstream; + private List<PropertyDescription> propDescs; + + private XStream xstream; /** * Create new XMLPropertiesDescriptionManager Modified: 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=1366609&r1=1366608&r2=1366609&view=diff ============================================================================== --- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java (original) +++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java Sat Jul 28 08:36:32 2012 @@ -48,8 +48,9 @@ import com.thoughtworks.xstream.io.xml.D */ public class XMLValueTypeDescriptionManager { - protected List<ValueTypeDescription> vTypes; - protected XStream xstream; + private List<ValueTypeDescription> vTypes; + + private XStream xstream; /** * Create a new XMLValueTypeDescriptionManager