
com.day.cq.dam.commons.metadata.XmpToJcrMetadataBuilder Maven / Gradle / Ivy
/*
* Copyright 1997-2008 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.dam.commons.metadata;
import com.adobe.xmp.XMPMeta;
import com.adobe.xmp.XMPIterator;
import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPMetaFactory;
import com.adobe.xmp.XMPDateTime;
import com.adobe.xmp.XMPDateTimeFactory;
import com.adobe.xmp.properties.XMPPropertyInfo;
import com.day.cq.dam.api.metadata.ExtractedMetadata;
import com.day.cq.dam.api.metadata.xmp.XmpMappings;
import com.day.cq.dam.commons.util.DateParser;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.NamespaceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.util.Text;
import java.util.Set;
import java.util.Calendar;
import java.util.Date;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* The XmpToJcrMetadataBuilder
class ...
* not in use
*/
public class XmpToJcrMetadataBuilder {
/**
* the default logger
*/
private static final Logger log = LoggerFactory.getLogger(XmpToJcrMetadataBuilder.class);
public static final String VALUE_NODE_NAME = "value";
public static final String PN_NAMESPACE = "namespace";
public static final String PN_VALUE = "value";
public static final String NT_XMP_PROPERTY = "xmp:Property";
public static final String NT_XMP_STRUCT = "xmp:Struct";
public static final String NT_XMP_SIMPLE = "xmp:Simple";
public static final String NT_RDF_BAG = "rdf:Bag";
public static final String NT_RDF_SEQ = "rdf:Seq";
public static final String NT_RDF_ALT = "rdf:Alt";
public void storeXmp(Node metadataRoot, XMPMeta meta) throws XMPException, RepositoryException {
XMPIterator itr = meta.iterator();
String rootPath = metadataRoot.getPath();
String parent = null;
while (itr.hasNext()) {
XMPPropertyInfo prop = (XMPPropertyInfo) itr.next();
if (!prop.getOptions().isSchemaNode()) {
parent = (parent != null && prop.getPath().startsWith(parent) ? parent : null);
if (prop.getOptions().isQualifier() || prop.getOptions().isSimple()) {
String p = rootPath + getPath(prop, parent);
// check namespace TODO: correct here?
checkNamespace(prop, metadataRoot);
Node node = getOrCreateNode(metadataRoot.getSession(), p, NT_XMP_PROPERTY);
node.setProperty(PN_NAMESPACE, prop.getNamespace());
log.debug("PATH: " + node.getPath() + " (" + NT_XMP_PROPERTY + ") namespace:" + prop.getNamespace() );
p = p + "/" + VALUE_NODE_NAME;
Node vnode = getOrCreateNode(metadataRoot.getSession(), p, NT_XMP_SIMPLE);
setProperty(vnode, prop);
log.debug("PATH: " + vnode.getPath() + " (" + NT_XMP_SIMPLE + ") value:" + prop.getValue());
} else if (prop.getOptions().isArray()) {
parent = prop.getPath();
checkNamespace(prop, metadataRoot);
String p = rootPath + "/" + prop.getPath();
Node node = getOrCreateNode(metadataRoot.getSession(), p, NT_XMP_PROPERTY);
log.debug("PATH: " + node.getPath() + " (" + NT_XMP_PROPERTY + ")");
String name = NT_RDF_BAG;
if (prop.getOptions().isArrayOrdered()) {
name = NT_RDF_SEQ;
} else if (prop.getOptions().isArrayAlternate()) {
name = NT_RDF_ALT;
}
p = rootPath + "/" + prop.getPath() + "/" + VALUE_NODE_NAME;
Node anode = getOrCreateNode(metadataRoot.getSession(), p, name);
log.debug("PATH: " + anode.getPath() + name);
} else if (prop.getOptions().isStruct()) {
parent = prop.getPath();
checkNamespace(prop, metadataRoot);
String p = rootPath + "/" + prop.getPath();
Node node = getOrCreateNode(metadataRoot.getSession(), p, NT_XMP_PROPERTY);
log.debug("PATH: " + node.getPath() + " (" + NT_XMP_PROPERTY + ")");
p = rootPath + "/" + prop.getPath() + "/" + VALUE_NODE_NAME;
Node snode = getOrCreateNode(metadataRoot.getSession(), p, NT_XMP_STRUCT);
log.debug("PATH: " + snode.getPath() + " (" + NT_XMP_STRUCT + ")");
}
}
}
metadataRoot.getSession().save();
}
public XMPMeta getXmpFromJcr(Node metadataRoot) throws RepositoryException, XMPException {
XMPMeta meta = XMPMetaFactory.create();
NodeIterator itr = metadataRoot.getNodes();
while (itr.hasNext()) {
Node n = itr.nextNode();
if (n.isNodeType(NT_XMP_PROPERTY)) {
Node value = n.getNode(VALUE_NODE_NAME);
String namespace;
if (n.hasProperty(PN_NAMESPACE)) {
namespace = n.getProperty(PN_NAMESPACE).getString();
} else {
// try to get namespace...
String nsPrefix = n.getName().substring(0, n.getName().indexOf(":"));
namespace = XMPMetaFactory.getSchemaRegistry().getNamespaceURI(nsPrefix);
}
Object val = getValue(value);
try {
String key = n.getName();
String nsPrefix = key.substring(0, key.indexOf(":"));
if (XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(namespace) == null) {
// register ns
XMPMetaFactory.getSchemaRegistry().registerNamespace(namespace, nsPrefix);
}
meta.setProperty(namespace, key, val);
} catch (XMPException xmpe) {
log.warn("Cannot set xmp property: " + xmpe.getMessage());
}
// todo qualifier
}
}
return meta;
}
public void storeAsXmp(ExtractedMetadata metadata, Node metadataRoot) throws XMPException, RepositoryException {
XMPMeta meta = XMPMetaFactory.create();
Set keys = metadata.getMetaDataProperties().keySet();
for (String key: keys) {
if (XmpMappings.defaultSimpleXmpMappings.containsKey(key)) {
String xmpKeys[] = getXmpKeys(XmpMappings.defaultSimpleXmpMappings.get(key));
for (String xmpKey: xmpKeys) {
try {
setXmpProperty(meta, xmpKey, metadata.getMetaDataProperties().get(key));
} catch (XMPException e) {
log.debug("Cannot create xmp property: " + e.getMessage());
}
}
} else if (XmpMappings.defaultBagXmpMappings.containsKey(key)) {
} else if (XmpMappings.defaultSeqXmpMappings.containsKey(key)) {
} else {
// fallback
// use dam namespace
if (key.indexOf(":") < 0) {
// no namespace at all
XMPMetaFactory.getSchemaRegistry().registerNamespace("http://www.day.com/dam/1.0", "dam");
try {
meta.setProperty("http://www.day.com/dam/1.0", "dam:" + key.replace(" ", "").trim(), metadata.getMetaDataProperties().get(key));
} catch (XMPException e) {
log.warn("Cannot set xmp property:" + e.getMessage());
}
} else {
try {
// already prefixed key
// check if namespace exists
String nsPrefix = key.substring(0, key.indexOf(":"));
String nsUri = metadataRoot.getSession().getNamespaceURI(nsPrefix); // TODO: better taken from ws
if (XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(nsUri) == null) {
// register ns
XMPMetaFactory.getSchemaRegistry().registerNamespace(nsUri, nsPrefix);
}
setXmpProperty(meta, key, metadata.getMetaDataProperties().get(key));
} catch (XMPException e) {
log.debug("Cannot create xmp property: " + e.getMessage());
}
}
}
}
storeXmp(metadataRoot, meta);
}
private void setXmpProperty(XMPMeta meta, String xmpKey, Object value) throws XMPException {
if (value instanceof Boolean) {
meta.setPropertyBoolean(getNamespace(xmpKey), xmpKey, (Boolean) value);
} else if (value instanceof Calendar) {
meta.setPropertyCalendar(getNamespace(xmpKey), xmpKey, (Calendar) value);
} else if (value instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) value);
meta.setPropertyDate(getNamespace(xmpKey), xmpKey, XMPDateTimeFactory.createFromCalendar(cal));
} else if (value instanceof Double) {
meta.setPropertyDouble(getNamespace(xmpKey), xmpKey, (Double) value);
} else if (value instanceof Integer) {
meta.setPropertyInteger(getNamespace(xmpKey), xmpKey, (Integer) value);
} else if (value instanceof Long) {
meta.setPropertyLong(getNamespace(xmpKey), xmpKey, (Long) value);
} else {
meta.setProperty(getNamespace(xmpKey), xmpKey, value);
}
}
private String[] getXmpKeys(String keyString) {
if (keyString.indexOf(",") > 0) {
return keyString.split(",");
} else {
return new String[] {keyString};
}
}
private String getNamespace(String xmpKey) {
if (xmpKey.indexOf(":") > 0) {
String nsPrefix = xmpKey.substring(0, xmpKey.indexOf(":"));
return XMPMetaFactory.getSchemaRegistry().getNamespaceURI(nsPrefix);
}
return null;
}
private Node getOrCreateNode(Session session, String path, String nodetype) throws RepositoryException {
if (session.itemExists(path)) {
return (Node) session.getItem(path);
} else {
return session.getRootNode().addNode(path.substring(1), nodetype);
}
}
private static String getPath(XMPPropertyInfo prop, String parent) {
if (parent != null) {
String postPath = prop.getPath().substring(parent.length());
postPath = (postPath.startsWith("/")) ? postPath.substring(1) : postPath;
if (postPath.indexOf(":") > 0) {
String name[] = postPath.split(":");
if (XMPMetaFactory.getSchemaRegistry().getNamespaceURI(name[0]) != null &&
XMPMetaFactory.getSchemaRegistry().getNamespaceURI(name[0]).equals(prop.getNamespace())) {
postPath = name[0] + ":" + Text.escapeIllegalJcrChars(name[1]);
} else {
postPath = Text.escapeIllegalJcrChars(postPath);
}
} else {
postPath = Text.escapeIllegalJcrChars(postPath);
}
String path = parent + "/" + VALUE_NODE_NAME + (postPath.startsWith("/") ? "" : "/") + postPath;
return path.startsWith("/") ? path : "/" + path;
} else {
return "/" + prop.getPath();
}
}
private void setProperty(Node node, XMPPropertyInfo prop) {
try {
Object val = prop.getOriValue();
if (node.hasProperty(PN_VALUE)) {
// existing string values that have to be converted into the correct type
int type = node.getProperty(PN_VALUE).getType();
switch (type) {
case PropertyType.DATE:
Object v = checkForDate(val);
if (v instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date)v);
node.setProperty(PN_VALUE, cal);
}
break;
case PropertyType.BOOLEAN:
node.setProperty(PN_VALUE, Boolean.valueOf((String) val));
break;
case PropertyType.DOUBLE:
node.setProperty(PN_VALUE, Double.valueOf((String) val));
break;
case PropertyType.LONG:
node.setProperty(PN_VALUE, Long.valueOf((String) val));
break;
default:
node.setProperty(PN_VALUE, (String) val);
}
} else {
// new value
val = checkForDate(val);
if (val instanceof Boolean) {
node.setProperty(PN_VALUE, (Boolean) val);
} else if (val instanceof Integer) {
node.setProperty(PN_VALUE, (Integer) val);
} else if (val instanceof Long) {
node.setProperty(PN_VALUE, (Long) val);
} else if (val instanceof Double) {
node.setProperty(PN_VALUE, (Double) val);
} else if (val instanceof XMPDateTime) {
node.setProperty(PN_VALUE, ((XMPDateTime) val).getCalendar());
} else if (val instanceof byte[]) {
node.setProperty(PN_VALUE,
node.getSession().getValueFactory().createBinary(new ByteArrayInputStream((byte[]) val)));
} else if (val instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) val);
node.setProperty(PN_VALUE, cal);
}else {
node.setProperty(PN_VALUE, (String) prop.getValue());
}
}
} catch (Throwable re) {
log.warn("Cannot set xmp property (" + prop.getPath() + "): " + re.getMessage());
}
}
private Object checkForDate(Object val) {
if (val instanceof String) {
Date date = DateParser.parseDate((String) val);
return (date == null) ? val : date;
} else {
return val;
}
}
private Object getValue(Node value) {
Object val = null;
try {
Property prop = value.getProperty(PN_VALUE);
switch (prop.getType()) {
case PropertyType.BINARY:
val = IOUtils.toByteArray(prop.getBinary().getStream());
break;
case PropertyType.DATE:
val = XMPDateTimeFactory.createFromCalendar(prop.getDate());
break;
case PropertyType.BOOLEAN:
val = prop.getBoolean();
break;
case PropertyType.DOUBLE:
val = prop.getDouble();
break;
case PropertyType.LONG:
val = prop.getLong();
break;
default:
val = prop.getString();
}
} catch (RepositoryException re) {
log.warn("Problem while getting xmp value from jcr property: "
+ re.getMessage());
} catch (IOException ioe) {
log.warn("Problem while getting binary xmp value from jcr property: "
+ ioe.getMessage());
}
return val;
}
private void checkNamespace(XMPPropertyInfo prop, Node metadataRoot) throws RepositoryException {
try {
String prefix = metadataRoot.getSession().getWorkspace().getNamespaceRegistry().getPrefix(prop.getNamespace());
} catch (NamespaceException e) {
String prefix = XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(prop.getNamespace());
prefix = prefix.substring(0, prefix.indexOf(":"));
try {
metadataRoot.getSession().getWorkspace().getNamespaceRegistry().registerNamespace(prefix, prop.getNamespace());
} catch (RepositoryException re) {}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy