You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sc...@apache.org on 2008/01/21 18:07:42 UTC

svn commit: r613936 - /webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java

Author: scheu
Date: Mon Jan 21 09:07:42 2008
New Revision: 613936

URL: http://svn.apache.org/viewvc?rev=613936&view=rev
Log:
AXIS2-3457
Contributor:Rich Scheuerle
Changed WSDL11ToAxisServiceBuilder to support HTTP binding operations that
reference messages whose parts are elements.   In addition, I added some more trace.

Modified:
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java?rev=613936&r1=613935&r2=613936&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/WSDL11ToAxisServiceBuilder.java Mon Jan 21 09:07:42 2008
@@ -158,9 +158,11 @@
     public static final String ENCODED_USE = "encoded";
 
     /**
-     * Keeps a list of processable operations initiate to an empty list
+     * List of BindingOperationEntry objects.
+     * Each object in the list may require a wrapped schema element for 
+     * the input/output or both.
      */
-    private List wrappableOperations = new ArrayList();
+    private List wrappableBOEs = new ArrayList();
     // used to keep the binding type of the selected binding
     private String bindingType;
 
@@ -672,9 +674,11 @@
                 }
 
                 if (isSetMessageQNames) {
+                    BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
+                    boolean isWrapped = (boe == null) ? false : boe.isWrappedInput();
                     addQNameReference(axisInMessage, wsdl4jOperation,
                                       wsdl4jBindingInput,
-                                      wrappableOperations.contains(wsdl4jBindingOperation));
+                                      isWrapped);
                 }
 
                 axisBindingInMessage.setAxisMessage(axisInMessage);
@@ -710,9 +714,11 @@
                 }
 
                 if (isSetMessageQNames) {
+                    BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
+                    boolean isWrapped = (boe == null) ? false : boe.isWrappedOutput();
                     addQNameReference(axisOutMessage, wsdl4jOperation,
                                       wsdl4jBindingOutput,
-                                      wrappableOperations.contains(wsdl4jBindingOperation));
+                                      isWrapped);
                 }
 
 
@@ -1462,11 +1468,11 @@
         // findwrappable operations return either the rpc soap operations or
         // Http binding operations
 
-        List wrappableBindingOperationsList = findWrappableBindingOperations(wsdl4jBinding);
+        List wrappableBOEList = findWrappableBindingOperations(wsdl4jBinding);
 
         // this method returns all the new schemas created when processing the rpc messages
         Map newSchemaMap = createSchemaForPorttype(porttypeNamespaceURI,
-                                                   wrappableBindingOperationsList,
+                                                   wrappableBOEList,
                                                    schemaMap);
 
         schemaElementList.addAll(newSchemaMap.values());
