/*=============================================================================*
* 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.Detail;
import javax.xml.soap.DetailEntry;
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 );
}
/**
* Adds a DOM {@link org.w3c.dom.Element} as an entry to a SAAJ {@link Detail}.
*
* @param detail a SAAJ detail
* @param domElem a DOM element to be added as an entry in the specified detail
*
* @return a SAAJ detail entry
*
* @throws javax.xml.soap.SOAPException
*/
public DetailEntry addDetailEntry( Detail detail, Element domElem )
throws SOAPException
{
if ( domElem == null )
{
return null;
}
DetailEntry detailEntry;
if ( domElem instanceof DetailEntry )
{
detailEntry = (DetailEntry) domElem;
}
else
{
detailEntry =
detail.addDetailEntry( m_soap_factory.createName( domElem.getLocalName(),
getPrefix( domElem ),
getNamespaceURI( domElem ) ) );
buildSOAPElement( domElem, detailEntry );
}
return detailEntry;
}
/**
* @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 ) );
}
}