org.firesoa.common.schema.DOMInitializer.java Source code

Java tutorial

Introduction

Here is the source code for org.firesoa.common.schema.DOMInitializer.java

Source

/**
 * Copyright 2007-2010 ?
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * 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 Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.firesoa.common.schema;

import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.StringUtils;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaAll;
import org.apache.ws.commons.schema.XmlSchemaAny;
import org.apache.ws.commons.schema.XmlSchemaAttribute;
import org.apache.ws.commons.schema.XmlSchemaAttributeGroup;
import org.apache.ws.commons.schema.XmlSchemaAttributeGroupMember;
import org.apache.ws.commons.schema.XmlSchemaAttributeGroupRef;
import org.apache.ws.commons.schema.XmlSchemaAttributeOrGroupRef;
import org.apache.ws.commons.schema.XmlSchemaChoice;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaComplexContent;
import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension;
import org.apache.ws.commons.schema.XmlSchemaComplexContentRestriction;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaContent;
import org.apache.ws.commons.schema.XmlSchemaContentModel;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaForm;
import org.apache.ws.commons.schema.XmlSchemaGroup;
import org.apache.ws.commons.schema.XmlSchemaGroupRef;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSequenceMember;
import org.apache.ws.commons.schema.XmlSchemaSimpleContent;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.apache.ws.commons.schema.constants.Constants;
import org.apache.ws.commons.schema.utils.XmlSchemaRef;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * 
 * 
 * @author ? nychen2000@163.com Fire Workflow www.firesoa.com 
 *         www.fireflow.org
 * 
 */
public class DOMInitializer {
    private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();

    public static String dom2String(Document dom) {
        try {
            Transformer transformer = transformerFactory.newTransformer();

            transformer.setOutputProperty(OutputKeys.ENCODING, Charset.defaultCharset().name());
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // transformer.transform()  XML Source? Result
            transformer.transform(new DOMSource(dom), new StreamResult(outputStream));
            return outputStream.toString();
        } catch (Exception e) {

            e.printStackTrace();
            return null;
        }

    }

    public static Document generateDocument(XmlSchemaCollection xmlSchemaCollection, QName rootElementQName)
            throws ParserConfigurationException {
        return generateDocument(xmlSchemaCollection, rootElementQName, false);
    }

    /**
     * ?schemaDocument
     * 
     * @param xmlSchemaCollection
     *            Schema
     * @param rootElementQName
     *            QName
     * @param createChoice
     *            ?XSDschema?choice?
     * @return
     * @throws ParserConfigurationException
     */
    public static Document generateDocument(XmlSchemaCollection xmlSchemaCollection, QName rootElementQName,
            boolean createChoice) throws ParserConfigurationException {

        XmlSchemaElement xmlSchemaElement = xmlSchemaCollection.getElementByQName(rootElementQName);

        if (xmlSchemaElement == null)
            return null;

        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();

        Document doc = docBuilder.newDocument();

        createElement(doc, doc, null, xmlSchemaElement, xmlSchemaCollection, createChoice);
        return doc;
    }

    /**
     * Element
     * @param doc
     * @param parentNode
     * @param childSchemaElement
     * @param xmlSchemaCollection
     * @param createChoice
     */
    protected static void createElement(Document doc, Node parentNode, XmlSchemaElement parentSchemaElement,
            XmlSchemaElement childSchemaElement, XmlSchemaCollection xmlSchemaCollection, boolean createChoice) {

        // 1?
        XmlSchemaRef<XmlSchemaElement> ref = childSchemaElement.getRef();
        if (ref != null && ref.getTarget() != null) {
            childSchemaElement = ref.getTarget();
        }

        if (childSchemaElement.getName().equals("foo_1")) {
            System.out.println("this is foo_1");
        }

        QName parentElmTypeQName = null;
        if (parentSchemaElement != null) {
            parentElmTypeQName = parentSchemaElement.getSchemaTypeName();
            if (parentElmTypeQName == null) {
                parentElmTypeQName = parentSchemaElement.getSchemaType().getQName();
            }

        }

        XmlSchemaForm schemaElementForm = childSchemaElement.getForm();

        QName childElmQName = childSchemaElement.getQName();
        Element childElem = null;
        if (schemaElementForm != null && XmlSchemaForm.QUALIFIED.equals(schemaElementForm)) {
            childElem = doc.createElementNS(childElmQName.getNamespaceURI(), getQualifiedName(doc, childElmQName));
        } else {
            if (parentElmTypeQName == null
                    || !equalStrings(parentElmTypeQName.getNamespaceURI(), childElmQName.getNamespaceURI())) {
                //
                childElem = doc.createElementNS(childElmQName.getNamespaceURI(),
                        getQualifiedName(doc, childElmQName));
            } else {
                //??namespace prefix
                childElem = doc.createElement(childElmQName.getLocalPart());
            }
        }

        parentNode.appendChild(childElem);

        // 2???
        XmlSchemaType xmlSchemaType = childSchemaElement.getSchemaType();
        if (xmlSchemaType == null) {
            QName qname = childSchemaElement.getSchemaTypeName();
            xmlSchemaType = xmlSchemaCollection.getTypeByQName(qname);
        }
        if (xmlSchemaType instanceof XmlSchemaSimpleType) {
            // ?
            XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) xmlSchemaType;
            String value = "";
            if (!StringUtils.isEmpty(childSchemaElement.getFixedValue())) {
                value = childSchemaElement.getFixedValue();
            } else if (!StringUtils.isEmpty(childSchemaElement.getDefaultValue())) {
                value = childSchemaElement.getDefaultValue();
            }
            if (!StringUtils.isEmpty(value)) {
                childElem.appendChild(doc.createTextNode(value));
            }
        } else if (xmlSchemaType instanceof XmlSchemaComplexType) {
            XmlSchemaComplexType complexType = (XmlSchemaComplexType) xmlSchemaType;

            createChildNode4ComplexType(doc, childElem, childSchemaElement, complexType, xmlSchemaCollection,
                    createChoice);
        }
    }

    /**
     * Element?Node?Element
     * @param doc
     * @param parentElement
     * @param parentSchemaElementComplexType
     * @param xmlSchemaCollection
     * @param createChoice
     */
    protected static void createChildNode4ComplexType(Document doc, Element parentElement,
            XmlSchemaElement parentSchemaElement, XmlSchemaComplexType parentSchemaElementComplexType,
            XmlSchemaCollection xmlSchemaCollection, boolean createChoice) {
        // 2.1 ?attribute
        List<XmlSchemaAttributeOrGroupRef> attributeSchemaList = parentSchemaElementComplexType.getAttributes();
        for (XmlSchemaAttributeOrGroupRef attrOrGroupRef : attributeSchemaList) {
            createAttribute(doc, parentElement, (XmlSchemaAttributeGroupMember) attrOrGroupRef);
        }

        // 2.2??
        // TODO ?ParticleComplextContent?
        XmlSchemaParticle particle = parentSchemaElementComplexType.getParticle();
        if (particle != null) {
            if (particle instanceof XmlSchemaAll) {
                XmlSchemaAll schemaAll = (XmlSchemaAll) particle;
                List<XmlSchemaElement> items = schemaAll.getItems();
                for (XmlSchemaElement item : items) {
                    createElement(doc, parentElement, parentSchemaElement, item, xmlSchemaCollection, createChoice);
                }
            } else if (particle instanceof XmlSchemaSequence) {
                XmlSchemaSequence schemaSeq = (XmlSchemaSequence) particle;
                createChildElement4Sequence(doc, parentElement, parentSchemaElement, schemaSeq, xmlSchemaCollection,
                        createChoice);
            } else if (particle instanceof XmlSchemaChoice) {
                createChildElement4Choice(doc, parentElement, parentSchemaElement, (XmlSchemaChoice) particle,
                        xmlSchemaCollection, createChoice);

            } else if (particle instanceof XmlSchemaGroupRef) {
                // TODO ?
            }
        } else {
            XmlSchemaContentModel contentModel = parentSchemaElementComplexType.getContentModel();
            if (contentModel instanceof XmlSchemaComplexContent) {
                XmlSchemaComplexContent complexContentModel = (XmlSchemaComplexContent) contentModel;
                XmlSchemaContent complexContent = complexContentModel.getContent();
                if (complexContent instanceof XmlSchemaComplexContentExtension) {
                    XmlSchemaComplexContentExtension complexContentExtension = (XmlSchemaComplexContentExtension) complexContent;
                    createChildElement4ComplexContentExtension(doc, parentElement, parentSchemaElement,
                            complexContentExtension, xmlSchemaCollection, createChoice);
                } else if (complexContent instanceof XmlSchemaComplexContentRestriction) {
                    //TODO ?
                }
            } else if (contentModel instanceof XmlSchemaSimpleContent) {
                // TODO simple
            }
        }
    }

    protected static void createChildElement4ComplexContentExtension(Document doc, Element parentElement,
            XmlSchemaElement parentSchemaElement, XmlSchemaComplexContentExtension complexContentExtension,
            XmlSchemaCollection xmlSchemaCollection, boolean createChoice) {
        QName baseTypeQName = complexContentExtension.getBaseTypeName();
        XmlSchemaComplexType comlexBaseType = (XmlSchemaComplexType) xmlSchemaCollection
                .getTypeByQName(baseTypeQName);
        createChildNode4ComplexType(doc, parentElement, parentSchemaElement, comlexBaseType, xmlSchemaCollection,
                createChoice);

        // 2.1 ?attribute
        List<XmlSchemaAttributeOrGroupRef> attributeSchemaList = complexContentExtension.getAttributes();
        for (XmlSchemaAttributeOrGroupRef attrOrGroupRef : attributeSchemaList) {
            createAttribute(doc, parentElement, (XmlSchemaAttributeGroupMember) attrOrGroupRef);
        }

        // 2.2??
        // TODO ?ParticleComplextContent?
        XmlSchemaParticle particle = complexContentExtension.getParticle();
        if (particle != null) {
            if (particle instanceof XmlSchemaAll) {
                XmlSchemaAll schemaAll = (XmlSchemaAll) particle;
                List<XmlSchemaElement> items = schemaAll.getItems();
                for (XmlSchemaElement item : items) {
                    createElement(doc, parentElement, parentSchemaElement, item, xmlSchemaCollection, createChoice);
                }
            } else if (particle instanceof XmlSchemaSequence) {
                XmlSchemaSequence schemaSeq = (XmlSchemaSequence) particle;
                createChildElement4Sequence(doc, parentElement, parentSchemaElement, schemaSeq, xmlSchemaCollection,
                        createChoice);
            } else if (particle instanceof XmlSchemaChoice) {
                createChildElement4Choice(doc, parentElement, parentSchemaElement, (XmlSchemaChoice) particle,
                        xmlSchemaCollection, createChoice);

            } else if (particle instanceof XmlSchemaGroupRef) {
                // TODO ?
            }
        }

    }

    protected static void createChildElement4Sequence(Document doc, Element parentElement,
            XmlSchemaElement parentSchemaElement, XmlSchemaSequence sequence,
            XmlSchemaCollection xmlSchemaCollection, boolean createChoice) {

        List<XmlSchemaSequenceMember> items = sequence.getItems();
        for (XmlSchemaSequenceMember item : items) {
            if (item instanceof XmlSchemaElement) {
                createElement(doc, parentElement, parentSchemaElement, ((XmlSchemaElement) item),
                        xmlSchemaCollection, createChoice);
            } else if (item instanceof XmlSchemaSequence) {
                createChildElement4Sequence(doc, parentElement, parentSchemaElement, ((XmlSchemaSequence) item),
                        xmlSchemaCollection, createChoice);
            } else if (item instanceof XmlSchemaChoice) {
                createChildElement4Choice(doc, parentElement, parentSchemaElement, ((XmlSchemaChoice) item),
                        xmlSchemaCollection, createChoice);
            } else if (item instanceof XmlSchemaAny) {
                // TODO
            } else if (item instanceof XmlSchemaGroup) {
                // TODO
            } else if (item instanceof XmlSchemaGroupRef) {
                // TODO
            }
        }

    }

    protected static void createChildElement4Choice(Document doc, Element parentElement,
            XmlSchemaElement parentSchemaElement, XmlSchemaChoice choice, XmlSchemaCollection xmlSchemaCollection,
            boolean createChoice) {
        if (!createChoice)
            return;
        List<XmlSchemaObject> choiceMember = choice.getItems();
        for (XmlSchemaObject schemaObj : choiceMember) {
            if (schemaObj instanceof XmlSchemaElement) {
                createElement(doc, parentElement, parentSchemaElement, ((XmlSchemaElement) schemaObj),
                        xmlSchemaCollection, createChoice);
            } else if (schemaObj instanceof XmlSchemaSequence) {
                createChildElement4Sequence(doc, parentElement, parentSchemaElement,
                        ((XmlSchemaSequence) schemaObj), xmlSchemaCollection, createChoice);
            } else if (schemaObj instanceof XmlSchemaChoice) {
                createChildElement4Choice(doc, parentElement, parentSchemaElement, ((XmlSchemaChoice) schemaObj),
                        xmlSchemaCollection, createChoice);
            }
        }
    }

    //TODO ?attribute qualifiedunqualified
    protected static void createAttribute(Document doc, Element elem, XmlSchemaAttributeGroupMember attrMember) {

        if (attrMember instanceof XmlSchemaAttribute) {
            XmlSchemaAttribute attrSchema = (XmlSchemaAttribute) attrMember;

            XmlSchemaForm attrForm = attrSchema.getForm();

            Attr attr = null;
            QName attrSchemaQName = attrSchema.getQName();
            if (XmlSchemaForm.QUALIFIED.equals(attrForm)) {
                String attrQualifiedName = getQualifiedName(doc, attrSchemaQName);
                attr = doc.createAttributeNS(attrSchemaQName.getNamespaceURI(), attrQualifiedName);
            } else {
                attr = doc.createAttribute(attrSchema.getName());
            }

            elem.setAttributeNode(attr);
            String value = "";
            if (!StringUtils.isEmpty(attrSchema.getFixedValue())) {
                value = attrSchema.getFixedValue();
            } else if (!StringUtils.isEmpty(attrSchema.getDefaultValue())) {
                value = attrSchema.getDefaultValue();
            }
            if (!StringUtils.isEmpty(value)) {
                attr.setValue(value);
            }
        } else if (attrMember instanceof XmlSchemaAttributeGroupRef) {
            XmlSchemaAttributeGroupRef attrGroupRef = (XmlSchemaAttributeGroupRef) attrMember;
            List<XmlSchemaAttributeGroupMember> groupMembers = attrGroupRef.getRef().getTarget().getAttributes();
            for (XmlSchemaAttributeGroupMember groupMember : groupMembers) {
                createAttribute(doc, elem, groupMember);
            }

        } else if (attrMember instanceof XmlSchemaAttributeGroup) {
            XmlSchemaAttributeGroup attrGroup = (XmlSchemaAttributeGroup) attrMember;
            List<XmlSchemaAttributeGroupMember> groupMembers = attrGroup.getAttributes();
            for (XmlSchemaAttributeGroupMember groupMember : groupMembers) {
                createAttribute(doc, elem, groupMember);
            }
        }

    }

    private static boolean equalStrings(String s1, String s2) {
        if (s1 == s2) {
            return true;
        }
        s1 = s1 == null ? "" : s1.trim();
        s2 = s2 == null ? "" : s2.trim();
        return s1.equals(s2);
    }

    private static String getQualifiedName(Document doc, QName qName) {
        Element rootElement = (Element) doc.getDocumentElement();

        if (rootElement != null && !equalStrings(qName.getNamespaceURI(), rootElement.getNamespaceURI())) {
            //         Attr attrTmp = rootElement.getAttributeNodeNS(Constants.XMLNS_ATTRIBUTE_NS_URI, "ns0");
            //         System.out.println("===========found attrTmp=="+attrTmp);

            String nsPrefix = null;
            nsPrefix = rootElement.lookupPrefix(qName.getNamespaceURI());
            if (nsPrefix == null || nsPrefix.trim().equals("")) {
                int nsNumber = 1;
                NamedNodeMap attrMap = rootElement.getAttributes();
                int length = attrMap.getLength();

                for (int i = 0; i < length; i++) {
                    Attr attr = (Attr) attrMap.item(i);
                    String name = attr.getName();
                    if (name.startsWith(Constants.XMLNS_ATTRIBUTE)) {
                        if (attr.getValue().equals(qName.getNamespaceURI())) {
                            // Namespace?
                            nsPrefix = attr.getLocalName();
                            break;
                        }
                        nsNumber++;
                    }
                }
                if (nsPrefix == null) {
                    nsPrefix = "ns" + nsNumber;
                }
            }

            Attr attr = doc.createAttributeNS(Constants.XMLNS_ATTRIBUTE_NS_URI,
                    Constants.XMLNS_ATTRIBUTE + ":" + nsPrefix);
            attr.setValue(qName.getNamespaceURI());
            rootElement.setAttributeNode(attr);

            return nsPrefix + ":" + qName.getLocalPart();
        } else {
            return "ns0:" + qName.getLocalPart();
        }

    }

    protected static XmlSchema findXmlSchema(XmlSchemaCollection schemaCollection, String targetNsUri) {
        XmlSchema[] xmlSchemas = schemaCollection.getXmlSchemas();
        String tmpUri = targetNsUri;
        if (tmpUri == null) {
            tmpUri = "";
        }
        for (XmlSchema schema : xmlSchemas) {
            if (tmpUri.equals(schema.getTargetNamespace())) {
                return schema;
            }
        }
        return null;
    }

    //   protected static XmlSchemaForm findElementFormDefault(XmlSchemaCollection schemaCollection ,String targetNsUri){
    //      XmlSchema schema = findXmlSchema(schemaCollection,targetNsUri);
    //      if (schema!=null){
    //         return schema.getElementFormDefault();
    //      }
    //      return XmlSchemaForm.UNQUALIFIED;
    //   }

}