@@ -1477,12 +1483,14 @@
     /**
      * Create a schema by looking at the port type
      *
-     * @param namespaceURI - namespace of the porttype uri we use this only if a user has not specified
-     *                     a namespace in soap:body
+     * @param namespaceURI - namespace of the porttype uri.
+     *  we use this only if a user has not specified a namespace in soap:body
+     * @param boeListToProcess - List of BindingOperationEntry objects which require wrappering
+     *                     
      * @return null if there is no element
      */
     private Map createSchemaForPorttype(String namespaceURI,
-                                        List operationListToProcess,
+                                        List boeListToProcess,
                                         Map existingSchemaMap) {
 
         // this map is used to keep the newly added schemas
@@ -1490,7 +1498,7 @@
         // first of all look at the operations list
         // we can return immediately if we get the operations list
         // as empty
-        if (operationListToProcess.isEmpty()) {
+        if (boeListToProcess.isEmpty()) {
             return newSchemaMap;
         }
 
@@ -1498,8 +1506,8 @@
         // messages
         // from the operations
         Map messageQnameToMessageMap = new HashMap();
-        Map operationToInputMessageMap = new HashMap();
-        Map operationToOutputMessageMap = new HashMap();
+        Map boeToInputMessageMap = new HashMap();
+        Map boeToOutputMessageMap = new HashMap();
 
         // this contains the required namespace imports. the key in this
         // map would be the namaspace URI
@@ -1513,22 +1521,22 @@
         // //////////////////////////////////////////////////////////////////////////////////////////////////
 
         // we really need to do this for a single porttype!
-        BindingOperation op;
-        for (int k = 0; k < operationListToProcess.size(); k++) {
-            op = (BindingOperation) operationListToProcess.get(k);
-            Input input = op.getOperation().getInput();
+        BindingOperationEntry boe;
+        for (int k = 0; k < boeListToProcess.size(); k++) {
+            boe = (BindingOperationEntry) boeListToProcess.get(k);
+            Input input = boe.getBindingOperation().getOperation().getInput();
             Message message;
             if (input != null) {
                 message = input.getMessage();
                 messageQnameToMessageMap.put(message.getQName(), message);
-                operationToInputMessageMap.put(op, message);
+                boeToInputMessageMap.put(boe, message);
             }
 
-            Output output = op.getOperation().getOutput();
+            Output output = boe.getBindingOperation().getOperation().getOutput();
             if (output != null) {
                 message = output.getMessage();
                 messageQnameToMessageMap.put(message.getQName(), message);
-                operationToOutputMessageMap.put(op, message);
+                boeToOutputMessageMap.put(boe, message);
             }
 
             // we do not want to process fault messages since they can only be used as document type
@@ -1543,19 +1551,19 @@
         Element elementDeclaration;
 
         //loop through the input op map and generate the elements
-        BindingOperation operation;
-        for (Iterator operationsIter = operationToInputMessageMap.keySet().iterator();
-             operationsIter.hasNext();) {
+        BindingOperationEntry boEntry;
+        for (Iterator boeIter = boeToInputMessageMap.keySet().iterator();
+             boeIter.hasNext();) {
 
-            operation = (BindingOperation) operationsIter.next();
+            boEntry = (BindingOperationEntry) boeIter.next();
             elementDeclaration = document.createElementNS(
                     XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
                                              + XML_SCHEMA_ELEMENT_LOCAL_NAME);
-            elementDeclaration.setAttribute(XSD_NAME, operation.getName());
+            elementDeclaration.setAttribute(XSD_NAME, boEntry.getBindingOperation().getName());
 
             //when creating the inner complex type we have to find the parts list from the binding input
-            BindingInput bindingInput = operation.getBindingInput();
-            Message message = (Message) operationToInputMessageMap.get(operation);
+            BindingInput bindingInput = boEntry.getBindingOperation().getBindingInput();
+            Message message = (Message) boeToInputMessageMap.get(boEntry);
 
             if (bindingInput != null) {
 
@@ -1574,7 +1582,8 @@
                     partsCollection = message.getParts().values();
                 }
 
-                List parameterOrder = operation.getOperation().getParameterOrdering();
+                List parameterOrder = 
+                   boEntry.getBindingOperation().getOperation().getParameterOrdering();
                 namespaceImportsMap = new HashMap();
                 namespacePrefixMap = new HashMap();
 
@@ -1584,7 +1593,8 @@
                                                          parameterOrder,
                                                          false,
                                                          namespaceImportsMap,
-                                                         namespacePrefixMap);
+                                                         namespacePrefixMap, 
+                                                         boEntry);
 
                 elementDeclaration.appendChild(newComplexType);
                 String namespaceToUse = namespaceURI;
@@ -1620,22 +1630,22 @@
                                                                    xsdPrefix);
                     newSchemaMap.put(namespaceToUse, newSchema);
                 }
-                resolvedRpcWrappedElementMap.put(operation.getName(), new QName(
-                        namespaceToUse, operation.getName(), AXIS2WRAPPED));
+                resolvedRpcWrappedElementMap.put(boEntry.getBindingOperation().getName(), new QName(
+                        namespaceToUse, boEntry.getBindingOperation().getName(), AXIS2WRAPPED));
 
             } else {
                 throw new WSDLProcessingException(
                         "No binding input is defiend for binding operation ==> "
-                        + operation.getName());
+                        + boEntry.getBindingOperation().getName());
             }
 
         }
 
         // loop through the output to map and generate the elements
