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 ba...@apache.org on 2006/12/27 03:10:38 UTC

svn commit: r490427 - in /webservices/axis2/trunk/java/modules: jaxws/src/org/apache/axis2/jaxws/server/ jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/ metadata/src/org/apache/axis2/ja...

Author: barrettj
Date: Tue Dec 26 18:10:37 2006
New Revision: 490427

URL: http://svn.apache.org/viewvc?view=rev&rev=490427
Log:
AXIS2-1878 and other related changes.
Ported the patch attached to 1878 to latest revision; added additional related logic for supporting return types of generics, arrays, 
and primitive types; added additional related fixes to service-implementation-method matching to an OperationDescription; added 
related tests for return type parsing.

Added:
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ReturnTypeParsingTests.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/AsyncPort.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/DocLitWrappedPortImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointInterfaceDescription.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/OperationDescription.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/MethodDescriptionComposite.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ParameterParsingTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java Tue Dec 26 18:10:37 2006
@@ -22,6 +22,7 @@
 import org.apache.axis2.jaxws.core.InvocationContext;
 import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.description.DescriptionFactory;
+import org.apache.axis2.jaxws.description.EndpointDescription;
 import org.apache.axis2.jaxws.description.ServiceDescription;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
@@ -140,9 +141,11 @@
         
         //Check to see if we've already created a ServiceDescription for this
         //service before trying to create a new one. 
-        if (axisSvc.getParameter("JAXWS_SERVICE_DESCRIPTION") != null) {
-            Parameter param = axisSvc.getParameter("JAXWS_SERVICE_DESCRIPTION");
-            ServiceDescription sd = (ServiceDescription) param.getValue();
+        
+        if (axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER) != null) {
+            Parameter param = axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER);
+            
+            ServiceDescription sd = ((EndpointDescription) param.getValue()).getServiceDescription();
             return sd;
         }
         else {

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java Tue Dec 26 18:10:37 2006
@@ -149,21 +149,19 @@
         EndpointDescription ed = eds[0];
         EndpointInterfaceDescription eid = ed.getEndpointInterfaceDescription();
         
-        OperationDescription[] ops = eid.getOperation(mc.getOperationName());
-        String methodName = mc.getOperationName().getLocalPart();
-        for (OperationDescription op:ops) {
-        	Method method = op.getSEIMethod();
-        	if (method.getName().equals(methodName)) {
-        		if (log.isDebugEnabled()) {
-                    log.debug("wsdl operation: " + op.getName());
-                    log.debug("   java method: " + op.getJavaMethodName());
-                }
-        		return op;
-        	}
-        			
+        OperationDescription[] ops = eid.getDispatchableOperation(mc.getOperationName());
+        // TODO: Implement signature matching.  Currently only matching on the wsdl:OperationName is supported.
+        //       That means that overloading of wsdl operations is not supported (although that's not supported in 
+        //       WSDL 1.1 anyway).
+        if (ops == null || ops.length == 0) {
+            // TODO: RAS & NLS
+            throw ExceptionFactory.makeWebServiceException("No operation found.  WSDL Operation name: " + mc.getOperationName());
+        }
+        if (ops.length > 1) {
+            // TODO: RAS & NLS
+            throw ExceptionFactory.makeWebServiceException("More than one operation found. Overloaded WSDL operations are not supported.  WSDL Operation name: " + mc.getOperationName());
         }
         OperationDescription op = ops[0];
-        
         if (log.isDebugEnabled()) {
             log.debug("wsdl operation: " + op.getName());
             log.debug("   java method: " + op.getJavaMethodName());
@@ -193,31 +191,20 @@
         return MethodMarshallerFactory.getMarshaller(operationDesc, false);
     }
     
-    public Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
-		 QName opName = mc.getOperationName();
-		 
-	        if (opName == null)
-	            // TODO: NLS
-	            throw ExceptionFactory.makeWebServiceException("Operation name was not set");
-	        
-	        String localPart = opName.getLocalPart();
-	        Method[] methods = serviceImplClass.getMethods();
-	        for (int i = 0; i < methods.length; ++i) {
-	        	String webMethodName = mc.getOperationDescription().getOperationName();
-	            if (localPart.equals(methods[i].getName())){
-	                return methods[i];
-	            }
-	            if(webMethodName.equals(methods[i].getName())){
-	            	return methods[i];
-	            }
-	            
-	        }
-	        
-	        if (log.isDebugEnabled()) {
-	            log.debug("No Java method found for the operation");
-	        }
-	        // TODO: NLS
-	        throw ExceptionFactory.makeWebServiceException(Messages.getMessage("JavaBeanDispatcherErr1"));
+    private Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
+        
+        OperationDescription opDesc = mc.getOperationDescription();
+        if (opDesc == null) {
+            // TODO: NLS
+            throw ExceptionFactory.makeWebServiceException("Operation Description was not set");
+        }
+        
+        Method returnMethod = opDesc.getMethodFromServiceImpl(serviceImplClass);
+        if (returnMethod == null) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("JavaBeanDispatcherErr1"));
+        }
+        
+        return returnMethod;
 	}
     /*
     protected boolean isDocLitBare(EndpointDescription endpointDesc, OperationDescription operationDesc){

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/AsyncPort.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/AsyncPort.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/AsyncPort.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/AsyncPort.java Tue Dec 26 18:10:37 2006
@@ -287,7 +287,7 @@
      * @return
      *     returns java.lang.String
      */
