/* * ------------------------------------------------------------------------- * Copyright 2014 * Centre for Information Modeling - Austrian Centre for Digital Humanities * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License * ------------------------------------------------------------------------- */ package org.emile.cirilo.ecm.utils; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactoryConfigurationException; import javax.xml.xpath.XPathFactory; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import java.util.Map; import java.util.HashMap; import java.util.Iterator; import java.util.Collections; import org.apache.log4j.Logger; /** * Utilities for performing Xpath operations in the ECM context. Already defines * all the relevant namespaces, so proper shorthands can be used. */ public class XpathUtils { private static Logger log = Logger.getLogger(XpathUtils.class); private static final String[][] NAMESPACE_TABLE = {{XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI}, {XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI}, {XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI}, {"rdf", Constants.NAMESPACE_RDF}, {"rdfs", Constants.NAMESPACE_RDFS}, {"owl", Constants.NAMESPACE_OWL}, {"xsi", Constants.NAMESPACE_XML_SCHEMA_INSTANCE}, {"dc", Constants.NAMESPACE_DC}, {"dcterms", Constants.NAMESPACE_DCTERMS}, {"oai", Constants.NAMESPACE_OAI}, {"oai_dc", Constants.NAMESPACE_OAIDC}, {"view", Constants.NAMESPACE_VIEW}, {"fedora-model", Constants.NAMESPACE_FEDORA_MODEL}, {"foxml", Constants.NAMESPACE_FOXML}, {"ds", Constants.NAMESPACE_DS_COMPOSITE}, {"doms", Constants.NAMESPACE_RELATIONS},//TODO, this should be deprecated {"ecm", Constants.NAMESPACE_RELATIONS},//To shorthands for same namespace {"schema", Constants.NAMESPACE_SCHEMA}, {"dobundle", Constants.NAMESPACE_DIGITAL_OBJECT_BUNDLE} }; private static final NamespaceContext ECM_NAMESPACE_CONTEXT = new NamespaceContext() { Map<String, String> nsPrefixMap = new HashMap<String, String>(NAMESPACE_TABLE.length); Map<String, String> inverseNsPrefixMap = new HashMap<String, String>(NAMESPACE_TABLE.length); { for (String[] pair : NAMESPACE_TABLE) { nsPrefixMap.put(pair[0], pair[1]); inverseNsPrefixMap.put(pair[0], pair[1]); } } public String getNamespaceURI(String prefix) { if (prefix == null) { throw new IllegalArgumentException("Prefix is null"); } String uri = nsPrefixMap.get(prefix); if (uri != null) { return uri; } else { return XMLConstants.NULL_NS_URI; } } public String getPrefix(String namespaceURI) { if (namespaceURI == null) { throw new IllegalArgumentException( "namespaceURI is null"); } return inverseNsPrefixMap.get(namespaceURI); } public Iterator getPrefixes(String namespaceURI) { if (namespaceURI == null) { throw new IllegalArgumentException( "namespaceURI is null"); } String prefix = getPrefix(namespaceURI); if (prefix == null) { return Collections.emptyList().iterator(); } else { return Collections.singletonList(prefix) .iterator(); } } }; /** * Helper method for doing an XPath query using ECM namespaces. * * @param node The node to start XPath query on. * @param xpathExpression The XPath expression, using default DOMS * namespace prefixes. * @return The result, as a node list. * * @throws XPathExpressionException On trouble parsing or evaluating the * expression. */ public static NodeList xpathQuery(Node node, String xpathExpression) throws XPathExpressionException, XPathFactoryConfigurationException{ XPath xPath = XPathFactory.newInstance( XPathFactory.DEFAULT_OBJECT_MODEL_URI, "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", ClassLoader.getSystemClassLoader()).newXPath(); xPath.setNamespaceContext(ECM_NAMESPACE_CONTEXT); return (NodeList) xPath .evaluate(xpathExpression, node, XPathConstants.NODESET); } }