/*=============================================================================*
* 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.helper;
import org.apache.ws.util.NameUtils;
import org.apache.ws.util.XmlConstants;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
/** LOG-DONE
* @author Ian P. Springer
*/
public class Dom2SaajConverter
{
private SOAPFactory m_soap_factory;
/**
* Creates a new {@link Dom2SaajConverter} object.
*
* @throws SOAPException DOCUMENT_ME
*/
public Dom2SaajConverter( )
throws SOAPException
{
m_soap_factory = SOAPFactory.newInstance( );
}
/**
* Converts a DOM {@link org.w3c.dom.Element} to a SAAJ {@link javax.xml.soap.SOAPElement}.
*
* @param domElem a DOM {@link org.w3c.dom.Element}
*
* @return a {@link javax.xml.soap.SOAPElement}
*
* @throws javax.xml.soap.SOAPException
*/
public SOAPElement toSOAPElement( Element domElem )
throws SOAPException
{
if ( domElem == null )
{
return null;
}
SOAPElement soapElem;
if ( domElem instanceof SOAPElement )
{
soapElem = (SOAPElement) domElem;
}
else
{
soapElem =
m_soap_factory.createElement( domElem.getLocalName( ),
getPrefix( domElem ),
getNamespaceURI( domElem ) );
buildSOAPElement( domElem, soapElem );
}
return ( soapElem );
}
/**
* @param attrib
*
* @return
*/
private static boolean isNamespaceDeclarationAttrib( org.w3c.dom.Node attrib )
{
String prefix = attrib.getPrefix( );
String ns_uri = attrib.getNamespaceURI( );
return ( ( ( prefix != null ) && prefix.equals( XmlConstants.NSPREFIX_XMLNS ) )
|| ( ( ns_uri != null ) && ns_uri.equals( XmlConstants.NSURI_XMLNS ) ) )
&& !attrib.getLocalName( ).equals( XmlConstants.NSPREFIX_XMLNS );
}
/**
* @param node
*
* @return
*/
private static String getNamespaceURI( org.w3c.dom.Node node )
{
String ns_uri = node.getNamespaceURI( );
return ( ( ns_uri != null ) ? ns_uri : "" );
}
/**
* @param node
*
* @return
*/
private static String getPrefix( org.w3c.dom.Node node )
{
String prefix = node.getPrefix( );
return ( ( prefix != null ) ? prefix : NameUtils.getNamespacePrefix( node.getNamespaceURI( ) ) );
}
/**
* DOCUMENT_ME
*
* @param soap_elem DOCUMENT_ME
* @param elem DOCUMENT_ME
*
* @throws SOAPException DOCUMENT_ME
*/
private SOAPElement addAttributes( SOAPElement soap_elem,
Element elem )
throws SOAPException
{
NamedNodeMap attribs = elem.getAttributes( );
for ( int i = 0; i < attribs.getLength( ); i++ )
{
org.w3c.dom.Node attrib = attribs.item( i );
if ( isNamespaceDeclarationAttrib( attrib ) )
{
soap_elem.addNamespaceDeclaration( attrib.getLocalName( ),
attrib.getNodeValue( ) );
}
else
{
if ( hasPrefix( soap_elem ) && attrib.getLocalName( ).equals( XmlConstants.NSPREFIX_XMLNS ) )
{
// don't add an xmlns="..." attribute if the element has a prefix
continue;
}
Name attrib_pqname =
m_soap_factory.createName( attrib.getLocalName( ),
attrib.getPrefix( ),
attrib.getNamespaceURI( ) );
soap_elem.addAttribute( attrib_pqname,
attrib.getNodeValue( ) );
}
}
return ( soap_elem );
}
/**
* DOCUMENT_ME
*
* @param soap_elem DOCUMENT_ME
* @param elem DOCUMENT_ME
*
* @throws SOAPException DOCUMENT_ME
*/
private SOAPElement addChildren( SOAPElement soap_elem,
Element elem )
throws SOAPException
{
NodeList children = elem.getChildNodes( );
for ( int i = 0; i < children.getLength( ); i++ )
{
org.w3c.dom.Node node = children.item( i );
short node_type = node.getNodeType( );
if ( node_type == org.w3c.dom.Node.ELEMENT_NODE )
{
SOAPElement new_elem =
soap_elem.addChildElement( node.getLocalName( ),
getPrefix( node ),
getNamespaceURI( node ) );
buildSOAPElement( (Element) node, new_elem );
}
else if ( node_type == org.w3c.dom.Node.TEXT_NODE )
{
soap_elem.addTextNode( node.getNodeValue( ) );
}
}
return ( soap_elem );
}
/**
* Workhorse method for {@link Dom2SaajConverter#toSOAPElement} - calls itself recursively.
*
* @param elem the DOM element to be converted
* @param soap_elem the SAAJ SOAP element being built
*
* @throws SOAPException
*/
private SOAPElement buildSOAPElement( Element elem,
SOAPElement soap_elem )
throws SOAPException
{
return ( addChildren( addAttributes( soap_elem, elem ),
elem ) );
}
/**
* DOCUMENT_ME
*
* @param soap_elem DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
private static boolean hasPrefix( SOAPElement soap_elem )
{
String prefix = soap_elem.getElementName( ).getPrefix( );
return ( ( prefix != null ) && !prefix.equals( XmlConstants.NSPREFIX_DEFAULT ) );
}
}