-    @WebMethod(action = "http://org/test/parallelasync/customAsync")
+    @WebMethod(operationName = "realCustomAsync", action = "http://org/test/parallelasync/customAsync")
     @WebResult(name = "response", targetNamespace = "")
     @RequestWrapper(localName = "customAsync", targetNamespace = "http://org/test/parallelasync", className = "org.test.parallelasync.CustomAsync")
     @ResponseWrapper(localName = "customAsyncResponse", targetNamespace = "http://org/test/parallelasync", className = "org.test.parallelasync.CustomAsyncResponse")

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/DocLitWrappedPortImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/DocLitWrappedPortImpl.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/DocLitWrappedPortImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/parallelasync/server/DocLitWrappedPortImpl.java Tue Dec 26 18:10:37 2006
@@ -163,7 +163,7 @@
     }
 
     public String customAsync(String request) {
-        return request;
+        return request + "from customAsync method";
     }
 
     public String another(String request) {
@@ -213,7 +213,7 @@
 
     public String remapped(String request) {
         // TODO Auto-generated method stub
-        return null;
+        return request;
     }
 
     public Future<?> remappedAsync(String request, AsyncHandler<CustomAsyncResponse> asyncHandler) {

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointInterfaceDescription.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointInterfaceDescription.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointInterfaceDescription.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/EndpointInterfaceDescription.java Tue Dec 26 18:10:37 2006
@@ -56,7 +56,36 @@
     public abstract String getTargetNamespace();
     
     public abstract OperationDescription getOperation(Method seiMethod);
+    /**
+     * Returns all the operations matching the operation QName associated with
+     * this endpoint description. Note that if the SEI or service implementation
+     * (and thus the implicit SEI) contained JAX-WS client side async operations
+     * then they will also be returned. Use getDispatchableOperations() to
+     * return an array of operations that does not include the JAX-WS client
+     * side async operations.
+     * @see #getDispatchableOperation(QName operationQName)
+     * 
+     * @param operationQName
+     * @return
+     */
     public abstract OperationDescription[] getOperation(QName operationQName);
+    /**
+     * Returns all the dispatchable operations matching the operation QName.  A dispatchable
+     * operation is one that is NOT a JAX-WS client-side async method invocation.  That is, 
+     * method signatures of the follogin forms are filtered out of this list:
+     *   javax.xml.ws.Response<T> method(...)
+     *   java.util.concurrent.Future<?> method(..., javax.xml.ws.AsyncHandler<T>)
+     *
+     * These methods are filtered because a common use case is to use the same SEI on both the
+     * client and service implementation side, generating both the client and service implemntation code from
+     * that SEI.  If that SEI happens to contain the client-side-only 
+     * JAX-WS methods, they should be ingored on the service implemenation side.  To return all
+     * the operations, use getOperation(QName).
+     * @see #getOperation(QName operationQName)
+     * @param operationQName
+     * @return
+     */
+    public abstract OperationDescription[] getDispatchableOperation(QName operationQName);
     public abstract OperationDescription getOperation(String operationName);
     public abstract OperationDescription[] getOperations();
     public abstract OperationDescription[] getOperationForJavaMethod(String javaMethodName);

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/OperationDescription.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/OperationDescription.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/OperationDescription.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/OperationDescription.java Tue Dec 26 18:10:37 2006
@@ -68,14 +68,39 @@
     
     public String getJavaMethodName();
     public String[] getJavaParameters();
+    // TODO: Fix up the difference between getSEIMethod and getMethodFromServiceImpl when java reflection is removed.
+    /**
+     * Client side and non-DBC service side only! Return the SEI method for which a service.getPort(Class SEIClass) created
+     * the EndpointDescriptionInterface and the associated OperationDescriptions.  Returns null on the
+     * service implementation side. 
+     * @return
+     */
     public Method getSEIMethod();
+    /**
+     * Service implementation side only!  Given a service implementation class, find the method
+     * on that class that corresponds to this operation description.  This is necessary because on
+     * the service impl side, the OperationDescriptions can be built using byte-scanning and without the
+     * class actually having been loaded.
+     * @param serviceImpl
+     * @return
+     */
+    public Method getMethodFromServiceImpl(Class serviceImpl);
+    
+    /**
+     * Answer if this operation corresponds to the JAX-WS Client-only async methods.  These methods
+     * are of the form:
+     *   javax.xml.ws.Response<T> method(...)
+     *   java.util.concurrent.Future<?> method(..., javax.xml.ws.AsyncHandler<T>)
+     *
+     * @return
+     */
+    public boolean isJAXWSAsyncClientMethod(); 
     
     public QName getName();
     public String getOperationName();
     public String getAction();
     public boolean isOneWay();
     public boolean isExcluded();
-    public boolean isAsync();
     public boolean isOperationReturningResult();
 
     public String getResultName();
@@ -86,15 +111,21 @@
     
     
     /**
-     * Return the Class of the type
+     * Return the Class of the return type.  For JAX-WS async returns of
+     * type Response<T> or AsyncHandler<T>, the class associated with Response
+     * or AsyncHanler respectively is returned.  To get the class associated with 
+     * <T>
+     * @see getResultActualType()
      * @return Class
      */
     public Class getResultType();
     
     /**
-     * Return the actual Class of the type.
-     * This method returns the actual Class that may be embedded
-     * inside a Response or Callback
+     * Return the actual Class of the type.  For a JAX-WS async return
+     * type of Response<T> or AsyncHandler<T>, the class associated with <T>
+     * is returned.  For non-JAX-WS async returns, the class associated with the 
+     * return type is returned.  Note that for a Generic return type, such as 
+     * List<Foo>, the class associated with List will be returned.
      * @return actual Class
      */
     public Class getResultActualType();

Added: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java?view=auto&rev=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java (added)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/DescriptionBuilderUtils.java Tue Dec 26 18:10:37 2006
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.description.builder;
+
+import org.apache.axis2.jaxws.ExceptionFactory;
+
+/**
+ * 
+ */
+class DescriptionBuilderUtils {
+    static String JAXWS_HOLDER_CLASS = "javax.xml.ws.Holder";
+
+    private static final String INT_PRIMITIVE = "int";
+    private static final String INT_PRIMITIVE_ENCODING = "I";
+    private static final String BYTE_PRIMITIVE = "byte";
+    private static final String BYTE_PRIMITIVE_ENCODING = "B";
+    private static final String CHAR_PRIMITIVE = "char";
+    private static final String CHAR_PRIMITIVE_ENCODING = "C";
+    private static final String SHORT_PRIMITIVE = "short";
+    private static final String SHORT_PRIMITIVE_ENCODING = "S";
+    private static final String BOOLEAN_PRIMITIVE = "boolean";
+    private static final String BOOLEAN_PRIMITIVE_ENCODING = "Z";
+    private static final String LONG_PRIMITIVE = "long";
+    private static final String LONG_PRIMITIVE_ENCODING = "J";
+    private static final String FLOAT_PRIMITIVE = "float";
+    private static final String FLOAT_PRIMITIVE_ENCODING = "F";
+    private static final String DOUBLE_PRIMITIVE = "double";
+    private static final String DOUBLE_PRIMITIVE_ENCODING = "D";
+    private static final String VOID_PRIMITIVE = "void";
+    // REVIEW: This may not be the correct encoding for Void
+    private static final String VOID_PRIMITIVE_ENCODING = "V";
+
+    /**
+     * Returns a string representing the outermost generic raw type class, or null if the argument
+     * is not a generic.  For example if the string "javax.xml.ws.Holder<my.package.MyObject>"
+     * is passed in, the string "javax.xml.ws.Holder" will be returned.
+     * @param inputType
+     * @return A string representing the generic raw type or null if there is no generic.
+     */
+    static String getRawType(String inputType) {
+        String returnRawType = null;
+        int leftBracket = inputType.indexOf("<");
+        if (leftBracket > 0 ) {
+            returnRawType = inputType.substring(0, leftBracket).trim();
+        }
+        return returnRawType;
+    }
+
+    /**
+     * Return the actual type in a JAX-WS holder declaration.  For example, for the 
+     * argument "javax.xml.ws.Holder<my.package.MyObject>", return "my.package.MyObject".
+     * If the actual type itself is a generic, then that raw type will be returned.  For 
+     * example, "javax.xml.ws.Holder<java.util.List<my.package.MyObject>>" will return 
+     * "java.util.List".
+     * 
+     * Important note!  The JAX-WS Holder generic only supports a single actual type, i.e. 
+     * the generic is javax.xml.ws.Holder<T>.  This method is not general purpose; it does not support 
+     * generics with multiple types such as Generic<K,V> at the outermost level.
+     * @param holderInputString
+     * @return return the actual argument class name for a JAX-WS Holder; returns null
+     *         if the argument is not a JAX-WS Holder
+     */
+    static String getHolderActualType(String holderInputString) {
+        String returnString = null;
+        if (DescriptionBuilderUtils.isHolderType(holderInputString)) {
+            int leftBracket = holderInputString.indexOf("<");
+            int rightBracket = holderInputString.lastIndexOf(">");
+            if (leftBracket > 0 && rightBracket > leftBracket + 1) {
+                String actualType = holderInputString.substring(leftBracket + 1, rightBracket).trim();
+                String rawType = getRawType(actualType);
+                if (rawType != null) {
+                    returnString = rawType;
+                }
+                else {
+                    return returnString = actualType;
+                }
+            }
+        }
+        return returnString;
+    }
+
+
+    /**
+     * Check if the input String is a JAX-WS Holder.  For example 
+     * "javax.xml.ws.Holder<my.package.MyObject>".
+     * @param checkType
+     * @return true if it is a JAX-WS Holder type; false otherwise.
+     */
+    static boolean isHolderType(String checkType) {
+        boolean isHolder = false;
+        if (checkType != null) {
+            String rawType = getRawType(checkType);
+            if (rawType != null && rawType.equals(JAXWS_HOLDER_CLASS)) {
+                isHolder = true;
+            }
+        }
+        return isHolder;
+    }
+
+    /**
+     * Answers if the String representing the class contains an array declaration.
+     * For example "Foo[][]" would return true, as would "int[]".
+     * @param className
+     * @return
+     */
+    static boolean isClassAnArray(String className) {
+        if (className != null && className.indexOf("[") > 0) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    /** 
+     * For an class name that is an array, return the non-array declaration portion.
+     * For example "my.package.Foo[][]" would return "my.package.Foo". Returns null if
+     * the argument does not contain an array declaration.
+     * @param fullClassName
+     * @return
+     */
+    static String getBaseArrayClassName(String fullClassName) {
+        String baseArrayClassName = null;
+        if (fullClassName != null) {
+            int firstArrayDimension = fullClassName.indexOf("[");
+            if (firstArrayDimension > 0) {
+                baseArrayClassName = fullClassName.substring(0, firstArrayDimension);
+            }
+        }
+        return baseArrayClassName;
+    }
+
+    /**
+     * Return a prefix suitable for passing to Class.forName(String) for an array.  Each array dimension
+     * represented by "[]" will be represented by a single "[".
+     * @param arrayClassName
+     * @return
+     */
+    static String getArrayDimensionPrefix(String arrayClassName) {
+        StringBuffer arrayDimPrefix = new StringBuffer();
+        
+        if (arrayClassName != null) {
+            int arrayDimIndex = arrayClassName.indexOf("[]");
+            while (arrayDimIndex > 0) {
+                arrayDimPrefix.append("[");
+                // Skip over this "[]" and see if there are any more.
+                int startNext = arrayDimIndex + 2;
+                arrayDimIndex = arrayClassName.indexOf("[]", startNext);
+            }
+        }
+        
+        if (arrayDimPrefix.length() > 0)
+            return arrayDimPrefix.toString();
+        else
+            return null;
+    }
+
+    /**
+     * For primitives, return the appropriate primitive class.  Note that arrays of primitives are
+     * handled differently, like arrays of objects.  Only non-array primitives are processed by this
+     * method.  This method understands both the typical primitive declaration (e.g. "int") and the
+     * encoding used as for arrays (e.g. "I").
+     * @param classType
+     * @return
+     */
+    static Class getPrimitiveClass(String classType) {
+    	
+    	Class paramClass = null;
+    
+    	if (INT_PRIMITIVE.equals(classType) || INT_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = int.class;
+    	} else if (BYTE_PRIMITIVE.equals(classType)|| BYTE_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = byte.class;
+    	} else if (CHAR_PRIMITIVE.equals(classType)|| CHAR_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = char.class;
+    	} else if (SHORT_PRIMITIVE.equals(classType)|| SHORT_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = short.class;
+    	} else if (BOOLEAN_PRIMITIVE.equals(classType)|| BOOLEAN_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = boolean.class;
+    	} else if (LONG_PRIMITIVE.equals(classType) || LONG_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = long.class;
+    	} else if (FLOAT_PRIMITIVE.equals(classType)|| FLOAT_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = float.class;
+    	} else if (DOUBLE_PRIMITIVE.equals(classType)|| DOUBLE_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = double.class;
+    	} else if (VOID_PRIMITIVE.equals(classType)|| VOID_PRIMITIVE_ENCODING.equals(classType)) {
+    		paramClass = void.class;
+    	}
+    	return paramClass;
+    }
+
+    /**
+     * Returns the encoding used to represent a Class for an array of 
+     * a primitive type.  For example, an array of boolean is represented by "Z".  
+     * This is as described in the javadoc for Class.getName().  If the argument is
+     * not a primitive type, a null will be returned.
+     * 
+     * Note that arrays of voids are not allowed; a null will be returned.
+     * @param primitiveType
+     * @return
+     */
+    static String getPrimitiveTypeArrayEncoding(String primitiveType) {
+        String encoding = null;
+        
+        if (BOOLEAN_PRIMITIVE.equals(primitiveType)) {
+            encoding = BOOLEAN_PRIMITIVE_ENCODING;
+        }
+        else if (BYTE_PRIMITIVE.equals(primitiveType)) {
+            encoding = BYTE_PRIMITIVE_ENCODING;
+        }
+        else if (CHAR_PRIMITIVE.equals(primitiveType)) {
+            encoding = CHAR_PRIMITIVE_ENCODING;
+        }
+        else if (DOUBLE_PRIMITIVE.equals(primitiveType)) {
+            encoding = DOUBLE_PRIMITIVE_ENCODING;
+        }
+        else if (FLOAT_PRIMITIVE.equals(primitiveType)) {
+            encoding = FLOAT_PRIMITIVE_ENCODING;
+        }
+        else if (INT_PRIMITIVE.equals(primitiveType)) {
+            encoding = INT_PRIMITIVE_ENCODING;
+        }
+        else if (LONG_PRIMITIVE.equals(primitiveType)) {
+            encoding = LONG_PRIMITIVE_ENCODING;
+        }
+        else if (SHORT_PRIMITIVE.equals(primitiveType)) {
+            encoding = SHORT_PRIMITIVE_ENCODING;
+        }
+        return encoding;
+    }
+
+    /**
+     * If the parameter represents and array, then the returned string is in a format that
+     * a Class.forName(String) can be done on it.  This format is described by Class.getName().
+     * If the parameter does not represent an array, the parememter is returned unmodified.
+     * 
+     * Note that arrays of primitives are processed as well as arrays of objects.
+     * @param classToLoad
+     * @return
+     */
+    static String reparseIfArray(String classToLoad) {
+        
+        String reparsedClassName = classToLoad;
+        if (isClassAnArray(classToLoad)) {
+            String baseType = getBaseArrayClassName(classToLoad);
+            String dimensionPrefix = getArrayDimensionPrefix(classToLoad);
+            if (getPrimitiveTypeArrayEncoding(baseType) != null) {
+                reparsedClassName = dimensionPrefix + getPrimitiveTypeArrayEncoding(baseType);
+            }
+            else {
+                reparsedClassName = dimensionPrefix + "L" + baseType + ";";  
+            }
+        }
+        return reparsedClassName;
+    }
+
+    /**
+     * Load a class represented in a Description Builder Composite.  If a classloader
+     * is specified, it will be used; otherwise the default classloader is used.
+     * @param classToLoad
+     * @param classLoader
+     * @return
+     */
+    static Class loadClassFromComposite(String classToLoad, ClassLoader classLoader) {
+        Class returnClass = null;
+        
+        // If this is an array, then create a string version as described by Class.getName.
+        // For example, "Foo[][]" becomes "[[LFoo".  Note that arrays of primitives must also be parsed.
+        classToLoad = DescriptionBuilderUtils.reparseIfArray(classToLoad);
+        
+        if (classLoader != null) {
+            // Use the specified classloader to load the class.
+            try {
+                returnClass = Class.forName(classToLoad, false, classLoader);
+            } 
+            catch (ClassNotFoundException ex) {
+                throw ExceptionFactory.makeWebServiceException("DescriptionBuilderUtils: Class not found for parameter: " +classToLoad);
+            }
+        } 
+        else {
+            //Use the default classloader to load the class.
+            try {
+                returnClass = Class.forName(classToLoad);
+            } 
+            catch (ClassNotFoundException ex) {
+                throw ExceptionFactory.makeWebServiceException("DescriptionBuilderUtils: Class not found for parameter: " +classToLoad);
+            }
+        }
+        return returnClass;
+    }
+}

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/MethodDescriptionComposite.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/MethodDescriptionComposite.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/MethodDescriptionComposite.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/MethodDescriptionComposite.java Tue Dec 26 18:10:37 2006
@@ -71,15 +71,60 @@
 	public String getMethodName() {
 		return methodName;
 	}
-
-	/**
+    /**
+     * Returns the String descrbing this method result type.  Note that this string is unparsed.  For example, if
+     * it represents a java.util.List<my.package.Foo>, then that excact string will be returned,
+     * i.e. "java.util.List<my.package.Foo>".  You can use other methods on this object to retrieve parsed values
+     * for Generics and Holders.
+     * 
 	 * @return Returns the returnType
 	 */
 	public String getReturnType() {
 		return returnType;
 	}
 
-	/**
+    /**
+     * Returns the class associated with the method result type.  Note that if the resturn type a generic (such as
+     * java.util.List<my.package.Foo>) then the class associated with the raw type is returned (i.e. java.util.List).
+     * 
+     * There are other methods that return the class for the actual type for certain JAX-WS specific generics such
+     * as Response<T> 
+     * 
+     * @return Returns the parameterTypeClass.
+     */
+	public Class getReturnTypeClass() {
+        Class returnTypeClass = null;
+        String fullReturnType = getReturnType();
+        if (fullReturnType != null) {
+            returnTypeClass = DescriptionBuilderUtils.getPrimitiveClass(fullReturnType);
+            if (returnTypeClass == null) {
+                // If this is a Generic, we need to load the class associated with the Raw Type, 
+                // i.e. for List<Foo>, we want to load List. Othwerise, load the type directly. 
+                String classToLoad = null;
+                if (DescriptionBuilderUtils.getRawType(fullReturnType) != null) {
+                    classToLoad = DescriptionBuilderUtils.getRawType(fullReturnType);
+                }
+                else {
+                    classToLoad = fullReturnType; 
+                }
+                returnTypeClass = loadClassFromMDC(classToLoad);
+            }
+        }
+        
+        return returnTypeClass;
+    }
+    private Class loadClassFromMDC(String classToLoad) {
+        Class returnClass = null;
+        ClassLoader classLoader = null;
+        
+        if (getDescriptionBuilderCompositeRef() != null){
+            classLoader = getDescriptionBuilderCompositeRef().getClassLoader();
+        }
+        returnClass = DescriptionBuilderUtils.loadClassFromComposite(classToLoad, classLoader);
+        return returnClass;
+    }
+
+    /**
 	 * @return returns whether this is OneWay
 	 */
 	public boolean isOneWay() {

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java Tue Dec 26 18:10:37 2006
@@ -6,9 +6,7 @@
 import org.apache.axis2.jaxws.ExceptionFactory;
 
 public class ParameterDescriptionComposite {
-    private static String JAXWS_HOLDER_CLASS = "javax.xml.ws.Holder";
-    
-	private String					parameterType;
+    private String					parameterType;
 	private Class					parameterTypeClass;
 	private WebParamAnnot			webParamAnnot;
 	private WebServiceRefAnnot 		webServiceRefAnnot;
@@ -36,6 +34,11 @@
 	}
 	
 	/**
+     * Returns the String descrbing this Parameter type.  Note that this string is unparsed.  For example, if
+     * it represents a java.util.List<my.package.Foo>, then that excact string will be returned,
+     * i.e. "java.util.List<my.package.Foo>".  You can use other methods to retrieve parsed values
+     * for Generics and Holders.  For example, getParameterTypeClass(), getRawType(), getHolderActualType(),
+     * and getHolderActualTypeClass().
 	 * @return Returns the parameterType.
 	 */
 	public String getParameterType() {
@@ -54,13 +57,13 @@
 		
 		if (parameterTypeClass == null) {
 			if (getParameterType() != null) {
-				parameterTypeClass = getPrimitiveClass(getParameterType());
+				parameterTypeClass = DescriptionBuilderUtils.getPrimitiveClass(getParameterType());
 				if (parameterTypeClass == null) {
 					// If this is a Generic, we need to load the class associated with the Raw Type, 
                     // i.e. for JAX-WS Holder<Foo>, we want to load Holder. Othwerise, load the type directly. 
                     String classToLoad = null;
-                    if (getRawType(parameterType) != null) {
-                        classToLoad = getRawType(parameterType);
+                    if (DescriptionBuilderUtils.getRawType(parameterType) != null) {
+                        classToLoad = DescriptionBuilderUtils.getRawType(parameterType);
                     }
                     else {
                         classToLoad = parameterType; 
@@ -79,8 +82,8 @@
     public Class getHolderActualTypeClass() {
         Class returnClass = null;
 
-        if (isHolderType(parameterType)) {
-            String classToLoad = getHolderActualType(parameterType);
+        if (DescriptionBuilderUtils.isHolderType(parameterType)) {
+            String classToLoad = DescriptionBuilderUtils.getHolderActualType(parameterType);
             returnClass = loadClassFromPDC(classToLoad);
         }
         return returnClass;
@@ -90,116 +93,16 @@
         Class returnClass = null;
         ClassLoader classLoader = null;
         
-        // If this is an array, then create a string version as described by Class.getName.
-        // For example, "Foo[][]" becomes "[[LFoo".  Note that arrays of primitives must also be parsed.
-        classToLoad = reparseIfArray(classToLoad);
-        
         if (getMethodDescriptionCompositeRef() != null) {
             if (getMethodDescriptionCompositeRef().getDescriptionBuilderCompositeRef() != null){
                 classLoader = getMethodDescriptionCompositeRef().getDescriptionBuilderCompositeRef().getClassLoader();
             }
         }
-        if (classLoader != null) {          
-            try {
-                returnClass = Class.forName(classToLoad, false, classLoader);
-                
-            } 
-            catch (ClassNotFoundException ex) {
-                throw ExceptionFactory.makeWebServiceException("ParameterDescriptionComposite: Class not found for parameter: " +classToLoad);
-            }
-        } 
-        else {
-            //Use the default classloader to get this strings class
-            try {
-                returnClass = Class.forName(classToLoad);
-            } 
-            catch (ClassNotFoundException ex) {
-                throw ExceptionFactory.makeWebServiceException("ParameterDescriptionComposite: Class not found for parameter: " +classToLoad);
-            }
-        }
+        returnClass = DescriptionBuilderUtils.loadClassFromComposite(classToLoad, classLoader);
         return returnClass;
     }
     
     /**
-     * If the parameter represents and array, then the returned string is in a format that
-     * a Class.forName(String) can be done on it.  This format is described by Class.getName().
-     * If the parameter does not represent an array, the parememter is returned unmodified.
-     * 
-     * Note that arrays of primitives are processed as well as arrays of objects.
-     * @param classToLoad
-     * @return
-     */
-	private String reparseIfArray(String classToLoad) {
-	    
-        String reparsedClassName = classToLoad;
-        if (isClassAnArray(classToLoad)) {
-            String baseType = getBaseArrayClassName(classToLoad);
-            String dimensionPrefix = getArrayDimensionPrefix(classToLoad);
-            if (getPrimitiveTypeArrayEncoding(baseType) != null) {
-                reparsedClassName = dimensionPrefix + getPrimitiveTypeArrayEncoding(baseType);
-            }
-            else {
-                reparsedClassName = dimensionPrefix + "L" + baseType + ";";  
-            }
-        }
-        return reparsedClassName;
-    }
-    /**
-     * Answers if the String representing the class contains an array declaration.
-     * For example "Foo[][]" would return true, as would "int[]".
-     * @param className
-     * @return
-     */
-    private boolean isClassAnArray(String className) {
-        if (className != null && className.indexOf("[") > 0) {
-            return true;
-        }
-        else {
-            return false;
-        }
-    }
-    /** 
-     * For an class name that is an array, return the non-array declaration portion.
-     * For example "my.package.Foo[][]" would return "my.package.Foo". Returns null if
-     * the argument does not contain an array declaration.
-     * @param fullClassName
-     * @return
-     */
-    private String getBaseArrayClassName(String fullClassName) {
-        String baseArrayClassName = null;
-        if (fullClassName != null) {
-            int firstArrayDimension = fullClassName.indexOf("[");
-            if (firstArrayDimension > 0) {
-                baseArrayClassName = fullClassName.substring(0, firstArrayDimension);
-            }
-        }
-        return baseArrayClassName;
-    }
-    /**
-     * Return a prefix suitable for passing to Class.forName(String) for an array.  Each array dimension
-     * represented by "[]" will be represented by a single "[".
-     * @param arrayClassName
-     * @return
-     */
-    private String getArrayDimensionPrefix(String arrayClassName) {
-        StringBuffer arrayDimPrefix = new StringBuffer();
-        
-        if (arrayClassName != null) {
-            int arrayDimIndex = arrayClassName.indexOf("[]");
-            while (arrayDimIndex > 0) {
-                arrayDimPrefix.append("[");
-                // Skip over this "[]" and see if there are any more.
-                int startNext = arrayDimIndex + 2;
-                arrayDimIndex = arrayClassName.indexOf("[]", startNext);
-            }
-        }
-        
-        if (arrayDimPrefix.length() > 0)
-            return arrayDimPrefix.toString();
-        else
-            return null;
-    }
-    /**
 	 * @return Returns the webParamAnnot.
 	 */
 	public WebParamAnnot getWebParamAnnot() {
@@ -282,101 +185,8 @@
 	public void setMethodDescriptionCompositeRef(MethodDescriptionComposite mdc) {
 		this.parentMDC = mdc;
 	}
-    
-    private static final String INT_PRIMITIVE = "int";
-    private static final String INT_PRIMITIVE_ENCODING = "I";
-    private static final String BYTE_PRIMITIVE = "byte";
-    private static final String BYTE_PRIMITIVE_ENCODING = "B";
-    private static final String CHAR_PRIMITIVE = "char";
-    private static final String CHAR_PRIMITIVE_ENCODING = "C";
-    private static final String SHORT_PRIMITIVE = "short";
-    private static final String SHORT_PRIMITIVE_ENCODING = "S";
-    private static final String BOOLEAN_PRIMITIVE = "boolean";
-    private static final String BOOLEAN_PRIMITIVE_ENCODING = "Z";
-    private static final String LONG_PRIMITIVE = "long";
-    private static final String LONG_PRIMITIVE_ENCODING = "J";
-    private static final String FLOAT_PRIMITIVE = "float";
-    private static final String FLOAT_PRIMITIVE_ENCODING = "F";
-    private static final String DOUBLE_PRIMITIVE = "double";
-    private static final String DOUBLE_PRIMITIVE_ENCODING = "D";
-    private static final String VOID_PRIMITIVE = "void";
-    // REVIEW: This may not be the correct encoding for Void
-    private static final String VOID_PRIMITIVE_ENCODING = "V";
 
     /**
-     * For primitives, return the appropriate primitive class.  Note that arrays of primitives are
-     * handled differently, like arrays of objects.  Only non-array primitives are processed by this
-     * method.  This method understands both the typical primitive declaration (e.g. "int") and the
-     * encoding used as for arrays (e.g. "I").
-     * @param classType
-     * @return
-     */
-	private Class getPrimitiveClass(String classType) {
-		
-		Class paramClass = null;
-
-		if (INT_PRIMITIVE.equals(classType) || INT_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = int.class;
-		} else if (BYTE_PRIMITIVE.equals(classType)|| BYTE_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = byte.class;
-		} else if (CHAR_PRIMITIVE.equals(classType)|| CHAR_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = char.class;
-		} else if (SHORT_PRIMITIVE.equals(classType)|| SHORT_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = short.class;
-		} else if (BOOLEAN_PRIMITIVE.equals(classType)|| BOOLEAN_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = boolean.class;
-		} else if (LONG_PRIMITIVE.equals(classType) || LONG_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = long.class;
-		} else if (FLOAT_PRIMITIVE.equals(classType)|| FLOAT_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = float.class;
-		} else if (DOUBLE_PRIMITIVE.equals(classType)|| DOUBLE_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = double.class;
-		} else if (VOID_PRIMITIVE.equals(classType)|| VOID_PRIMITIVE_ENCODING.equals(classType)) {
-			paramClass = void.class;
-		}
-		return paramClass;
-	}
-    /**
-     * Returns the encoding used to represent a Class for an array of 
-     * a primitive type.  For example, an array of boolean is represented by "Z".  
-     * This is as described in the javadoc for Class.getName().  If the argument is
-     * not a primitive type, a null will be returned.
-     * 
-     * Note that arrays of voids are not allowed; a null will be returned.
-     * @param primitiveType
-     * @return
-     */
-    private String getPrimitiveTypeArrayEncoding(String primitiveType) {
-        String encoding = null;
-        
-        if (BOOLEAN_PRIMITIVE.equals(primitiveType)) {
-            encoding = BOOLEAN_PRIMITIVE_ENCODING;
-        }
-        else if (BYTE_PRIMITIVE.equals(primitiveType)) {
-            encoding = BYTE_PRIMITIVE_ENCODING;
-        }
-        else if (CHAR_PRIMITIVE.equals(primitiveType)) {
-            encoding = CHAR_PRIMITIVE_ENCODING;
-        }
-        else if (DOUBLE_PRIMITIVE.equals(primitiveType)) {
-            encoding = DOUBLE_PRIMITIVE_ENCODING;
-        }
-        else if (FLOAT_PRIMITIVE.equals(primitiveType)) {
-            encoding = FLOAT_PRIMITIVE_ENCODING;
-        }
-        else if (INT_PRIMITIVE.equals(primitiveType)) {
-            encoding = INT_PRIMITIVE_ENCODING;
-        }
-        else if (LONG_PRIMITIVE.equals(primitiveType)) {
-            encoding = LONG_PRIMITIVE_ENCODING;
-        }
-        else if (SHORT_PRIMITIVE.equals(primitiveType)) {
-            encoding = SHORT_PRIMITIVE_ENCODING;
-        }
-        return encoding;
-    }
-	
-	/**
 	 * Convenience method for unit testing. We will print all of the 
 	 * data members here.
 	 */
@@ -403,78 +213,12 @@
 	}
     
     public String getRawType() {
-        return getRawType(parameterType);
+        return DescriptionBuilderUtils.getRawType(parameterType);
     }
     public String getHolderActualType() {
-        return getHolderActualType(parameterType);
+        return DescriptionBuilderUtils.getHolderActualType(parameterType);
     }
     public boolean isHolderType() {
-        return isHolderType(parameterType);
-    }
-
-    /**
-     * Returns a string representing the outermost generic raw type class, or null if the argument
-     * is not a generic.  For example if the string "javax.xml.ws.Holder<my.package.MyObject>"
-     * is passed in, the string "javax.xml.ws.Holder" will be returned.
-     * @param inputType
-     * @return A string representing the generic raw type or null if there is no generic.
-     */
-    public static String getRawType(String inputType) {
-        String returnRawType = null;
-        int leftBracket = inputType.indexOf("<");
-        if (leftBracket > 0 ) {
-            returnRawType = inputType.substring(0, leftBracket).trim();
-        }
-        return returnRawType;
-    }
-
-    /**
-     * Return the actual type in a JAX-WS holder declaration.  For example, for the 
-     * argument "javax.xml.ws.Holder<my.package.MyObject>", return "my.package.MyObject".
-     * If the actual type itself is a generic, then that raw type will be returned.  For 
-     * example, "javax.xml.ws.Holder<java.util.List<my.package.MyObject>>" will return 
-     * "java.util.List".
-     * 
-     * Important note!  The JAX-WS Holder generic only supports a single actual type, i.e. 
-     * the generic is javax.xml.ws.Holder<T>.  This method is not general purpose; it does not support 
-     * generics with multiple types such as Generic<K,V> at the outermost level.
-     * @param holderInputString
-     * @return return the actual argument class name for a JAX-WS Holder; returns null
-     *         if the argument is not a JAX-WS Holder
-     */
-    public static String getHolderActualType(String holderInputString) {
-        String returnString = null;
-        if (isHolderType(holderInputString)) {
-            int leftBracket = holderInputString.indexOf("<");
-            int rightBracket = holderInputString.lastIndexOf(">");
-            if (leftBracket > 0 && rightBracket > leftBracket + 1) {
-                String actualType = holderInputString.substring(leftBracket + 1, rightBracket).trim();
-                String rawType = getRawType(actualType);
-                if (rawType != null) {
-                    returnString = rawType;
-                }
-                else {
-                    return returnString = actualType;
-                }
-            }
-        }
-        return returnString;
-    }
-    
-    /**
-     * Check if the input String is a JAX-WS Holder.  For example 
-     * "javax.xml.ws.Holder<my.package.MyObject>".
-     * @param checkType
-     * @return true if it is a JAX-WS Holder type; false otherwise.
-     */
-    public static boolean isHolderType(String checkType) {
-        boolean isHolder = false;
-        if (checkType != null) {
-            String rawType = getRawType(checkType);
-            if (rawType != null && rawType.equals(JAXWS_HOLDER_CLASS)) {
-                isHolder = true;
-            }
-        }
-        return isHolder;
+        return DescriptionBuilderUtils.isHolderType(parameterType);
     }
 }

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java Tue Dec 26 18:10:37 2006
@@ -775,12 +775,30 @@
                 // Note the namespace is not included on the WSDL Port.
                 if (wsdlPort.getName().equals(portQName.getLocalPart())) {
                     
-                	// Create the Endpoint Interface Description based on the WSDL.
-                    endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(this);
+                    // Build the EndpointInterface based on the specified SEI if there is one
+                    // or on the service impl class (i.e. an implicit SEI).
+                    if (getServiceDescriptionImpl().isDBCMap()) {
+                        String seiClassName = getAnnoWebServiceEndpointInterface();
+                        if (DescriptionUtils.isEmpty(seiClassName)) {
+                            // No SEI specified, so use the service impl as an implicit SEI
+                            endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(composite, true, this);
+                        } else {
+                            // Otherwise, build the EID based on the SEI composite
+                            endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl( 
+                                        getServiceDescriptionImpl().getDBCMap().get(seiClassName), 
+                                        false, 
+                                        this);
+                        }
+
+                    }
+                    else {
+                        // Create the Endpoint Interface Description based on the WSDL.
+                        endpointInterfaceDescription = new EndpointInterfaceDescriptionImpl(this);
  
-                    // Update the EndpointInterfaceDescription created with WSDL with information from the
-                    // annotations in the SEI
-                    ((EndpointInterfaceDescriptionImpl) endpointInterfaceDescription).updateWithSEI(implOrSEIClass);
+                        // Update the EndpointInterfaceDescription created with WSDL with information from the
+                        // annotations in the SEI
+                        ((EndpointInterfaceDescriptionImpl) endpointInterfaceDescription).updateWithSEI(implOrSEIClass);
+                    }
                     wsdlPortFound = true;
                 }
             }

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java Tue Dec 26 18:10:37 2006
@@ -387,6 +387,28 @@
         }
         return returnOperations;
     }
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.EndpointInterfaceDescription#getDispatchableOperation(QName operationQName)
+     */
+    public OperationDescription[] getDispatchableOperation(QName operationQName) {
+        OperationDescription[] returnOperations = null;
+        OperationDescription[] allMatchingOperations = getOperation(operationQName);
+        if (allMatchingOperations != null && allMatchingOperations.length > 0) {
+            ArrayList<OperationDescription> dispatchableOperations = new ArrayList<OperationDescription>();
+            for (OperationDescription operation : allMatchingOperations) {
+                if (!operation.isJAXWSAsyncClientMethod()) {
+                    dispatchableOperations.add(operation);
+                }
+            }
+            
+            if (dispatchableOperations.size() > 0) {
+                returnOperations = dispatchableOperations.toArray(new OperationDescription[0]);
+            }
+        }
+        return returnOperations;
+    }
+
+
     
     /**
      * Return an OperationDescription for the corresponding SEI method.  Note that this ONLY works

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java Tue Dec 26 18:10:37 2006
@@ -1148,39 +1148,50 @@
      * @see org.apache.axis2.jaxws.description.OperationDescription#getResultType()
      */
     public Class getResultType() {
-        Method seiMethod = this.getSEIMethod();
-        return seiMethod.getReturnType();
+
+        if (!isDBC()) {
+            Method seiMethod = this.getSEIMethod();
+            return seiMethod.getReturnType();           
+        } 
+        else {
+            return methodComposite.getReturnTypeClass();
+        }
     }
 
     /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.description.OperationDescription#getResultActualType()
      */
     public Class getResultActualType() {
-        
-        // REVIEW:
-        // Do we want to add a getParameterActualGenericType that would return Type
-        // instead of Class ?
-        
-        // NOTE
-        // If you change this code, please remember to change 
-        // ParameterDescription.getParameterActualType
+        // TODO: Fix this!  it isn't doing the right thing for DBC as noted below with FIXME comments
+        //       This is used to marshall the rsp on the service (dbc) and demarshall on the client (reflection)
+        //       But we shouldn't get an async OpDesc on the service since getDispatchableOperation(QN) removes them.
         
        Class returnType = getResultType();
-       if(isAsync()){
+       if(isJAXWSAsyncClientMethod()){
            //pooling implementation
            if(Response.class == returnType){
-               Type type = seiMethod.getGenericReturnType();
-               ParameterizedType pType = (ParameterizedType) type;
-               Type aType = pType.getActualTypeArguments()[0];
-               if (aType != null && ParameterizedType.class.isInstance(aType)) {
-                   return (Class) ((ParameterizedType) aType).getRawType();
-               }
-               return (Class) aType;    
+               if (!isDBC()) {
+                   Type type = seiMethod.getGenericReturnType();
+                   ParameterizedType pType = (ParameterizedType) type;
+                   Type aType = pType.getActualTypeArguments()[0];
+                   if (aType != null && ParameterizedType.class.isInstance(aType)) {
+                       return (Class) ((ParameterizedType) aType).getRawType();
+                   }
+                   return (Class) aType;
+               } else {
+                 // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+                 //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+                 //        This needs to return T for Response<T>, or List for Response<List<T>>>
+                 return returnType;  
+               }   
            }
            //Callback Implementation
            else{
-               Type[] type = seiMethod.getGenericParameterTypes();
-               Class parameters[]= seiMethod.getParameterTypes();
+               // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+               //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+               //        This needs to find and return T for AsyncHandler<T>, or List for AsyncHandler<List<T>>>
+               Type[] type = getGenericParameterTypes();
+               Class parameters[]= getParameterTypes();
                int i=0;
                for(Class param:parameters){
                    if(AsyncHandler.class.isAssignableFrom(param)){
@@ -1194,23 +1205,111 @@
                    i++;
                }
            }
-           
        }
        
        return returnType;  
     }
 
-    /**
-     * @param operationDesc
-     * @return if asyc operation
+    
+    private Type[] getGenericParameterTypes() {
+       if (isDBC()) {
+           // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+           //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+           //        And this method is only used to parse out the JAX-WS Async parameter types to find 
+           //        AsyncHandler<T>.  The problem with the code that was removed is that a Type can not be
+           //        instantiated, so we can't new up a Type inside the PDC.
+           throw new UnsupportedOperationException("OperationDescriptionImpl.getParameterActualGenericType not supported for DBC");
+//           Type [] type = new Type[parameterDescriptions.length];
+//           for (int i=0; i < parameterDescriptions.length; i++){
+//               type[i] = ((ParameterDescriptionImpl) parameterDescriptions[i]).getParameterActualGenericType();
+//           }
+//           return type;
+       } else {
+           Type [] type = seiMethod.getGenericParameterTypes();
+           return type;
+       }
+    }
+    
+    private Class[] getParameterTypes() {
+       if (isDBC()) {
+           Class [] parameters = new Class[parameterDescriptions.length];
+           for (int i=0; i < parameterDescriptions.length; i++){
+               parameters[i] = parameterDescriptions[i].getParameterType();
+           }
+           return parameters;
+       } else {
+           Class [] parameters = seiMethod.getParameterTypes();
+           return parameters;
+       }
+    }
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.OperationDescription#isJAXWSAsyncClientMethod()
      */
-    public boolean isAsync(){
-        Method method = this.getSEIMethod();
-        if(method == null){
-            return false;
-        }
-        String methodName = method.getName();
-        Class returnType = method.getReturnType();
-        return methodName.endsWith("Async") && (returnType.isAssignableFrom(Response.class) || returnType.isAssignableFrom(Future.class));
+    public boolean isJAXWSAsyncClientMethod() {
+        boolean answer = false;
+        String methodName = null;
+        String returnTypeName = null;
+        if (isDBC()) {
+            methodName = getMethodDescriptionComposite().getMethodName();
+            returnTypeName = getMethodDescriptionComposite().getReturnType();
+        }
+        else {
+            Method method = this.getSEIMethod();
+            if(method != null) {
+                methodName = method.getName();
+                returnTypeName = method.getReturnType().getName();
+            }
+        }
+        if (methodName != null && returnTypeName != null) {
+            // REVIEW: Not sure the method MUST end with "Async"; I think it can be customized.
+            answer = methodName.endsWith("Async") 
+                     && (returnTypeName.equals(Response.class.getName()) || returnTypeName.equals(Future.class.getName()));
+        }
+        return answer;
     }
+
+    public Method getMethodFromServiceImpl(Class serviceImpl) {
+        Method serviceImplMethod = null;
+        
+        // TODO: This doesn't support overloaded methods in the service impl  This is
+        //       DIFFERENT than overloaded WSDL operations (which aren't supported).  We
+        //       MUST support overloaded service impl methods as long as they have different
+        //       wsdl operation names.  For example:
+        //  ServiceImple Class          SEI Class
+        //                              @WebMethod.name = Foo1
+        //  void foo()                  void foo()
+        //                              @WebMethod.name = Foo2
+        //  void foo(int)               void foo(int)
+        //                              @WebMethod.name = Foo3
+        //  void foo(String)            void foo(String)
+        //
+        //  There will be two OpDescs, Foo1 and Foo2; the incoming wsdl operation will correctly identify
+        //  which OpDesc.  However, to return the correct service impl method, we need to compare the
+        //  signatures, not just the method names.
+        
+        Method[] methods = serviceImpl.getMethods();
+        String opDescMethodName = getJavaMethodName();
+        ParameterDescription[] paramDesc = getParameterDescriptions();
+        // TODO: As noted above, a full signature is necessary, not just number of params
+        int numberOfParams = 0;
+        if (paramDesc != null) {
+            numberOfParams = paramDesc.length;
+        }
+        
+        // Loop through all the methods on the service impl and find the method that maps
+        // to this OperationDescripton
+        for (Method checkMethod : methods) {
+            if (checkMethod.getName().equals(opDescMethodName)) {
+                Class[] methodParams = checkMethod.getParameterTypes();
+                // TODO: As noted above, a full signature is necessary, not just number of params
+                if (methodParams.length == numberOfParams) {
+                    serviceImplMethod = checkMethod;
+                    break;
+                }
+            }
+        }
+        
+        return serviceImplMethod;
+    } 
 }

Modified: webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ParameterParsingTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ParameterParsingTests.java?view=diff&rev=490427&r1=490426&r2=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ParameterParsingTests.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ParameterParsingTests.java Tue Dec 26 18:10:37 2006
@@ -36,16 +36,16 @@
         pdc.setParameterType(holderInputString);
         assertEquals("javax.xml.ws.Holder<java.lang.Object>", pdc.getParameterType());
         
-        assertTrue(ParameterDescriptionComposite.isHolderType(holderInputString));
+        assertTrue(DescriptionBuilderUtils.isHolderType(holderInputString));
         assertTrue(pdc.isHolderType());
-        String holderResultString = ParameterDescriptionComposite.getRawType(holderInputString);
+        String holderResultString = DescriptionBuilderUtils.getRawType(holderInputString);
         assertEquals("javax.xml.ws.Holder", holderResultString);
         holderResultString = pdc.getRawType();
         assertEquals("javax.xml.ws.Holder", holderResultString);
         javax.xml.ws.Holder validateHolder = new javax.xml.ws.Holder();
         assertEquals(validateHolder.getClass(), pdc.getParameterTypeClass());
               
-        String actualTypeResult = ParameterDescriptionComposite.getHolderActualType(holderInputString);
+        String actualTypeResult = DescriptionBuilderUtils.getHolderActualType(holderInputString);
         assertEquals("java.lang.Object", actualTypeResult);
         actualTypeResult = pdc.getHolderActualType();
         assertEquals("java.lang.Object", actualTypeResult);
@@ -104,8 +104,8 @@
         Class[] primitiveClasses = {boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class, void.class};
         
         for (int i = 0; i < primitivesToTest.length; i++) {
-            assertFalse(ParameterDescriptionComposite.isHolderType(primitivesToTest[i]));
-            assertNull(ParameterDescriptionComposite.getRawType(primitivesToTest[i]));
+            assertFalse(DescriptionBuilderUtils.isHolderType(primitivesToTest[i]));
+            assertNull(DescriptionBuilderUtils.getRawType(primitivesToTest[i]));
             ParameterDescriptionComposite pdc = new ParameterDescriptionComposite();
             pdc.setParameterType(primitivesToTest[i]);
             assertEquals(primitiveClasses[i], pdc.getParameterTypeClass());
@@ -117,8 +117,8 @@
         Class[] primitiveClasses = {boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class, void.class};
         
         for (int i = 0; i < primitivesToTest.length; i++) {
-            assertFalse(ParameterDescriptionComposite.isHolderType(primitivesToTest[i]));
-            assertNull(ParameterDescriptionComposite.getRawType(primitivesToTest[i]));
+            assertFalse(DescriptionBuilderUtils.isHolderType(primitivesToTest[i]));
+            assertNull(DescriptionBuilderUtils.getRawType(primitivesToTest[i]));
             ParameterDescriptionComposite pdc = new ParameterDescriptionComposite();
             pdc.setParameterType(primitivesToTest[i]);
             assertEquals(primitiveClasses[i], pdc.getParameterTypeClass());

Added: webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ReturnTypeParsingTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ReturnTypeParsingTests.java?view=auto&rev=490427
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ReturnTypeParsingTests.java (added)
+++ webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/builder/ReturnTypeParsingTests.java Tue Dec 26 18:10:37 2006
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.description.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the parsing of Generics that are used in the DescriptionBuilderComposite
+ * processing.
+ */
+public class ReturnTypeParsingTests extends TestCase {
+    
+    public void testNonHolderGenric() {
+        String inputString = "java.util.List<org.apache.axis2.jaxws.description.builder.MyReturnTestObject>";
+        MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+        mdc.setReturnType(inputString);
+        assertEquals(
+                "java.util.List<org.apache.axis2.jaxws.description.builder.MyReturnTestObject>",
+                mdc.getReturnType());
+
+        assertEquals(java.util.List.class, mdc.getReturnTypeClass());
+    }
+
+    public void testPrimitivesEncoded() {
+        String[] primitivesToTest = { "Z", "B", "C", "D", "F", "I", "J", "S",
+                "V" };
+        Class[] primitiveClasses = { boolean.class, byte.class, char.class,
+                double.class, float.class, int.class, long.class, short.class,
+                void.class };
+
+        for (int i = 0; i < primitivesToTest.length; i++) {
+            assertNull(DescriptionBuilderUtils.getRawType(primitivesToTest[i]));
+            MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+            mdc.setReturnType(primitivesToTest[i]);
+            assertEquals(primitiveClasses[i], mdc.getReturnTypeClass());
+        }
+    }
+
+    public void testPrimitives() {
+        String[] primitivesToTest = { "boolean", "byte", "char", "double",
+                "float", "int", "long", "short", "void" };
+        Class[] primitiveClasses = { boolean.class, byte.class, char.class,
+                double.class, float.class, int.class, long.class, short.class,
+                void.class };
+
+        for (int i = 0; i < primitivesToTest.length; i++) {
+            assertNull(DescriptionBuilderUtils.getRawType(primitivesToTest[i]));
+            MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+            mdc.setReturnType(primitivesToTest[i]);
+            assertEquals(primitiveClasses[i], mdc.getReturnTypeClass());
+        }
+    }
+
+    public void testPrimitiveArrays() {
+        String[] primitivesToTest = { "boolean[]", "byte[]", "char[]",
+                "double[]", "float[]", "int[]", "long[]", "short[]" };
+        Class[] primitiveClasses = { boolean[].class, byte[].class,
+                char[].class, double[].class, float[].class, int[].class,
+                long[].class, short[].class };
+
+        for (int i = 0; i < primitivesToTest.length; i++) {
+            MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+            mdc.setReturnType(primitivesToTest[i]);
+            assertEquals(primitiveClasses[i], mdc.getReturnTypeClass());
+        }
+    }
+
+    public void testPrimitiveMultiDimArrays() {
+        String[] primitivesToTest = { "boolean[][]", "byte[][][]",
+                "char[][][][]", "double[][][][][]", "float[][][][][][]",
+                "int[]", "long[]", "short[]" };
+        Class[] primitiveClasses = { boolean[][].class, byte[][][].class,
+                char[][][][].class, double[][][][][].class,
+                float[][][][][][].class, int[].class, long[].class,
+                short[].class };
+        for (int i = 0; i < primitivesToTest.length; i++) {
+            MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+            mdc.setReturnType(primitivesToTest[i]);
+            assertEquals(primitiveClasses[i], mdc.getReturnTypeClass());
+        }
+    }
+
+    public void testJavaLangObjectArrays() {
+        MethodDescriptionComposite pdcObject = new MethodDescriptionComposite();
+        pdcObject.setReturnType("java.lang.Object[]");
+        Object[] verifyObject = new Object[5];
+        assertEquals(verifyObject.getClass(), pdcObject.getReturnTypeClass());
+
+        MethodDescriptionComposite pdcString = new MethodDescriptionComposite();
+        pdcString.setReturnType("java.lang.String[][][]");
+        String[][][] verifyString = new String[5][1][3];
+        assertEquals(verifyString.getClass(), pdcString.getReturnTypeClass());
+
+        MethodDescriptionComposite pdcInteger = new MethodDescriptionComposite();
+        pdcInteger.setReturnType("java.lang.Integer[][][][]");
+        Integer[][][][] verifyInteger = new Integer[5][1][3][12];
+        assertEquals(verifyInteger.getClass(), pdcInteger
+                .getReturnTypeClass());
+    }
+
+    public void testMyObjectArray() {
+        MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+        mdc.setReturnType("org.apache.axis2.jaxws.description.builder.MyReturnTestObject[][]");
+        MyReturnTestObject[][] myObject = new MyReturnTestObject[2][3];
+        assertEquals(myObject.getClass(), mdc.getReturnTypeClass());
+    }
+
+    public void testArrayListOfPrimitiveArray() {
+        MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+        mdc.setReturnType("java.util.ArrayList<byte[]>");
+        assertEquals("java.util.ArrayList<byte[]>", mdc.getReturnType());
+        assertEquals(ArrayList.class, mdc.getReturnTypeClass());
+    }
+
+    public void testListOfMyObjectArray() {
+        MethodDescriptionComposite mdc = new MethodDescriptionComposite();
+        mdc.setReturnType("java.util.List<org.apache.axis2.jaxws.description.builder.MyReturnTestObject[][]>");
+        assertEquals(
+                "java.util.List<org.apache.axis2.jaxws.description.builder.MyReturnTestObject[][]>",
+                mdc.getReturnType());
+
+        assertEquals(List.class, mdc.getReturnTypeClass());
+    }
+}
+
+class MyReturnTestObject {
+
+}
\ No newline at end of file



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