From ebab1fabdbeea0f9b76d4253636e85c51451de42 Mon Sep 17 00:00:00 2001 From: MaximPlusov Date: Thu, 1 Feb 2024 13:44:33 +0300 Subject: [PATCH] Add extension schema methods (#1402) --- .../VeraPDFExtensionSchemaDefinition.java | 94 +++++++++++++++++++ .../impl/VeraPDFExtensionSchemaProperty.java | 46 +++++++++ .../VeraPDFExtensionSchemasContainer.java | 57 +++++++++++ .../org/verapdf/xmp/impl/VeraPDFMeta.java | 21 ++++- .../org/verapdf/xmp/impl/VeraPDFXMPNode.java | 4 + 5 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaDefinition.java create mode 100644 xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaProperty.java create mode 100644 xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemasContainer.java diff --git a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaDefinition.java b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaDefinition.java new file mode 100644 index 000000000..de41d1152 --- /dev/null +++ b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaDefinition.java @@ -0,0 +1,94 @@ +package org.verapdf.xmp.impl; + +import org.verapdf.xmp.XMPConst; +import org.verapdf.xmp.XMPException; +import org.verapdf.xmp.options.PropertyOptions; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class VeraPDFExtensionSchemaDefinition { + + private static final String PROPERTY = "property"; + public static final String NAMESPACE_URI = "namespaceURI"; + private static final String PREFIX = "prefix"; + private static final String SCHEMA = "schema"; + private static final String PDFA_SCHEMA_PREFIX = "pdfaSchema"; + + private final VeraPDFXMPNode xmpNode; + + public VeraPDFExtensionSchemaDefinition(VeraPDFXMPNode xmpNode) { + this.xmpNode = xmpNode; + } + + public List getExtensionSchemaProperties() { + if (this.xmpNode != null) { + List res = new ArrayList<>(); + for (VeraPDFXMPNode child : this.xmpNode.getChildren()) { + if (XMPConst.NS_PDFA_SCHEMA.equals(child.getNamespaceURI()) && PROPERTY.equals(child.getName())) { + if (child.getOptions().isArray()) { + for (VeraPDFXMPNode node : child.getChildren()) { + res.add(new VeraPDFExtensionSchemaProperty(node)); + } + } + break; + } + } + return res; + } + return Collections.emptyList(); + } + + public VeraPDFXMPNode getPropertiesNode() { + if (this.xmpNode != null) { + for (VeraPDFXMPNode child : this.xmpNode.getChildren()) { + if (XMPConst.NS_PDFA_SCHEMA.equals(child.getNamespaceURI()) && PROPERTY.equals(child.getName())) { + return child; + } + } + } + return null; + } + + public void addExtensionSchemaProperty(VeraPDFExtensionSchemaProperty propertyDefinitionXMPNode) throws XMPException { + if (this.xmpNode != null) { + getPropertiesNode().getOriginalNode().addChild(propertyDefinitionXMPNode.getXmpNode()); + } + } + + public String getNamespaceURI() { + for (VeraPDFXMPNode child : this.xmpNode.getChildren()) { + if (XMPConst.NS_PDFA_SCHEMA.equals(child.getNamespaceURI()) && NAMESPACE_URI.equals(child.getName())) { + return child.getValue(); + } + } + return null; + } + + public String getPrefix() { + for (VeraPDFXMPNode child : this.xmpNode.getChildren()) { + if (XMPConst.NS_PDFA_SCHEMA.equals(child.getNamespaceURI()) && PREFIX.equals(child.getName())) { + return child.getValue(); + } + } + return null; + } + + public XMPNode getXmpNode() { + return xmpNode.getOriginalNode(); + } + + public static VeraPDFExtensionSchemaDefinition createExtensionSchemaDefinitionNode(String schema, String namespaceURI, String prefix) throws XMPException { + XMPNode node = new XMPNode(XMPConst.ARRAY_ITEM_NAME,"", new PropertyOptions(PropertyOptions.STRUCT), "rdf"); + node.addChild(new XMPNode(PDFA_SCHEMA_PREFIX + ":" + SCHEMA, schema, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_SCHEMA_PREFIX)); + node.addChild(new XMPNode(PDFA_SCHEMA_PREFIX + ":" + NAMESPACE_URI, namespaceURI, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_SCHEMA_PREFIX)); + node.addChild(new XMPNode(PDFA_SCHEMA_PREFIX + ":" + PREFIX, prefix, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_SCHEMA_PREFIX)); + node.addChild(new XMPNode(PDFA_SCHEMA_PREFIX + ":" + PROPERTY,"", + new PropertyOptions(PropertyOptions.ARRAY + PropertyOptions.ARRAY_ORDERED), PDFA_SCHEMA_PREFIX)); + return new VeraPDFExtensionSchemaDefinition(VeraPDFXMPNode.fromXMPNode(node)); + } +} diff --git a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaProperty.java b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaProperty.java new file mode 100644 index 000000000..fc5d6505f --- /dev/null +++ b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemaProperty.java @@ -0,0 +1,46 @@ +package org.verapdf.xmp.impl; + +import org.verapdf.xmp.XMPConst; +import org.verapdf.xmp.XMPException; +import org.verapdf.xmp.options.PropertyOptions; + +public class VeraPDFExtensionSchemaProperty { + + private static final String NAME = "name"; + private static final String VALUE_TYPE = "valueType"; + private static final String CATEGORY = "category"; + private static final String DESCRIPTION = "description"; + private static final String PDFA_PROPERTY_PREFIX = "pdfaProperty"; + + private final VeraPDFXMPNode xmpNode; + + public VeraPDFExtensionSchemaProperty(VeraPDFXMPNode xmpNode) { + this.xmpNode = xmpNode; + } + + public String getName() { + for (VeraPDFXMPNode child : this.xmpNode.getChildren()) { + if (XMPConst.NS_PDFA_PROPERTY.equals(child.getNamespaceURI()) && NAME.equals(child.getName())) { + return child.getValue(); + } + } + return null; + } + + public XMPNode getXmpNode() { + return xmpNode.getOriginalNode(); + } + + public static VeraPDFExtensionSchemaProperty createPropertyDefinitionNode(String name, String valueType, String category, String description) throws XMPException { + XMPNode node = new XMPNode(XMPConst.ARRAY_ITEM_NAME,"", new PropertyOptions(PropertyOptions.STRUCT), "rdf"); + node.addChild(new XMPNode(PDFA_PROPERTY_PREFIX + ":" + NAME, name, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_PROPERTY_PREFIX)); + node.addChild(new XMPNode(PDFA_PROPERTY_PREFIX + ":" + VALUE_TYPE, valueType, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_PROPERTY_PREFIX)); + node.addChild(new XMPNode(PDFA_PROPERTY_PREFIX + ":" + CATEGORY, category, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_PROPERTY_PREFIX)); + node.addChild(new XMPNode(PDFA_PROPERTY_PREFIX + ":" + DESCRIPTION, description, + new PropertyOptions(PropertyOptions.NO_OPTIONS), PDFA_PROPERTY_PREFIX)); + return new VeraPDFExtensionSchemaProperty(VeraPDFXMPNode.fromXMPNode(node)); + } +} diff --git a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemasContainer.java b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemasContainer.java new file mode 100644 index 000000000..034c7c2a3 --- /dev/null +++ b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFExtensionSchemasContainer.java @@ -0,0 +1,57 @@ +package org.verapdf.xmp.impl; + +import org.verapdf.xmp.XMPException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class VeraPDFExtensionSchemasContainer { + + public static final String PDFA_SCHEMA_PREFIX = "pdfaSchema"; + public static final String PDFA_PROPERTY_PREFIX = "pdfaProperty"; + public static final String NAMESPACE_URI = "namespaceURI"; + + private final VeraPDFXMPNode veraPDFXMPNode; + + public VeraPDFExtensionSchemasContainer(VeraPDFXMPNode veraPDFXMPNode) { + this.veraPDFXMPNode = veraPDFXMPNode; + } + + public void addExtensionSchemaDefinition(VeraPDFExtensionSchemaDefinition veraPDFExtensionSchemaDefinition) throws XMPException { + veraPDFXMPNode.getOriginalNode().addChild(veraPDFExtensionSchemaDefinition.getXmpNode()); + } + + public VeraPDFExtensionSchemaProperty getPropertyDefinition(String namespaceURI, String prefix, String name) { + VeraPDFExtensionSchemaDefinition definition = getExtensionSchemaDefinitionXMPNode(namespaceURI, prefix); + if (definition != null) { + for (VeraPDFExtensionSchemaProperty propertyDefinitionXMPNode : definition.getExtensionSchemaProperties()) { + if (Objects.equals(propertyDefinitionXMPNode.getName(), name)) { + return propertyDefinitionXMPNode; + } + } + } + return null; + } + + public VeraPDFExtensionSchemaDefinition getExtensionSchemaDefinitionXMPNode(String namespaceURI, String prefix) { + for (VeraPDFExtensionSchemaDefinition definition : getExtensionSchemaDefinitions()) { + if (Objects.equals(definition.getNamespaceURI(), namespaceURI) && Objects.equals(definition.getPrefix(), prefix)) { + return definition; + } + } + return null; + } + + private List getExtensionSchemaDefinitions() { + if (this.veraPDFXMPNode != null && this.veraPDFXMPNode.getOptions().isArray()) { + List res = new ArrayList<>(); + for (VeraPDFXMPNode node : this.veraPDFXMPNode.getChildren()) { + res.add(new VeraPDFExtensionSchemaDefinition(node)); + } + return Collections.unmodifiableList(res); + } + return Collections.emptyList(); + } +} diff --git a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFMeta.java b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFMeta.java index 155ab6bd6..76da02a64 100644 --- a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFMeta.java +++ b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFMeta.java @@ -2,6 +2,8 @@ import org.verapdf.xmp.*; import org.verapdf.xmp.options.ParseOptions; +import org.verapdf.xmp.impl.xpath.XMPPath; +import org.verapdf.xmp.impl.xpath.XMPPathParser; import org.verapdf.xmp.options.PropertyOptions; import org.verapdf.xmp.options.SerializeOptions; import org.verapdf.xmp.properties.XMPProperty; @@ -16,6 +18,8 @@ public class VeraPDFMeta { public static final String PDFAID_PREFIX = "pdfaid"; public static final String PDFUAID_PREFIX = "pdfuaid"; + public static final String PDFA_EXTENSION_PREFIX = "pdfaExtension"; + public static final String SCHEMAS = "schemas"; public static final String CONFORMANCE = "conformance"; public static final String PART = "part"; public static final String REVISION_YEAR = "rev"; @@ -57,7 +61,7 @@ private void addSchema(XMPNode xmpSchema) { int prefixEndIndex = originalName.indexOf(":"); String name = originalName.substring(prefixEndIndex + 1, originalName.length()); String namespaceURI = registry.getNamespaceURI(originalName.substring(0, Math.max(prefixEndIndex, 0))); - if (XMPMetaImpl.NS_PDFA_EXTENSION.equals(namespaceURI) && "schemas".equals(name)) { + if (XMPMetaImpl.NS_PDFA_EXTENSION.equals(namespaceURI) && SCHEMAS.equals(name)) { this.extensionSchemasNode = VeraPDFXMPNode.fromXMPNode(xmpChild); } else { this.properties.add(VeraPDFXMPNode.fromXMPNode(xmpChild)); @@ -65,6 +69,21 @@ private void addSchema(XMPNode xmpSchema) { } } } + + public VeraPDFExtensionSchemasContainer getExtensionSchema() throws XMPException { + final XMPPath expPath = XMPPathParser.expandXPath(XMPMetaImpl.NS_PDFA_EXTENSION, SCHEMAS); + final XMPNode propNode = XMPNodeUtils.findNode(meta.getRoot(), expPath, false, null); + return propNode != null ? new VeraPDFExtensionSchemasContainer(VeraPDFXMPNode.fromXMPNode(propNode)) : null; + } + + public void createExtensionSchema() throws XMPException { + XMPNode extension = new XMPNode(PDFA_EXTENSION_PREFIX + ":" + SCHEMAS, "", + new PropertyOptions(PropertyOptions.ARRAY), PDFA_EXTENSION_PREFIX); + XMPNode node = new XMPNode(XMPConst.NS_PDFA_EXTENSION, PDFA_EXTENSION_PREFIX + ":", + new PropertyOptions(PropertyOptions.SCHEMA_NODE), null); + node.addChild(extension); + meta.getRoot().addChild(node); + } public static VeraPDFMeta create() { XMPMetaImpl xmpMeta = (XMPMetaImpl) XMPMetaFactory.create(); diff --git a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFXMPNode.java b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFXMPNode.java index 95f04821a..30bb72d1c 100644 --- a/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFXMPNode.java +++ b/xmp-core/src/main/java/org/verapdf/xmp/impl/VeraPDFXMPNode.java @@ -146,6 +146,10 @@ public List getQualifier(){ public List getChildren() { return children; } + + protected XMPNode getOriginalNode() { + return originalNode; + } public PropertyOptions getOptions() { return options;