/* GNU GENERAL LICENSE Copyright (C) 2006 The Lobo Project. Copyright (C) 2014 - 2017 Lobo Evolution This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either verion 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General License for more details. You should have received a copy of the GNU General Public along with this program. If not, see <http://www.gnu.org/licenses/>. Contact info: lobochief@users.sourceforge.net; ivan.difrancesco@yahoo.it */ package org.lobobrowser.xpath.function; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.xpath.XPathFunction; import javax.xml.xpath.XPathFunctionResolver; /** * The Class XPathFunctionResolverImpl. * * @author richardallenbair */ public class XPathFunctionResolverImpl implements XPathFunctionResolver, NamespaceContext { /** The Constant NAMESPACE. */ private static final String NAMESPACE = "http://swinglabs.org/xpath/fn"; /** The functions. */ private static Map<Signature, XPathFunction> functions = new HashMap<Signature, XPathFunction>(); /** The namespaces. */ private static Map<String, String> namespaces = new HashMap<String, String>(); static { installFunction(new Abs()); installFunction(new EndsWith()); installFunction(new EscapeUri()); installFunction(new LowerCase()); installFunction(new Matches()); installFunction(new Replace()); installFunction(new UpperCase()); installFunction(new EqualsIgnoreCase()); } /* * (non-Javadoc) * @see * javax.xml.xpath.XPathFunctionResolver#resolveFunction(javax.xml.namespace * .QName, int) */ @Override public XPathFunction resolveFunction(QName functionName, int arity) { return functions.get(new Signature(functionName, arity)); } /** * Install function. * * @param function * the function */ public static void installFunction(AbstractFunction function) { functions.put(new Signature(new QName(NAMESPACE, function.getName()), function.getArity()), function); } /* * (non-Javadoc) * @see * javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String) */ @Override public String getNamespaceURI(String prefix) { if (prefix == null) { throw new NullPointerException("Null prefix"); } else if ("fn".equals(prefix)) { return NAMESPACE; } else if ("xml".equals(prefix)) { return XMLConstants.XML_NS_URI; } prefix = prefix.intern(); if (namespaces.containsKey(prefix)) { return namespaces.get(prefix); } return XMLConstants.NULL_NS_URI; } // This method isn't necessary for XPath processing. /* * (non-Javadoc) * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String) */ @Override public String getPrefix(String uri) { throw new UnsupportedOperationException(); } // This method isn't necessary for XPath processing either. /* * (non-Javadoc) * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String) */ @Override public Iterator getPrefixes(String uri) { throw new UnsupportedOperationException(); } /** * Adds the namespace mapping. * * @param namespacePrefix * the namespace prefix * @param namespace * the namespace */ public void addNamespaceMapping(String namespacePrefix, String namespace) { namespaces.put(namespacePrefix.intern(), namespace.intern()); } /** * Removes the namespace mapping. * * @param namespacePrefix * the namespace prefix */ public void removeNamespaceMapping(String namespacePrefix) { namespaces.remove(namespacePrefix.intern()); } /** * The Class Signature. */ private static final class Signature { /** The function name. */ private QName functionName; /** The arity. */ private int arity; /** * Instantiates a new signature. * * @param functionName * the function name * @param arity * the arity */ public Signature(QName functionName, int arity) { this.functionName = functionName; this.arity = arity; } /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object o) { if (o instanceof Signature) { Signature s = (Signature) o; return (s.arity == arity) && s.functionName.equals(functionName); } return false; } /* * (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return functionName.hashCode() + arity; } } }