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;

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

   /**
    * @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 an array containing all child elements, with the specified name, of the specified XMLBean.
    *
    * @param xBean an XMLBean that represents an XML element
    * @param name  the name to look for, or null to return all child elements
    *
    * @return an array containing all child elements, with the specified name, of the specified XMLBean
    */
   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] );
   }

   /**
    * Returns an array containing all child elements of the specified XMLBean.
    *
    * @param xBean an XMLBean that represents an XML element
    *
    * @return an array containing all child elements of the specified XMLBean
    */
   public static XmlObject[] getChildElements( XmlObject xBean )
   {
      return getChildElements( xBean, null );
   }

   /**
    * 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;
   }

   /**
    * Returns true if the specified XMLBean represents an XML document, or false if it does not.
    *
    * @param xBean an XMLBean
    *
    * @return true if the specified XMLBean represents an XML document, or false if it does not
    */
   public static boolean isDocument( XmlObject xBean )
   {
      return xBean.schemaType(  ).isDocumentType(  );
   }

   /**
    * @param xBean
    */
   public static void setName( XmlObject xBean,
                               QName     name )
   {
      if ( xBean == null )
      {
         throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_PARAM_NOT_ALLOWED ) );
      }

      XmlCursor xCursor = xBean.newCursor(  );
      setName( xCursor, name );
      xCursor.dispose(  );
   }

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

   /**
    * @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
    * @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
    *
    * @return
    */
   public static String getValue( XmlObject xBean )
   {
      XmlCursor xCursor = xBean.newCursor(  );
      String    value = xCursor.getTextValue(  );
      xCursor.dispose(  );
      return value;
   }

   /**
    * @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
    *
    * @return
    */
   public static QName getValueAsQName( XmlObject xBean )
   {
      String value = getValue( xBean );
      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 (low priority): 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 XmlBean <code>newChild</code> as the last child of the XmlBean <code>parent</code>.
    *
    * @param parent   the XmlBean to be added to; must represent an element or a document
    * @param newChild the XmlBean to be added; must represent an element or a document
    */
   public static XmlObject addChildElement( XmlObject parent,
                                            XmlObject newChild )
   {
      parent = getRootElement( parent );
      Node parentNode   = parent.getDomNode(  );
      Node newChildNode = newChild.newDomNode(  ); // no need to use newDomNode() because importNode() will make a copy
      if ( newChildNode.getNodeType(  ) == Node.DOCUMENT_NODE )
      {
         newChildNode = ( (Document) newChildNode ).getDocumentElement(  );
      }

      newChildNode = parentNode.getOwnerDocument(  ).importNode( newChildNode, true ); //
      parentNode.appendChild( newChildNode );

      // get a ref to the XmlObject corresponding to the child we've just added...
      XmlCursor cursor = parent.newCursor(  );
      cursor.toLastChild(  );
      newChild = cursor.getObject(  );
      cursor.dispose(  );
      return newChild;
   }

   /**
    * Creates a new XmlBean named <code>name</code> and adds it as the last child of the XmlBean <code>parent</code>.
    *
    * @param parent the XmlBean to be added to; must represent an element or a document
    * @param name   the name of the new XmlBean to be added
    */
   public static XmlObject addChildElement( XmlObject parent,
                                            QName     name )
   {
      parent = getRootElement( parent );
      XmlCursor parentCursor = parent.newCursor(  );
      if ( parentCursor.toLastChild(  ) ) // has children
      {
         parentCursor.toEndToken(  );
         parentCursor.toNextToken(  );
      }
      else // childless
      {
         parentCursor.toEndToken(  );
      }

      parentCursor.insertElement( name );
      parentCursor.toPrevSibling(  );
      XmlObject newChild = parentCursor.getObject(  );
      parentCursor.dispose(  );
      return newChild;
   }

   /**
    * 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;
   }

   /**
    * DOCUMENT_ME
    *
    * @param elemName DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public static XmlObject createElement( QName elemName )
   {
      XmlObject xBean = XmlObject.Factory.newInstance(  );
      setName( xBean, elemName );
      return xBean;
   }

   /**
    * 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 );*/
      Node    domNode = xBean.newDomNode(  );
      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;
   }

   /**
    * Creates a new XMLBean element with the specified name.
    *
    * @param elemName the element name
    *
    * @return a new XMLBean element with the specified name
    */
   public XmlObject newInstance( QName elemName )
   {
      XmlObject xBean   = XmlObject.Factory.newInstance(  );
      XmlCursor xCursor = xBean.newCursor(  );
      xCursor.setName( elemName );
      xCursor.dispose(  );
      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 );
   }
}
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.