-        for (Iterator operationsIterator = operationToOutputMessageMap.keySet().iterator();
-             operationsIterator.hasNext();) {
-            operation = (BindingOperation) operationsIterator.next();
-            String baseoutputOpName = operation.getName();
+        for (Iterator boeIterator = boeToOutputMessageMap.keySet().iterator();
+             boeIterator.hasNext();) {
+            boEntry = (BindingOperationEntry) boeIterator.next();
+            String baseoutputOpName = boEntry.getBindingOperation().getName();
             // see basic profile 4.7.19
             String outputOpName = baseoutputOpName + WRAPPED_OUTPUTNAME_SUFFIX;
             elementDeclaration = document.createElementNS(
@@ -1643,8 +1653,8 @@
                                              + XML_SCHEMA_ELEMENT_LOCAL_NAME);
             elementDeclaration.setAttribute(XSD_NAME, outputOpName);
 
-            BindingOutput bindingOutput = operation.getBindingOutput();
-            Message message = (Message) operationToOutputMessageMap.get(operation);
+            BindingOutput bindingOutput = boEntry.getBindingOperation().getBindingOutput();
+            Message message = (Message) boeToOutputMessageMap.get(boEntry);
 
             if (bindingOutput != null) {
                 Collection partsCollection = null;
@@ -1663,7 +1673,8 @@
                     partsCollection = message.getParts().values();
                 }
 
-                List parameterOrder = operation.getOperation().getParameterOrdering();
+                List parameterOrder = 
+                    boEntry.getBindingOperation().getOperation().getParameterOrdering();
 
                 // we have to initialize the hash maps always since we add the elements onece we
                 // generate it
@@ -1676,7 +1687,8 @@
                                                          parameterOrder,
                                                          true,
                                                          namespaceImportsMap,
-                                                         namespacePrefixMap);
+                                                         namespacePrefixMap,
+                                                         boEntry);
                 elementDeclaration.appendChild(newComplexType);
 
                 String namespaceToUse = namespaceURI;
@@ -1718,7 +1730,7 @@
             } else {
                 throw new WSDLProcessingException(
                         "No binding out put is defined for binding operation ==>" +
-                        operation.getName());
+                        boEntry.getBindingOperation().getName());
             }
         }
 
@@ -1877,6 +1889,7 @@
      * @param isOutMessage
      * @param namespaceImportsMap
      * @param namespacePrefixMap
+     * @param boe BindingOperationEntry for this partCollection
      * @return new element
      */
     private Element getNewComplextType(Document document,
@@ -1885,7 +1898,8 @@
                                        List parameterOrder,
                                        boolean isOutMessage,
                                        Map namespaceImportsMap,
-                                       Map namespacePrefixMap) {
+                                       Map namespacePrefixMap,
+                                       BindingOperationEntry boe) {
         // add the complex type
         Element newComplexType = document.createElementNS(
                 XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
@@ -1906,7 +1920,9 @@
                                  xsdPrefix,
                                  namespaceImportsMap,
                                  namespacePrefixMap,
-                                 cmplxTypeSequence);
+                                 cmplxTypeSequence,
+                                 isOutMessage,
+                                 boe);
 
             }
         } else {
@@ -1928,11 +1944,13 @@
                                      xsdPrefix,
                                      namespaceImportsMap,
                                      namespacePrefixMap,
-                                     cmplxTypeSequence);
+                                     cmplxTypeSequence, 
+                                     isOutMessage,
+                                     boe);
                     partsMap.remove(partName);
                 }
             }
-            // if this is an out put message then we have to set the
+            // if this is an output message then we have to set the
             // return type if exists
             if (isOutMessage) {
                 if (partsMap.size() > 0) {
@@ -1940,13 +1958,15 @@
                         part = (Part) partsMap.values().iterator().next();
                         // change the name of this part
                         // this is the return type and its name should be result
-//                        part.setName("result");
+                        // part.setName("result");
                         addPartToElement(part,
                                          document,
                                          xsdPrefix,
                                          namespaceImportsMap,
                                          namespacePrefixMap,
-                                         cmplxTypeSequence);
+                                         cmplxTypeSequence,
+                                         isOutMessage,
+                                         boe);
                     } else {
                         throw new WSDLProcessingException("the parameter order can left atmost" +
                                                           " one part");
@@ -1959,12 +1979,24 @@
         return newComplexType;
     }
 
