diff --git a/.gitignore b/.gitignore index 16006d3..ce9a994 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Package Files # *.jar +!/metsMetadata-plugin/src/main/resources/mets-api.jar *.war *.ear diff --git a/iccdump-plugin/pom.xml b/iccdump-plugin/pom.xml index 65b9d40..d3f3e94 100644 --- a/iccdump-plugin/pom.xml +++ b/iccdump-plugin/pom.xml @@ -11,5 +11,4 @@ iccdump-plugin - \ No newline at end of file diff --git a/mediaconch/pom.xml b/mediaconch/pom.xml new file mode 100644 index 0000000..bd1430a --- /dev/null +++ b/mediaconch/pom.xml @@ -0,0 +1,15 @@ + + + + verapdf-library-samples + org.verapdf + 1.0-SNAPSHOT + + 4.0.0 + + mediaconch-plugin + + + \ No newline at end of file diff --git a/mediaconch/src/main/java/org/verapdf/MediaConchConfig.java b/mediaconch/src/main/java/org/verapdf/MediaConchConfig.java new file mode 100644 index 0000000..970455c --- /dev/null +++ b/mediaconch/src/main/java/org/verapdf/MediaConchConfig.java @@ -0,0 +1,125 @@ +/** + * + */ +package org.verapdf; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.*; + +/** + * @author Maksim Bezrukov + */ +@XmlRootElement(namespace = "http://www.verapdf.org/MediaConchConfig", name = "mediaconchConfig") +final class MediaConchConfig { + + @XmlElement + private final String cliPath; + @XmlElement + private final String outFolder; + + private MediaConchConfig() { + this("", ""); + } + + private MediaConchConfig(String outFolder, String cliPath) { + this.outFolder = outFolder; + this.cliPath = cliPath; + } + + public String getCliPath() { + return cliPath; + } + + public String getOutFolder() { + return outFolder; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MediaConchConfig that = (MediaConchConfig) o; + + if (cliPath != null ? !cliPath.equals(that.cliPath) : that.cliPath != null) return false; + return !(outFolder != null ? !outFolder.equals(that.outFolder) : that.outFolder != null); + + } + + @Override + public int hashCode() { + int result = cliPath != null ? cliPath.hashCode() : 0; + result = 31 * result + (outFolder != null ? outFolder.hashCode() : 0); + return result; + } + + static MediaConchConfig defaultInstance() { + return new MediaConchConfig("mediaconch", null); + } + + static MediaConchConfig fromValues(final String cliPath, final String outFolder) { + return new MediaConchConfig(cliPath, outFolder); + } + + static String toXml(final MediaConchConfig toConvert, Boolean prettyXml) + throws JAXBException, IOException { + String retVal = ""; + try (StringWriter writer = new StringWriter()) { + toXml(toConvert, writer, prettyXml); + retVal = writer.toString(); + return retVal; + } + } + + static MediaConchConfig fromXml(final String toConvert) + throws JAXBException { + try (StringReader reader = new StringReader(toConvert)) { + return fromXml(reader); + } + } + + static void toXml(final MediaConchConfig toConvert, + final OutputStream stream, Boolean prettyXml) throws JAXBException { + Marshaller varMarshaller = getMarshaller(prettyXml); + varMarshaller.marshal(toConvert, stream); + } + + static MediaConchConfig fromXml(final InputStream toConvert) + throws JAXBException { + Unmarshaller stringUnmarshaller = getUnmarshaller(); + return (MediaConchConfig) stringUnmarshaller.unmarshal(toConvert); + } + + static void toXml(final MediaConchConfig toConvert, final Writer writer, + Boolean prettyXml) throws JAXBException { + Marshaller varMarshaller = getMarshaller(prettyXml); + varMarshaller.marshal(toConvert, writer); + } + + static MediaConchConfig fromXml(final Reader toConvert) + throws JAXBException { + Unmarshaller stringUnmarshaller = getUnmarshaller(); + return (MediaConchConfig) stringUnmarshaller.unmarshal(toConvert); + } + + private static Unmarshaller getUnmarshaller() throws JAXBException { + JAXBContext context = JAXBContext + .newInstance(MediaConchConfig.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + return unmarshaller; + } + + private static Marshaller getMarshaller(Boolean setPretty) + throws JAXBException { + JAXBContext context = JAXBContext + .newInstance(MediaConchConfig.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, setPretty); + return marshaller; + } +} diff --git a/mediaconch/src/main/java/org/verapdf/MediaConchExtractor.java b/mediaconch/src/main/java/org/verapdf/MediaConchExtractor.java new file mode 100644 index 0000000..40a54b8 --- /dev/null +++ b/mediaconch/src/main/java/org/verapdf/MediaConchExtractor.java @@ -0,0 +1,144 @@ +package org.verapdf; + +import org.verapdf.core.FeatureParsingException; +import org.verapdf.features.AbstractEmbeddedFileFeaturesExtractor; +import org.verapdf.features.EmbeddedFileFeaturesData; +import org.verapdf.features.tools.FeatureTreeNode; + +import javax.xml.bind.JAXBException; +import java.io.*; +import java.util.*; + +/** + * @author Maksim Bezrukov + */ +public class MediaConchExtractor extends AbstractEmbeddedFileFeaturesExtractor { + + @Override + public List getEmbeddedFileFeatures(EmbeddedFileFeaturesData embeddedFileFeaturesData) { + if (!isValidType(embeddedFileFeaturesData.getSubtype())) { + return null; + } + List result = new ArrayList<>(); + try { + try { + MediaConchConfig config = getConfig(result); + File temp = generateTempFile(embeddedFileFeaturesData.getStream(), embeddedFileFeaturesData.getName()); + execCLI(result, config, temp); + } catch (IOException | InterruptedException e) { + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue("Error in execution. Error message: " + e.getMessage()); + result.add(node); + } + } catch (FeatureParsingException e) { + throw new IllegalStateException(e); + } + return result; + } + + private File generateTempFile(byte[] stream, String name) throws IOException { + File fold = getTempFolder(); + File temp = File.createTempFile(name == null ? "" : name, "", fold); + temp.deleteOnExit(); + FileOutputStream out = new FileOutputStream(temp); + out.write(stream); + out.close(); + return temp; + } + + private void execCLI(List nodes, MediaConchConfig config, File temp) throws InterruptedException, FeatureParsingException, IOException { + List res = new ArrayList<>(); + Runtime rt = Runtime.getRuntime(); + String cliPath; + String configCliPath = config.getCliPath(); + if (configCliPath == null || configCliPath.isEmpty()) { + cliPath = "mediaconch"; + } else { + cliPath = configCliPath; + } + File out = getOutFile(config, nodes); + String[] str = new String[]{cliPath, "-mc", "-fx", temp.getCanonicalPath()}; + Process pr = rt.exec(str); + FileOutputStream outStream = new FileOutputStream(out); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = pr.getInputStream().read(buffer)) != -1) + { + outStream.write(buffer, 0, bytesRead); + } + pr.waitFor(); + FeatureTreeNode node = FeatureTreeNode.createRootNode("resultPath"); + node.setValue(out.getCanonicalPath()); + nodes.add(node); + + } + + private File getOutFile(MediaConchConfig config, List nodes) throws FeatureParsingException, IOException { + if (config.getOutFolder() == null) { + File tempFolder = getTempFolder(); + File res = getOutFileInFolder(tempFolder); + return res; + } else { + File outFolder = new File(config.getOutFolder()); + if (outFolder.isDirectory()) { + File res = getOutFileInFolder(outFolder); + return res; + } else { + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue("Config file contains out folder path but it doesn't link a directory."); + nodes.add(node); + File tempFolder = getTempFolder(); + File res = getOutFileInFolder(tempFolder); + return res; + } + } + } + + private File getTempFolder() { + File tempDir = new File(System.getProperty("java.io.tmpdir")); + File tempFolder = new File(tempDir, "veraPDFMediaConchPluginTemp"); + if (!tempFolder.exists()) { + tempFolder.mkdir(); + } + return tempFolder; + } + + private File getOutFileInFolder(File folder) throws IOException { + File out = File.createTempFile("veraPDF_MediaConch_Plugin_out", ".xml", folder); + return out; + } + + private MediaConchConfig getConfig(List nodes) throws FeatureParsingException { + MediaConchConfig config = MediaConchConfig.defaultInstance(); + File conf = getConfigFile(); + if (conf.isFile() && conf.canRead()) { + try { + config = MediaConchConfig.fromXml(new FileInputStream(conf)); + } catch (JAXBException | FileNotFoundException e) { + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue("Config file contains wrong syntax. Error message: " + e.getMessage()); + nodes.add(node); + } + } + return config; + } + + private File getConfigFile() { + return new File(getFolderPath().toFile(), "config.xml"); + } + + private boolean isValidType(String type) { + return type.toLowerCase().startsWith("video/"); + } + + @Override + public String getID() { + return "8725b233-1597-490e-9b45-b989303d2c5b"; + } + + @Override + public String getDescription() { + //TODO: check this description + return "Generates mediaconch report of the given embedded video file"; + } +} diff --git a/metsMetadata-plugin/pom.xml b/metsMetadata-plugin/pom.xml new file mode 100644 index 0000000..b25000d --- /dev/null +++ b/metsMetadata-plugin/pom.xml @@ -0,0 +1,34 @@ + + + + verapdf-library-samples + org.verapdf + 1.0-SNAPSHOT + + 4.0.0 + + metsMetadata-plugin + + + + au.edu.apsr.mtk + mets + 1.0 + system + ${project.basedir}/src/main/resources/mets-api.jar + + + org.verapdf + feature-report + [0.11.0,0.12.0) + + + org.verapdf + verapdf-xmp-core + [0.11.0,0.12.0) + + + + \ No newline at end of file diff --git a/metsMetadata-plugin/src/main/java/org/verapdf/METSConfig.java b/metsMetadata-plugin/src/main/java/org/verapdf/METSConfig.java new file mode 100644 index 0000000..ae3c374 --- /dev/null +++ b/metsMetadata-plugin/src/main/java/org/verapdf/METSConfig.java @@ -0,0 +1,112 @@ +package org.verapdf; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.*; + +/** + * @author Maksim Bezrukov + */ +@XmlRootElement(namespace = "http://www.verapdf.org/METSConfig", name = "metsConfig") +final class METSConfig { + + @XmlElement + private final String outFolder; + + private METSConfig() { + this(""); + } + + private METSConfig(String outFolder) { + this.outFolder = outFolder; + } + + public String getOutFolder() { + return outFolder; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + METSConfig that = (METSConfig) o; + + return !(outFolder != null ? !outFolder.equals(that.outFolder) : that.outFolder != null); + + } + + @Override + public int hashCode() { + return outFolder != null ? outFolder.hashCode() : 0; + } + + static METSConfig defaultInstance() { + return new METSConfig(null); + } + + static METSConfig fromValues(final String outFolder) { + return new METSConfig(outFolder); + } + + static String toXml(final METSConfig toConvert, Boolean prettyXml) + throws JAXBException, IOException { + String retVal = ""; + try (StringWriter writer = new StringWriter()) { + toXml(toConvert, writer, prettyXml); + retVal = writer.toString(); + return retVal; + } + } + + static METSConfig fromXml(final String toConvert) + throws JAXBException { + try (StringReader reader = new StringReader(toConvert)) { + return fromXml(reader); + } + } + + static void toXml(final METSConfig toConvert, + final OutputStream stream, Boolean prettyXml) throws JAXBException { + Marshaller varMarshaller = getMarshaller(prettyXml); + varMarshaller.marshal(toConvert, stream); + } + + static METSConfig fromXml(final InputStream toConvert) + throws JAXBException { + Unmarshaller stringUnmarshaller = getUnmarshaller(); + return (METSConfig) stringUnmarshaller.unmarshal(toConvert); + } + + static void toXml(final METSConfig toConvert, final Writer writer, + Boolean prettyXml) throws JAXBException { + Marshaller varMarshaller = getMarshaller(prettyXml); + varMarshaller.marshal(toConvert, writer); + } + + static METSConfig fromXml(final Reader toConvert) + throws JAXBException { + Unmarshaller stringUnmarshaller = getUnmarshaller(); + return (METSConfig) stringUnmarshaller.unmarshal(toConvert); + } + + private static Unmarshaller getUnmarshaller() throws JAXBException { + JAXBContext context = JAXBContext + .newInstance(METSConfig.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + return unmarshaller; + } + + private static Marshaller getMarshaller(Boolean setPretty) + throws JAXBException { + JAXBContext context = JAXBContext + .newInstance(METSConfig.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, setPretty); + return marshaller; + } +} diff --git a/metsMetadata-plugin/src/main/java/org/verapdf/METSMetadataExtractor.java b/metsMetadata-plugin/src/main/java/org/verapdf/METSMetadataExtractor.java new file mode 100644 index 0000000..0d623e6 --- /dev/null +++ b/metsMetadata-plugin/src/main/java/org/verapdf/METSMetadataExtractor.java @@ -0,0 +1,284 @@ +package org.verapdf; + +import au.edu.apsr.mtk.base.*; +import com.adobe.xmp.XMPException; +import com.adobe.xmp.XMPMeta; +import com.adobe.xmp.XMPMetaFactory; +import com.adobe.xmp.impl.VeraPDFMeta; +import com.adobe.xmp.impl.VeraPDFXMPNode; +import com.adobe.xmp.impl.XMPSchemaRegistryImpl; +import org.verapdf.core.FeatureParsingException; +import org.verapdf.features.AbstractMetadataFeaturesExtractor; +import org.verapdf.features.MetadataFeaturesData; +import org.verapdf.features.tools.FeatureTreeNode; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import javax.xml.bind.JAXBException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.*; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Maksim Bezrukov + */ +public class METSMetadataExtractor extends AbstractMetadataFeaturesExtractor { + + private XMPMeta dmdMeta = null; + private XMPMeta rightsMeta = null; + private XMPMeta techMeta = null; + private XMPMeta sourceMeta = null; + private XMPMeta digiprovMeta = null; + + @Override + public List getMetadataFeatures(MetadataFeaturesData metadataFeaturesData) { + List result = new ArrayList<>(1); + try { + File outFile = getOutFile(result); + byte[] bytes = metadataFeaturesData.getStream(); + convertXMPToMETS(new ByteArrayInputStream(bytes), new FileOutputStream(outFile)); + FeatureTreeNode node = FeatureTreeNode.createRootNode("resultFile"); + node.setValue(outFile.getCanonicalPath()); + result.add(node); + } catch (XMPException | METSException | IOException | SAXException | FeatureParsingException | ParserConfigurationException e) { + try { + result.clear(); + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue(e.getMessage()); + result.add(node); + } catch (FeatureParsingException e1) { + throw new IllegalStateException(e1); + } + } + return result; + } + + private void convertXMPToMETS(InputStream toConvert, OutputStream out) throws XMPException, METSException, IOException, SAXException, ParserConfigurationException { + VeraPDFMeta meta = VeraPDFMeta.parse(toConvert); + divideMetas(meta); + METSWrapper metsWrapper = new METSWrapper(); + createMETS(metsWrapper); + //TODO: fix mets creation in such way that validating will not generate any exceptions +// metsWrapper.validate(); + metsWrapper.write(out); + } + + private void createMETS(METSWrapper metsWrapper) throws METSException, SAXException, ParserConfigurationException, XMPException, IOException { + METS mets = metsWrapper.getMETSObject(); + + if (this.dmdMeta != null) { + DmdSec dmd = mets.newDmdSec(); + dmd.setID("DMD_ID_1"); + MdWrap dmdWrap = dmd.newMdWrap(); + addXMPTreeToMdWrap(dmdWrap, this.dmdMeta); + dmd.setMdWrap(dmdWrap); + mets.addDmdSec(dmd); + } + + if (this.rightsMeta != null || this.techMeta != null || this.sourceMeta != null || this.digiprovMeta != null) { + AmdSec amd = mets.newAmdSec(); + + if (this.rightsMeta != null) { + RightsMD rightsMD = amd.newRightsMD(); + rightsMD.setID("RIGHTSMD_ID_1"); + MdWrap rightsWrap = rightsMD.newMdWrap(); + addXMPTreeToMdWrap(rightsWrap, this.rightsMeta); + rightsMD.setMdWrap(rightsWrap); + amd.addRightsMD(rightsMD); + } + + if (this.techMeta != null) { + TechMD techMD = amd.newTechMD(); + techMD.setID("TECHMD_ID_1"); + MdWrap techWrap = techMD.newMdWrap(); + addXMPTreeToMdWrap(techWrap, this.techMeta); + techMD.setMdWrap(techWrap); + amd.addTechMD(techMD); + } + + if (this.sourceMeta != null) { + SourceMD sourceMD = amd.newSourceMD(); + sourceMD.setID("SOURCEMD_ID_1"); + MdWrap sourceWrap = sourceMD.newMdWrap(); + addXMPTreeToMdWrap(sourceWrap, this.sourceMeta); + sourceMD.setMdWrap(sourceWrap); + amd.addSourceMD(sourceMD); + } + + if (this.digiprovMeta != null) { + DigiprovMD digiprovMD = amd.newDigiprovMD(); + digiprovMD.setID("DIGIPROVMD_ID_1"); + MdWrap digiprovWrap = digiprovMD.newMdWrap(); + addXMPTreeToMdWrap(digiprovWrap, this.digiprovMeta); + digiprovMD.setMdWrap(digiprovWrap); + amd.addDigiprovMD(digiprovMD); + } + + mets.addAmdSec(amd); + } + } + + private void addXMPTreeToMdWrap(MdWrap wrap, XMPMeta meta) throws XMPException, ParserConfigurationException, IOException, SAXException { + ByteArrayOutputStream bstream = new ByteArrayOutputStream(); + XMPMetaFactory.serialize(meta, bstream); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new ByteArrayInputStream(bstream.toByteArray())); + wrap.setXmlData(doc.getDocumentElement()); + wrap.setMDType("OTHER"); + wrap.setOtherMDType("XMP"); + } + + private void divideMetas(VeraPDFMeta meta) { + + List xmpProps = meta.getProperties(); + List properties; + + if (meta.getExtensionSchemasNode() != null) { + properties = new ArrayList<>(xmpProps.size() + 1); + properties.add(new String[]{XMPSchemaRegistryImpl.NS_PDFA_EXTENSION, "schemas"}); + } else { + properties = new ArrayList<>(xmpProps.size()); + } + + for (VeraPDFXMPNode node : xmpProps) { + properties.add(new String[]{node.getNamespaceURI(), node.getName()}); + } + + this.dmdMeta = meta.getCloneOfInitialMeta(); + this.rightsMeta = meta.getCloneOfInitialMeta(); + this.techMeta = meta.getCloneOfInitialMeta(); + this.sourceMeta = meta.getCloneOfInitialMeta(); + this.digiprovMeta = meta.getCloneOfInitialMeta(); + + boolean isDMDEmpty = true; + boolean isRightsEmpty = true; + boolean isTechEmpty = true; + boolean isSourceEmpty = true; + boolean isDIGIPROVEmpty = true; + + for (String[] el : properties) { + switch (METSTypeRegistry.getTypeForProperty(el[0], el[1])) { + case DMD_SEC: + isDMDEmpty = false; + rightsMeta.deleteProperty(el[0], el[1]); + techMeta.deleteProperty(el[0], el[1]); + sourceMeta.deleteProperty(el[0], el[1]); + digiprovMeta.deleteProperty(el[0], el[1]); + break; + case RIGHTS_MD: + isRightsEmpty = false; + dmdMeta.deleteProperty(el[0], el[1]); + techMeta.deleteProperty(el[0], el[1]); + sourceMeta.deleteProperty(el[0], el[1]); + digiprovMeta.deleteProperty(el[0], el[1]); + break; + case TECH_MD: + isTechEmpty = false; + dmdMeta.deleteProperty(el[0], el[1]); + rightsMeta.deleteProperty(el[0], el[1]); + sourceMeta.deleteProperty(el[0], el[1]); + digiprovMeta.deleteProperty(el[0], el[1]); + break; + case SOURCE_MD: + isSourceEmpty = false; + dmdMeta.deleteProperty(el[0], el[1]); + rightsMeta.deleteProperty(el[0], el[1]); + techMeta.deleteProperty(el[0], el[1]); + digiprovMeta.deleteProperty(el[0], el[1]); + break; + case DIGIPROV_MD: + isDIGIPROVEmpty = false; + dmdMeta.deleteProperty(el[0], el[1]); + rightsMeta.deleteProperty(el[0], el[1]); + techMeta.deleteProperty(el[0], el[1]); + sourceMeta.deleteProperty(el[0], el[1]); + break; + } + } + + if (isDMDEmpty) { + this.dmdMeta = null; + } + if (isRightsEmpty) { + this.rightsMeta = null; + } + if (isTechEmpty) { + this.techMeta = null; + } + if (isSourceEmpty) { + this.sourceMeta = null; + } + if (isDIGIPROVEmpty) { + this.digiprovMeta = null; + } + } + + private File getOutFile(List nodes) throws FeatureParsingException, IOException { + METSConfig config = getConfig(nodes); + if (config.getOutFolder() == null) { + File tempFolder = getTempFolder(); + File res = getOutFileInFolder(tempFolder); + return res; + } else { + File outFolder = new File(config.getOutFolder()); + if (outFolder.isDirectory()) { + File res = getOutFileInFolder(outFolder); + return res; + } else { + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue("Config file contains out folder path but it doesn't link a directory."); + nodes.add(node); + File tempFolder = getTempFolder(); + File res = getOutFileInFolder(tempFolder); + return res; + } + } + } + + private File getTempFolder() { + File tempDir = new File(System.getProperty("java.io.tmpdir")); + File tempFolder = new File(tempDir, "veraPDFMETSPluginTemp"); + if (!tempFolder.exists()) { + tempFolder.mkdir(); + } + return tempFolder; + } + + private File getOutFileInFolder(File folder) throws IOException { + return File.createTempFile("veraPDF_METS_Plugin_out", ".xml", folder); + } + + private METSConfig getConfig(List nodes) throws FeatureParsingException { + METSConfig config = METSConfig.defaultInstance(); + File conf = getConfigFile(); + if (conf.isFile() && conf.canRead()) { + try { + config = METSConfig.fromXml(new FileInputStream(conf)); + } catch (JAXBException | FileNotFoundException e) { + FeatureTreeNode node = FeatureTreeNode.createRootNode("error"); + node.setValue("Config file contains wrong syntax. Error message: " + e.getMessage()); + nodes.add(node); + } + } + return config; + } + + private File getConfigFile() { + return new File(getFolderPath().toFile(), "config.xml"); + } + + @Override + public String getID() { + return "63f0a295-587b-4e50-909c-4b47e02f64f7"; + } + + @Override + public String getDescription() { + return "This extractor generates METS file based on XMP package."; + } +} diff --git a/metsMetadata-plugin/src/main/java/org/verapdf/METSTypeRegistry.java b/metsMetadata-plugin/src/main/java/org/verapdf/METSTypeRegistry.java new file mode 100644 index 0000000..cfbe451 --- /dev/null +++ b/metsMetadata-plugin/src/main/java/org/verapdf/METSTypeRegistry.java @@ -0,0 +1,139 @@ +package org.verapdf; + +import com.adobe.xmp.impl.XMPSchemaRegistryImpl; + +/** + * @author Maksim Bezrukov + */ +public class METSTypeRegistry { + + public enum METSType { + DMD_SEC, + RIGHTS_MD, + TECH_MD, + SOURCE_MD, + DIGIPROV_MD + } + + public static METSType getTypeForProperty(String namespace, String name) { + + switch (namespace) { + case XMPSchemaRegistryImpl.NS_DC: + return getDCType(name); + case XMPSchemaRegistryImpl.NS_XMP: + return getXMPType(name); + case XMPSchemaRegistryImpl.TYPE_IDENTIFIERQUAL: + return METSType.TECH_MD; + case XMPSchemaRegistryImpl.NS_XMP_RIGHTS: + return METSType.RIGHTS_MD; + case XMPSchemaRegistryImpl.NS_XMP_MM: + return METSType.DIGIPROV_MD; + case XMPSchemaRegistryImpl.NS_XMP_BJ: + case XMPSchemaRegistryImpl.TYPE_PAGEDFILE: + case XMPSchemaRegistryImpl.NS_PHOTOSHOP: + case XMPSchemaRegistryImpl.NS_CAMERARAW: + case XMPSchemaRegistryImpl.NS_EXIF: + case XMPSchemaRegistryImpl.NS_EXIF_AUX: + return METSType.TECH_MD; + case XMPSchemaRegistryImpl.NS_DM: + return getDMType(name); + case XMPSchemaRegistryImpl.NS_PDF: + return getPDFType(name); + case XMPSchemaRegistryImpl.NS_TIFF: + return getTIFFType(name); + default: + return METSType.TECH_MD; + } + } + + private static METSType getDCType(String name) { + switch (name) { + case "description": + case "language": + case "relation": + case "source": + case "subject": + case "title": + case "type": + return METSType.DMD_SEC; + case "contributor": + case "creator": + case "publisher": + case "rights": + return METSType.RIGHTS_MD; + case "coverage": + case "format": + case "identifier": + return METSType.TECH_MD; + case "date": + return METSType.DIGIPROV_MD; + default: + return METSType.TECH_MD; + } + } + + private static METSType getXMPType(String name) { + switch (name) { + case "Nickname": + return METSType.DMD_SEC; + case "BaseURL": + case "Identifier": + case "Label": + case "Rating": + case "Thumbnails": + return METSType.TECH_MD; + case "CreatorTool": + return METSType.SOURCE_MD; + case "Advisory": + case "CreateDate": + case "MetadataDate": + case "ModifyDate": + return METSType.DIGIPROV_MD; + default: + return METSType.TECH_MD; + } + } + + private static METSType getDMType(String name) { + switch (name) { + case "copyright": + return METSType.RIGHTS_MD; + case "projectRef": + return METSType.SOURCE_MD; + case "videoModDate": + case "audioModDate": + case "metadataModDate": + return METSType.DIGIPROV_MD; + default: + return METSType.TECH_MD; + } + } + + private static METSType getPDFType(String name) { + switch (name) { + case "Keywords": + case "PDFVersion": + return METSType.TECH_MD; + case "Producer": + return METSType.SOURCE_MD; + default: + return METSType.TECH_MD; + } + } + + private static METSType getTIFFType(String name) { + switch (name) { + case "ImageDescription": + return METSType.DMD_SEC; + case "Artist": + case "Copyright": + return METSType.RIGHTS_MD; + case "Software": + return METSType.SOURCE_MD; + case "DateTime": + return METSType.DIGIPROV_MD; + default: + return METSType.TECH_MD; + } + } +} diff --git a/metsMetadata-plugin/src/main/resources/mets-api.jar b/metsMetadata-plugin/src/main/resources/mets-api.jar new file mode 100644 index 0000000..3efe6b4 Binary files /dev/null and b/metsMetadata-plugin/src/main/resources/mets-api.jar differ diff --git a/pom.xml b/pom.xml index 362d999..da94c37 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,8 @@ fontSample-plugin embeddedfileSample-plugin imageSample-plugin + metsMetadata-plugin + mediaconch