Package org.apache.ws.util

Source Code of org.apache.ws.util.XmlBeanUtils

/*=============================================================================*
*  Copyright 2004 The Apache Software Foundation
*
*  Licensed 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.
*=============================================================================*/
package org.apache.ws.util;

import org.apache.ws.util.i18n.Keys;
import org.apache.ws.util.i18n.Messages;
import org.apache.ws.util.i18n.MessagesImpl;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* LOG-DONE Generic utility methods for working with Apache XMLBeans.
*
* @author Ian P. Springer, Sal Campana
*/
public abstract class XmlBeanUtils
{
   
    private static final Messages MSG = MessagesImpl.getInstance();

    /**
     * TODO
     *
     * @param xBean
     * @param name  name to look for, or null to return all child elements
     *
     * @return
     */
    public static XmlObject[] getChildElements( XmlObject xBean,
                                                QName name )
    {
        List foundElems = new ArrayList();
        xBean = getRootElement( xBean );
        XmlCursor xCursor = xBean.newCursor();
        for ( boolean hasNext = xCursor.toFirstChild(); hasNext; hasNext = xCursor.toNextSibling() )
        {
            if ( ( name == null ) || getName( xCursor ).equals( name ) )
            {
                foundElems.add( xCursor.getObject() );
            }
        }
        xCursor.dispose();
        return (XmlObject[]) foundElems.toArray( new XmlObject[0] );
    }

    /**
     * TODO
     *
     * @param xBean
     *
     * @return
     */
    public static XmlObject[] getChildElements( XmlObject xBean )
    {
        return getChildElements( xBean, null );
    }

    /**
     * DOCUMENT_ME
     *
     * @param xBean DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public static boolean isDocument( XmlObject xBean )
    {
        return xBean.schemaType().isDocumentType();
    }

    /**
     * Returns the document XmlBean that is associated with the specified XmlBean.
     *
     * @param xBean an XmlBean
     *
     * @return the document XmlBean that is associated with the specified XmlBean
     */
    public static XmlObject getDocument( XmlObject xBean )
    {
        XmlCursor xCursor = xBean.newCursor();
        xCursor.toStartDoc();
        XmlObject docXBean = xCursor.getObject();
        xCursor.dispose();
        return docXBean;
    }

