Package org.eclipse.sapphire.modeling.xml

Source Code of org.eclipse.sapphire.modeling.xml.XmlUtil

/******************************************************************************
* Copyright (c) 2014 Oracle
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/

package org.eclipse.sapphire.modeling.xml;

import java.util.Map;

import javax.xml.namespace.QName;

import org.eclipse.sapphire.ElementType;
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
import org.eclipse.sapphire.modeling.xml.schema.XmlDocumentSchema;
import org.eclipse.sapphire.modeling.xml.schema.XmlDocumentSchemasCache;
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;
import org.w3c.dom.NodeList;

/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/

public final class XmlUtil
{
    public static final String EMPTY_STRING = "";
   
    public static final String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    public static final String XMLNS = "xmlns";
    public static final String XMLNS_COLON = "xmlns:";
   
    public static final String XSI_NAMESPACE_PREFIX = "xsi";
    public static final String XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
    public static final String XSI_SCHEMA_LOCATION_ATTR = "schemaLocation";
    public static final String XSI_SCHEMA_LOCATION_ATTR_QUALIFIED = XSI_NAMESPACE_PREFIX + ":" + XSI_SCHEMA_LOCATION_ATTR;
   
    public static void changeNamespace( final Document document,
                                        final String oldNamespace,
                                        final String newNamespace,
                                        final String newSchemaLocation )
    {
        final Element oldRootElement = document.getDocumentElement();
       
        if( oldRootElement != null )
        {
            final Node nodeAfterRootElement = oldRootElement.getNextSibling();
            final Node newRootElement = changeNamespace( oldRootElement, oldNamespace, newNamespace, newSchemaLocation );
            document.removeChild( oldRootElement );
            document.insertBefore( newRootElement, nodeAfterRootElement );
        }
    }
   
    private static Node changeNamespace( final Node node,
                                         final String oldNamespace,
                                         final String newNamespace,
                                         final String newSchemaLocation )
    {
        if( node instanceof Element )
        {
            String elementNameSpaceUri = node.getNamespaceURI();
            String elementQualifiedName = node.getNodeName();
            String nameSpaceDeclarationAttr = null;
           
            if( elementNameSpaceUri != null && elementNameSpaceUri.equals( oldNamespace ) )
            {
                elementNameSpaceUri = newNamespace;
               
                final String prefix = node.getPrefix();
                nameSpaceDeclarationAttr = ( prefix == null ? XMLNS : XMLNS_COLON + prefix );
            }
           
            final Document document = node.getOwnerDocument();
            final Element newElement = document.createElementNS( elementNameSpaceUri, elementQualifiedName );
            final NodeList children = node.getChildNodes();
           
            for( int i = 0, n = children.getLength(); i < n; i++ )
            {
                final Node oldChildNode = children.item( i );
               
                final Node newChildNode
                    = changeNamespace( oldChildNode, oldNamespace, newNamespace, newSchemaLocation );
               
                newElement.appendChild( newChildNode );
            }
           
            final NamedNodeMap attributes = node.getAttributes();
           
            boolean updatedNamespace = false;
            boolean updatedSchemaLocation = false;
           
            for( int i = 0, n = attributes.getLength(); i < n; i++ )
            {
                final Attr attr = (Attr) attributes.item( i );
                final String attrNameSpaceUri = attr.getNamespaceURI();
                final String attrQualifiedName = attr.getNodeName();
                String attrValue = attr.getValue();
               
                if( attrQualifiedName.equals( nameSpaceDeclarationAttr ) )
                {
                    attrValue = newNamespace;
                    updatedNamespace = true;
                }
                else if( attr.getLocalName() != null && attr.getLocalName().equals( XSI_SCHEMA_LOCATION_ATTR ) )
                {
                    attrValue = createSchemaLocationAttrValue( newSchemaLocation );
                    updatedSchemaLocation = true;
                }
               
                newElement.setAttributeNS( attrNameSpaceUri, attrQualifiedName, attrValue );
            }
           
            if( updatedNamespace && ! updatedSchemaLocation )
            {
                configSchemaLocation( newElement, newSchemaLocation );
            }
           
            return newElement;
        }
        else
        {
            return node.cloneNode( true );
        }
    }
   
    public static void configSchemaLocation( final Element element,
                                             final String primarySchemaLocation )
    {
        final String schemaLocationAttrValue = createSchemaLocationAttrValue( primarySchemaLocation );
       
        element.setAttributeNS( null, XMLNS_COLON + XSI_NAMESPACE_PREFIX, XSI_NAMESPACE );
        element.setAttributeNS( XSI_NAMESPACE, XSI_SCHEMA_LOCATION_ATTR_QUALIFIED, schemaLocationAttrValue );
    }

    private static String createSchemaLocationAttrValue( final String primarySchemaLocation )
    {
        final XmlDocumentSchema xmlDocumentSchema = XmlDocumentSchemasCache.getSchema( primarySchemaLocation );
        final StringBuilder buf = new StringBuilder();
       
        for( Map.Entry<String,String> entry : xmlDocumentSchema.getSchemaLocations().entrySet() )
        {
            if( buf.length() > 0 )
            {
                buf.append( ' ' );
            }
           
            buf.append( entry.getKey() );
            buf.append( ' ' );
            buf.append( entry.getValue() );
        }
       
        return buf.toString();
    }
   
    /**
     * Converts the document into namespace-qualified form.
     *
     * @param document the document to convert
     * @param namespace the namespace to use
     */
   
    public static void convertToNamespaceForm( final Document document,
                                               final String namespace )
    {
        convertToNamespaceForm( document, namespace, null );
    }
   
    /**
     * Converts the document into namespace-qualified form.
     *
     * @param document the document to convert
     * @param namespace the namespace to use
     * @param schemaLocation the schema location to use
     */
   
    public static void convertToNamespaceForm( final Document document,
                                               final String namespace,
                                               final String schemaLocation )
    {
        final Element oldRootElement = document.getDocumentElement();
       
        if( oldRootElement != null )
        {
            final Node nodeAfterRootElement = oldRootElement.getNextSibling();
            final Node newRootElement = convertToNamespaceForm( oldRootElement, namespace, schemaLocation );
            document.removeChild( oldRootElement );
            document.insertBefore( newRootElement, nodeAfterRootElement );
        }
    }
   
    private static Node convertToNamespaceForm( final Node node,
                                                final String namespace,
                                                final String schemaLocation )
    {
        if( node instanceof Element )
        {
            final Document document = node.getOwnerDocument();
            final Element newElement = document.createElementNS( namespace, node.getLocalName() );
            final NodeList children = node.getChildNodes();
           
            if( node.getParentNode() instanceof Document )
            {
                newElement.setAttributeNS( null, XMLNS, namespace );
               
                if( schemaLocation != null && ! schemaLocation.equals( namespace ) )
                {
                    configSchemaLocation( newElement, schemaLocation );
                }
            }
           
            for( int i = 0, n = children.getLength(); i < n; i++ )
            {
                final Node oldChildNode = children.item( i );
                final Node newChildNode = convertToNamespaceForm( oldChildNode, namespace, schemaLocation );
               
                newElement.appendChild( newChildNode );
            }
           
            final NamedNodeMap attributes = node.getAttributes();
           
            for( int i = 0, n = attributes.getLength(); i < n; i++ )
            {
                final Attr attr = (Attr) attributes.item( i );
                newElement.setAttributeNS( null, attr.getNodeName(), attr.getValue() );
            }
           
            return newElement;
        }
        else
        {
            return node.cloneNode( true );
        }
    }
   
    /**
     * Converts the document from namespace-qualified form into unqualified form by removing all
     * namespace information.
     *
     * @param document the document to convert
     */
   
    public static void convertFromNamespaceForm( final Document document )
    {
        final Element oldRootElement = document.getDocumentElement();
       
        if( oldRootElement != null )
        {
            final Node nodeAfterRootElement = oldRootElement.getNextSibling();
            final Node newRootElement = convertFromNamespaceForm( oldRootElement );
            document.removeChild( oldRootElement );
            document.insertBefore( newRootElement, nodeAfterRootElement );
        }
    }
   
    private static Node convertFromNamespaceForm( final Node node )
    {
        if( node instanceof Element )
        {
            final Document document = node.getOwnerDocument();
            final Element newElement = document.createElementNS( null, node.getLocalName() );
            final NodeList children = node.getChildNodes();
           
            for( int i = 0, n = children.getLength(); i < n; i++ )
            {
                final Node oldChildNode = children.item( i );
                final Node newChildNode = convertFromNamespaceForm( oldChildNode );
               
                newElement.appendChild( newChildNode );
            }
           
            final NamedNodeMap attributes = node.getAttributes();
           
            for( int i = 0, n = attributes.getLength(); i < n; i++ )
            {
                final Attr attr = (Attr) attributes.item( i );
                final String attrQualifiedName = attr.getNodeName();
                final String attrLocalName = attr.getLocalName();
               
                if( ! attrQualifiedName.equals( XMLNS ) && ! attrQualifiedName.startsWith( XMLNS_COLON ) && ! attrLocalName.equals( XSI_SCHEMA_LOCATION_ATTR ) )
                {
                    newElement.setAttributeNS( null, attrLocalName, attr.getValue() );
                }
            }
           
            return newElement;
        }
        else
        {
            return node.cloneNode( true );
        }
    }
   
    public static QName createQualifiedName( final String name,
                                             final XmlNamespaceResolver xmlNamespaceResolver )
    {
        final QName qname;
       
        if( xmlNamespaceResolver == null )
        {
            qname = new QName( null, name, "" );
        }
        else
        {
            qname = xmlNamespaceResolver.createQualifiedName( name );
        }
       
        return qname;
    }
   
    public static QName createQualifiedName( final Node node )
    {
        final String namespace = node.getNamespaceURI();
        final String localName = node.getLocalName();
        return new QName( namespace, localName );
    }
   
    public static QName createDefaultElementName( final ElementType type )
    {
        QName name = null;
       
        final XmlBinding xmlBindingAnnotation = type.getAnnotation( XmlBinding.class );
        final XmlNamespaceResolver xmlNamespaceResolver = new StandardXmlNamespaceResolver( type );
       
        if( xmlBindingAnnotation != null )
        {
            final XmlPath path = new XmlPath( xmlBindingAnnotation.path(), xmlNamespaceResolver );
           
            if( path.getSegmentCount() == 1 )
            {
                final XmlPath.Segment firstSegment = path.getSegment( 0 );
               
                if( ! firstSegment.isAttribute() && ! firstSegment.isComment() )
                {
                    name = firstSegment.getQualifiedName();
                }
            }
        }
       
        if( name == null )
        {
            String xmlElementName = type.getSimpleName();
           
            if( xmlElementName.charAt( 0 ) == 'I' && xmlElementName.length() > 1 && Character.isUpperCase( xmlElementName.charAt( 1 ) ) )
            {
                xmlElementName = xmlElementName.substring( 1 );
            }

            name = createQualifiedName( xmlElementName, xmlNamespaceResolver );
        }
       
        return name;
    }
   
    public static boolean equal( final QName a,
                                 final QName b,
                                 final String defaultNamespace )
    {
        if( a.getLocalPart().equals( b.getLocalPart() ) )
        {
            String nsa = a.getNamespaceURI();
            String nsb = b.getNamespaceURI();
           
            if( nsa == null || nsa.length() == 0 )
            {
                nsa = defaultNamespace;
            }
           
            if( nsb == null || nsb.length() == 0 )
            {
                nsb = defaultNamespace;
            }
           
            return nsa.equals( nsb );
        }
       
        return false;
    }
   
    public static boolean contains( final QName[] qnames,
                                    final QName qname,
                                    final String defaultNamespace )
    {
        for( QName a : qnames )
        {
            if( equal( a, qname, defaultNamespace ) )
            {
                return true;
            }
        }
       
        return false;
    }
   
}
TOP

Related Classes of org.eclipse.sapphire.modeling.xml.XmlUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.