blob: 29a84f7c1ab977beafdd0687edbbd344d30a44ea [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/* CVS Header
$Id$
$Log$
*/
package org.apache.axis2.xmlbeans;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
public class XSDConfig {
private static final String XMLBEANS_NS = "http://xml.apache.org/xmlbeans/2004/02/xbean/config";
private static final String XMLBEANS_QNAME_NODE = "qname";
private static final String XMLBEANS_NS_NODE = "namespace";
/** The parsed xsdconfig file */
private Document xsdConfigDoc = null;
/** The list of prefixes on the document root */
private HashMap prefixesToURIMappings = null;
/** The list of schema tyes to Java class names */
private HashMap qnamesToJavaNamesMappings = null;
/** The list of namespaces to Java package names */
private HashMap nsToJavaPackagesMap = null;
/** Indicates whether we have any QName to Java class name mappings */
public boolean hasQNameToJavaNameMappings = false;
/** Indicates whether we have any namespace to Java package mappings */
public boolean hasNamespaceToJavaPackageMappings = false;
public XSDConfig(String xsdConfigFile) {
try {
DocumentBuilder builder = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(false);
builder = factory.newDocumentBuilder();
builder.setErrorHandler(new ParseErrorHandler());
xsdConfigDoc = builder.parse(new File(xsdConfigFile));
// Create a mapping for all the namespaces in the document
prefixesToURIMappings = new HashMap();
NamedNodeMap attributes = xsdConfigDoc.getDocumentElement().getAttributes();
for (int c = 0; c < attributes.getLength(); c++) {
/* Do we have a namespace declaration?
* xmlns:mv="urn:weegietech:minerva"
*/
if (attributes.item(c).getNodeName().indexOf("xmlns:") != -1) {
String[] parts = attributes.item(c).getNodeName().split(":");
// Add the prefix to uri mapping to our list
prefixesToURIMappings.put(parts[1], attributes.item(c).getNodeValue());
}
}
// Load up the list of QName to Java class name mappings
qnamesToJavaNamesMappings = getQNamesToJavaNames();
if (qnamesToJavaNamesMappings.size() > 0)
hasQNameToJavaNameMappings = true;
// Load up the list of namespaces to Java packages mappings
nsToJavaPackagesMap = getNamespacesToPackages();
if (nsToJavaPackagesMap.size() > 0)
hasNamespaceToJavaPackageMappings = true;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
} catch (SAXException se) {
throw new RuntimeException(se);
} catch (IllegalArgumentException iae) {
throw new RuntimeException(iae);
} catch (ParserConfigurationException pce) {
throw new RuntimeException(pce);
}
}
/**
* Returns the pre loaded schema types to Java class names mappings.
*
* @return HashMap of schema types to Java class names mappings as as specified in the xsdconfig
* file.
*/
public HashMap getSchemaTypesToJavaNames() {
return qnamesToJavaNamesMappings;
}
/**
* Returns the pre loaded namespace to Java package mappings.
*
* @return HashMap of namespace to Java package mappings as as specified in the xsdconfig file.
*/
public HashMap getNamespacesToJavaPackages() {
return nsToJavaPackagesMap;
}
/**
* Loads the schema types to Java class name mappings
*
* @return HashMap containing the schema types to Java class name mappings as specified in the
* xsdconfig file. If there are no mappings, the returned HashMap will be empty.
*/
private HashMap getQNamesToJavaNames() {
HashMap qnamesToJavaNamesMap = new HashMap();
/* Look for all the <xb:qname ... /> nodes as these specify
* xml schema types to Java class mappings.
* <xb:qname name="mv:moduleType" javaname="Module"/>
*/
NodeList qnameNodes = xsdConfigDoc.getElementsByTagNameNS(XMLBEANS_NS, XMLBEANS_QNAME_NODE);
for (int c = 0; c < qnameNodes.getLength(); c++) {
Node qnameNode = qnameNodes.item(c);
/* In the xsdconfig file we'll get schema types with a prefix and not a uri.
* <xb:qname name="mv:moduleType" javaname="Module"/>
* but XMLBeans will call BindingConfig::lookupJavanameForQName with a QName
* which has a namespace uri and no prefix.
* So we'll store the fully qualifed schema type name in the mapping list.
* i.e. we pick it up from the xsdconfig file as:
* mv:moduleType
* but we'll store it as urn:weegietech:minerva:moduleType
*/
String schemaType = qnameNode.getAttributes().getNamedItem("name").getNodeValue();
if (schemaType.indexOf(":") != -1) {
// mv:moduleType
String prefix = schemaType.split(":")[0];
String localName = schemaType.split(":")[1];
if (prefixesToURIMappings.containsKey(prefix)) {
// Store as urn:weegietech:minerva:moduleType
String key = (String)prefixesToURIMappings.get(prefix) + ":" + localName;
// Direct mapping now from schema types to Java class names
qnamesToJavaNamesMap.put(key, qnameNode.getAttributes()
.getNamedItem("javaname").getNodeValue());
}
}
}
return qnamesToJavaNamesMap;
}
/**
* Loads the namespace to Java package mappings
*
* @return HashMap containing the namespace to Java package mappings as specified in the
* xsdconfig file. If there are no mappings, the returned HashMap will be empty.
*/
private HashMap getNamespacesToPackages() {
HashMap nsToJavaPackagesMap = new HashMap();
/* Look for all the <xb:namespace ... /> nodes as these specify
* xml namespace to Java package mappings.
* <xb:qname name="mv:moduleType" javaname="Module"/>
*/
NodeList nsNodes = xsdConfigDoc.getElementsByTagNameNS(XMLBEANS_NS, XMLBEANS_NS_NODE);
for (int nsNodesCount = 0; nsNodesCount < nsNodes.getLength(); nsNodesCount++) {
Node nsNode = nsNodes.item(nsNodesCount);
// What's the current namespace?
String uri = nsNode.getAttributes().getNamedItem("uri").getNodeValue();
// Get the package name for the current namespace uri
String packageName = null;
NodeList childNodes = nsNode.getChildNodes();
for (int childNodesCount = 0; childNodesCount < childNodes.getLength();
childNodesCount++) {
Node childNode = childNodes.item(childNodesCount);
if (childNode.getLocalName() != null) {
if (childNode.getLocalName().equals("package")) {
packageName = childNode.getFirstChild().getNodeValue();
}
}
}
// Store the namespace uri to Java package mapping
if (packageName != null) {
nsToJavaPackagesMap.put(uri, packageName);
}
}
return nsToJavaPackagesMap;
}
class ParseErrorHandler implements ErrorHandler {
public void error(SAXParseException exception) throws SAXException {
throw new SAXException(exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
throw new SAXException(exception);
}
public void warning(SAXParseException exception) throws SAXException {
throw new SAXException(exception);
}
}
}