    /**
     * @param xBean
     *
     * @return
     */
    public static QName getName( XmlObject xBean )
    {
        if ( xBean == null )
        {
            throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_PARAM_NOT_ALLOWED ) );
        }
        SchemaType docSchemaType;
        if ( isDocument( xBean ) )
        {
            docSchemaType = xBean.schemaType();
        }
        else
        {
            docSchemaType = xBean.schemaType().getOuterType();
        }

        QName name;
        if ( docSchemaType != null )
        {
            name = docSchemaType.getDocumentElementName();
        }
        else
        {
            XmlCursor xCursor = xBean.newCursor();
            name = getName( xCursor );
            xCursor.dispose();
        }
        return name;
    }

    /**
     * Note. this method does not dispose of the cursor
     *
     * @param xCursor
     *
     * @return
     */
    public static QName getName( XmlCursor xCursor )
    {
        QName name;
        if ( xCursor.currentTokenType().equals( XmlCursor.TokenType.STARTDOC ) )
        {
            xCursor.toFirstChild();
            name = xCursor.getName();
            xCursor.toParent();
        }
        else
        {
            name = xCursor.getName();
        }
        return name;
    }

    /**
     * Returns the root element of the specified document XMLBean. If the specified XMLBean is not a document, the
     * XMLBean itself is returned.
     *
     * @param docXBean a document XMLBean
     *
     * @return the root element of the specified document XMLBean, or, if the specified XMLBean is not a document, the
     *         XMLBean itself
     */
    public static XmlObject getRootElement( XmlObject docXBean )
    {
        XmlObject rootElemXBean;
        if ( isDocument( docXBean ) )
        {
            XmlCursor xCursor = docXBean.newCursor();
            if ( xCursor.toFirstChild() )
            {
                rootElemXBean = xCursor.getObject();
            }
            else
            {
                rootElemXBean = null;
            }
            xCursor.dispose();
        }
        else
        {
            rootElemXBean = docXBean;
        }
        return rootElemXBean;
    }

    /**
     * @param xBean
     *
     * @return
     */
    public static String getValue( XmlObject xBean )
    {
        XmlCursor xCursor = xBean.newCursor();
        String value = xCursor.getTextValue();
        xCursor.dispose();
        return value;
    }

    /**
     * @param xBean
     *
     * @return
     */
    public static QName getValueAsQName( XmlObject xBean )
    {
        String value = getValue( xBean );
        return toQName( value, xBean );
    }

    /**
     * @param xBean
     * @param value
     */
    public static void setValue( XmlObject xBean,
                                 String value )
    {
        XmlCursor xCursor = xBean.newCursor();
        if ( xCursor.isStartdoc() )
        {
            xCursor.toFirstChild();
        }
        xCursor.setTextValue( value );
        xCursor.dispose();
    }

    /**
     * @param xBean
     * @param qName
     *
     */
    public static void setValueAsQName( XmlObject xBean, QName qName )
    {
        XmlCursor xCursor = xBean.newCursor();
        String prefix = xCursor.prefixForNamespace( qName.getNamespaceURI() );
        String value = prefix + ":" + qName.getLocalPart();
        xCursor.setTextValue( value );
        xCursor.dispose();
    }

    /**
     *
     * @param xBean
     * @param attribName
     * @return
     */
    public static String getAttributeValue( XmlObject xBean, QName attribName )
    {
        XmlCursor xCursor = xBean.newCursor();
        String value = xCursor.getAttributeText( attribName );
        xCursor.dispose();
        return value;
    }

    /**
     * @param xBean
     *
     * @return
     */
    public static QName getAttributeValueAsQName( XmlObject xBean, QName attribName )
    {
        String value = getAttributeValue( xBean, attribName );
        return toQName( value, xBean );
    }

    /**
     * Returns a Map keyed on Element QName to a List containing the "Any" XmlObjects types.
     * <p/>
     * The way we determine that an element is an Any is by asking for the element property of the schemaType for the
     * element by the element's QName.
     *
     * @param xmlObjectToSearch The XmlObject to find the Any elements in.
     *
     * @return Map keyed on Element QName to a List containing the "Any" XmlObjects
     */
    public static Map getXmlBeanAnyMap( XmlObject xmlObjectToSearch )
    {
        Map qnameToListMap = new HashMap();
        XmlCursor xCursor = xmlObjectToSearch.newCursor();
        for ( boolean hasNext = xCursor.toFirstChild(); hasNext; hasNext = xCursor.toNextSibling() )
        {
            XmlObject siblingXmlObject = xCursor.getObject();
            QName siblingXmlObjectQname = getName(siblingXmlObject);

            // TODO: should this be tested against the original bean
            //if it contains the ElementProperty, then it is not an Any
            if ( siblingXmlObject.schemaType().getElementProperty( siblingXmlObjectQname ) != null )
            {
                continue;
            }

            //check to see if we have a xmlObjectList to add to for this QName
            List xmlObjectList = (List) qnameToListMap.get( siblingXmlObjectQname );

            if ( xmlObjectList == null )
            {
                xmlObjectList = new ArrayList();
            }

            xmlObjectList.add( siblingXmlObject );
            qnameToListMap.put( siblingXmlObjectQname, xmlObjectList );
        }

        xCursor.dispose();

        return qnameToListMap;
    }

    /**
     * Adds a copy of the specified XmlBean as the last child element of the
     * specified parent XmlBean.
     *
     * @param parentXBean
     * @param xBean
     */
    public static XmlObject addChildElement( XmlObject parentXBean,
                                             XmlObject xBean )
    {
        parentXBean = getRootElement( parentXBean );
        xBean = getRootElement( xBean );
        XmlCursor parentCursor = parentXBean.newCursor();
        if ( parentCursor.toLastChild() ) // has children
        {
            parentCursor.toEndToken();
            parentCursor.toNextToken();
        }
        else                              // childless
        {
            parentCursor.toEndToken();
        }
        parentCursor.insertElement( getName( xBean ) );
        parentCursor.toPrevSibling();
        XmlObject childXBean = parentCursor.getObject();
        parentCursor.dispose();
        return childXBean.set( xBean );
    }

    /**
     * Adds an XmlBean with the specified name as the last of the specified parent XmlBean.
     *
     * @param parentXBean
     * @param name
     */
    public static XmlObject addChildElement( XmlObject parentXBean,
                                             QName name )
    {
        parentXBean = getRootElement( parentXBean );
        XmlCursor parentCursor = parentXBean.newCursor();
        if ( parentCursor.toLastChild() )  // has children
        {
            parentCursor.toEndToken();
            parentCursor.toNextToken();
        }
        else                               // childless
        {
            parentCursor.toEndToken();
        }
        parentCursor.insertElement( name );
        parentCursor.toPrevSibling();
        XmlObject childXBean = parentCursor.getObject();
        parentCursor.dispose();
        return childXBean;       
    }

    /**
     * Removes the specifed XMLBean from its parent element.
     *
     * @param xBean an XMLBean
     */
    public static void remove( XmlObject xBean )
    {
        XmlCursor xCursor = xBean.newCursor();
        xCursor.removeXml();

        xCursor.dispose();
    }

    /**
     * Removes all child elements, with the specified name, from the specified XMLBean.
     *
     * @param xBean an XMLBean
     *
     * @return true if all child elements, with the specified name, were successfully removed
     */
    public static boolean removeChildElements( XmlObject xBean,
                                               QName name )
    {
        boolean succeeded = true;
        xBean = getRootElement( xBean );
        XmlCursor xCursor = xBean.newCursor();
        for ( boolean hasNext = xCursor.toFirstChild(); hasNext; hasNext = xCursor.toNextSibling() )
        {
            if ( name == null || getName( xCursor ).equals( name ) )
            {
                succeeded = succeeded && xCursor.removeXml();
            }
        }
        xCursor.dispose();
        return succeeded;
    }

    /**
     * Removes all child elements of the specified XMLBean.
     *
     * @param xBean an XMLBean
     *
     * @return true if all child elements were successfully removed
     */
    public static boolean removeChildElements( XmlObject xBean )
    {
        return removeChildElements( xBean, null );
    }

    /**
     * @param xBean
     *
     * @return
     *
     * @throws Exception
     */
    public static SOAPElement toSOAPElement( XmlObject xBean )
            throws Exception
    {
        XmlOptions xSaveOpts = new XmlOptions().setSaveOuter().setSavePrettyPrint().setSavePrettyPrintIndent( 2 );
        Node domNode = xBean.newDomNode( xSaveOpts );
        Element domElem = null;
        if ( domNode instanceof Document )
        {
            domElem = ( (Document) domNode ).getDocumentElement();
        }
        else if ( domNode instanceof DocumentFragment )
        {
            NodeList childNodes = domNode.getChildNodes();
            for ( int i = 0; i < childNodes.getLength(); i++ )
            {
                if ( childNodes.item( i ).getNodeType() == Node.ELEMENT_NODE )
                {
                    domElem = (Element) childNodes.item( i );
                    break;
                }
            }
        }
        return SaajUtils.toSOAPElement( domElem );
    }

    /**
     * DOCUMENT_ME
     *
     * @param elems DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     *
     * @throws Exception DOCUMENT_ME
     */
    public static SOAPElement[] toSOAPElementArray( final XmlObject[] elems )
            throws Exception
    {
        SOAPElement[] soapElems = new SOAPElement[elems.length];

        for ( int i = 0; i < elems.length; i++ )
        {
            soapElems[i] = toSOAPElement( elems[i] );
        }

        return soapElems;
    }

    /**
     * If possible, converts the specified object to an XMLBean.
     *
     * @param obj an object
     *
     * @return an XMLBean, or null if the parameter is null
     *
     * @throws Exception if the object cannot be converted to an XMLBean
     */
    public static XmlObject toXmlObject( Object obj )
            throws Exception
    {
        XmlObject xBean;

        if ( obj == null)
        {
            return null;
        }

        if ( obj instanceof XmlObject )
        {
            xBean = (XmlObject) obj;
        }
        else if ( obj instanceof SOAPElement )
        {
            // !!!NOTE!!! It is critical to do parse( obj.toString() ) here, instead of parse( (Node)obj ),
            //            because Axis 1.2's DOM impl (MessageElement) strips off all attributes, including
            //            namespace decls! (TODO: file an Axis bug for the aforementioned issue)
            xBean = XmlObject.Factory.parse( obj.toString() );
        }
        else if ( obj instanceof Node )
        {
            xBean = XmlObject.Factory.parse( (Node) obj );
        }
        else if ( obj instanceof String )
        {
            xBean = XmlObject.Factory.parse( (String) obj );
        }
        else if ( obj instanceof InputStream )
        {
            xBean = XmlObject.Factory.parse( (InputStream) obj );
        }
        else if ( obj instanceof Reader )
        {
            xBean = XmlObject.Factory.parse( (Reader) obj );
        }
        else if ( obj instanceof File )
        {
            xBean = XmlObject.Factory.parse( (File) obj );
        }
        else if ( obj instanceof URL )
        {
            xBean = XmlObject.Factory.parse( (URL) obj );
        }
        else
        {
            throw new IllegalArgumentException( MSG.getMessage( Keys.PARAM_MUST_BE_TYPE + " " + obj.getClass().getName());
        }

        return xBean;
    }

    /**
     *
     * @param elemName
     * @return
     */
    public XmlObject newInstance( QName elemName )
    {
        XmlObject xBean = XmlObject.Factory.newInstance();
        // TODO: finish implementing
        return xBean;
    }

    private static QName toQName( String value, XmlObject xBean )
    {
        int colonIndex = value.indexOf( ':' );
        String nsURI;
        if ( colonIndex != -1 )
        {
            String prefix = value.substring( 0, colonIndex );
            XmlCursor xCursor = xBean.newCursor();
            nsURI = xCursor.namespaceForPrefix( prefix );
            if ( nsURI == null )
            {
                throw new RuntimeException( "No namespace is associated with prefix '" + prefix + "'" );
            }
            xCursor.dispose();
        }
        else
        {
            nsURI = "";
        }
        String localName = value.substring( colonIndex + 1 );
        return new QName( nsURI, localName );
    }

    /**
     * Makes and returns a copy of the specified XMLBean.
     *
     * @param srcXBean the XMLBean to be copied
     *
     * @return a copy of the specified XMLBean
     */
    public static XmlObject copyXmlBean( XmlObject srcXBean )
    {
        try
        {
            return XmlObject.Factory.parse( srcXBean.xmlText( new XmlOptions().setSaveOuter() ) );
        }
        catch ( XmlException xe )
        {
            throw new RuntimeException( xe );
        }

        /*XmlCursor srcCursor = srcXBean.newCursor(  );

       // create an object of the appropriate type to copy to
       XmlObject destXBean = XmlObject.Factory.newInstance( new XmlOptions( ).setDocumentType( srcXBean.schemaType() ) );
       XmlCursor destCursor = destXBean.newCursor(  );

       // move into the document
       destCursor.toNextToken(  );

       // copy the xml into the new document
       srcCursor.copyXml( destCursor );

       // clean up our cursors
       destCursor.dispose(  );
       srcCursor.dispose(  );

       return destXBean;*/
    }

    /**
     * Makes and returns a copy of the specified XMLBean array.
     *
     * @param srcXBeans the array of XMLBeans to be copied
     *
     * @return a copy of the specified XMLBean array
     */
    public static XmlObject[] copyXmlBeans( XmlObject[] srcXBeans )
    {
       if ( srcXBeans == null )
       {
          return null;
       }

       XmlObject[] destXBeans = new XmlObject[srcXBeans.length];

       for ( int i = 0; i < srcXBeans.length; i++ )
       {
          destXBeans[i] = copyXmlBean( srcXBeans[i] );
       }

       return destXBeans;
    }

}
TOP

Related Classes of org.apache.ws.util.XmlBeanUtils

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.