com.sun.jbi.wsdl2.impl.WsdlReader Maven / Gradle / Ivy
/*
* BEGIN_HEADER - DO NOT EDIT
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* If applicable add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced with
* your own identifying information: Portions Copyright
* [year] [name of copyright owner]
*/
/*
* @(#)WsdlReader.java
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
*
* END_HEADER - DO NOT EDIT
*/
package com.sun.jbi.wsdl2.impl;
import com.sun.jbi.wsdl2.WsdlException;
import java.io.File;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.logging.Logger;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.w3.ns.wsdl.DescriptionDocument;
import org.w3.ns.wsdl.DocumentationDocument;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
/**
* This class provides the ability to read WSDL documents, converting them
* into Description
.
*
* This is loosely based on the WSDLReaderImpl in the JSR-110 RI, in order
* to preserve some sort of compatibility with 110-based code. The actual
* implementation is quite different.
*
* @author Sun Microsystems, Inc.
*/
final class WsdlReader implements com.sun.jbi.wsdl2.WsdlReader
{
/** This is for backward compatible with version of x2006.x01 */
private final String OLD_NS_STRING = "www.w3.org/2006/01/wsdl";
private final String NEW_NS_STRING = "www.w3.org/ns/wsdl";
/** The logger to be used by this WSDL reader */
private final Logger mLogger = Logger.getLogger(Constants.LOGGER_NAME);
/**
* Get the logger used by this WSDL reader.
This avoids exposing our
* logger name, which may change.
*
* @return Logger used by WSDL readers.
*/
public Logger getLogger()
{
return this.mLogger;
}
/**
* Read the given WSDL document, converting it into a Description
* object.
*
* @param wsdlUri A URI pointing to the WSDL XML document resource to read.
* @return Definition corresponding to the given WSDL document
* @exception WsdlException If the WSDL document contains errors.
* @exception MalformedURLException If the wsdlUri isn't a valid URL or file
* name.
* @exception IOException If an IO error occurs whilst reading the
* wsdlUri.
*/
public com.sun.jbi.wsdl2.Description readDescription(String wsdlUri)
throws WsdlException, MalformedURLException, IOException
{
return this.readDescription(null, wsdlUri);
}
/**
* @deprecated - replaced by readDescription
*/
public com.sun.jbi.wsdl2.Definitions readWsdl(String wsdlURI)
throws WsdlException, MalformedURLException, IOException
{
return (com.sun.jbi.wsdl2.Definitions) readDescription(wsdlURI);
}
/**
* Read the given WSDL2 document, in the given context URI, converting it into
* a Description
object.
*
* @param contextUri The context to evaluate the wsdlUri
in.
* @param wsdlUri A URI pointing to the WSDL XML document resource to
* read. This can be a URL or a filename.
* @return Description
corresponding to the given WSDL document
* @exception WsdlException If the WSDL document contains errors.
* @exception MalformedURLException If one of the URIs given isn't a valid
* URL or file name.
* @exception IOException If an error occurs reading the
* resource given in wsdlUri
.
*/
public com.sun.jbi.wsdl2.Description readDescription(String contextUri,
String wsdlUri) throws WsdlException, MalformedURLException, IOException
{
Description result = null;
URL contextURL = contextUri != null
? getURL(null, contextUri)
: null;
URL wsdlURL = getURL(contextURL, wsdlUri);
DescriptionDocument defDoc = null;
try
{
try
{
defDoc = DescriptionDocument.Factory.parse(wsdlURL);
}
catch(Exception exp)
{
mLogger.fine("May not be the final WSDL 2.0 version, let's try 2006.01");
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
Document doc = domBuilder.parse(wsdlURL.toString());
/* This is for backward compable (compatibble with 2006.01) */
recursivelyUpdate(doc);
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer trans = transFactory.newTransformer();
StringWriter strWriter = new StringWriter();
StreamResult resultStream = new StreamResult(strWriter);
trans.transform(new DOMSource(doc), resultStream);
domFactory.setNamespaceAware(true);
DocumentBuilder domBuilder1 = domFactory.newDocumentBuilder();
Document newDoc = domBuilder1.parse(
new StringBufferInputStream(strWriter.getBuffer().toString()));
defDoc = DescriptionDocument.Factory.parse(newDoc);
strWriter.close();
}
validate(defDoc);
}
catch (XmlException ex)
{
throw new WsdlException(ex.getMessage());
}
catch(org.xml.sax.SAXException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(ParserConfigurationException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(TransformerConfigurationException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(TransformerException exp)
{
throw new WsdlException(exp.getMessage());
}
return DescriptionImpl.Factory.getInstance(defDoc, wsdlURL.toExternalForm());
}
/**
* @param doc the document which needs to be updated if necessary
*/
private void recursivelyUpdate(Node theNode)
{
NamedNodeMap attrs = theNode.getAttributes();
if(attrs != null)
{
for(int i=0; i < attrs.getLength(); ++i)
{
Node attr = attrs.item(i);
String attrValue = "" + attr.getNodeValue();
attrValue = attrValue.replace(OLD_NS_STRING,
NEW_NS_STRING);
attr.setNodeValue(attrValue);
}
}
NodeList nodeList = theNode.getChildNodes();
for(int i=0; i < nodeList.getLength(); ++i)
{
Node childNode = nodeList.item(i);
recursivelyUpdate(childNode);
}
}
/**
* @deprecated use readDescription
*/
public com.sun.jbi.wsdl2.Definitions readWsdl(String contextURI, String wsdlURI)
throws WsdlException, MalformedURLException, IOException
{
return (com.sun.jbi.wsdl2.Definitions) readDescription(contextURI, wsdlURI);
}
/**
* Validate the given document.
*
* @param defDoc The definitions document to be validated.
* @exception WsdlException if the document is invalid.
*/
private static void validate(DescriptionDocument defDoc)
throws WsdlException
{
XmlOptions validateOptions = new XmlOptions();
ArrayList errorList = new ArrayList();
validateOptions.setErrorListener(errorList);
boolean isValid = defDoc.validate(validateOptions);
// If the XML isn't valid, loop through the listener's contents,
// constructing a suitable error message.
if (!isValid)
{
StringBuffer sb = new StringBuffer();
for (int i = 0; i < errorList.size(); i++)
{
XmlError error = (XmlError) errorList.get(i);
if (i > 0)
{
sb.append( "\n\n" );
}
sb.append("Message: ");
sb.append( error.getMessage() );
sb.append( "\n" );
sb.append( "Location of invalid XML: " );
sb.append(error.getCursorLocation().xmlText());
sb.append( "\n\n" );
// Location by line / column not available by default
// with XmlBeans.
}
throw new WsdlException(sb.toString());
}
}
/**
* Read the given document (we assume it is WSDL 2.0) into a
* Description
object.
*
* @param documentBaseUri The base url for the WSDL document
* @param document The WSDL document as a DOM tree.
* @return A WSDL Description component corresponding to the given
* WSDL 2.0 document
.
* @exception WsdlException if an XML parsing error occurs.
*/
public com.sun.jbi.wsdl2.Description readDescription(String documentBaseUri,
Document document) throws WsdlException, IOException
{
return readDescription(documentBaseUri, document.getDocumentElement());
}
/**
* @deprecated use readDescription
*/
public com.sun.jbi.wsdl2.Definitions readWsdl(String documentBaseURI,
Document document)
throws WsdlException, MalformedURLException, IOException
{
return (com.sun.jbi.wsdl2.Definitions) readDescription(documentBaseURI,
document);
}
/**
* Read the given document (we assume it is WSDL 2.0) into a
* Description
object.
*
* @param documentBaseUri The base url for the WSDL document
* @param element The <definitions> element for the WSDL instance.
* @return Description
object representing the WSDL document read.
* @exception WsdlException If a parsing or processing error occurs.
*/
public com.sun.jbi.wsdl2.Description readDescription(String documentBaseUri,
Element element) throws WsdlException, IOException
{
DescriptionDocument defDoc = null;
try
{
try
{
defDoc = DescriptionDocument.Factory.parse(element);
}
catch(Exception exp)
{
mLogger.fine("May not be the final WSDL 2.0 version, let's try 2006.01");
/* This is for backward compable (compatibble with 2006.01) */
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder tmpBuilder = domFactory.newDocumentBuilder();
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer trans = transFactory.newTransformer();
StringWriter strWriter = new StringWriter();
StreamResult tmpStream = new StreamResult(strWriter);
trans.transform(new DOMSource(element), tmpStream);
// Load the doc with namespace as attribute for the 1st time
domFactory.setNamespaceAware(false);
Document tmpElement = tmpBuilder.parse(
new StringBufferInputStream(strWriter.getBuffer().toString()));
strWriter.close();
recursivelyUpdate(tmpElement);
strWriter = new StringWriter();
StreamResult resultStream = new StreamResult(strWriter);
trans.transform(new DOMSource(tmpElement), resultStream);
// Load the doc with namespace as namesapce for the 2nd time
domFactory.setNamespaceAware(true);
DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
Document newElement = domBuilder.parse(
new StringBufferInputStream(strWriter.getBuffer().toString()));
defDoc = DescriptionDocument.Factory.parse(newElement);
strWriter.close();
}
validate(defDoc);
}
catch (XmlException ex)
{
throw new WsdlException(ex.getMessage());
}
catch(org.xml.sax.SAXException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(ParserConfigurationException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(TransformerConfigurationException exp)
{
throw new WsdlException(exp.getMessage());
}
catch(TransformerException exp)
{
throw new WsdlException(exp.getMessage());
}
return DescriptionImpl.Factory.getInstance(defDoc, documentBaseUri);
}
/**
* @deprecated use readDescription
*/
public com.sun.jbi.wsdl2.Definitions readWsdl(String documentBaseURI,
Element definitionsElement)
throws WsdlException, MalformedURLException, IOException
{
return (com.sun.jbi.wsdl2.Definitions) readDescription(documentBaseURI,
definitionsElement);
}
/**
* Read a WSDL document into a WSDL definition.
*
* @param documentBaseURI The document base URI of the WSDL definition
* described by the document. Will be set as the
* documentBaseURI of the returned Definition.
* Can be null, in which case it will be ignored.
* @param inputSource An InputSource pointing to the WSDL document, an
* XML document obeying the WSDL schema.
* @return The WSDL document pointed to by the inputSource
,
* as a Description component.
* @exception WsdlException if an XML parsing error occurs.
* @exception IOException if an error occurs reading
* inputSource
.
*/
public com.sun.jbi.wsdl2.Description readDescription(String documentBaseURI,
InputSource inputSource) throws WsdlException, IOException
{
return this.readDescription(
documentBaseURI,
DOMUtilities.getDocument(documentBaseURI, inputSource));
}
/**
* @deprecated use readDescription
*/
public com.sun.jbi.wsdl2.Definitions readWsdl(String documentBaseURI,
InputSource inputSource)
throws WsdlException, MalformedURLException, IOException
{
return (com.sun.jbi.wsdl2.Definitions) readDescription(documentBaseURI,
inputSource);
}
/**
* Get the URL, based on the specification string and context URL (if any).
*
* @param contextURL The context in which to resolve the specification
* string.
* @param specification The URL specification string or filename.
* @return The URL corresponding the the given specification
,
* in the given context contextURL
(if not null).
* @exception MalformedURLException if the specification
* string is not a legal URL.
*
* This is based loosely on the JSR 110 RI StringUtil method of the same
* name.
*/
static URL getURL(URL contextURL, String specification)
throws MalformedURLException
{
if (contextURL != null)
{
File tempFile = new File(specification);
if (tempFile.isAbsolute())
{
return tempFile.toURL();
}
}
try
{
return new URL(contextURL, specification);
}
catch (MalformedURLException e)
{
if (contextURL == null)
{
return new File(specification).toURL();
}
else
{
throw e;
}
}
}
}