blob: fe9b029ef51219728c353734f6266e242da6c87f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsdl.tests.util;
import java.io.FileOutputStream;
import java.util.Iterator;
import javax.wsdl.OperationType;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.BindingFault;
import org.eclipse.wst.wsdl.BindingInput;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.BindingOutput;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibilityElement;
import org.eclipse.wst.wsdl.ExtensibleElement;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.MessageReference;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.xsd.XSDSchema;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* @author Kihup Boo
*/
public class WSDLConverter extends DefinitionVisitor
{
private Document doc;
private Element description;
private Element currentTypes;
private Element currentService;
private Element currentEndpoint;
private Element currentInterface;
private Element currentOperation;
private Element currentBinding;
private Element currentBindingOperation;
private Element currentBindingInput;
private Element currentBindingOutput;
private Element currentBindingFault;
private String wsdlNamespacePrefix;
private String xsdNamespacePrefix;
// Added for JUnit
public WSDLConverter(String name)
{
super(name);
}
/**
* @param definition
*/
public WSDLConverter(Definition definition)
{
super(definition);
// TODO Auto-generated constructor stub
}
public void generate20(String filename) throws Exception
{
createDocument();
visit();
serialize(filename);
}
private void serialize(String filename) throws Exception
{
Source domSource = new DOMSource(doc);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(domSource, new StreamResult(new FileOutputStream(filename)));
}
private void createDocument() throws ParserConfigurationException
{
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
}
private Element createWSDLElement(String name)
{
Element element = doc.createElementNS("http://www.w3.org/2004/08/wsdl", name);
if (wsdlNamespacePrefix != null)
element.setPrefix(wsdlNamespacePrefix);
return element;
}
private void processDocumentation(Element docElement, Element parent)
{
if (docElement == null)
return;
Element adoptedDocElement = (Element)doc.importNode(docElement, true);
parent.appendChild(adoptedDocElement);
}
protected void visitDefinition(Definition def)
{
description = createWSDLElement("description");
processDocumentation(def.getDocumentationElement(), description);
// TBD - Determine later if we want to convert the document to use SOAP 1.2.
// However adding these two namespaces may not be harmful.
description.setAttribute("xmlns:soapenv", "http://www.w3.org/2003/05/soap-envelop");
description.setAttribute("xmlns:wsoap", "http://www.w3.org/2004/08/soap12");
String targetNamespace = def.getTargetNamespace();
if (targetNamespace != null)
description.setAttribute("targetNamespace", targetNamespace);
Iterator iterator = def.getNamespaces().keySet().iterator();
String prefix = null;
String namespace = null;
/*
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"*/
while (iterator.hasNext())
{
prefix = (String)iterator.next();
namespace = def.getNamespace(prefix);
if ("http://schemas.xmlsoap.org/wsdl/".equals(namespace))
{
if (prefix.length() == 0) // meant to be default namespace
description.setAttribute("xmlns", "http://www.w3.org/2004/08/wsdl");
else
{
description.setAttribute("xmlns:" + prefix, "http://www.w3.org/2004/08/wsdl");
wsdlNamespacePrefix = prefix;
description.setPrefix(wsdlNamespacePrefix);
}
continue;
}
// SOAP 1.2
if ("http://schemas.xmlsoap.org/wsdl/soap/".equals(namespace))
{
// SOAP 1.2
description.setAttribute("xmlns:" + prefix, "http://www.w3.org/2003/05/soap-envelop");
// WSDL 2.0 binding for SOAP 1.2
description.setAttribute("xmlns:wsoap", "http://www.w3.org/2004/08/soap12");
continue;
}
//if ("http://schemas.xmlsoap.org/soap/encoding/".equals(namespace))
// continue;
if ("http://www.w3.org/2001/XMLSchema".equals(namespace))
xsdNamespacePrefix = prefix; // We will use this in visitImport().
if (prefix.length() == 0) // meant to be default namespace
description.setAttribute("xmlns" + prefix, namespace);
else
description.setAttribute("xmlns:" + prefix, namespace);
}
doc.appendChild(description);
super.visitDefinition(def);
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitImport(org.eclipse.wst.wsdl.Import)
*/
protected void visitImport(Import wsdlImport)
{
// Determine if we <import> a schema.
if (importingSchema(wsdlImport))
{
currentTypes = createWSDLElement("types");
description.appendChild(currentTypes);
// <xs:import namespace="http://foo.com" schemaLocation= "bar.xsd"/>
Element schemaImport = doc.createElementNS("http://www.w3.org/2001/XMLSchema", "import");
if (xsdNamespacePrefix == null) // need to add one
{
description.setAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
xsdNamespacePrefix = "xs";
schemaImport.setPrefix(xsdNamespacePrefix);
}
else if (!"".equals(xsdNamespacePrefix)) // it is not default namespace
schemaImport.setPrefix(xsdNamespacePrefix);
schemaImport.setAttribute("namespace", wsdlImport.getNamespaceURI());
schemaImport.setAttribute("schemaLocation", wsdlImport.getLocationURI());
processDocumentation(wsdlImport.getDocumentationElement(), schemaImport);
currentTypes.appendChild(schemaImport);
}
else
{
Element importElement = wsdlImport.getElement();
Element adoptedImportElement = (Element)doc.importNode(importElement, true);
processDocumentation(wsdlImport.getDocumentationElement(), adoptedImportElement);
description.appendChild(adoptedImportElement);
}
}
private boolean importingSchema(Import myImport)
{
if (myImport.getDefinition() != null) // it is WSDL import
return false;
else
return true;
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitTypes(org.eclipse.wst.wsdl.Types)
*/
protected void visitTypes(Types types)
{
// currentTypes may have been created in visitImport().
if (currentTypes == null)
{
currentTypes = createWSDLElement("types");
processDocumentation(types.getDocumentationElement(), currentTypes);
description.appendChild(currentTypes);
}
Iterator iterator = types.getSchemas().iterator();
XSDSchema schema = null;
Element schemaElement = null;
Element adoptedSchemaElement = null;
while (iterator.hasNext())
{
schema = (XSDSchema)iterator.next();
schema.updateElement();
schemaElement = schema.getElement();
adoptedSchemaElement = (Element)doc.importNode(schemaElement, true);
currentTypes.appendChild(adoptedSchemaElement);
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitPart(org.eclipse.wst.wsdl.Part)
*/
protected void visitPart(Part part)
{
// TODO Auto-generated method stub
}
protected void visitPortType(PortType portType)
{
currentInterface = createWSDLElement("interface");
processDocumentation(portType.getDocumentationElement(), currentInterface);
Element portTypeElement = portType.getElement();
if (portTypeElement.hasAttribute("name"))
currentInterface.setAttribute("name", portTypeElement.getAttribute("name"));
description.appendChild(currentInterface);
super.visitPortType(portType);
}
protected void visitOperation(Operation operation)
{
currentOperation = createWSDLElement("operation");
processDocumentation(operation.getDocumentationElement(), currentOperation);
Element operationElement = operation.getElement();
if (operationElement.hasAttribute("name"))
currentOperation.setAttribute("name", operationElement.getAttribute("name"));
OperationType opType = operation.getStyle();
if (OperationType.REQUEST_RESPONSE == opType)
currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/in-out");
else if (OperationType.SOLICIT_RESPONSE == opType)
currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/out-in");
else if (OperationType.NOTIFICATION == opType)
currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/out-only");
else if (OperationType.ONE_WAY == opType)
currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/in-only");
currentInterface.appendChild(currentOperation);
super.visitOperation(operation);
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitInput(org.eclipse.wst.wsdl.Input)
*/
protected void visitInput(Input input)
{
Element currentInput = createWSDLElement("input");
processDocumentation(input.getDocumentationElement(), currentInput);
Element inputElement = input.getElement();
if (inputElement.hasAttribute("name"))
currentInput.setAttribute("messageLabel", inputElement.getAttribute("name"));
Element partElement = getPartElement(input);
if (partElement.hasAttribute("element"))
currentInput.setAttribute("element", partElement.getAttribute("element"));
// TBD - what if the part uses "type"?
currentOperation.appendChild(currentInput);
}
private Element getPartElement(MessageReference messageRef)
{
Iterator iterator = messageRef.getEMessage().getEParts().iterator();
// TBD - for now, take the first part.
Part part = (Part)iterator.next();
Element partElement = part.getElement();
return partElement;
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitOutput(org.eclipse.wst.wsdl.Output)
*/
protected void visitOutput(Output output)
{
Element currentOutput = createWSDLElement("output");
processDocumentation(output.getDocumentationElement(), currentOutput);
Element outputElement = output.getElement();
if (outputElement.hasAttribute("name"))
currentOutput.setAttribute("messageLabel", outputElement.getAttribute("name"));
Element partElement = getPartElement(output);
if (partElement.hasAttribute("element"))
currentOutput.setAttribute("element", partElement.getAttribute("element"));
// TBD - what if the part uses "type"?
currentOperation.appendChild(currentOutput);
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitFault(org.eclipse.wst.wsdl.Fault)
*/
protected void visitFault(Fault fault)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitBinding(org.eclipse.wst.wsdl.Binding)
*/
protected void visitBinding(Binding binding)
{
currentBinding = createWSDLElement("binding");
processDocumentation(binding.getDocumentationElement(), currentBinding);
Element bindingElement = binding.getElement();
if (bindingElement.hasAttribute("name"))
currentBinding.setAttribute("name", bindingElement.getAttribute("name"));
if (bindingElement.hasAttribute("type"))
currentBinding.setAttribute("interface", bindingElement.getAttribute("type"));
// TBD - is the next line fixed for SOAP?
currentBinding.setAttribute("type", "http://www.w3.org/2004/08/wsdl/soap12");
currentBinding.setAttribute("wsoap:protocol", "http://www.w3.org/2003/05/soap/bindings/HTTP");
currentBinding.setAttribute("wsoap:mepDefault", "http://www.w3.org.2003/05/soap/mep/request-response");
description.appendChild(currentBinding);
super.visitBinding(binding);
}
protected void visitBindingOperation(BindingOperation operation)
{
currentBindingOperation = createWSDLElement("operation");
processDocumentation(operation.getDocumentationElement(), currentBindingOperation);
String operationName = operation.getEOperation().getName();
// Determine prefix
String prefix = null;
String targetNamespace = null;
Definition def = operation.getEnclosingDefinition();
if (def != null)
targetNamespace = def.getTargetNamespace();
if (targetNamespace != null)
prefix = def.getPrefix(targetNamespace);
if (prefix == null)
prefix = "";
else
prefix += ":";
currentBindingOperation.setAttribute("ref", prefix + operationName);
currentBinding.appendChild(currentBindingOperation);
super.visitBindingOperation(operation);
}
protected void visitBindingInput(BindingInput input)
{
currentBindingInput = createWSDLElement("input");
processDocumentation(input.getDocumentationElement(), currentBindingInput);
Element inputElement = input.getElement();
String inputName = input.getName();
if (inputName != null)
inputElement.setAttribute("name", inputName);
currentBindingOperation.appendChild(currentBindingInput);
super.visitBindingInput(input);
}
protected void visitBindingOutput(BindingOutput output)
{
currentBindingOutput = createWSDLElement("output");
processDocumentation(output.getDocumentationElement(), currentBindingOutput);
Element outputElement = output.getElement();
String outputName = output.getName();
if (outputName != null)
outputElement.setAttribute("name", outputName);
currentBindingOperation.appendChild(currentBindingOutput);
super.visitBindingOutput(output);
}
protected void visitBindingFault(BindingFault fault)
{
currentBindingFault = createWSDLElement("fault");
processDocumentation(fault.getDocumentationElement(), currentBindingFault);
Element faultElement = fault.getElement();
String faultName = fault.getName();
if (faultName != null)
faultElement.setAttribute("name", faultName);
currentBindingOperation.appendChild(currentBindingFault);
super.visitBindingFault(fault);
}
protected void visitService(Service service)
{
currentService = createWSDLElement("service");
processDocumentation(service.getDocumentationElement(), currentService);
Element serviceElement = service.getElement();
if (serviceElement.hasAttribute("name"))
currentService.setAttribute("name", serviceElement.getAttribute("name"));
description.appendChild(currentService);
super.visitService(service);
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitPort(org.eclipse.wst.wsdl.Port)
*/
protected void visitPort(Port port)
{
currentEndpoint = createWSDLElement("endpoint");
processDocumentation(port.getDocumentationElement(), currentEndpoint);
Element portElement = port.getElement();
if (portElement.hasAttribute("name"))
currentEndpoint.setAttribute("name", portElement.getAttribute("name"));
if (portElement.hasAttribute("binding"))
currentEndpoint.setAttribute("binding", portElement.getAttribute("binding"));
// Add interface to current service
Binding binding = port.getEBinding();
if (binding != null) // binding could not be resolved
{
Element bindingElement = binding.getElement();
if (bindingElement.hasAttribute("type"))
currentService.setAttribute("interface", bindingElement.getAttribute("type"));
}
currentService.appendChild(currentEndpoint);
super.visitPort(port);
}
/* (non-Javadoc)
* @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitExtensibilityElement(org.eclipse.wst.wsdl.ExtensibleElement, org.eclipse.wst.wsdl.ExtensibilityElement)
*/
protected void visitExtensibilityElement(ExtensibleElement owner, ExtensibilityElement extensibilityElement)
{
// TBD - It is not just SOAP binding
if (owner instanceof org.eclipse.wst.wsdl.internal.impl.PortImpl)
{
Element soapElement = extensibilityElement.getElement();
if (soapElement.hasAttribute("location"))
currentEndpoint.setAttribute("address", soapElement.getAttribute("location"));
}
else
{
Element domElement = extensibilityElement.getElement();
Element adoptedDOMElement = (Element)doc.importNode(domElement, true);
if (owner instanceof org.eclipse.wst.wsdl.internal.impl.DefinitionImpl)
description.insertBefore(adoptedDOMElement, description.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.ServiceImpl)
currentService.insertBefore(adoptedDOMElement, currentService.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.PortTypeImpl)
currentInterface.insertBefore(adoptedDOMElement, currentInterface.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.OperationImpl)
currentOperation.insertBefore(adoptedDOMElement, currentOperation.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingImpl)
currentBinding.insertBefore(adoptedDOMElement, currentBinding.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingOperationImpl)
currentBindingOperation.insertBefore(adoptedDOMElement, currentBindingOperation.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingInputImpl)
currentBindingInput.insertBefore(adoptedDOMElement, currentBindingInput.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingOutputImpl)
currentBindingOutput.insertBefore(adoptedDOMElement, currentBindingOutput.getFirstChild());
else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingFaultImpl)
currentBindingFault.insertBefore(adoptedDOMElement, currentBindingFault.getFirstChild());
}
}
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new WSDLConverter("Convert")
{
protected void runTest()
{
testConvert();
}
});
return suite;
}
public void testConvert()
{
try
{
Definition def = DefinitionLoader.load("d:/eclipse301/eclipse/workspace/org.eclipse.wst.wsdl.tests/PTATimeDistribution.wsdl");
WSDLConverter converter = new WSDLConverter(def);
converter.generate20("d:/eclipse301/eclipse/workspace/org.eclipse.wst.wsdl.tests/PTATimeDistribution20.wsdl");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
/*
try
{
Definition def = DefinitionLoader.load(args[0]);
WSDLConverter converter = new WSDLConverter(def);
converter.generate20("test20.wsdl");
}
catch (Exception e)
{
e.printStackTrace();
}*/
}
}