alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * 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);
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.