+    /**
+     * @param part
+     * @param document
+     * @param xsdPrefix
+     * @param namespaceImportsMap
+     * @param namespacePrefixMap
+     * @param cmplxTypeSequence
+     * @param isOutMessage (true is part is referenced by the output clause)
+     * @param boe BindingOperationEntry that caused the creation of this part.
+     */
     private void addPartToElement(Part part,
                                   Document document,
                                   String xsdPrefix,
                                   Map namespaceImportsMap,
                                   Map namespacePrefixMap,
-                                  Element cmplxTypeSequence) {
+                                  Element cmplxTypeSequence,
+                                  boolean isOutMessage,
+                                  BindingOperationEntry boe) {
         Element child;
         String elementName = part.getName();
 
@@ -2013,9 +2045,34 @@
             cmplxTypeSequence.appendChild(child);
 
         } else {
-            // see the basic profile 4.4.1 for rpc-literal messages parts can have only types
-            throw new WSDLProcessingException("RPC-literal type message part " +
-                                              part.getName() + " should have a type attribute ");
+            String bindingOperationName = boe.getBindingOperation().getName();
+            String partName = part.getName();
+            if (boe.isRPC()) {
+                // see the basic profile 4.4.1 for rpc-literal.
+                // messages parts can have only types
+                throw new WSDLProcessingException(
+                   "The binding operation " + bindingOperationName + " is RPC/literal. " +
+                   "The message parts for this operation must use the type " +
+                   "attribute as specificed by " +
+                   "WS-I Basic Profile specification (4.4.1).  Message part, " + 
+                   partName + ", violates" +
+                   "this rule.  Please remove the element attribute " +
+                   "and use the type attribute.");
+            } else {
+                // The presense of an element means that a wrapper xsd element is not needed.
+                if (isOutMessage) {
+                    boe.setWrappedOutput(false);
+                } else {
+                    boe.setWrappedOutput(false);
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug("The binding operation " + bindingOperationName + 
+                              " references message part " +
+                              partName + ".  This part does not use the " +
+                              "type attribute, so a wrappering element is not added.");
+                }
+            }
+            
         }
     }
 
@@ -2483,6 +2540,7 @@
      * Look for the wrappable operations depending on the style
      *
      * @param binding
+     * @return List of BindingOperationEntry objects
      */
     private List findWrappableBindingOperations(Binding binding) {
         // first find the global style declaration.
@@ -2523,6 +2581,13 @@
                 this.bindingType = BINDING_TYPE_HTTP;
             }
         }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Binding Name    =" + binding.getQName());
+            log.debug("  isSOAPBinding =" + isSOAPBinding );
+            log.debug("  isHttpBinding =" + isHttpBinding );
+            log.debug("  isRPC         =" + isRPC );
+        }
 
         // go through every operation and get their styles.
         // each one can have a style override from the global
