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/15 21:30:28 UTC

svn commit: r487650 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/description/builder/ src/org/apache/axis2/jaxws/description/impl/ test/org/apache/axis2/jaxws/description/builder/ test/org/apache/axis2/jaxws/framework/

Author: barrettj
Date: Fri Dec 15 12:30:28 2006
New Revision: 487650

URL: http://svn.apache.org/viewvc?view=rev&rev=487650
Log:
Fix ParameterDescriptionComposite to correctly load JAX-WS Holder<T> and other generic classes used as parameters.
Previously the code try to do a Class.forName("javax.ws.Holder<java.lang.Object>"); added logic to parse out Holder<T> as a special
case and also provide access to the Class for type T.  For other generics, provides access to the class such as java.util.List for
java.util.List<my.package.MyClass>.

Added:
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/builder/GenericsParsingTests.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/impl/ParameterDescriptionImpl.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java?view=diff&rev=487650&r1=487649&r2=487650
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/builder/ParameterDescriptionComposite.java Fri Dec 15 12:30:28 2006
@@ -3,16 +3,14 @@
  */
 package org.apache.axis2.jaxws.description.builder;
 
-import java.lang.reflect.Type;
-
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.i18n.Messages;
 
 public class ParameterDescriptionComposite {
-	
+    private static String JAXWS_HOLDER_CLASS = "javax.xml.ws.Holder";
+    
 	private String					parameterType;
 	private Class					parameterTypeClass;
-	private Type					parameterGenericType;
 	private WebParamAnnot			webParamAnnot;
 	private WebServiceRefAnnot 		webServiceRefAnnot;
 	private WebServiceContextAnnot	webServiceContextAnnot;
@@ -27,14 +25,12 @@
 	public ParameterDescriptionComposite (	
 			String					parameterType,
 			Class 					parameterTypeClass,
-			Type					parameterGenericType,
 			WebParamAnnot 			webParamAnnot,
 			WebServiceRefAnnot 		webServiceRefAnnot,
 			WebServiceContextAnnot	webServiceContextAnnot) {
 
 		this.parameterType 			= parameterType;
 		this.parameterTypeClass		= parameterTypeClass;
-		this.parameterGenericType	= parameterGenericType;
 		this.webParamAnnot 			= webParamAnnot;
 		this.webServiceRefAnnot 	= webServiceRefAnnot;
 		this.webServiceContextAnnot = webServiceContextAnnot;
@@ -48,55 +44,79 @@
 	}
 
 	/**
+     * Returns the class associated with the Parameter.  Note that if this is a generic (including a JAXWS
+     * Holder<T>) then the class associated with the raw type is returned (i.e. Holder.class).
+     * 
+     * For a JAX-WS Holder<T>, use getHolderActualType(...) to get the class associated with T.
+     * 
 	 * @return Returns the parameterTypeClass.
-	 * Do lazy loading
 	 */
 	public Class getParameterTypeClass() {
 		
-		ClassLoader classLoader = null; 
-		
-		if (getMethodDescriptionCompositeRef() != null) {
-			if (getMethodDescriptionCompositeRef().getDescriptionBuilderCompositeRef() != null){
-				classLoader = getMethodDescriptionCompositeRef().getDescriptionBuilderCompositeRef().getClassLoader();
-			}
-		}
-		
 		if (parameterTypeClass == null) {
 			if (getParameterType() != null) {
 				parameterTypeClass = getPrimitiveClass(getParameterType());
 				if (parameterTypeClass == null) {
-					
-					if (classLoader != null) {			
-						try {
-							parameterTypeClass = Class.forName(parameterType, false, classLoader);
-							
-						} catch (ClassNotFoundException ex) {
-							throw ExceptionFactory.makeWebServiceException("ParameterDescriptionComposite: Class not found for parameter: " +parameterType);
-						}
-					} else {
-						//Use the default classloader to get this strings class
-						try {
-							parameterTypeClass = Class.forName(parameterType);
-						} catch (ClassNotFoundException ex) {
-							throw ExceptionFactory.makeWebServiceException("ParameterDescriptionComposite: Class not found for parameter: " +parameterType);
-						}
-					}
+					// 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);
+                    }
+                    else {
+                        classToLoad = parameterType; 
+                    }
+                    parameterTypeClass = loadClassFromPDC(classToLoad);
 				}
 			}
 		}
 		return parameterTypeClass;
 	}
 
-	/**
-	 * @return Returns the parameterGenericType.
-	 * Do lazy loading
-	 */
-	public Type getParameterGenericType() {
-		
-		//TODO: Determine if this is a parameterized generic type
-		//TODO: Need to set this based on the parameterTypeClass ...hmmm
-		return parameterGenericType;
-	}
+    /**
+     * For JAX-WS Holder<T>, returns the class associated with T.  For non-JAX-WS Holders
+     * returns null.
+     */
+    public Class getHolderActualTypeClass() {
+        Class returnClass = null;
+
+        if (isHolderType(parameterType)) {
+            String classToLoad = getHolderActualType(parameterType);
+            returnClass = loadClassFromPDC(classToLoad);
+        }
+        return returnClass;
+    }
+    
+    private Class loadClassFromPDC(String classToLoad) {
+        Class returnClass = null;
+        ClassLoader classLoader = null; 
+        
+        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);
+            }
+        }
+        return returnClass;
+    }
+    
 
 	/**
 	 * @return Returns the webParamAnnot.
@@ -148,13 +168,6 @@
 	}
 
 	/**
-	 * @param parameterGenericType The parameterGenericType to set.
-	 */
-	private void setParameterGenericType(Type parameterGenericType) {
-		this.parameterGenericType = parameterGenericType;
-	}
-
-	/**
 	 * @param webParamAnnot The webParamAnnot to set.
 	 */
 	public void setWebParamAnnot(WebParamAnnot webParamAnnot) {
@@ -240,4 +253,80 @@
 		sb.append("***** END ParameterDescriptionComposite *****");
 		return sb.toString();
 	}
