001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: /* CVS Header
021: $Id$
022: $Log$
023: */
024:
025: package org.apache.axis2.xmlbeans;
026:
027: import org.w3c.dom.Document;
028: import org.w3c.dom.NamedNodeMap;
029: import org.w3c.dom.Node;
030: import org.w3c.dom.NodeList;
031: import org.xml.sax.ErrorHandler;
032: import org.xml.sax.SAXException;
033: import org.xml.sax.SAXParseException;
034:
035: import javax.xml.parsers.DocumentBuilder;
036: import javax.xml.parsers.DocumentBuilderFactory;
037: import javax.xml.parsers.ParserConfigurationException;
038: import java.io.File;
039: import java.io.IOException;
040: import java.util.HashMap;
041:
042: public class XSDConfig {
043: private static final String XMLBEANS_NS = "http://xml.apache.org/xmlbeans/2004/02/xbean/config";
044: private static final String XMLBEANS_QNAME_NODE = "qname";
045: private static final String XMLBEANS_NS_NODE = "namespace";
046:
047: /** The parsed xsdconfig file */
048: private Document xsdConfigDoc = null;
049: /** The list of prefixes on the document root */
050: private HashMap prefixesToURIMappings = null;
051: /** The list of schema tyes to Java class names */
052: private HashMap qnamesToJavaNamesMappings = null;
053: /** The list of namespaces to Java package names */
054: private HashMap nsToJavaPackagesMap = null;
055: /** Indicates whether we have any QName to Java class name mappings */
056: public boolean hasQNameToJavaNameMappings = false;
057: /** Indicates whether we have any namespace to Java package mappings */
058: public boolean hasNamespaceToJavaPackageMappings = false;
059:
060: public XSDConfig(String xsdConfigFile) {
061: try {
062: DocumentBuilder builder = null;
063: DocumentBuilderFactory factory = DocumentBuilderFactory
064: .newInstance();
065:
066: factory.setNamespaceAware(true);
067: factory.setValidating(false);
068:
069: builder = factory.newDocumentBuilder();
070: builder.setErrorHandler(new ParseErrorHandler());
071:
072: xsdConfigDoc = builder.parse(new File(xsdConfigFile));
073:
074: // Create a mapping for all the namespaces in the document
075: prefixesToURIMappings = new HashMap();
076: NamedNodeMap attributes = xsdConfigDoc.getDocumentElement()
077: .getAttributes();
078: for (int c = 0; c < attributes.getLength(); c++) {
079: /* Do we have a namespace declaration?
080: * xmlns:mv="urn:weegietech:minerva"
081: */
082: if (attributes.item(c).getNodeName().indexOf("xmlns:") != -1) {
083: String[] parts = attributes.item(c).getNodeName()
084: .split(":");
085:
086: // Add the prefix to uri mapping to our list
087: prefixesToURIMappings.put(parts[1], attributes
088: .item(c).getNodeValue());
089: }
090: }
091:
092: // Load up the list of QName to Java class name mappings
093: qnamesToJavaNamesMappings = getQNamesToJavaNames();
094: if (qnamesToJavaNamesMappings.size() > 0)
095: hasQNameToJavaNameMappings = true;
096:
097: // Load up the list of namespaces to Java packages mappings
098: nsToJavaPackagesMap = getNamespacesToPackages();
099: if (nsToJavaPackagesMap.size() > 0)
100: hasNamespaceToJavaPackageMappings = true;
101: } catch (IOException ioe) {
102: throw new RuntimeException(ioe);
103: } catch (SAXException se) {
104: throw new RuntimeException(se);
105: } catch (IllegalArgumentException iae) {
106: throw new RuntimeException(iae);
107: } catch (ParserConfigurationException pce) {
108: throw new RuntimeException(pce);
109: }
110: }
111:
112: /**
113: * Returns the pre loaded schema types to Java class names mappings.
114: *
115: * @return HashMap of schema types to Java class names mappings as as specified in the xsdconfig
116: * file.
117: */
118: public HashMap getSchemaTypesToJavaNames() {
119: return qnamesToJavaNamesMappings;
120: }
121:
122: /**
123: * Returns the pre loaded namespace to Java package mappings.
124: *
125: * @return HashMap of namespace to Java package mappings as as specified in the xsdconfig file.
126: */
127: public HashMap getNamespacesToJavaPackages() {
128: return nsToJavaPackagesMap;
129: }
130:
131: /**
132: * Loads the schema types to Java class name mappings
133: *
134: * @return HashMap containing the schema types to Java class name mappings as specified in the
135: * xsdconfig file. If there are no mappings, the returned HashMap will be empty.
136: */
137: private HashMap getQNamesToJavaNames() {
138: HashMap qnamesToJavaNamesMap = new HashMap();
139:
140: /* Look for all the <xb:qname ... /> nodes as these specify
141: * xml schema types to Java class mappings.
142: * <xb:qname name="mv:moduleType" javaname="Module"/>
143: */
144: NodeList qnameNodes = xsdConfigDoc.getElementsByTagNameNS(
145: XMLBEANS_NS, XMLBEANS_QNAME_NODE);
146:
147: for (int c = 0; c < qnameNodes.getLength(); c++) {
148: Node qnameNode = qnameNodes.item(c);
149:
150: /* In the xsdconfig file we'll get schema types with a prefix and not a uri.
151: * <xb:qname name="mv:moduleType" javaname="Module"/>
152: * but XMLBeans will call BindingConfig::lookupJavanameForQName with a QName
153: * which has a namespace uri and no prefix.
154: * So we'll store the fully qualifed schema type name in the mapping list.
155: * i.e. we pick it up from the xsdconfig file as:
156: * mv:moduleType
157: * but we'll store it as urn:weegietech:minerva:moduleType
158: */
159: String schemaType = qnameNode.getAttributes().getNamedItem(
160: "name").getNodeValue();
161: if (schemaType.indexOf(":") != -1) {
162: // mv:moduleType
163: String prefix = schemaType.split(":")[0];
164: String localName = schemaType.split(":")[1];
165:
166: if (prefixesToURIMappings.containsKey(prefix)) {
167: // Store as urn:weegietech:minerva:moduleType
168: String key = (String) prefixesToURIMappings
169: .get(prefix)
170: + ":" + localName;
171:
172: // Direct mapping now from schema types to Java class names
173: qnamesToJavaNamesMap.put(key, qnameNode
174: .getAttributes().getNamedItem("javaname")
175: .getNodeValue());
176: }
177: }
178: }
179:
180: return qnamesToJavaNamesMap;
181: }
182:
183: /**
184: * Loads the namespace to Java package mappings
185: *
186: * @return HashMap containing the namespace to Java package mappings as specified in the
187: * xsdconfig file. If there are no mappings, the returned HashMap will be empty.
188: */
189: private HashMap getNamespacesToPackages() {
190: HashMap nsToJavaPackagesMap = new HashMap();
191:
192: /* Look for all the <xb:namespace ... /> nodes as these specify
193: * xml namespace to Java package mappings.
194: * <xb:qname name="mv:moduleType" javaname="Module"/>
195: */
196: NodeList nsNodes = xsdConfigDoc.getElementsByTagNameNS(
197: XMLBEANS_NS, XMLBEANS_NS_NODE);
198:
199: for (int nsNodesCount = 0; nsNodesCount < nsNodes.getLength(); nsNodesCount++) {
200: Node nsNode = nsNodes.item(nsNodesCount);
201:
202: // What's the current namespace?
203: String uri = nsNode.getAttributes().getNamedItem("uri")
204: .getNodeValue();
205:
206: // Get the package name for the current namespace uri
207: String packageName = null;
208: NodeList childNodes = nsNode.getChildNodes();
209: for (int childNodesCount = 0; childNodesCount < childNodes
210: .getLength(); childNodesCount++) {
211: Node childNode = childNodes.item(childNodesCount);
212: if (childNode.getLocalName() != null) {
213: if (childNode.getLocalName().equals("package")) {
214: packageName = childNode.getFirstChild()
215: .getNodeValue();
216: }
217: }
218: }
219:
220: // Store the namespace uri to Java package mapping
221: if (packageName != null) {
222: nsToJavaPackagesMap.put(uri, packageName);
223: }
224: }
225:
226: return nsToJavaPackagesMap;
227: }
228:
229: class ParseErrorHandler implements ErrorHandler {
230: public void error(SAXParseException exception)
231: throws SAXException {
232: throw new SAXException(exception);
233: }
234:
235: public void fatalError(SAXParseException exception)
236: throws SAXException {
237: throw new SAXException(exception);
238: }
239:
240: public void warning(SAXParseException exception)
241: throws SAXException {
242: throw new SAXException(exception);
243: }
244: }
245: }
|