Author: mmerz Date: Mon Oct 18 14:41:09 2004 New Revision: 55032 Added: incubator/beehive/trunk/wsm/drt/tests/Bar2.java incubator/beehive/trunk/wsm/drt/tests/Bar3.java incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar2TestCase.java incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar3TestCase.java incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface2Test.java incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface3Test.java Modified: incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/processor/reflection/WsmReflectionAnnotationProcessor.java Log: Additions to endpoint interface support.
Contributor: Wolfgang Added: incubator/beehive/trunk/wsm/drt/tests/Bar2.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/Bar2.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,44 @@ +/* + * Copyright 2001-2004 The Apache Software Foundation. + * + * Licensed 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. + */ + +import javax.jws.WebService; +import javax.jws.WebMethod; + +/******************************************************************************* + * + * This class is for a failure test case. + * + * this class doesn't implement the dropMoney method in + * the endpoint interface (cheetorama). + * + */ [EMAIL PROTECTED](name = "Abacus", endpointInterface = "Cheetorama") +public class Bar2 +{ + @WebMethod + public boolean getNutty(int level, String detail) + { + return (level > 5); + } + + @WebMethod + public void goHome(long time) + { + return; + } + +} + Added: incubator/beehive/trunk/wsm/drt/tests/Bar3.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/Bar3.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,47 @@ +/* + * Copyright 2001-2004 The Apache Software Foundation. + * + * Licensed 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. + */ + +import javax.jws.WebService; +import javax.jws.WebMethod; + +/******************************************************************************* + * + * Although this class implements the dropMoney method in + * the endpoint interface (cheetorama), the method is not + * annotated with @WebMethod. + * + */ [EMAIL PROTECTED](name = "Abacus", endpointInterface = "Cheetorama") +public class Bar3 +{ + @WebMethod + public boolean getNutty(int level, String detail) + { + return (level > 5); + } + + @WebMethod + public void goHome(long time) + { + return; + } + + public int dropMoney(int amount) + { + return amount; + } +} + Added: incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar2TestCase.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar2TestCase.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,85 @@ +package org.apache.beehive.wsm.jsr181.model; + +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + * + * $Header:$ + */ + +import java.util.Collection; + +import junit.framework.TestCase; + +/** + * This class serves as the base class for all TestCases based on Bar.java. It + * verifies the values of all parameters in the object model defined in Cheetorama.java + * specified as the @WebService.endpointInterface annotation in Bar.java. + * Default values are expected to be filled in. If a subclass can't fully comply + * with JSR-181 (e.g. if it can't fill in all default values) it needs to + * override the respective tests. + */ +public class Bar2TestCase extends TestCase +{ + protected static final String CLASSNAME = "Bar2"; + protected static final String SRCFILENAME = "Bar2.java"; + + protected AnnotationModel objectModel; + + protected WebServiceMETHODMetadata getMethod(String methodName) + { + if ((null == methodName) || (null == objectModel)) + { + return null; + } + + for (WebServiceMETHODMetadata method : ((WebServiceTYPEMetadata) objectModel).getMethods()) + { + if (methodName.equals(method.getWmOperationName())) + { + return method; + } + } + return null; + } + + protected WebServicePARAMETERMetadata getParam(String methodName, int pos) + { + if ((null == methodName) || (null == objectModel)) + { + return null; + } + + Collection<WebServiceMETHODMetadata> webMethods = + ((WebServiceTYPEMetadata) objectModel).getMethods(); + for (WebServiceMETHODMetadata method : webMethods) + { + if (methodName.equals(method.getWmOperationName())) + { + int i = 0; + for (WebServicePARAMETERMetadata param : method.getParams()) + { + if (i == pos) + { + return param; + } + i++; + } + } + } + return null; + } +} + + Added: incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar3TestCase.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/model/Bar3TestCase.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,84 @@ +package org.apache.beehive.wsm.jsr181.model; + +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + * + * $Header:$ + */ + +import java.util.Collection; + +import junit.framework.TestCase; + +/** + * This class serves as the base class for all TestCases based on Bar.java. It + * verifies the values of all parameters in the object model defined in Cheetorama.java + * specified as the @WebService.endpointInterface annotation in Bar.java. + * Default values are expected to be filled in. If a subclass can't fully comply + * with JSR-181 (e.g. if it can't fill in all default values) it needs to + * override the respective tests. + */ +public class Bar3TestCase extends TestCase +{ + protected static final String CLASSNAME = "Bar3"; + protected static final String SRCFILENAME = "Bar3.java"; + + protected AnnotationModel objectModel; + + protected WebServiceMETHODMetadata getMethod(String methodName) + { + if ((null == methodName) || (null == objectModel)) + { + return null; + } + + for (WebServiceMETHODMetadata method : ((WebServiceTYPEMetadata) objectModel).getMethods()) + { + if (methodName.equals(method.getWmOperationName())) + { + return method; + } + } + return null; + } + + protected WebServicePARAMETERMetadata getParam(String methodName, int pos) + { + if ((null == methodName) || (null == objectModel)) + { + return null; + } + + Collection<WebServiceMETHODMetadata> webMethods = + ((WebServiceTYPEMetadata) objectModel).getMethods(); + for (WebServiceMETHODMetadata method : webMethods) + { + if (methodName.equals(method.getWmOperationName())) + { + int i = 0; + for (WebServicePARAMETERMetadata param : method.getParams()) + { + if (i == pos) + { + return param; + } + i++; + } + } + } + return null; + } +} + Added: incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface2Test.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface2Test.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,55 @@ +package org.apache.beehive.wsm.jsr181.processor.reflection; + +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + * + * $Header:$ + */ + +import org.apache.beehive.wsm.jsr181.model.Bar2TestCase; +import org.apache.beehive.wsm.jsr181.model.WebServiceTYPEMetadata; + +public class WsmAnnotationProcessorEndpointInterface2Test extends Bar2TestCase { + + @Override + public void setUp() throws Exception + { + // empty + } + + @Override + public void tearDown() throws Exception + { + // empty + } + + public void testConsistency() throws Exception + { + Class clazz = Class.forName(CLASSNAME); + try + { + objectModel = WsmReflectionAnnotationProcessor.getObjectModel(clazz); + fail("Failed to generate error for the service implementation which doesn't implement the methods declared " + + "in the corresponding endpoint interface."); + } + catch(Exception e) + { + // good case + } + + } + +} + Added: incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface3Test.java ============================================================================== --- (empty file) +++ incubator/beehive/trunk/wsm/drt/tests/org/apache/beehive/wsm/jsr181/processor/reflection/WsmAnnotationProcessorEndpointInterface3Test.java Mon Oct 18 14:41:09 2004 @@ -0,0 +1,54 @@ +package org.apache.beehive.wsm.jsr181.processor.reflection; + +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + * + * $Header:$ + */ + +import org.apache.beehive.wsm.jsr181.model.Bar3TestCase; +import org.apache.beehive.wsm.jsr181.model.WebServiceTYPEMetadata; + +public class WsmAnnotationProcessorEndpointInterface3Test extends Bar3TestCase { + + @Override + public void setUp() throws Exception + { + // empty + } + + @Override + public void tearDown() throws Exception + { + // empty + } + + public void testConsistency() throws Exception + { + Class clazz = Class.forName(CLASSNAME); + try + { + objectModel = WsmReflectionAnnotationProcessor.getObjectModel(clazz); + } + catch(Exception e) + { + fail("The processor must not throw an exception."); + } + + } + +} + + Modified: incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/processor/reflection/WsmReflectionAnnotationProcessor.java ============================================================================== --- incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/processor/reflection/WsmReflectionAnnotationProcessor.java (original) +++ incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/processor/reflection/WsmReflectionAnnotationProcessor.java Mon Oct 18 14:41:09 2004 @@ -48,31 +48,36 @@ public static WebServiceTYPEMetadata getObjectModel(Class clazz) { - return getObjectModel(clazz, true); - } - - // isImplementationBean indicates the specified clazz is whether a service implementation bean or - // service endpoint interface. - public static WebServiceTYPEMetadata getObjectModel(Class clazz, boolean isImplementationBean) - { WebService wsAnnotation; if (null == (wsAnnotation = (WebService) clazz.getAnnotation(WebService.class))) // no @WebService { return null; } - Method[] methods = clazz.getMethods(); - Collection<WebServiceMETHODMetadata> webMethods = - new ArrayList<WebServiceMETHODMetadata>(); - for (Method method : methods) - { - //method is a webmethod - if (isImplementationBean && (null == method.getAnnotation(WebMethod.class))) - { - // This method is declared in a service implementation bean, but not annotated with @WebMethod. - // Thus, this method will not be exposed. - continue; - } + // isImplementationBean indicates the specified clazz is whether a service implementation bean or + // service endpoint interface. + boolean isImplementationBean = (! clazz.isInterface()); + boolean hasEndpointInterface = false; + + if (isImplementationBean) + { + hasEndpointInterface = (wsAnnotation.endpointInterface().trim().length() != 0); + } + + Method[] methods = clazz.getMethods(); + Collection<WebServiceMETHODMetadata> webMethods = + new ArrayList<WebServiceMETHODMetadata>(); + for (Method method : methods) + { + boolean isAnnotated = method.getAnnotation(WebMethod.class) != null ? true : false ; + + if (isImplementationBean && !isAnnotated && !hasEndpointInterface ) + { + // This method is declared in a service implementation bean and not annotated with @WebMethod. + // Furthermore, the service implementation bean doesn't specify an endpoint interface. + // Thus, this method should NOT be stored in the object model. + continue; + } // get all parameters List<WebServicePARAMETERMetadata> params = @@ -134,27 +139,39 @@ } try{ - // check the service endpoint interface only for the service implementation bean. - if( isImplementationBean ){ - wstm = handleEndpointInterface(wstm); - } - }catch (Throwable t) - { - t.printStackTrace(); // todo proper error handling - } - - return wstm; - } - - // copied from WsmAnnotationProcessor and removed a search funcitionality of source files. - public static WebServiceTYPEMetadata handleEndpointInterface(WebServiceTYPEMetadata webServiceTYPEMetadata) - throws ClassNotFoundException - { - String endpointInterface = webServiceTYPEMetadata.getWsEndpointInterface(); - if (null == endpointInterface || 0 == endpointInterface.length()) - { - return webServiceTYPEMetadata; + if( hasEndpointInterface ){ + // this service implementation bean specifies the endpoint interface. + // Thus, process it. + wstm = handleEndpointInterface(wstm); + } } + catch (ProcessorException pe) + { + // todo proper error handling + // actually, this try-catch clause is NOT needed, just throw the ProcessorException + // up to the caller. + pe.printStackTrace(); + Throwable t = pe.getCause(); + if ( t != null ) + { + t.printStackTrace(); + } + // throw a RuntimeException for now. + throw new RuntimeException("Failed to build the object model of the endpoint interface."); + } + + return wstm; + } + + // constructs the endpoint interface of the specified webServiceTYPEMetadata. + public static WebServiceTYPEMetadata handleEndpointInterface(WebServiceTYPEMetadata webServiceTYPEMetadata) + throws ProcessorException + { + String endpointInterface = webServiceTYPEMetadata.getWsEndpointInterface(); + if (0 == endpointInterface.trim().length()) + { + return webServiceTYPEMetadata; + } // the endpoint interface is specified by this webServiceTYPEMetadata. // Thus, load it. @@ -183,9 +200,18 @@ } else { - - endpointInterfaceMetadata = - getObjectModel( Class.forName(endpointInterface) , false); + try + { + endpointInterfaceMetadata = + getObjectModel(Class.forName(endpointInterface)); + } + catch (ClassNotFoundException cnfe) + { + ProcessorException processException = + new ProcessorException ("The endpoint interface ["+endpointInterface+"] couldn't be found."); + processException.initCause(cnfe); + throw processException; + } /* Not implemented. // a java CLASS file is specified for the endpoint interface. @@ -211,9 +237,10 @@ if (null == endpointInterfaceMetadata) { // The endpoint interface is specified, but couldn't be found ! - // todo: Must throw an Exception but just return the original - // webServiceTYPEMetadata for now. - return webServiceTYPEMetadata; + throw new ProcessorException( + "The endpoint interface ("+endpointInterface+") is specified " + + "but building the object model of the interface failed." + ); } endpointInterfaceMetadata.setWsServiceName( @@ -223,6 +250,81 @@ webServiceTYPEMetadata.getWsEndpointInterface() ); + validate(webServiceTYPEMetadata, endpointInterfaceMetadata); + return endpointInterfaceMetadata; } + + // check whether the implementation bean implements all the methods specified in the endpointInterface. + private static void validate(WebServiceTYPEMetadata implementationMetadata, WebServiceTYPEMetadata interfaceMetadata) + throws ProcessorException + { + Collection<WebServiceMETHODMetadata> implementationMethods = implementationMetadata.getMethods(); + + Collection<WebServiceMETHODMetadata> interfaceMethods = interfaceMetadata.getMethods(); + + for( WebServiceMETHODMetadata interfaceMethod : interfaceMethods ) + { + boolean exists = false; + for( WebServiceMETHODMetadata implementationMethod : implementationMethods ) + { + exists = isSameMethodSignature( interfaceMethod, implementationMethod ); + if( exists ) + { + break; + } + } + + if(!exists) + { + throw new ProcessorException("The implementation bean ("+ implementationMetadata.getJavaFQClassName() + + ") doesn't implement the " + interfaceMethod.getWmOperationName() + + " method in the endpoint interface ("+ interfaceMetadata.getJavaFQClassName() + + ")" + ); + } + + } + + } + + // compare the signature of specified methods. + private static boolean isSameMethodSignature(WebServiceMETHODMetadata m1, WebServiceMETHODMetadata m2) + { + // check java method names. + if( ! m1.getJavaMethodName().equals(m2.getJavaMethodName()) ) + { + return false; + } + + // check java return types. + if( ! m1.getJavaReturnType().equals(m2.getJavaReturnType()) ) + { + return false; + } + + List<WebServicePARAMETERMetadata> m1Params = m1.getParams(); + List<WebServicePARAMETERMetadata> m2Params = m2.getParams(); + + // check the number of parameters. + if( m1Params.size() != m2Params.size() ) + { + return false; + } + + // check each parameter's type. + for( int i = 0 ; i < m1Params.size() ; i++ ) + { + WebServicePARAMETERMetadata m1Param = m1Params.get(i); + WebServicePARAMETERMetadata m2Param = m2Params.get(i); + + if( m1Param.getJavaType() != m2Param.getJavaType() ) + { + return false; + } + } + + return true; + } + }
