
org.eclipse.persistence.oxm.NamespaceResolver Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.oxm;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import org.eclipse.persistence.internal.descriptors.Namespace;
import org.eclipse.persistence.platform.xml.XMLNamespaceResolver;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* It is common for an XML document to include one or more namespaces.
* TopLink supports this using its NamespaceResolver. The namespace resolver maintains
* pairs of namespace prefixes and URIs. TopLink uses these prefixes in conjunction with the
* XPath statements you specify on EIS mappings to XML records and XML mappings.
*
*
Although TopLink captures namespace prefixes in the XPath statements for mappings (if applicable),
* the input document is not required to use the same namespace prefixes. TopLink will use the namespace
* prefixes specified in the mapping when creating new documents.
*
*
Code Sample
*
* NamespaceResolver resolver = new NamespaceResolver();
* resolver.put( "ns", "urn:namespace-example");
*
* XMLDescriptor descriptor = new XMLDescriptor();
* descriptor.setJavaClass(Customer.class);
* descriptor.setDefaultRootElement("ns:customer");
* descriptor.setNamespaceResolver(resolver);
*
* XMLDirectMapping mapping = new XMLDirectMapping();
* mapping.setAttributeName("id");
* mapping.setXPath("ns:id/text()");
* descriptor.addMapping(mapping);
*
*
* @see org.eclipse.persistence.oxm.XMLDescriptor
* @see org.eclipse.persistence.eis.EISDescriptor
*
*/
public class NamespaceResolver implements XMLNamespaceResolver {
private static final String BASE_PREFIX = "ns";
private String defaultNamespaceURI;
private Map prefixesToNamespaces;
int prefixCounter;
private Node dom;
/**
* Default constructor, creates a new NamespaceResolver.
*/
public NamespaceResolver() {
super();
}
public Map getPrefixesToNamespaces() {
if(null == prefixesToNamespaces) {
prefixesToNamespaces = new HashMap();
}
return prefixesToNamespaces;
}
public boolean hasPrefixesToNamespaces() {
return null != prefixesToNamespaces;
}
public void setDOM(Node dom) {
this.dom = dom;
}
/**
* Returns the namespace URI associated with a specified namespace prefix
*
* @param prefix The prefix to lookup a namespace URI for
* @return The namespace URI associated with the specified prefix
*/
public String resolveNamespacePrefix(String prefix) {
if (null == prefix || prefix.length() == 0) {
return defaultNamespaceURI;
}
String uri = null;
if(null != prefixesToNamespaces) {
uri = prefixesToNamespaces.get(prefix);
}
if(null != uri) {
return uri;
} else if (XMLConstants.XML_NAMESPACE_PREFIX.equals(prefix)) {
return XMLConstants.XML_NAMESPACE_URL;
} else if (XMLConstants.XMLNS.equals(prefix)) {
return XMLConstants.XMLNS_URL;
}
if(dom != null) {
return XMLPlatformFactory.getInstance().getXMLPlatform().resolveNamespacePrefix(dom, prefix);
}
return null;
}
/**
* Return the namespace prefix associated with a namespace URI.
* @param uri A namespace URI.
* @return The prefix associated with the namespace URI.
*/
public String resolveNamespaceURI(String uri) {
if(null == uri) {
return null;
}
if(null != prefixesToNamespaces) {
for(Entry entry : prefixesToNamespaces.entrySet()) {
if(uri.equals(entry.getValue())) {
return entry.getKey();
}
}
}
if (uri.equalsIgnoreCase(XMLConstants.XMLNS_URL)) {
return XMLConstants.XMLNS;
} else if (uri.equalsIgnoreCase(XMLConstants.XML_NAMESPACE_URL)) {
return XMLConstants.XML_NAMESPACE_PREFIX;
}
return resolveNamespaceURI(dom, uri);
}
private String resolveNamespaceURI(Node node, String uri) {
if(null == node) {
return null;
}
// If the element is of the same namespace URI, then return the prefix.
if(uri.equals(node.getNamespaceURI())) {
return node.getPrefix();
}
// Check the namespace URI declarations.
NamedNodeMap namedNodeMap = node.getAttributes();
if(null != namedNodeMap) {
int namedNodeMapSize = namedNodeMap.getLength();
for(int x=0; x entry: prefixesToNamespaces.entrySet()) {
Namespace namespace = new Namespace(entry.getKey(), entry.getValue());
names.addElement(namespace);
}
return names;
}
/**
* INTERNAL:
* Set the namespaces on the namespace resolver based on the specified Vector of Namespace objects
* Used for deployment XML
* @param names A Vector of namespace URIs
*/
public void setNamespaces(Vector names) {
prefixesToNamespaces = new HashMap(names.size());
for(Namespace namespace : (Vector) names) {
if ((namespace.getPrefix() != null) && (namespace.getNamespaceURI() != null)) {
prefixesToNamespaces.put(namespace.getPrefix(), namespace.getNamespaceURI());
}
}
}
public String generatePrefix() {
return generatePrefix(getNextPrefix());
}
private String getNextPrefix() {
return BASE_PREFIX + prefixCounter++;
}
public String generatePrefix(String defaultPrefix) {
String lookup = resolveNamespacePrefix(defaultPrefix);
while (lookup != null) {
defaultPrefix = getNextPrefix();
lookup = resolveNamespacePrefix(defaultPrefix);
}
return defaultPrefix;
}
public void removeNamespace(String prefix) {
if(null != prefixesToNamespaces) {
prefixesToNamespaces.remove(prefix);
}
}
public void setDefaultNamespaceURI(String namespaceUri) {
if(namespaceUri == null){
defaultNamespaceURI = namespaceUri;
}else{
defaultNamespaceURI = namespaceUri.intern();
}
}
public String getDefaultNamespaceURI() {
return defaultNamespaceURI;
}
private static class IteratorEnumeration implements Enumeration {
private Iterator iterator;
public IteratorEnumeration(Iterator iterator) {
this.iterator = iterator;
}
public boolean hasMoreElements() {
if(null == iterator) {
return false;
}
return iterator.hasNext();
}
public Object nextElement() {
return iterator.next();
}
}
}