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();
      }
  }