blob: 027935443c1eb4b73aea1e7c776e10974093cc2b [file] [log] [blame]
/*
* Copyright 2001-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.axis.utils ;
import org.apache.axis.AxisEngine;
import org.apache.axis.Constants;
import org.apache.axis.InternalException;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.AxisProperties;
import org.apache.axis.components.encoding.XMLEncoder;
import org.apache.axis.components.encoding.XMLEncoderFactory;
import org.apache.axis.components.logger.LogFactory;
import org.apache.commons.logging.Log;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
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;
import org.w3c.dom.Text;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
public class XMLUtils {
protected static Log log =
LogFactory.getLog(XMLUtils.class.getName());
public static final String httpAuthCharEncoding = "ISO-8859-1";
private static final String saxParserFactoryProperty =
"javax.xml.parsers.SAXParserFactory";
private static DocumentBuilderFactory dbf = getDOMFactory();
private static SAXParserFactory saxFactory;
private static Stack saxParsers = new Stack();
private static DefaultHandler doNothingContentHandler = new DefaultHandler();
private static String EMPTY = "";
private static ByteArrayInputStream bais = new ByteArrayInputStream(EMPTY.getBytes());
private static boolean tryReset= true;
protected static boolean enableParserReuse = false;
private static class ThreadLocalDocumentBuilder extends ThreadLocal {
protected Object initialValue() {
try {
return getDOMFactory().newDocumentBuilder();
} catch (ParserConfigurationException e) {
log.error(Messages.getMessage("parserConfigurationException00"),
e);
}
return null;
}
}
private static ThreadLocalDocumentBuilder documentBuilder = new ThreadLocalDocumentBuilder();
static {
// Initialize SAX Parser factory defaults
initSAXFactory(null, true, false);
String value = AxisProperties.getProperty(AxisEngine.PROP_XML_REUSE_SAX_PARSERS,
"" + true);
if (value.equalsIgnoreCase("true") ||
value.equals("1") ||
value.equalsIgnoreCase("yes")) {
enableParserReuse = true;
} else {
enableParserReuse = false;
}
}
/**
* Encode a string appropriately for XML.
* @param orig the String to encode
* @return a String in which XML special chars are repalced by entities
*/
public static String xmlEncodeString(String orig)
{
XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
return encoder.encode(orig);
}
/**
* Get the current XMLEncoder
* @return XMLEncoder
*/
public static XMLEncoder getXMLEncoder(MessageContext msgContext) {
return getXMLEncoder(getEncoding(null, msgContext));
}
/**
* Get the XMLEncoder for specific encoding
* @return XMLEncoder
*/
public static XMLEncoder getXMLEncoder(String encoding) {
XMLEncoder encoder = null;
try {
encoder = XMLEncoderFactory.getEncoder(encoding);
} catch (Exception e) {
log.error(Messages.getMessage("exception00"), e);
encoder = XMLEncoderFactory.getDefaultEncoder();
}
return encoder;
}
/**
* Get the current encoding in effect
* @return string
*/
public static String getEncoding(MessageContext msgContext) {
XMLEncoder encoder = getXMLEncoder(msgContext);
return encoder.getEncoding();
}
/**
* Get the current encoding in effect
* @return string
*/
public static String getEncoding() {
XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
return encoder.getEncoding();
}
/** Initialize the SAX parser factory.
*
* @param factoryClassName The (optional) class name of the desired
* SAXParserFactory implementation. Will be
* assigned to the system property
* <b>javax.xml.parsers.SAXParserFactory</b>
* unless this property is already set.
* If <code>null</code>, leaves current setting
* alone.
* @param namespaceAware true if we want a namespace-aware parser
* @param validating true if we want a validating parser
*
*/
public static void initSAXFactory(String factoryClassName,
boolean namespaceAware,
boolean validating)
{
if (factoryClassName != null) {
try {
saxFactory = (SAXParserFactory)Class.forName(factoryClassName).
newInstance();
/*
* Set the system property only if it is not already set to
* avoid corrupting environments in which Axis is embedded.
*/
if (System.getProperty(saxParserFactoryProperty) == null) {
System.setProperty(saxParserFactoryProperty,
factoryClassName);
}
} catch (Exception e) {
log.error(Messages.getMessage("exception00"), e);
saxFactory = null;
}
} else {
saxFactory = SAXParserFactory.newInstance();
}
saxFactory.setNamespaceAware(namespaceAware);
saxFactory.setValidating(validating);
// Discard existing parsers
saxParsers.clear();
}
private static DocumentBuilderFactory getDOMFactory() {
DocumentBuilderFactory dbf;
try {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
}
catch( Exception e ) {
log.error(Messages.getMessage("exception00"), e );
dbf = null;
}
return( dbf );
}
/**
* Gets a DocumentBuilder
* @return DocumentBuilder
* @throws ParserConfigurationException
*/
public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
return (DocumentBuilder) documentBuilder.get();
}
/**
* Releases a DocumentBuilder
* @param db
*/
public static void releaseDocumentBuilder(DocumentBuilder db) {
try {
db.setErrorHandler(null); // setting implementation default
} catch (Throwable t) {
log.debug("Failed to set ErrorHandler to null on DocumentBuilder",
t);
}
try {
db.setEntityResolver(null); // setting implementation default
} catch (Throwable t) {
log.debug("Failed to set EntityResolver to null on DocumentBuilder",
t);
}
}
/** Get a SAX parser instance from the JAXP factory.
*
* @return a SAXParser instance.
*/
public static synchronized SAXParser getSAXParser() {
if(enableParserReuse && !saxParsers.empty()) {
return (SAXParser )saxParsers.pop();
}
try {
SAXParser parser = saxFactory.newSAXParser();
XMLReader reader = parser.getXMLReader();
// parser.getParser().setEntityResolver(new DefaultEntityResolver());
// The above commented line and the following line are added
// for preventing XXE (bug #14105).
// We may need to uncomment the deprecated setting
// in case that it is considered necessary.
try {
reader.setEntityResolver(DefaultEntityResolver.INSTANCE);
} catch (Throwable t) {
log.debug("Failed to set EntityResolver on DocumentBuilder", t);
}
reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
return parser;
} catch (ParserConfigurationException e) {
log.error(Messages.getMessage("parserConfigurationException00"), e);
return null;
} catch (SAXException se) {
log.error(Messages.getMessage("SAXException00"), se);
return null;
}
}
/** Return a SAX parser for reuse.
* @param parser A SAX parser that is available for reuse
*/
public static void releaseSAXParser(SAXParser parser) {
if(!tryReset || !enableParserReuse) return;
//Free up possible ref. held by past contenthandler.
try{
XMLReader xmlReader= parser.getXMLReader();
if(null != xmlReader){
xmlReader.setContentHandler(doNothingContentHandler);
xmlReader.setDTDHandler(doNothingContentHandler);
try {
xmlReader.setEntityResolver(doNothingContentHandler);
} catch (Throwable t) {
log.debug("Failed to set EntityResolver on DocumentBuilder", t);
}
try {
xmlReader.setErrorHandler(doNothingContentHandler);
} catch (Throwable t) {
log.debug("Failed to set ErrorHandler on DocumentBuilder", t);
}
synchronized (XMLUtils.class ) {
saxParsers.push(parser);
}
}
else {
tryReset= false;
}
} catch (org.xml.sax.SAXException e) {
tryReset= false;
}
}
/**
* Get an empty new Document
*
* @return Document
* @throws ParserConfigurationException if construction problems occur
*/
public static Document newDocument()
throws ParserConfigurationException {
DocumentBuilder db = null;
try {
db = getDocumentBuilder();
Document doc = db.newDocument();
return doc;
} finally {
if (db != null) {
releaseDocumentBuilder(db);
}
}
}
/**
* Get a new Document read from the input source
* @return Document
* @throws ParserConfigurationException if construction problems occur
* @throws SAXException if the document has xml sax problems
* @throws IOException if i/o exceptions occur
*/
public static Document newDocument(InputSource inp)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilder db = null;
try {
db = getDocumentBuilder();
try {
db.setEntityResolver(DefaultEntityResolver.INSTANCE);
} catch (Throwable t) {
log.debug("Failed to set EntityResolver on DocumentBuilder", t);
}
try {
db.setErrorHandler(new XMLUtils.ParserErrorHandler());
} catch (Throwable t) {
log.debug("Failed to set ErrorHandler on DocumentBuilder", t);
}
Document doc = db.parse(inp);
return doc;
} finally {
if (db != null) {
releaseDocumentBuilder(db);
}
}
}
/**
* Get a new Document read from the input stream
* @return Document
* @throws ParserConfigurationException if construction problems occur
* @throws SAXException if the document has xml sax problems
* @throws IOException if i/o exceptions occur
*/
public static Document newDocument(InputStream inp)
throws ParserConfigurationException, SAXException, IOException
{
return XMLUtils.newDocument(new InputSource(inp));
}
/**
* Get a new Document read from the indicated uri
* @return Document
* @throws ParserConfigurationException if construction problems occur
* @throws SAXException if the document has xml sax problems
* @throws IOException if i/o exceptions occur
*/
public static Document newDocument(String uri)
throws ParserConfigurationException, SAXException, IOException
{
// call the authenticated version as there might be
// username/password info embeded in the uri.
return XMLUtils.newDocument(uri, null, null);
}
/**
* Create a new document from the given URI, use the username and password
* if the URI requires authentication.
* @param uri the resource to get
* @param username basic auth username
* @param password basic auth password
* @throws ParserConfigurationException if construction problems occur
* @throws SAXException if the document has xml sax problems
* @throws IOException if i/o exceptions occur
*/
public static Document newDocument(String uri, String username, String password)
throws ParserConfigurationException, SAXException, IOException
{
InputSource ins = XMLUtils.getInputSourceFromURI(uri, username, password);
Document doc = XMLUtils.newDocument(ins);
// Close the Stream
if (ins.getByteStream() != null) {
ins.getByteStream().close();
} else if (ins.getCharacterStream() != null) {
ins.getCharacterStream().close();
}
return doc;
}
private static String privateElementToString(Element element,
boolean omitXMLDecl)
{
return DOM2Writer.nodeToString(element, omitXMLDecl);
}
/**
* turn an element into an XML fragment
* @param element
* @return stringified element
*/
public static String ElementToString(Element element) {
return privateElementToString(element, true);
}
/**
* turn a whole DOM document into XML
* @param doc DOM document
* @return string representation of the document, including XML declaration
*/
public static String DocumentToString(Document doc) {
return privateElementToString(doc.getDocumentElement(), false);
}
public static String PrettyDocumentToString(Document doc) {
StringWriter sw = new StringWriter();
PrettyElementToWriter(doc.getDocumentElement(), sw);
return sw.toString();
}
public static void privateElementToWriter(Element element, Writer writer,
boolean omitXMLDecl,
boolean pretty) {
DOM2Writer.serializeAsXML(element, writer, omitXMLDecl, pretty);
}
public static void ElementToStream(Element element, OutputStream out) {
Writer writer = getWriter(out);
privateElementToWriter(element, writer, true, false);
}
public static void PrettyElementToStream(Element element, OutputStream out) {
Writer writer = getWriter(out);
privateElementToWriter(element, writer, true, true);
}
public static void ElementToWriter(Element element, Writer writer) {
privateElementToWriter(element, writer, true, false);
}
public static void PrettyElementToWriter(Element element, Writer writer) {
privateElementToWriter(element, writer, true, true);
}
public static void DocumentToStream(Document doc, OutputStream out) {
Writer writer = getWriter(out);
privateElementToWriter(doc.getDocumentElement(), writer, false, false);
}
public static void PrettyDocumentToStream(Document doc, OutputStream out) {
Writer writer = getWriter(out);
privateElementToWriter(doc.getDocumentElement(), writer, false, true);
}
private static Writer getWriter(OutputStream os) {
Writer writer = null;
try {
writer = new OutputStreamWriter(os, "UTF-8");
} catch (UnsupportedEncodingException uee) {
log.error(Messages.getMessage("exception00"), uee);
writer = new OutputStreamWriter(os);
}
return writer;
}
public static void DocumentToWriter(Document doc, Writer writer) {
privateElementToWriter(doc.getDocumentElement(), writer, false, false);
}
public static void PrettyDocumentToWriter(Document doc, Writer writer) {
privateElementToWriter(doc.getDocumentElement(), writer, false, true);
}
/**
* Convert a simple string to an element with a text node
*
* @param namespace - element namespace
* @param name - element name
* @param string - value of the text node
* @return element - an XML Element, null if no element was created
*/
public static Element StringToElement(String namespace, String name, String string) {
try {
Document doc = XMLUtils.newDocument();
Element element = doc.createElementNS(namespace, name);
Text text = doc.createTextNode(string);
element.appendChild(text);
return element;
}
catch (ParserConfigurationException e) {
// This should not occur
throw new InternalException(e);
}
}
/**
* get the inner XML inside an element as a string. This is done by
* converting the XML to its string representation, then extracting the
* subset between beginning and end tags.
* @param element
* @return textual body of the element, or null for no inner body
*/
public static String getInnerXMLString(Element element) {
String elementString = ElementToString(element);
int start, end;
start = elementString.indexOf(">") + 1;
end = elementString.lastIndexOf("</");
if (end > 0)
return elementString.substring(start,end);
else
return null;
}
public static String getPrefix(String uri, Node e) {
while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) {
NamedNodeMap attrs = e.getAttributes();
for (int n = 0; n < attrs.getLength(); n++) {
Attr a = (Attr)attrs.item(n);
String name;
if ((name = a.getName()).startsWith("xmlns:") &&
a.getNodeValue().equals(uri)) {
return name.substring(6);
}
}
e = e.getParentNode();
}
return null;
}
/**
* Searches for the namespace URI of the given prefix in the given DOM range.
*
* The namespace is not searched in parent of the "stopNode". This is
* usefull to get all the needed namespaces when you need to ouput only a
* subtree of a DOM document.
*
* @param prefix the prefix to find
* @param e the starting node
* @param stopNode null to search in all the document or a parent node where the search must stop.
* @return null if no namespace is found, or the namespace URI.
*/
public static String getNamespace(String prefix, Node e, Node stopNode) {
while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) {
Attr attr = null;
if (prefix == null) {
attr = ((Element) e).getAttributeNode("xmlns");
} else {
attr = ((Element) e).getAttributeNodeNS(Constants.NS_URI_XMLNS,
prefix);
}
if (attr != null) return attr.getValue();
if (e == stopNode)
return null;
e = e.getParentNode();
}
return null;
}
public static String getNamespace(String prefix, Node e) {
return getNamespace(prefix, e, null);
}
/**
* Return a QName when passed a string like "foo:bar" by mapping
* the "foo" prefix to a namespace in the context of the given Node.
*
* @return a QName generated from the given string representation
*/
public static QName getQNameFromString(String str, Node e) {
return getQNameFromString(str, e, false);
}
/**
* Return a QName when passed a string like "foo:bar" by mapping
* the "foo" prefix to a namespace in the context of the given Node.
* If default namespace is found it is returned as part of the QName.
*
* @return a QName generated from the given string representation
*/
public static QName getFullQNameFromString(String str, Node e) {
return getQNameFromString(str, e, true);
}
private static QName getQNameFromString(String str, Node e, boolean defaultNS) {
if (str == null || e == null)
return null;
int idx = str.indexOf(':');
if (idx > -1) {
String prefix = str.substring(0, idx);
String ns = getNamespace(prefix, e);
if (ns == null)
return null;
return new QName(ns, str.substring(idx + 1));
} else {
if (defaultNS) {
String ns = getNamespace(null, e);
if (ns != null)
return new QName(ns, str);
}
return new QName("", str);
}
}
/**
* Return a string for a particular QName, mapping a new prefix
* if necessary.
*/
public static String getStringForQName(QName qname, Element e)
{
String uri = qname.getNamespaceURI();
String prefix = getPrefix(uri, e);
if (prefix == null) {
int i = 1;
prefix = "ns" + i;
while (getNamespace(prefix, e) != null) {
i++;
prefix = "ns" + i;
}
e.setAttributeNS(Constants.NS_URI_XMLNS,
"xmlns:" + prefix, uri);
}
return prefix + ":" + qname.getLocalPart();
}
/**
* Concat all the text and cdata node children of this elem and return
* the resulting text.
* (by Matt Duftler)
*
* @param parentEl the element whose cdata/text node values are to
* be combined.
* @return the concatanated string.
*/
public static String getChildCharacterData (Element parentEl) {
if (parentEl == null) {
return null;
}
Node tempNode = parentEl.getFirstChild();
StringBuffer strBuf = new StringBuffer();
CharacterData charData;
while (tempNode != null) {
switch (tempNode.getNodeType()) {
case Node.TEXT_NODE :
case Node.CDATA_SECTION_NODE : charData = (CharacterData)tempNode;
strBuf.append(charData.getData());
break;
}
tempNode = tempNode.getNextSibling();
}
return strBuf.toString();
}
public static class ParserErrorHandler implements ErrorHandler {
protected static Log log =
LogFactory.getLog(ParserErrorHandler.class.getName());
/**
* Returns a string describing parse exception details
*/
private String getParseExceptionInfo(SAXParseException spe) {
String systemId = spe.getSystemId();
if (systemId == null) {
systemId = "null";
}
String info = "URI=" + systemId +
" Line=" + spe.getLineNumber() +
": " + spe.getMessage();
return info;
}
// The following methods are standard SAX ErrorHandler methods.
// See SAX documentation for more info.
public void warning(SAXParseException spe) throws SAXException {
if (log.isDebugEnabled())
log.debug( Messages.getMessage("warning00", getParseExceptionInfo(spe)));
}
public void error(SAXParseException spe) throws SAXException {
String message = "Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
public void fatalError(SAXParseException spe) throws SAXException {
String message = "Fatal Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
}
/**
* Utility to get the bytes uri.
* Does NOT handle authenticated URLs,
* use getInputSourceFromURI(uri, username, password)
*
* @param uri the resource to get
* @see #getInputSourceFromURI(String uri, String username, String password)
*/
public static InputSource getInputSourceFromURI(String uri) {
return new InputSource(uri);
}
/**
* Utility to get the bytes uri
*
* @param source the resource to get
*/
public static InputSource sourceToInputSource(Source source) {
if (source instanceof SAXSource) {
return ((SAXSource) source).getInputSource();
} else if (source instanceof DOMSource) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Node node = ((DOMSource)source).getNode();
if (node instanceof Document) {
node = ((Document)node).getDocumentElement();
}
Element domElement = (Element)node;
ElementToStream(domElement, baos);
InputSource isource = new InputSource(source.getSystemId());
isource.setByteStream(new ByteArrayInputStream(baos.toByteArray()));
return isource;
} else if (source instanceof StreamSource) {
StreamSource ss = (StreamSource) source;
InputSource isource = new InputSource(ss.getSystemId());
isource.setByteStream(ss.getInputStream());
isource.setCharacterStream(ss.getReader());
isource.setPublicId(ss.getPublicId());
return isource;
} else {
return getInputSourceFromURI(source.getSystemId());
}
}
/**
* Utility to get the bytes at a protected uri
*
* This will retrieve the URL if a username and password are provided.
* The java.net.URL class does not do Basic Authentication, so we have to
* do it manually in this routine.
*
* If no username is provided, we create an InputSource from the uri
* and let the InputSource go fetch the contents.
*
* @param uri the resource to get
* @param username basic auth username
* @param password basic auth password
*/
private static InputSource getInputSourceFromURI(String uri,
String username,
String password)
throws IOException, ProtocolException, UnsupportedEncodingException
{
URL wsdlurl = null;
try {
wsdlurl = new URL(uri);
} catch (MalformedURLException e) {
// we can't process it, it might be a 'simple' foo.wsdl
// let InputSource deal with it
return new InputSource(uri);
}
// if no authentication, just let InputSource deal with it
if (username == null && wsdlurl.getUserInfo() == null) {
return new InputSource(uri);
}
// if this is not an HTTP{S} url, let InputSource deal with it
if (!wsdlurl.getProtocol().startsWith("http")) {
return new InputSource(uri);
}
URLConnection connection = wsdlurl.openConnection();
// Does this work for https???
if (!(connection instanceof HttpURLConnection)) {
// can't do http with this URL, let InputSource deal with it
return new InputSource(uri);
}
HttpURLConnection uconn = (HttpURLConnection) connection;
String userinfo = wsdlurl.getUserInfo();
uconn.setRequestMethod("GET");
uconn.setAllowUserInteraction(false);
uconn.setDefaultUseCaches(false);
uconn.setDoInput(true);
uconn.setDoOutput(false);
uconn.setInstanceFollowRedirects(false);
uconn.setUseCaches(false);
// username/password info in the URL overrides passed in values
String auth = null;
if (userinfo != null) {
auth = userinfo;
} else if (username != null) {
auth = (password == null) ? username : username + ":" + password;
}
if (auth != null) {
uconn.setRequestProperty("Authorization",
"Basic " +
base64encode(auth.getBytes(httpAuthCharEncoding)));
}
uconn.connect();
return new InputSource(uconn.getInputStream());
}
public static final String base64encode(byte[] bytes) {
return new String(Base64.encode(bytes));
}
public static InputSource getEmptyInputSource() {
return new InputSource(bais);
}
/**
* Find a Node with a given QName
*
* @param node parent node
* @param name QName of the child we need to find
* @return child node
*/
public static Node findNode(Node node, QName name){
if(name.getNamespaceURI().equals(node.getNamespaceURI()) &&
name.getLocalPart().equals(node.getLocalName()))
return node;
NodeList children = node.getChildNodes();
for(int i=0;i<children.getLength();i++){
Node ret = findNode(children.item(i), name);
if(ret != null)
return ret;
}
return null;
}
/**
* Trim all new lines from text nodes.
*
* @param node
*/
public static void normalize(Node node) {
if (node.getNodeType() == Node.TEXT_NODE) {
String data = ((Text) node).getData();
if (data.length() > 0) {
char ch = data.charAt(data.length()-1);
if(ch == '\n' || ch == '\r' || ch == ' ') {
String data2 = trim(data);
((Text) node).setData(data2);
}
}
}
for (Node currentChild = node.getFirstChild(); currentChild != null; currentChild = currentChild.getNextSibling()) {
normalize(currentChild);
}
}
public static String trim(String str) {
if (str.length() == 0) {
return str;
}
if (str.length() == 1) {
if ("\r".equals(str) || "\n".equals(str)) {
return "";
} else {
return str;
}
}
int lastIdx = str.length() - 1;
char last = str.charAt(lastIdx);
while(lastIdx > 0) {
if(last != '\n' && last != '\r' && last != ' ')
break;
lastIdx--;
last = str.charAt(lastIdx);
}
if(lastIdx == 0)
return "";
return str.substring(0, lastIdx);
}
/**
* Converts a List with org.w3c.dom.Element objects to an Array
* with org.w3c.dom.Element objects.
* @param list List containing org.w3c.dom.Element objects
* @return Element[] Array with org.w3c.dom.Element objects
*/
public static Element[] asElementArray(List list) {
Element[] elements = new Element[list.size()];
int i = 0;
Iterator detailIter = list.iterator();
while (detailIter.hasNext()) {
elements[i++] = (Element) detailIter.next();
}
return elements;
}
public static String getEncoding(Message message,
MessageContext msgContext) {
return getEncoding(message, msgContext,
XMLEncoderFactory.getDefaultEncoder());
}
public static String getEncoding(Message message,
MessageContext msgContext,
XMLEncoder defaultEncoder) {
String encoding = null;
try {
if(message != null) {
encoding = (String) message.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
}
} catch (SOAPException e) {
}
if(msgContext == null) {
msgContext = MessageContext.getCurrentContext();
}
if(msgContext != null && encoding == null){
encoding = (String) msgContext.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
}
if (msgContext != null && encoding == null && msgContext.getAxisEngine() != null) {
encoding = (String) msgContext.getAxisEngine().getOption(AxisEngine.PROP_XML_ENCODING);
}
if (encoding == null && defaultEncoder != null) {
encoding = defaultEncoder.getEncoding();
}
return encoding;
}
}