You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ba...@apache.org on 2007/04/12 23:00:13 UTC

svn commit: r528232 - in /webservices/axis2/trunk/java/modules/metadata: src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java

Author: barrettj
Date: Thu Apr 12 14:00:11 2007
New Revision: 528232

URL: http://svn.apache.org/viewvc?view=rev&rev=528232
Log:
Validate impl signatures against SEI.  Add associated test case.

Added:
    webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java
Modified:
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java?view=diff&rev=528232&r1=528231&r2=528232
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java Thu Apr 12 14:00:11 2007
@@ -966,6 +966,7 @@
                 seiMethodHashMap.values().iterator();
         while (verifySEIIterator.hasNext()) {
             MethodDescriptionComposite mdc = verifySEIIterator.next();
+            // TODO: This does not take into consideration overloaded java methods!
             MethodDescriptionComposite implMDC = compositeHashMap.get(mdc.getMethodName());
             
             if (implMDC == null) {
@@ -978,18 +979,112 @@
             } else {
                 //At least we found it, now make sure that signatures match up
                 
-                //Check for exceptions matching
+                //Check for exception and signature matching
                 validateMethodExceptions(mdc, implMDC, seic.getClassName());
-                                
-                // REVIEW:  Probably should do other signature comparisons
+                validateMethodReturnValue(mdc, implMDC, seic.getClassName());
+                validateMethodParameters(mdc, implMDC, seic.getClassName());
             }
         }
     }
-    
+
+    private void validateMethodParameters(MethodDescriptionComposite seiMDC,
+        MethodDescriptionComposite implMDC, String className) {
+        List<ParameterDescriptionComposite> seiPDCList = seiMDC
+            .getParameterDescriptionCompositeList();
+        List<ParameterDescriptionComposite> implPDCList = implMDC
+            .getParameterDescriptionCompositeList();
+        if ((seiPDCList == null || seiPDCList.isEmpty())
+            && (implPDCList == null || implPDCList.isEmpty())) {
+            // There are no parameters on the SEI or the impl; all is well
+        } else if ((seiPDCList == null || seiPDCList.isEmpty())
+            && !(implPDCList == null || implPDCList.isEmpty())) {
+            String message = "Validation error: SEI indicates no parameters but implementation method specifies parameters: "
+                + implPDCList
+                + "; Implementation class: "
+                + composite.getClassName()
+                + "; Method name: " + seiMDC.getMethodName() + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+        } else if ((seiPDCList != null && !seiPDCList.isEmpty())
+            && !(implPDCList != null && !implPDCList.isEmpty())) {
+            String message = "Validation error: SEI indicates parameters " + seiPDCList
+                + " but implementation method specifies no parameters; Implementation class: "
+                + composite.getClassName() + "; Method name: " + seiMDC.getMethodName()
+                + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+        } else if (seiPDCList.size() != implPDCList.size()) {
+            String message = "Validation error: The number of parameters on the SEI method ("
+                + seiPDCList.size()
+                + ") does not match the number of parameters on the implementation ( "
+                + implPDCList.size() + "); Implementation class: " + composite.getClassName()
+                + "; Method name: " + seiMDC.getMethodName() + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+
+        } else {
+            // Make sure the order and type of parameters match
+            // REVIEW: This checks for strict equality of the fully qualified
+            // type. It does not
+            // take into consideration object hierachy. For example foo(Animal)
+            // will not equal bar(Zebra)
+            boolean parametersMatch = true;
+            String failingMessage = null;
+            for (int paramNumber = 0; paramNumber < seiPDCList.size(); paramNumber++) {
+                String seiParamType = seiPDCList.get(paramNumber).getParameterType();
+                String implParamType = implPDCList.get(paramNumber).getParameterType();
+                if (!seiParamType.equals(implParamType)) {
+                    parametersMatch = false;
+                    failingMessage = "Validation error: SEI and implementation parameters do not match.  Parameter number "
+                        + paramNumber
+                        + " on the SEI is "
+                        + seiParamType
+                        + "; on the implementation it is "
+                        + implParamType
+                        + "; Implementation class: "
+                        + composite.getClassName()
+                        + "; Method name: "
+                        + seiMDC.getMethodName() + "; Endpoint Interface: " + className;
+                    break;
+                }
+            }
+            if (!parametersMatch) {
+                throw ExceptionFactory.makeWebServiceException(failingMessage);
+            }
+        }
+    }
+
+    private void validateMethodReturnValue(MethodDescriptionComposite seiMDC,
+        MethodDescriptionComposite implMDC, String className) {
+        String seiReturnValue = seiMDC.getReturnType();
+        String implReturnValue = implMDC.getReturnType();
+
+        if (seiReturnValue == null && implReturnValue == null) {
+            // Neither specify a return value; all is well
+        } else if (seiReturnValue == null && implReturnValue != null) {
+            String message = "Validation error: SEI indicates no return value but implementation method specifies return value: "
+                + implReturnValue
+                + "; Implementation class: "
+                + composite.getClassName()
+                + "; Method name: " + seiMDC.getMethodName() + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+        } else if (seiReturnValue != null && implReturnValue == null) {
+            String message = "Validation error: SEI indicates return value " + seiReturnValue
+                + " but implementation method specifies no return value; Implementation class: "
+                + composite.getClassName() + "; Method name: " + seiMDC.getMethodName()
+                + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+        } else if (!seiReturnValue.equals(implReturnValue)) {
+            String message = "Validation error: SEI return value " + seiReturnValue
+                + " does not match implementation method return value " + implReturnValue
+                + "; Implementation class: " + composite.getClassName() + "; Method name: "
+                + seiMDC.getMethodName() + "; Endpoint Interface: " + className;
+            throw ExceptionFactory.makeWebServiceException(message);
+        }
+
+    }
+
     private void validateMethodExceptions ( MethodDescriptionComposite seiMDC, 
-                                            MethodDescriptionComposite implMDC,
-                                            String className) {
-        
+        MethodDescriptionComposite implMDC,
+        String className) {
+
         String[] seiExceptions = seiMDC.getExceptions();
         String[] implExceptions = implMDC.getExceptions();
 

Added: webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java?view=auto&rev=528232
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java (added)
+++ webservices/axis2/trunk/java/modules/metadata/test/org/apache/axis2/jaxws/description/ValidateServiceImplTests.java Thu Apr 12 14:00:11 2007
@@ -0,0 +1,251 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.List;
+
+import javax.jws.WebService;
+
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
+import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
+import org.apache.axis2.jaxws.description.builder.converter.JavaClassToDBCConverter;
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ */
+public class ValidateServiceImplTests extends TestCase {
+
+    public void testValidServiceImpl() {
+        try {
+            Class serviceImplClass = ServiceImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            assertNotNull(serviceDescList);
+            assertEquals(1, serviceDescList.size());
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+            fail("Caught unexpected exception" + e);
+        }
+    }
+    
+    public void testMissingMethods() {
+        try {
+            Class serviceImplClass = MissingMethodsImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+    
+    public void testInvalidThrows() {
+        try {
+            Class serviceImplClass = InvalidThrowsImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+    
+    public void testMismatchedReturnTypesDBC() {
+        try {
+            Class serviceImplClass = ServiceImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            // Set the return types for one of the methods on the impl class to mismatch the SEI
+            DescriptionBuilderComposite implDBC = dbcMap.get("org.apache.axis2.jaxws.description.ServiceImpl");
+            assertNotNull(implDBC);
+            List<MethodDescriptionComposite> m1MDCList = implDBC.getMethodDescriptionComposite("method1");
+            assertNotNull(m1MDCList);
+            assertEquals(1, m1MDCList.size());
+            MethodDescriptionComposite m1MDC = m1MDCList.get(0);
+            assertEquals("java.lang.String", m1MDC.getReturnType());
+            m1MDC.setReturnType("lava.lang.Integer");
+            
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+
+    public void testMismatchedReturnTypes() {
+        try {
+            Class serviceImplClass = MismatchedReturnTypesImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+
+    public void testMismatchedParameterNumber() {
+        try {
+            Class serviceImplClass = MismatchedParameterNumberImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+
+    public void testMismatchedParameterTypes() {
+        try {
+            Class serviceImplClass = MismatchedParameterTypesImpl.class;
+            JavaClassToDBCConverter converter = new JavaClassToDBCConverter(serviceImplClass);
+            HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
+            List<ServiceDescription> serviceDescList =  DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
+            fail("Should have caused exception");
+        }
+        catch (Exception e) {
+            // Expected path
+        }
+    }
+
+}
+
+@WebService
+interface EndpointInterface {
+    public String method1(int param1, int param2) throws MyException;
+    
+    public void method2(String param1) throws MyException;
+    
+    public int method3();
+}
+
+class MyException extends Exception {
+    
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class ServiceImpl {
+    public String method1(int param1, int param2) throws MyException {
+        return null;
+    }
+    
+    // Intentionally doesn't throw MyException.  It is valid for a service impl to throw
+    // fewer exceptions than the endpoint interface
+    public void method2(String param1) {
+        
+    }
+    
+    public int method3() {
+        return 0;
+    }
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class MissingMethodsImpl {
+    public String method1(int param1, int param2) {
+        return null;
+    }
+    
+//    public void method2(String param1) {
+//        
+//    }
+    
+    public int method3() {
+        return 0;
+    }
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class InvalidThrowsImpl {
+    public String method1(int param1, int param2) throws MyException {
+        return null;
+    }
+    
+    // Intentionally doesn't throw MyException.  It is valid for a service impl to throw
+    // fewer exceptions than the endpoint interface
+    public void method2(String param1) {
+        
+    }
+    // It is invalid to throw more exceptions than the endpoint interface
+    public int method3() throws MyException {
+        return 0;
+    }
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class MismatchedReturnTypesImpl {
+    // Return type doesn't match SEI
+    public Integer method1(int param1, int param2) throws MyException {
+        return null;
+    }
+    
+    public void method2(String param1) {
+        
+    }
+    
+    public int method3() {
+        return 0;
+    }
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class MismatchedParameterNumberImpl {
+    public String method1(int param1) throws MyException {
+        return null;
+    }
+    
+    public void method2(String param1) {
+        
+    }
+    
+    public int method3() {
+        return 0;
+    }
+}
+
+@WebService (endpointInterface = "org.apache.axis2.jaxws.description.EndpointInterface")
+class MismatchedParameterTypesImpl {
+    public String method1(int param1, String param2) throws MyException {
+        return null;
+    }
+    
+    // Intentionally doesn't throw MyException.  It is valid for a service impl to throw
+    // fewer exceptions than the endpoint interface
+    public void method2(String param1) {
+        
+    }
+    
+    public int method3() {
+        return 0;
+    }
+}



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