+    
+    public String getRawType() {
+        return getRawType(parameterType);
+    }
+    public String getHolderActualType() {
+        return 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;
+    }
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/impl/ParameterDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/impl/ParameterDescriptionImpl.java?view=diff&rev=487650&r1=487649&r2=487650
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/impl/ParameterDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/impl/ParameterDescriptionImpl.java Fri Dec 15 12:30:28 2006
@@ -38,10 +38,18 @@
  */
 class ParameterDescriptionImpl implements ParameterDescription, ParameterDescriptionJava, ParameterDescriptionWSDL {
     private OperationDescription parentOperationDescription;
+    // The Class representing the parameter.  Note that for a Generic, including the JAX-WS Holder<T> Generic, 
+    // this represents the raw type of the Generic (e.g. List for List<T> or Holder for Holder<T>).
     private Class parameterType;
-    private ParameterizedType parameterGenericType;
+    // For the JAX-WS Generic Holder<T> (e.g. Holder<Foo>), this will be the actual type argument (e.g. Foo).  For 
+    // any other parameter (including other Generics), this will be null. 
+    // Note that since JAX-WS Holder<T> only supports a single actual type T (not multiple types such as <K,V>)
+    private Class parameterHolderActualType;
+    
     // 0-based number of the parameter in the argument list
     private int parameterNumber = -1;
+    // The Parameter Description Composite used to build the ParameterDescription
+    private ParameterDescriptionComposite paramDescComposite;
 
     // ANNOTATION: @WebMethod
     private WebParam            webParamAnnotation;
@@ -59,23 +67,24 @@
         this.parameterType = parameterType;
         
         // The Type argument could be a Type (if the parameter is a Paramaterized Generic) or
-        // just a Class (if it is not).  We only need to keep track of Paramaterized Type information. 
-        if (ParameterizedType.class.isInstance(parameterGenericType)) {   
-            this.parameterGenericType = (ParameterizedType) parameterGenericType;
+        // just a Class (if it is not).  If it JAX-WS Holder<T> parameterized type, then get the 
+        // actual parameter type and hang on to that, too.
+        if (ParameterizedType.class.isInstance(parameterGenericType)) {
+            this.parameterHolderActualType = getGenericParameterActualType((ParameterizedType) parameterGenericType);
         }
         findWebParamAnnotation(parameterAnnotations);
     }
     
     ParameterDescriptionImpl(int parameterNumber, ParameterDescriptionComposite pdc, OperationDescription parent) {
+        this.paramDescComposite = pdc;
         this.parameterNumber = parameterNumber;
         this.parentOperationDescription = parent;
         this.parameterType = pdc.getParameterTypeClass();
-        
-        
-        if (ParameterizedType.class.isInstance(pdc.getParameterGenericType())) {   
-            this.parameterGenericType = (ParameterizedType) pdc.getParameterGenericType();
+        // If this is a JAX-WS Holder<T>, then get the Class for the actual type T also.
+        if (pdc.isHolderType()) {
+            this.parameterHolderActualType = pdc.getHolderActualTypeClass();
         }
-
+        
         webParamAnnotation = pdc.getWebParamAnnot();
         
         //TODO: Need to build the schema map. Need to add logic to add this parameter
@@ -105,16 +114,43 @@
         return parentOperationDescription;
     }
     
+    /**
+     * Returns the class associated with the parameter.  Note that for the JAX-WS Holder<T> type, you can use
+     * getParameterActualType() to get the class associated with T.
+     */
     public Class getParameterType() {
         return parameterType;
     }
     
     /**
-     * For a non-Holder type, returns the parameter class.  For a Holder<T> type, returns the class of T
+     * For a non-Holder type, returns the parameter class.  For a Holder<T> type, returns the class of T.
      * @return
      */
     public Class getParameterActualType() {
-        if (isHolderType() && parameterGenericType != null) {
+        if (parameterHolderActualType != null) {
+            return parameterHolderActualType;
+        }
+        else {
+            return parameterType;
+        }
+    }
+    /**
+     * TEMPORARY METHOD!  For a JAX-WS Holder<T> this returns the class associated with <T>.
+     * For a Holder<Generic<...>>, it returns the class associated with Generic.  If the type
+     * is not a JAX-WS Holder, return a null.
+     * 
+     * This method SHOULD BE REMOVED when the description layer is refactored to use only DBC 
+     * and not Java reflection directly.
+     * @param parameterGenericType
+     * @return
+     */
+    // TODO: Remove this method when code refactored to only use DBC.
+    private Class getGenericParameterActualType(ParameterizedType parameterGenericType) {
+        Class returnClass = null;
+        // If this is a JAX-WS Holder type, then get the actual type.  Note that we can't use the
+        // isHolderType method yet because the class variable it is going to check (parameterHolderActualType)
+        // hasn't been initialized yet.
+        if (parameterGenericType != null && parameterGenericType.getRawType() == javax.xml.ws.Holder.class) {
             
             // REVIEW:
             // Do we want to add a getParameterActualGenericType that would return Type
@@ -125,27 +161,30 @@
             // OperationDesc.getResultActualType
             
             // For types of Holder<T>, return the class associated with T
+            // For types of Holder<Generic<K,V>>, return class associated with Generic 
             Type type = parameterGenericType.getActualTypeArguments()[0];
             if (type != null && ParameterizedType.class.isInstance(type)) {
                 return (Class) ((ParameterizedType) type).getRawType();
             }
             return (Class) type;
         }
-        else {
-            return parameterType;
-        }
-            
+        
+        return returnClass;
     }
-    
+
+    /**
+     * Answer whether this ParameterDescription represents a JAX-WS Holder<T> type.
+     */
     public boolean isHolderType() {
+        // If this is a JAX-WS Holder<T> type, then we set the the class of the actual
+        // parameter <T> in the constructor.  Otherwise, that is null.
         // Holder types are defined by JSR-224 JAX-WS 2.0, Sec 2.3.3, pg 16
-        boolean returnValue = false;
-        if (parameterGenericType != null && ParameterizedType.class.isInstance(parameterGenericType)) {   
-            if (parameterGenericType.getRawType() == javax.xml.ws.Holder.class) {
-                returnValue = true;
-            }
+        if (parameterHolderActualType != null) {
+            return true;
+        }
+        else {
+            return false;
         }
-        return returnValue;
     }
 
     // =====================================

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/builder/GenericsParsingTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/builder/GenericsParsingTests.java?view=auto&rev=487650
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/builder/GenericsParsingTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/description/builder/GenericsParsingTests.java Fri Dec 15 12:30:28 2006
@@ -0,0 +1,60 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * Tests the parsing of Generics that are used in the DescriptionBuilderComposite
+ * processing.
+ */
+public class GenericsParsingTests extends TestCase {
+    private static String JAXWS_HOLDER = "javax.xml.ws.Holder";
+    
+    public void testHolder() {
+        String holderInputString = JAXWS_HOLDER + "<java.lang.Object>";
+        assertTrue(ParameterDescriptionComposite.isHolderType(holderInputString));
+        String holderResultString = ParameterDescriptionComposite.getRawType(holderInputString);
+        assertEquals(JAXWS_HOLDER, holderResultString);
+        
+        String actualTypeResult = ParameterDescriptionComposite.getHolderActualType(holderInputString);
+        assertEquals("java.lang.Object", actualTypeResult);
+    }
+
+    public void testNonHolderGenric() {
+        String inputString = "java.util.List<my.package.MyClass>";
+        assertFalse(ParameterDescriptionComposite.isHolderType(inputString));
+        String genericType = ParameterDescriptionComposite.getRawType(inputString);
+        assertEquals("java.util.List", genericType);
+        // This should be null since the generic is not a Holder type
+        String actualParam = ParameterDescriptionComposite.getHolderActualType(inputString);
+        assertNull(actualParam);
+    }
+    
+    public void testHolderGeneric() {
+        String holderInputString = JAXWS_HOLDER + "<java.util.List<java.lang.Object>>";
+        assertTrue(ParameterDescriptionComposite.isHolderType(holderInputString));
+        String holderResultString = ParameterDescriptionComposite.getRawType(holderInputString);
+        assertEquals(JAXWS_HOLDER, holderResultString);
+        
+        String actualTypeResult = ParameterDescriptionComposite.getHolderActualType(holderInputString);
+        assertEquals("java.util.List", actualTypeResult);
+        
+    }
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java?view=diff&rev=487650&r1=487649&r2=487650
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java Fri Dec 15 12:30:28 2006
@@ -42,6 +42,7 @@
 import org.apache.axis2.jaxws.description.WSDLTests;
 import org.apache.axis2.jaxws.description.WrapperPackageTests;
 import org.apache.axis2.jaxws.description.builder.DescriptionBuilderTests;
+import org.apache.axis2.jaxws.description.builder.GenericsParsingTests;
 import org.apache.axis2.jaxws.description.impl.ServiceDescriptionImplTests;
 import org.apache.axis2.jaxws.dispatch.DispatchTestSuite;
 import org.apache.axis2.jaxws.dispatch.SOAP12Dispatch;
@@ -85,7 +86,7 @@
     
     static {
         // Uncomment the followign line to enable debug
-        BasicConfigurator.configure();
+//        BasicConfigurator.configure();
     }
     
     /**
@@ -115,6 +116,7 @@
         suite.addTestSuite(ServiceAnnotationTests.class);
         suite.addTestSuite(WSDLTests.class);
         suite.addTestSuite(DescriptionBuilderTests.class);
+        suite.addTestSuite(GenericsParsingTests.class);
         suite.addTestSuite(ServiceDescriptionImplTests.class);
         suite.addTestSuite(WSDLDescriptionTests.class);
         suite.addTestSuite(AnnotationDescriptionTests.class);



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