You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by to...@apache.org on 2001/09/14 22:08:09 UTC
cvs commit: xml-axis/java/src/org/apache/axis/wsdl WsdlAttributes.java Emitter.java
tomj 01/09/14 13:08:09
Modified: java/src/org/apache/axis/wsdl Emitter.java
Added: java/src/org/apache/axis/wsdl WsdlAttributes.java
Log:
Add WSDL attribute class to help track meta data.
Add code to handle use="literal" soap body.
Do not emit code for non-Soap bindings.
Do not emit code for portTypes not mentioned in Soap bindings.
Output WSDL documentation nodes where appropirate.
Fix other various emitter issues.
Revision Changes Path
1.21 +143 -56 xml-axis/java/src/org/apache/axis/wsdl/Emitter.java
Index: Emitter.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/Emitter.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Emitter.java 2001/09/12 14:51:01 1.20
+++ Emitter.java 2001/09/14 20:08:09 1.21
@@ -105,6 +105,7 @@
public class Emitter {
private Document doc = null;
private Definition def = null;
+ private WsdlAttributes wsdlAttr = null;
private boolean bEmitSkeleton = false;
private boolean bMessageContext = false;
private boolean bVerbose = false;
@@ -147,12 +148,26 @@
if (bVerbose && packageName != null) {
System.out.println("Using package name: " + packageName);
}
- writeTypes();
+
+ // Collect information about ports and operations
+ wsdlAttr = new WsdlAttributes(def, new HashMap());
+
+ // output interfaces for portTypes
HashMap portTypesInfo = writePortTypes();
+
+ // Output Stub classes for bindings
writeBindings(portTypesInfo);
+
+ // Output Java classes for types
+ writeTypes();
+
+ // Output factory classes for services
writeServices();
+
+ // Output deploy.xml and undeploy.xml
if (bEmitSkeleton)
writeDeploymentXML();
+
}
catch (WSDLException e) {
e.printStackTrace();
@@ -246,13 +261,13 @@
Input input = operation.getInput();
if (input != null)
- partStrings(v, input.getMessage().getOrderedParts(null));
+ partStrings(v, input.getMessage().getOrderedParts(null), false);
// Collect all the output types
Output output = operation.getOutput();
if (output != null)
- partStrings(v, output.getMessage().getOrderedParts(null));
+ partStrings(v, output.getMessage().getOrderedParts(null), false);
// Collect all the types in faults
Map faults = operation.getFaults();
@@ -261,7 +276,7 @@
Iterator i = faults.values().iterator();
while (i.hasNext())
- partStrings(v, ((Fault) i.next()).getMessage().getOrderedParts(null));
+ partStrings(v, ((Fault) i.next()).getMessage().getOrderedParts(null), false);
}
// Put all these types into a set. This operation eliminates all duplicates.
@@ -306,7 +321,11 @@
while (i.hasNext()) {
PortType portType = (PortType) i.next();
- // FIXME - Skip portTypes that aren't mentioned in a SOAP rpc binding
+ // If this portType wasn't mentioned in a binding we are emitting,
+ // skip it.
+ if (!wsdlAttr.isInSoapBinding(portType)) {
+ continue;
+ }
HashMap portTypeInfo = writePortType(portType);
if (bEmitSkeleton && bMessageContext)
@@ -325,7 +344,7 @@
String fileName = nameValue + ".java";
PrintWriter interfacePW = new PrintWriter(new FileWriter(fileName));
if (bVerbose)
- System.out.println("Generating portType interface: " + nameValue + ".java");
+ System.out.println("Generating portType interface: " + fileName);
writeFileHeader(fileName, interfacePW);
interfacePW.println("public interface " + nameValue + " extends java.rmi.Remote {");
@@ -455,13 +474,23 @@
// Collect the input parts
Input input = operation.getInput();
- if (input != null)
- partStrings(inputs, input.getMessage().getOrderedParts(parameterOrder));
+ if (input != null) {
+ if (wsdlAttr.getInputBodyType(operation) == WsdlAttributes.USE_LITERAL) {
+ partStrings(inputs, input.getMessage().getOrderedParts(parameterOrder), true);
+ } else {
+ partStrings(inputs, input.getMessage().getOrderedParts(parameterOrder), false);
+ }
+ }
// Collect the output parts
Output output = operation.getOutput();
- if (output != null)
- partStrings(outputs, output.getMessage().getOrderedParts(parameterOrder));
+ if (output != null) {
+ if (wsdlAttr.getOutputBodyType(operation) == WsdlAttributes.USE_LITERAL) {
+ partStrings(outputs, output.getMessage().getOrderedParts(parameterOrder), true);
+ } else {
+ partStrings(outputs, output.getMessage().getOrderedParts(parameterOrder), false);
+ }
+ }
if (parameterOrder == null) {
// Get the mode info about the parts. Since no parameterOrder is defined
@@ -473,13 +502,17 @@
p.name = name;
p.type = (String) inputs.get(i - 1);
- for (int j = 1; j < outputs.size(); j += 2)
- if (name.equals(outputs.get(j))) {
- p.mode = Parameter.INOUT;
- outputs.remove(j);
- outputs.remove(j - 1);
- break;
+ // If we have more than 1 output, check for inouts
+ if (outputs.size() > 2) {
+ for (int j = 1; j < outputs.size(); j += 2) {
+ if (name.equals(outputs.get(j))) {
+ p.mode = Parameter.INOUT;
+ outputs.remove(j);
+ outputs.remove(j - 1);
+ break;
+ }
}
+ }
if (p.mode == Parameter.IN)
++parameters.inputs;
else
@@ -636,15 +669,20 @@
* This method returns a vector whose odd numbered elements are element types and whose
* even numbered elements are element values.
*/
- private void partStrings(Vector v, Collection parts) {
+ private void partStrings(Vector v, Collection parts, boolean elements) {
Iterator i = parts.iterator();
while (i.hasNext()) {
Part part = (Part) i.next();
- if (part.getTypeName() != null) {
- v.add(type(part.getTypeName().getLocalPart()));
+ if (elements) {
+ v.add("org.w3c.dom.Element");
v.add(part.getName());
+ } else {
+ if (part.getTypeName() != null) {
+ v.add(type(part.getTypeName().getLocalPart()));
+ v.add(part.getName());
+ }
}
}
} // partStrings
@@ -656,6 +694,7 @@
String name = operation.getName();
Parameters parms = parameters(operation);
+ writeComment(interfacePW, operation.getDocumentationElement());
interfacePW.println(parms.signature + ";");
return parms;
@@ -690,7 +729,7 @@
Vector params = new Vector();
- partStrings(params, operation.getMessage().getOrderedParts(null));
+ partStrings(params, operation.getMessage().getOrderedParts(null), false);
for (int i = 0; i < params.size(); i += 2)
pw.println(" public " + params.get(i) + " " + params.get(i + 1) + ";");
@@ -728,9 +767,10 @@
while (i.hasNext()) {
Binding binding = (Binding) i.next();
- // If this isn't an RPC binding, skip it
- if (!isRpcBinding(binding))
+ // If this isn't a SOAP binding, skip it
+ if (wsdlAttr.getBindingType(binding) != WsdlAttributes.TYPE_SOAP) {
continue;
+ }
HashMap portTypeInfo = (HashMap) portTypesInfo.get(binding.getPortType());
@@ -906,6 +946,7 @@
String name = operation.getName();
+ writeComment(stubPW, operation.getDocumentationElement());
writeStubOperation(name, parms, soapAction, namespace, stubPW);
if (bEmitSkeleton)
writeSkeletonOperation(name, parms, skelPW);
@@ -1108,19 +1149,23 @@
// declare class
servicePW.println("public class " + serviceName + " {");
+ // output comments
+ writeComment(servicePW, service.getDocumentationElement());
+
// get ports
Map portMap = service.getPorts();
Iterator portIterator = portMap.values().iterator();
- // write a get method for each of the ports with a Soap RPC binding
+ // write a get method for each of the ports with a SOAP binding
while (portIterator.hasNext()) {
Port p = (Port) portIterator.next();
String portName = p.getName();
Binding binding = p.getBinding();
- // If this isn't an RPC binding, skip it
- if (!isRpcBinding(binding))
+ // If this isn't an SOAP binding, skip it
+ if (wsdlAttr.getBindingType(binding) != WsdlAttributes.TYPE_SOAP) {
continue;
+ }
String stubClass = binding.getQName().getLocalPart() + "Stub";
String bindingType = binding.getPortType().getQName().getLocalPart();
@@ -1141,6 +1186,7 @@
// Write out the get<PortName> methods
servicePW.println();
servicePW.println(" // Use to get a proxy class for " + portName);
+ writeComment(servicePW, p.getDocumentationElement());
servicePW.println(" private final java.lang.String " + portName + "_address = \"" + address + "\";");
servicePW.println(" public " + bindingType + " get" + portName + "() {");
servicePW.println(" java.net.URL endpoint;");
@@ -1170,24 +1216,6 @@
servicePW.close();
}
- /**
- * Return true if this binding has a <soap:binding style="rpc> attribute
- */
- private boolean isRpcBinding(Binding binding) {
- Iterator i = binding.getExtensibilityElements().iterator();
- while (i.hasNext()) {
- Object obj = i.next();
- if (obj instanceof SOAPBinding) {
- SOAPBinding sb = (SOAPBinding) obj;
- String style = sb.getStyle();
- if (style.equalsIgnoreCase("rpc"))
- return true;
- else
- return false;
- }
- }
- return false;
- }
/**
* Return the endpoint address from a <soap:address location="..."> tag
@@ -1330,15 +1358,7 @@
Binding binding = port.getBinding();
String serviceName = port.getName();
- boolean isRPC = false;
- Iterator operationExtensibilityIterator = binding.getExtensibilityElements().iterator();
- for (; operationExtensibilityIterator.hasNext();) {
- Object obj = operationExtensibilityIterator.next();
- if (obj instanceof SOAPBinding) {
- isRPC = ((SOAPBinding) obj).getStyle().equals("rpc");
- break;
- }
- }
+ boolean isRPC = (wsdlAttr.getBindingStyle(binding) == WsdlAttributes.STYLE_RPC);
deployPW.println(" <service name=\"" + serviceName
+ "\" pivot=\"" + (isRPC ? "RPCDispatcher" : "MsgDispatcher") + "\">");
@@ -1391,7 +1411,10 @@
*/
private void writeType(Node node) throws IOException {
NamedNodeMap attributes = node.getAttributes();
- String nameValue = capitalize(attributes.getNamedItem("name").getNodeValue());
+
+ // scrounge for type name
+ String nameValue = findTypeName(node);
+
String fileName = nameValue + ".java";
PrintWriter typePW = new PrintWriter(new FileWriter(fileName));
if (bVerbose)
@@ -1441,12 +1464,43 @@
} // writeType
/**
+ * Look in the node and the parent node for type name
+ * Example:
+ * <element name="foo">
+ * <complexType>
+ * OR
+ * <complexType name="foo">
+ * ...
+ *
+ */
+ private String findTypeName(Node node) throws IOException {
+ String nameValue = null;
+
+ Node attrNode = node.getAttributes().getNamedItem("name");
+ if (attrNode != null) {
+ nameValue = capitalize(attrNode.getNodeValue());
+ }
+ else {
+ Node n1 = node.getParentNode();
+ NamedNodeMap a1 = n1.getAttributes();
+ Node parentAttrNode = node.getParentNode().getAttributes().getNamedItem("name");
+ if (parentAttrNode != null) {
+ nameValue = parentAttrNode.getNodeValue();
+ }
+ }
+ if (nameValue == null) {
+ throw new IOException("Unable to find type name for " + node.getNodeName());
+ }
+ return nameValue;
+ }
+
+ /**
* Generate the holder for the given complex type.
*/
private void writeHolder(Node type) throws IOException {
NamedNodeMap attributes = type.getAttributes();
- String typeName =
- capitalize(attributes.getNamedItem("name").getNodeValue());
+ String typeName = findTypeName(type);
+
String fileName = typeName + "Holder.java";
PrintWriter pw =
new PrintWriter(new FileWriter(fileName));
@@ -1487,7 +1541,8 @@
} // findNameValue
/**
- * This method returns the complexType node with the given type name. If the given name does not describe a complex type, this method returns null.
+ * This method returns the complexType node with the given type name.
+ * If the given name does not describe a complex type, this method returns null.
*/
private Node complexType(String typeName) {
Vector types = findChildNodesByName(doc, "complexType");
@@ -1536,6 +1591,38 @@
//
// Utility methods
//
+
+ /**
+ * output documentation element as a Java comment
+ */
+ private void writeComment(PrintWriter pw, Element element) {
+ // This control how many characters per line
+ final int LINE_LENGTH = 65;
+
+ if (element == null)
+ return;
+
+ String comment = element.getFirstChild().getNodeValue();
+ if (comment != null) {
+ int start = 0;
+
+ pw.println(); // blank line
+
+ // make the comment look pretty
+ while (start < comment.length()) {
+ int end = start + LINE_LENGTH;
+ if (end > comment.length())
+ end = comment.length();
+ // look for next whitespace
+ while (end < comment.length() &&
+ !Character.isWhitespace(comment.charAt(end))) {
+ end++;
+ }
+ pw.println(" // " + comment.substring(start, end).trim());
+ start = end + 1;
+ }
+ }
+ }
/**
* For a given string, strip off the prefix - everything before the colon.
1.1 xml-axis/java/src/org/apache/axis/wsdl/WsdlAttributes.java
Index: WsdlAttributes.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.wsdl;
import com.ibm.wsdl.extensions.soap.SOAPBody;
import com.ibm.wsdl.extensions.soap.SOAPBinding;
import com.ibm.wsdl.extensions.http.HTTPBinding;
import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Binding;
import javax.wsdl.PortType;
import javax.wsdl.BindingOperation;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
/**
* This class provides attribute storage for elements in the WSDL document
* It is used to answer questions about items that are tough to reach. For
* example finding out something about the operation in a binding when you are
* working with an operation in a portType.
*
* @author Tom Jordahl (tjordahl@macromedia.com)
*/
public class WsdlAttributes {
// The WSDL document
private Definition def;
// Our map of elements and attributes
private HashMap attributes;
// Operation use types
public static final int USE_ENCODED = 0;
public static final int USE_LITERAL = 1;
// Binding styles
public static final int STYLE_RPC = 0;
public static final int STYLE_DOCUMENT = 1;
// Binding types
public static final int TYPE_SOAP = 0;
public static final int TYPE_HTTP_GET = 1;
public static final int TYPE_HTTP_POST = 2;
// init flag
private boolean bInit = false;
/**
* Constructor takes WSDL document and attribute map
*/
public WsdlAttributes(Definition def, HashMap attibutes) {
this.def = def;
this.attributes = attibutes;
init();
}
private synchronized void init() {
if (!bInit) {
scanBindings();
bInit = true;
}
}
///////////////////////////////////////////
// Attribute classes
//
/**
* Contains attributes for Bindings
* - Type: Soap, HTTP get, HTTP post
* - Style: rpc or document
*/
private class BindingAttr {
private int type;
private int style;
public BindingAttr(int type, int style) {
this.type = type;
this.style = style;
}
public boolean isRpc() {
return style == STYLE_RPC;
}
public int getType() {
return type;
}
public int getStyle() {
return style;
}
}
/**
* Contains attributes for Operations
* - Body type: encoded or literal
*/
private class OperationAttr {
private int inputBodyType;
private int outputBodyType;
private int faultBodyType;
public OperationAttr(int inputBodyType, int outputBodyType, int faultBodyType) {
this.inputBodyType = inputBodyType;
this.outputBodyType = outputBodyType;
this.faultBodyType = faultBodyType;
}
public int getInputBodyType() {
return inputBodyType;
}
public int getOutputBodyType() {
return outputBodyType;
}
public int getFaultBodyType() {
return faultBodyType;
}
}
/**
* Contains attributes for PortTypes
* - inSoapBinding - is this portType interesting to wsdl2java
*/
private class PortTypeAttr {
private boolean inSoapBinding;
public PortTypeAttr(boolean inSoapBinding) {
this.inSoapBinding = inSoapBinding;
}
public boolean isInSoapBinding() {
return inSoapBinding;
}
}
////////////////////////////////////////////
// Initialization
//
/**
* Scan the bindings to determine attributes:
* - note binding Style: rpc or document
* - note operations body type: encoded or literal
*
*/
private void scanBindings() {
Map bindings = def.getBindings();
Iterator i = bindings.values().iterator();
int bindingStyle = STYLE_RPC;
int bindingType = TYPE_SOAP;
// loop through each binding
while (i.hasNext()) {
Binding binding = (Binding) i.next();
Iterator ExtensibilityElementsIterator = binding.getExtensibilityElements().iterator();
while (ExtensibilityElementsIterator.hasNext()) {
Object obj = ExtensibilityElementsIterator.next();
if (obj instanceof SOAPBinding) {
bindingType = TYPE_SOAP;
SOAPBinding sb = (SOAPBinding) obj;
String style = sb.getStyle();
if (style.equalsIgnoreCase("rpc")) {
bindingStyle = STYLE_RPC;
}
else if (style.equalsIgnoreCase("document")) {
bindingStyle = STYLE_DOCUMENT;
}
}
else if (obj instanceof HTTPBinding) {
HTTPBinding hb = (HTTPBinding) obj;
if (hb.getVerb().equalsIgnoreCase("post")) {
bindingType = TYPE_HTTP_POST;
}
else {
bindingType = TYPE_HTTP_GET;
}
}
}
attributes.put(binding, new BindingAttr(bindingType, bindingStyle));
PortType port = binding.getPortType();
if (bindingType == TYPE_SOAP) {
attributes.put(port, new PortTypeAttr(true));
} else {
attributes.put(port, new PortTypeAttr(false));
}
// Check the Binding Operations for use="literal"
int inputBodyType = USE_ENCODED;
int outputBodyType = USE_ENCODED;
int faultBodyType = USE_ENCODED;
List bindList = binding.getBindingOperations();
for (Iterator opIterator = bindList.iterator(); opIterator.hasNext();) {
BindingOperation bindOp = (BindingOperation) opIterator.next();
// input
Iterator inIter = bindOp.getBindingInput().getExtensibilityElements().iterator();
for (; inIter.hasNext();) {
Object obj = inIter.next();
if (obj instanceof SOAPBody) {
String use = ((SOAPBody) obj).getUse();
if (use.equalsIgnoreCase("literal")) {
inputBodyType = USE_LITERAL;
}
else {
inputBodyType = USE_ENCODED;
}
}
}
// output
Iterator outIter = bindOp.getBindingOutput().getExtensibilityElements().iterator();
for (; outIter.hasNext();) {
Object obj = outIter.next();
if (obj instanceof SOAPBody) {
String use = ((SOAPBody) obj).getUse();
if (use.equalsIgnoreCase("literal")) {
if (use.equalsIgnoreCase("literal")) {
outputBodyType = USE_LITERAL;
}
else {
outputBodyType = USE_ENCODED;
}
}
}
}
// fault
Iterator faultIter = bindOp.getBindingOutput().getExtensibilityElements().iterator();
for (; faultIter.hasNext();) {
Object obj = faultIter.next();
if (obj instanceof SOAPBody) {
String use = ((SOAPBody) obj).getUse();
if (use.equalsIgnoreCase("literal")) {
if (use.equalsIgnoreCase("literal")) {
faultBodyType = USE_LITERAL;
}
else {
faultBodyType = USE_ENCODED;
}
}
}
}
// Associate the portType operation that goes with this binding
// with the body types.
attributes.put(bindOp.getOperation(),
new OperationAttr(inputBodyType, outputBodyType, faultBodyType));
} // binding operations
} // bindings
return;
} // scanBindings
//////////////////////////////////////////
//
// Operations
//
/**
* Return body type of operation: literal or encoded
*/
public int getInputBodyType(Operation operation) {
OperationAttr attr = (OperationAttr) attributes.get(operation);
if (attr == null) {
// XXX - we may not have seen all operations
return USE_ENCODED;
}
return attr.getInputBodyType();
}
/**
* Return body type of operation: literal or encoded
*/
public int getOutputBodyType(Operation operation) {
OperationAttr attr = (OperationAttr) attributes.get(operation);
if (attr == null) {
// XXX - we may not have seen all operations
return USE_ENCODED;
}
return attr.getInputBodyType();
}
/**
* Return body type of operation: literal or encoded
*/
public int getFaultBodyType(Operation operation) {
OperationAttr attr = (OperationAttr) attributes.get(operation);
if (attr == null) {
// XXX - we may not have seen all operations
return USE_ENCODED;
}
return attr.getInputBodyType();
}
/**
* Return Soap binding style: document or rpc
*/
public int getBindingStyle(Binding binding) {
BindingAttr attr = (BindingAttr) attributes.get(binding);
if (attr == null) {
// defensive code, as we should have seen all bindings
return STYLE_RPC;
}
return attr.getStyle();
}
/**
* Return binding type: Soap, HTTP get, HTTP post
*/
public int getBindingType(Binding binding) {
BindingAttr attr = (BindingAttr) attributes.get(binding);
// defensive code, as we should have seen all bindings
if (attr == null) {
return TYPE_SOAP;
}
return attr.getType();
}
/**
* Return true if this portType is referenced in a Soap binding
*/
public boolean isInSoapBinding(PortType port) {
PortTypeAttr attr = (PortTypeAttr) attributes.get(port);
if (attr == null) {
// we haven't seen it, so its not in a soap binding
return false;
}
return attr.isInSoapBinding();
}
}