@@ -2536,23 +2601,57 @@
                     binding.getBindingOperations().iterator(); bindingOperationsIterator.hasNext();)
             {
                 bindingOp = (BindingOperation) bindingOperationsIterator.next();
+                
+                if (log.isDebugEnabled()) {
+                    log.debug("  Binding Operation  =" + bindingOp.getName());
+                }
                 if (isSOAPBinding) {
                     String style = getSOAPStyle(bindingOp);
+                    if (log.isDebugEnabled()) {
+                        log.debug("    SOAPStyle  =" + style);
+                    }
                     if (style == null) {
                         // no style specified
                         // use the global style to determine whether to put this one or
                         // not
                         if (isRPC) {
-                            returnList.add(bindingOp);
+                            if (log.isDebugEnabled()) {
+                                log.debug("    schema wrappering required");
+                            }
+                            BindingOperationEntry boe = 
+                                new BindingOperationEntry(bindingOp, 
+                                                          true, 
+                                                          false,
+                                                          style,
+                                                          true);
+                            returnList.add(boe);
                         }
                     } else if (RPC_STYLE.equals(style)) {
                         // add to the list
-                        returnList.add(bindingOp);
+                        if (log.isDebugEnabled()) {
+                            log.debug("    schema wrappering required");
+                        }
+                        BindingOperationEntry boe = 
+                            new BindingOperationEntry(bindingOp, 
+                                                      true, 
+                                                      false,
+                                                      style,
+                                                      true);
+                        returnList.add(boe);
                     }
                     // if not RPC we just leave it - default is doc
                 } else {
                     // i.e an http binding then we have to add the operation any way
-                    returnList.add(bindingOp);
+                    if (log.isDebugEnabled()) {
+                        log.debug("    schema wrappering required");
+                    }
+                    BindingOperationEntry boe = 
+                        new BindingOperationEntry(bindingOp, 
+                                                  false, 
+                                                  true,
+                                                  null,
+                                                  false);
+                    returnList.add(boe);
                 }
             }
         }
@@ -2560,7 +2659,7 @@
         // if the binding is not either soap or http binding then we return and empty list
 
         // set this to the global list
-        wrappableOperations = returnList;
+        wrappableBOEs = returnList;
         return returnList;
     }
 
@@ -2857,5 +2956,88 @@
             }
         }
         return isAvailable;
+    }
+    
+    /**
+     * Find BindingOperationEntry
+     * @param boes List of BindingOperationEntry
+     * @param bo BindingOperation 
+     * @return BindingOperation or null
+     */
+    private BindingOperationEntry find(List boes, BindingOperation bo) {
+        for (int i=0; i < boes.size(); i++) {
+            BindingOperationEntry boe = (BindingOperationEntry) boes.get(i);
+            if (boe.getBindingOperation() == bo) {
+                return boe;
+            }
+        }
+        return null;
+    }
+    /**
+     * BindingOperation plus state information
+     */
+    class BindingOperationEntry {
+        
+        private BindingOperation bindingOperation;
+        private boolean isSOAPBinding;
+        private boolean isHTTPBinding;
+        private String soapStyle;
+        private boolean isRPC;
+        private boolean wrappedInput = true;
+        private boolean wrappedOutput = true;
+        
+        public BindingOperationEntry(BindingOperation bindingOperation, boolean isSOAPBinding, boolean isHTTPBinding, String soapStyle, boolean isRPC) {
+            super();
+            this.bindingOperation = bindingOperation;
+            this.isSOAPBinding = isSOAPBinding;
+            this.isHTTPBinding = isHTTPBinding;
+            this.soapStyle = soapStyle;
+            this.isRPC = isRPC;
+        }
+        
+        public boolean isHTTPBinding() {
+            return isHTTPBinding;
+        }
+        public boolean isSOAPBinding() {
+            return isSOAPBinding;
+        }
+        public String getSoapStyle() {
+            return soapStyle;
+        }
+        
+        public boolean isRPC() {
+            return isRPC;
+        }
+        public BindingOperation getBindingOperation() {
+            return bindingOperation;
+        }
+
+        /**
+         * @return true if wrapper xsd is used
+         */
+        public boolean isWrappedInput() {
+            return wrappedInput;
+        }
+
+        /**
+         * @param wrappedInput indicate if wrapper xsd is needed
+         */
+        public void setWrappedInput(boolean wrappedInput) {
+            this.wrappedInput = wrappedInput;
+        }
+
+        /**
+         * @return true if wrapper xsd is needed for the output message
+         */
+        public boolean isWrappedOutput() {
+            return wrappedOutput;
+        }
+
+        /**
+         * @param wrappedOutput indicate if wrapper xsd is needed on the output message
+         */
+        public void setWrappedOutput(boolean wrappedOutput) {
+            this.wrappedOutput = wrappedOutput;
+        }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org