From 47f6879e357c5f878e3e43164e243cd41e056df0 Mon Sep 17 00:00:00 2001 From: slaws Date: Tue, 13 Jul 2010 09:12:08 +0000 Subject: TUSCANY-3616 - Add code to check that that interface contracts a reference and reference binding and at service and service binding match. Motivated by BWS_2007. TO do this properly we have to test that the interfaces are described using the same IDL and if not convert to WSDL1.1 are required by the SCA specifications. There are a lot of changes here as doing this upset quite a few tests. Further work is required to look at the details of our WSDL generation process which looks a little suspect around wrapper namespaces. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@963624 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany-oasis-sca-tests-errors.properties | 6 +- sca-java-2.x/trunk/itest/bpel/helloworld/pom.xml | 6 + .../main/resources/wsdl/wrapped/hello-service.wsdl | 3 +- .../sca/itest/interfaces/LocalClientComponent.java | 6 +- .../itest/interfaces/LocalClientComponentImpl.java | 6 +- .../sca/itest/interfaces/InterfacesTestCase.java | 6 +- .../main/resources/jmsobject/helloworld.composite | 1 - .../src/main/resources/jmsobject/helloworld.wsdl | 368 --------------------- .../jmsbytes/helloworld/CheckedException.java | 28 -- .../jmsbytes/helloworld/HelloWorldReference.java | 32 -- .../helloworld/HelloWorldReferenceImpl.java | 50 --- .../jmsbytes/helloworld/HelloWorldService.java | 35 -- .../jmsbytes/helloworld/HelloWorldServiceImpl.java | 40 --- .../helloworld/HelloWorldServiceReference.java | 35 -- .../src/main/resources/jmstextxml/helloworld.wsdl | 8 +- .../sca/binding/ws/axis2/CustomerProfileData.java | 10 + .../tuscany/sca/binding/ws/axis2/customerdata.xsd | 2 +- .../sca/binding/ws/axis2/questionmark-include.wsdl | 6 +- .../assembly/builder/BuilderExtensionPoint.java | 22 ++ .../sca/assembly/builder/ContractBuilder.java | 37 +++ .../builder/DefaultBuilderExtensionPoint.java | 71 ++++ .../tuscany/sca/assembly/impl/EndpointImpl.java | 4 + .../sca/assembly/impl/EndpointReferenceImpl.java | 6 +- .../sca/interfacedef/InterfaceContract.java | 18 + .../interfacedef/impl/InterfaceContractImpl.java | 13 + .../impl/InterfaceContractMapperImpl.java | 174 ++++++++-- .../assembly-validation-messages.properties | 2 + .../service/mocks/TestInterfaceContract.java | 13 + .../testing/service/mocks/TestRuntimeWire.java | 13 + .../binding/ws/wsdlgen/BindingWSDLGenerator.java | 67 +++- .../ws/wsdlgen/Interface2WSDLGenerator.java | 18 +- .../binding/ws/wsdlgen/WSDLContractBuilder.java | 90 +++++ ...he.tuscany.sca.assembly.builder.ContractBuilder | 18 + .../sca/binding/ws/impl/WebServiceBindingImpl.java | 22 +- .../sca/builder/impl/ComponentBuilderImpl.java | 87 ++++- .../impl/CompositeComponentTypeBuilderImpl.java | 81 ++++- .../tuscany/sca/runtime/RuntimeEndpoint.java | 24 ++ .../sca/runtime/RuntimeEndpointReference.java | 25 ++ .../core/assembly/impl/CompositeActivatorImpl.java | 11 + .../core/assembly/impl/RuntimeEndpointImpl.java | 62 +++- .../impl/RuntimeEndpointReferenceImpl.java | 78 ++++- .../runtime/impl/EndpointReferenceBinderImpl.java | 12 +- .../interfacedef/java/JavaInterfaceContract.java | 2 +- .../java/impl/JavaInterfaceContractImpl.java | 14 + .../wsdl/impl/WSDLInterfaceContractImpl.java | 9 + 45 files changed, 971 insertions(+), 670 deletions(-) delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.wsdl delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/CheckedException.java delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReference.java delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReferenceImpl.java delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldService.java delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceImpl.java delete mode 100644 sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceReference.java create mode 100644 sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/ContractBuilder.java create mode 100644 sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLContractBuilder.java create mode 100644 sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ContractBuilder (limited to 'sca-java-2.x') diff --git a/sca-java-2.x/trunk/compliance-tests/assembly/src/test/resources/tuscany-oasis-sca-tests-errors.properties b/sca-java-2.x/trunk/compliance-tests/assembly/src/test/resources/tuscany-oasis-sca-tests-errors.properties index 9a7a2e1439..f2a8fe4342 100644 --- a/sca-java-2.x/trunk/compliance-tests/assembly/src/test/resources/tuscany-oasis-sca-tests-errors.properties +++ b/sca-java-2.x/trunk/compliance-tests/assembly/src/test/resources/tuscany-oasis-sca-tests-errors.properties @@ -80,8 +80,8 @@ ASM_9005=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http:/ ASM_10001=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_10001, Artifact: META-INF/definitions.xml, Definitions: jar:file:***ASM_10001***.zip!/META-INF/definitions.xml] - [ASM10001,POL30002] Duplicate intent {http://docs.oasis-open.org/ns/opencsa/scatests/200903}Fred found in domain ASM_10003=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_10003, Artifact: META-INF/definitions.xml, Definitions: jar:file:***ASM_10003***.zip!/META-INF/definitions.xml] - XMLSchema validation error occured in: Test_ASM_10003.composite ,line = ***, column = ***, Message = cvc-complex-type.2.4.a: Invalid content was found starting with element 'component'. One of '{"http://docs.oasis-open.org/ns/opencsa/sca/200912":documentation, "http://docs.oasis-open.org/ns/opencsa/sca/200912":intent, "http://docs.oasis-open.org/ns/opencsa/sca/200912":policySet, "http://docs.oasis-open.org/ns/opencsa/sca/200912":bindingType, "http://docs.oasis-open.org/ns/opencsa/sca/200912":implementationType, WC[##other:"http://docs.oasis-open.org/ns/opencsa/sca/200912"]}' is expected. ASM_12003=org.apache.tuscany.sca.contribution.processor.ContributionResolveException: Invalid interface when resolving -ASM_12007=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http://docs.oasis-open.org/ns/opencsa/sca/200912}, Component: TestComponent1] - [ASM50004,JCA30002,JCI80001] Component service interface incompatible with implementation service interface: Component = TestComponent1 Service = Service1 Operation operation1 not found on target -ASM_12008=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http://docs.oasis-open.org/ns/opencsa/sca/200912}, Component: TEST_ASM_12008TestComponent1] - [ASM50004,JCA30002,JCI80001] Component service interface incompatible with implementation service interface: Component = TEST_ASM_12008TestComponent1 Service = Service1 Operation operation1 not found on target +ASM_12007=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http://docs.oasis-open.org/ns/opencsa/sca/200912}, Component: TestComponent1, Composite: {http://docs.oasis-open.org/ns/opencsa/scatests/2009032}TestComposite5, Component: TestComposite5TestComponent1] - [ASM50004,JCA30002,JCI80001] Component service interface incompatible with implementation service interface: Component = TestComposite5TestComponent1 Service = Service1 Operations called operation2 are not compatible Operation argument types source = {http://www.w3.org/2001/XMLSchema}int target = {http://www.w3.org/2001/XMLSchema}string don't match for output types +ASM_12008=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http://docs.oasis-open.org/ns/opencsa/sca/200912}, Component: TEST_ASM_12008TestComponent1, Composite: {http://docs.oasis-open.org/ns/opencsa/scatests/2009032}TestComposite5, Component: TestComposite5TestComponent1] - [ASM50004,JCA30002,JCI80001] Component service interface incompatible with implementation service interface: Component = TestComposite5TestComponent1 Service = Service1 Operations called operation2 are not compatible Operation argument types source = {http://www.w3.org/2001/XMLSchema}int target = {http://www.w3.org/2001/XMLSchema}string don't match for output types ASM_12011=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http://docs.oasis-open.org/ns/opencsa/sca/200912}, Component: TestComponent1] - [ASM60030,JCI50004,JCI80001] Component implementation not resolved: Component = TestComponent1 Uri = TestComponent1 ASM_12012=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_12012, Artifact: META-INF/sca-contribution.xml] - XMLSchema validation error occured in: jar:file:***ASM_12012***.zip!/META-INF/sca-contribution.xml ,line = ***, column = ***, Message = cvc-complex-type.2.4.a: Invalid content was found starting with element 'component'. One of '{"http://docs.oasis-open.org/ns/opencsa/sca/200912":documentation, "http://docs.oasis-open.org/ns/opencsa/sca/200912":deployable, "http://docs.oasis-open.org/ns/opencsa/sca/200912":importBase, "http://docs.oasis-open.org/ns/opencsa/sca/200912":exportBase, WC[##other:"http://docs.oasis-open.org/ns/opencsa/sca/200912"]}' is expected. ASM_13001=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13001, Artifact: Test_ASM_13001.composite] - XMLSchema validation error occured in: Test_ASM_13001.composite ,line = ***, column = ***, Message = cvc-complex-type.2.4.a: Invalid content was found starting with element 'sevrice'. One of '{"http://docs.oasis-open.org/ns/opencsa/sca/200912":service, "http://docs.oasis-open.org/ns/opencsa/sca/200912":reference, "http://docs.oasis-open.org/ns/opencsa/sca/200912":property, "http://docs.oasis-open.org/ns/opencsa/sca/200912":requires, "http://docs.oasis-open.org/ns/opencsa/sca/200912":policySetAttachment, WC[##other:"http://docs.oasis-open.org/ns/opencsa/sca/200912"]}' is expected. @@ -91,4 +91,4 @@ ASM_13004=org.apache.tuscany.sca.monitor.ValidationException: [Composite: {http: ASM_13005=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13005, Artifact: Test_ASM_13005.composite] - XMLSchema validation error occured in: Test_ASM_13005.composite ,line = ***, column = ***, Message = cvc-elt.2: The value of {abstract} in the element declaration for 'implementation' must be false. ASM_13006=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13006, Artifact: Test_ASM_13006.composite] - XMLSchema validation error occured in: Test_ASM_13006.composite ,line = ***, column = ***, Message = cvc-complex-type.3.2.2: Attribute 'callback' is not allowed to appear in element 'interface.java'. ASM_13007=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13007, Artifact: Test_ASM_13007.composite] - XMLSchema validation error occured in: Test_ASM_13007.composite ,line = ***, column = ***, Message = cvc-complex-type.3.2.2: Attribute 'mulplicity' is not allowed to appear in element 'reference'. -ASM_13008=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13008, Artifact: Test_ASM_13008.composite] - XMLSchema validation error occured in: Test_ASM_13008.composite ,line = ***, column = ***, Message = cvc-complex-type.2.4.a: Invalid content was found starting with element 'operation'. One of '{"http://docs.oasis-open.org/ns/opencsa/sca/200912":documentation, "http://docs.oasis-open.org/ns/opencsa/sca/200912":wireFormat, "http://docs.oasis-open.org/ns/opencsa/sca/200912":operationSelector, "http://docs.oasis-open.org/ns/opencsa/sca/200912":requires, "http://docs.oasis-open.org/ns/opencsa/sca/200912":policySetAttachment}' is expected. \ No newline at end of file +ASM_13008=org.apache.tuscany.sca.monitor.ValidationException: [Contribution: ASM_13008, Artifact: Test_ASM_13008.composite] - XMLSchema validation error occured in: Test_ASM_13008.composite ,line = ***, column = ***, Message = cvc-complex-type.2.4.a: Invalid content was found starting with element 'operation'. One of '{"http://docs.oasis-open.org/ns/opencsa/sca/200912":documentation, "http://docs.oasis-open.org/ns/opencsa/sca/200912":wireFormat, "http://docs.oasis-open.org/ns/opencsa/sca/200912":operationSelector, "http://docs.oasis-open.org/ns/opencsa/sca/200912":requires, "http://docs.oasis-open.org/ns/opencsa/sca/200912":policySetAttachment}' is expected. diff --git a/sca-java-2.x/trunk/itest/bpel/helloworld/pom.xml b/sca-java-2.x/trunk/itest/bpel/helloworld/pom.xml index 18e5dc6d43..2e01bee7c2 100644 --- a/sca-java-2.x/trunk/itest/bpel/helloworld/pom.xml +++ b/sca-java-2.x/trunk/itest/bpel/helloworld/pom.xml @@ -56,6 +56,12 @@ 2.0-SNAPSHOT runtime + + + org.apache.tuscany.sca + tuscany-binding-ws-wsdlgen + 2.0-SNAPSHOT + xerces diff --git a/sca-java-2.x/trunk/itest/databindings/jaxb-top-down/src/main/resources/wsdl/wrapped/hello-service.wsdl b/sca-java-2.x/trunk/itest/databindings/jaxb-top-down/src/main/resources/wsdl/wrapped/hello-service.wsdl index 4041e848d1..a76e5c5802 100644 --- a/sca-java-2.x/trunk/itest/databindings/jaxb-top-down/src/main/resources/wsdl/wrapped/hello-service.wsdl +++ b/sca-java-2.x/trunk/itest/databindings/jaxb-top-down/src/main/resources/wsdl/wrapped/hello-service.wsdl @@ -28,7 +28,8 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> - + diff --git a/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponent.java b/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponent.java index 5fc9ed51b3..3c7a398abd 100644 --- a/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponent.java +++ b/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponent.java @@ -28,11 +28,11 @@ public interface LocalClientComponent { String foo1(ParameterObject po); - String foo1(String str) throws Exception; + String foo2(String str) throws Exception; - String foo2(String str, int i); + String foo3(String str, int i); - String foo2(int i, String str) throws Exception; + String foo4(int i, String str) throws Exception; void callback(String str); diff --git a/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponentImpl.java b/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponentImpl.java index 6cd937af12..fc88c4f119 100644 --- a/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponentImpl.java +++ b/sca-java-2.x/trunk/itest/interfaces/src/main/java/org/apache/tuscany/sca/itest/interfaces/LocalClientComponentImpl.java @@ -35,15 +35,15 @@ public class LocalClientComponentImpl implements LocalClientComponent, LocalCall return "AComponent"; } - public String foo1(String str) throws Exception { + public String foo2(String str) throws Exception { return str + "AComponent"; } - public String foo2(String str, int i) { + public String foo3(String str, int i) { return str + "AComponent" + i; } - public String foo2(int i, String str) throws Exception { + public String foo4(int i, String str) throws Exception { return str + "AComponent" + i; } diff --git a/sca-java-2.x/trunk/itest/interfaces/src/test/java/org/apache/tuscany/sca/itest/interfaces/InterfacesTestCase.java b/sca-java-2.x/trunk/itest/interfaces/src/test/java/org/apache/tuscany/sca/itest/interfaces/InterfacesTestCase.java index d7ceeda6b6..d04351f51e 100644 --- a/sca-java-2.x/trunk/itest/interfaces/src/test/java/org/apache/tuscany/sca/itest/interfaces/InterfacesTestCase.java +++ b/sca-java-2.x/trunk/itest/interfaces/src/test/java/org/apache/tuscany/sca/itest/interfaces/InterfacesTestCase.java @@ -60,10 +60,10 @@ public class InterfacesTestCase { assertEquals("AComponent", local.foo1(po)); assertEquals("AComponent", po.field1); - assertEquals("AAComponent", local.foo1("A")); + assertEquals("AAComponent", local.foo2("A")); - assertEquals("AAComponent1", local.foo2("A", 1)); - assertEquals("AAComponent1", local.foo2(1, "A")); + assertEquals("AAComponent1", local.foo3("A", 1)); + assertEquals("AAComponent1", local.foo4(1, "A")); } catch (Exception e) { fail(); } diff --git a/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.composite b/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.composite index aa81e59b52..7950309b07 100644 --- a/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.composite +++ b/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.composite @@ -42,7 +42,6 @@ - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.wsdl b/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.wsdl deleted file mode 100644 index 4625f46578..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmsobject/src/main/resources/jmsobject/helloworld.wsdl +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/CheckedException.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/CheckedException.java deleted file mode 100644 index 1acbfbd5ae..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/CheckedException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - -public class CheckedException extends Exception { - private static final long serialVersionUID = 1L; - - public CheckedException(String s) { - super(s); - } -} diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReference.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReference.java deleted file mode 100644 index 2d19d4bd82..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReference.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - -import org.oasisopen.sca.annotation.Remotable; - -/** - * This is the business interface of the HelloWorld greetings service. - */ -@Remotable -public interface HelloWorldReference { - - public String getGreetings(String message); - -} - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReferenceImpl.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReferenceImpl.java deleted file mode 100644 index 3ccd54e9bd..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldReferenceImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - -import org.oasisopen.sca.annotation.Reference; - - -public class HelloWorldReferenceImpl implements HelloWorldReference { - - @Reference - protected HelloWorldServiceReference helloWorldService1; - - public String getGreetings(String name){ - byte[] bytesValue = helloWorldService1.getByteArrayGreetings(name.getBytes()); - String stringValue = new String(bytesValue); - - try { - helloWorldService1.throwChecked(name.getBytes()); - } catch (Exception e) { - // Test to see what happens if we talk to a service - // that declares a checked exception through an - // interface that doesn't - stringValue += " " + e.getCause().getMessage(); - } - - try { - helloWorldService1.throwUnChecked(name.getBytes()); - } catch (Exception e) { - stringValue += " " + e.getMessage(); - } - return stringValue; - } -} - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldService.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldService.java deleted file mode 100644 index b9a1ffd5ef..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldService.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - -import org.oasisopen.sca.annotation.Remotable; - -/** - * This is the business interface of the HelloWorld greetings service. - */ -@Remotable -public interface HelloWorldService { - - public byte[] getByteArrayGreetings(byte[] msg); - - public void throwChecked(byte[] msg) throws CheckedException; - public void throwUnChecked(byte[] msg); - -} - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceImpl.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceImpl.java deleted file mode 100644 index b92959cfd3..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - - -public class HelloWorldServiceImpl implements HelloWorldService { - - public byte[] getByteArrayGreetings(byte[] msg){ - - String name = new String(msg); - name = "Hello " + name; - - return name.getBytes(); - } - - public void throwChecked(byte[] msg) throws CheckedException { - throw new CheckedException("foo"); - } - - public void throwUnChecked(byte[] msg) { - throw new RuntimeException("bla"); - } -} - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceReference.java b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceReference.java deleted file mode 100644 index ff5cf617f2..0000000000 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/java/org/apache/tuscany/sca/binding/jms/format/jmsbytes/helloworld/HelloWorldServiceReference.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.tuscany.sca.binding.jms.format.jmsbytes.helloworld; - -import org.oasisopen.sca.annotation.Remotable; - -/** - * This is the business interface of the HelloWorld greetings service. - */ -@Remotable -public interface HelloWorldServiceReference { - - public byte[] getByteArrayGreetings(byte[] msg); - - public void throwChecked(byte[] msg) ; - public void throwUnChecked(byte[] msg); - -} - diff --git a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/resources/jmstextxml/helloworld.wsdl b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/resources/jmstextxml/helloworld.wsdl index 53db66ea7e..75ff351153 100644 --- a/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/resources/jmstextxml/helloworld.wsdl +++ b/sca-java-2.x/trunk/itest/jms/format-jmstextxml/src/main/resources/jmstextxml/helloworld.wsdl @@ -65,7 +65,13 @@ - + + + + + + + diff --git a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/CustomerProfileData.java b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/CustomerProfileData.java index 2574788dfa..6f6a374450 100644 --- a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/CustomerProfileData.java +++ b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/CustomerProfileData.java @@ -33,6 +33,16 @@ public class CustomerProfileData { private String loginID; private String password; private int id; + + public CustomerProfileData() { + firstName = "John"; + lastName = "Doe"; + address = "345 Main Street"; + email = "john@doe.org"; + this.loginID = "DefaultloginID"; + password = "hello"; + id = 1234; + } public CustomerProfileData(String loginID) { firstName = "John"; diff --git a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/customerdata.xsd b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/customerdata.xsd index 421d5d6166..2479f3dbe5 100644 --- a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/customerdata.xsd +++ b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/customerdata.xsd @@ -21,7 +21,7 @@ targetNamespace="http://accounts" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - + diff --git a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/questionmark-include.wsdl b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/questionmark-include.wsdl index 4b6f982c26..7a7a4033ce 100644 --- a/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/questionmark-include.wsdl +++ b/sca-java-2.x/trunk/itest/ws/wsdl/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/questionmark-include.wsdl @@ -44,11 +44,7 @@ - + type="account:customerProfileData" /> diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BuilderExtensionPoint.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BuilderExtensionPoint.java index d432bf3f29..14ae2042d3 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BuilderExtensionPoint.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BuilderExtensionPoint.java @@ -33,6 +33,28 @@ import org.apache.tuscany.sca.assembly.Implementation; * @tuscany.spi.extension.asclient */ public interface BuilderExtensionPoint { + + /** + * Adds a contract builder. + * + * @param compositeBuilder + */ + void addContractBuilder(ContractBuilder contractBuilder); + + /** + * Removes a contract builder. + * + * @param compositeBuilder + */ + void removeContractBuilder(ContractBuilder contractBuilder); + + /** + * Returns the contract builder + * + * @param id + * @return + */ + ContractBuilder getContractBuilder(); /** * Adds a composite builder. diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/ContractBuilder.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/ContractBuilder.java new file mode 100644 index 0000000000..99a58dc1c8 --- /dev/null +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/ContractBuilder.java @@ -0,0 +1,37 @@ +/* + * 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.tuscany.sca.assembly.builder; + +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; + +/** + * A builder that builds WSDL versions of component contracts so that the + * component contracts can be compared with binding contracts in a generic way. + * The generic interface format defined by the Assembly spec is WSDL 1.1 + */ +public interface ContractBuilder { + + /** + * Build the WSDL version of the Interface Contract + */ + boolean build(InterfaceContract interfaceContract, BuilderContext context); +} diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/DefaultBuilderExtensionPoint.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/DefaultBuilderExtensionPoint.java index 64f929c659..8b037a7534 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/DefaultBuilderExtensionPoint.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/DefaultBuilderExtensionPoint.java @@ -41,6 +41,7 @@ import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDeclarationParser; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; /** @@ -56,6 +57,7 @@ public class DefaultBuilderExtensionPoint implements BuilderExtensionPoint, Life private final Map implementationBuilders = new HashMap(); private final Map policyBuilders = new HashMap(); + private ContractBuilder contractBuilder = null; private boolean loaded; @@ -85,6 +87,19 @@ public class DefaultBuilderExtensionPoint implements BuilderExtensionPoint, Life loadBuilders(); return builders.get(id); } + + public void addContractBuilder(ContractBuilder contractBuilder){ + this.contractBuilder = contractBuilder; + } + + public void removeContractBuilder(ContractBuilder contractBuilder){ + this.contractBuilder = null; + } + + public ContractBuilder getContractBuilder(){ + loadBuilders(); + return contractBuilder; + } /** * Load builders declared under META-INF/services. @@ -147,6 +162,16 @@ public class DefaultBuilderExtensionPoint implements BuilderExtensionPoint, Life PolicyBuilder builder = new LazyPolicyBuilder(builderDeclaration); policyBuilders.put(builder.getPolicyType(), builder); } + + try { + builderDeclarations = serviceDiscovery.getServiceDeclarations(ContractBuilder.class); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + for (ServiceDeclaration builderDeclaration : builderDeclarations) { + contractBuilder = new LazyContractBuilder(builderDeclaration); + } loaded = true; @@ -405,4 +430,50 @@ public class DefaultBuilderExtensionPoint implements BuilderExtensionPoint, Life return getBuilder().build(endpointReference, endpoint, context); } } + + private class LazyContractBuilder implements ContractBuilder { + private ServiceDeclaration sd; + private ContractBuilder builder; + + /** + * @param sd + */ + public LazyContractBuilder(ServiceDeclaration sd) { + super(); + this.sd = sd; + } + +/* + public boolean build(EndpointReference endpointReference, BuilderContext context){ + return getBuilder().build(endpointReference, context); + } + + public boolean build(Endpoint endpoint, BuilderContext context){ + return getBuilder().build(endpoint, context); + } +*/ + + public boolean build(InterfaceContract interfaceContract, BuilderContext context){ + return getBuilder().build(interfaceContract, context); + } + + private synchronized ContractBuilder getBuilder() { + if (builder == null) { + try { + Class builderClass = sd.loadClass(); + try { + Constructor constructor = builderClass.getConstructor(ExtensionPointRegistry.class); + builder = (ContractBuilder)constructor.newInstance(registry); + } catch (NoSuchMethodException e) { + Constructor constructor = builderClass.getConstructor(); + builder = (ContractBuilder)constructor.newInstance(); + + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return builder; + } + } } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointImpl.java index 34ece5a24b..65af22c3e7 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointImpl.java @@ -26,6 +26,8 @@ import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentService; import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.policy.ExtensionType; @@ -42,6 +44,8 @@ public class EndpointImpl implements Endpoint { private static final long serialVersionUID = 7344399683703812593L; protected transient ExtensionPointRegistry registry; + protected transient BuilderExtensionPoint builders; + protected transient ContractBuilder contractBuilder; protected boolean unresolved; protected String uri; protected Component component; diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReferenceImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReferenceImpl.java index d13740b287..ac35b45678 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReferenceImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReferenceImpl.java @@ -26,6 +26,8 @@ import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentReference; import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.policy.ExtensionType; @@ -41,7 +43,9 @@ import org.apache.tuscany.sca.policy.PolicySubject; public class EndpointReferenceImpl implements EndpointReference { private static final long serialVersionUID = 8838066441709300972L; - protected ExtensionPointRegistry registry; + protected transient ExtensionPointRegistry registry; + protected transient BuilderExtensionPoint builders; + protected transient ContractBuilder contractBuilder; protected boolean unresolved = true; protected String uri; protected Component component; diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/InterfaceContract.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/InterfaceContract.java index 054b18c349..3eda9f37e5 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/InterfaceContract.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/InterfaceContract.java @@ -78,5 +78,23 @@ public interface InterfaceContract extends Cloneable { * Implementations must support cloning. */ Object clone() throws CloneNotSupportedException; + + /** + * For matching purposes the Java interface contract is + * turned into a WSDL contract in the cases where it needs to be matched + * against another WSDL contract + * + * @return WSDL interface contract + */ + InterfaceContract getNormalizedWSDLContract(); + + /** + * For matching purposes the Java interface contract is + * turned into a WSDL contract in the cases where it needs to be matched + * against another WSDL contract + * + * @param wsdlInterfaceContract + */ + void setNormailizedWSDLContract(InterfaceContract wsdlInterfaceContract); } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java index a62813edd4..4fad64ac89 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java @@ -125,5 +125,18 @@ public abstract class InterfaceContractImpl implements InterfaceContract { } return true; } + + // By default there is no normailized contract + // as only Java needs it + public InterfaceContract getNormalizedWSDLContract() { + return null; + } + + // By default there is no normailized contract + // as only Java needs it + public void setNormailizedWSDLContract( + InterfaceContract wsdlInterfaceContract) { + // do nothing + } } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java index 468083c839..c507dcaa9e 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java @@ -21,6 +21,11 @@ package org.apache.tuscany.sca.interfacedef.impl; import java.util.List; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; @@ -28,27 +33,95 @@ import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.apache.tuscany.sca.policy.ExtensionType; /** * @version $Rev$ $Date$ */ public class InterfaceContractMapperImpl implements InterfaceContractMapper { - + + protected ExtensionPointRegistry registry; + protected BuilderExtensionPoint builders; + protected ContractBuilder contractBuilder; + + public InterfaceContractMapperImpl(ExtensionPointRegistry registry){ + this.registry = registry; + this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class); + } + public boolean isCompatible(DataType source, DataType target, boolean passByValue) { + return isCompatible(source, target, passByValue, null); + } + + public boolean isCompatible(DataType source, DataType target, boolean passByValue, StringBuffer audit) { if (source == target) { return true; } if (!passByValue) { if (source == null || target == null) { + if (audit != null){ + audit.append("One of either the source or target data types is null for"); + } return false; } // For local case return target.getPhysical().isAssignableFrom(source.getPhysical()); } else { - // FIXME: [rfeng] How to test if two remotable data type is compatible? - // We will need to understand the different typing system used by the databindings - // We should probably delegate to some extensions here - return true; + // For remote interfaces where the target is represented with WSDL + // the source will have been converted to WSDL so we rely on JAXB mappings + // being the same in both cases and just compare the type names directly. + // TODO - is this right? + XMLType sourceLogicalType = null; + + // There is some nesting of data types (when GeneratedDataType is used) so + // dig a bit deeper to find the real data type + if (source.getLogical() instanceof DataType){ + sourceLogicalType = (XMLType)((DataType)source.getLogical()).getLogical(); + } else { + sourceLogicalType = (XMLType)source.getLogical(); + } + + XMLType targetLogicalType = null; + + if (target.getLogical() instanceof DataType){ + targetLogicalType = (XMLType)((DataType)target.getLogical()).getLogical(); + } else { + targetLogicalType = (XMLType)target.getLogical(); + } + + // The logical type seems to be null in some cases, e.g. when the + // argument or return type is something like a Map. + // TODO - check when some type give rise to a null logical type + if (sourceLogicalType.getTypeName() == null || + targetLogicalType.getTypeName() == null) { + return true; + } + + boolean match = sourceLogicalType.getTypeName().equals(targetLogicalType.getTypeName()); + + if (!match){ + + QName anyType = new QName("http://www.w3.org/2001/XMLSchema", "anyType"); + if (sourceLogicalType.getTypeName().equals(anyType) || + targetLogicalType.getTypeName().equals(anyType)){ + // special case where a Java interface uses a generic type, e.g. + // public OMElement getGreetings(OMElement om) + // while the provided WSDL uses a specific type. So we assume + // that xsd:anyType matched anything + match = true; + } else { + if (audit != null){ + audit.append("Operation argument types source = " + + sourceLogicalType.getTypeName() + + " target = " + + targetLogicalType.getTypeName() + + " don't match for"); + } + } + } + + return match; } } @@ -62,6 +135,9 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { * @return */ public boolean isMutuallyCompatible(InterfaceContract source, InterfaceContract target) { + ExtensionType ext = source.getInterface().getExtensionType(); + InterfaceContract sourceContract = null; + // Are the forward interfaces equal? if (isMutuallyCompatible(source.getInterface(), target.getInterface())) { // Is there a Callback interface? @@ -120,6 +196,10 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { } public boolean isCompatible(Operation source, Operation target, Compatibility compatibilityType, boolean byValue) { + return isCompatible(source, target, compatibilityType, true, null); + } + + public boolean isCompatible(Operation source, Operation target, Compatibility compatibilityType, boolean byValue, StringBuffer audit) { if (source == target) { return true; } @@ -130,10 +210,22 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { // Check name if (!source.getName().equals(target.getName())) { + if (audit != null){ + audit.append("operation names are not the same source = " + + source.getName() + + " target = " + + target.getName()); + } return false; } if (source.getInterface().isRemotable() != target.getInterface().isRemotable()) { + if (audit != null){ + audit.append("Interfaces have different remote settings source = " + + source.getName() + + " target = " + + target.getName()); + } return false; } @@ -164,21 +256,32 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { checkTargetWrapper = false; } +/* TODO - Why are we assuming compatibility if one side is wrapped and the other is not? if (checkSourceWrapper != checkTargetWrapper) { return true; } +*/ - if (!isCompatible(targetOutputType, sourceOutputType, passByValue)) { + if (!isCompatible(targetOutputType, sourceOutputType, passByValue, audit)) { + if (audit != null){ + audit.append(" output types"); + } return false; } if (sourceInputType.size() != targetInputType.size()) { + if (audit != null){ + audit.append("different number of input types"); + } return false; } int size = sourceInputType.size(); for (int i = 0; i < size; i++) { - if (!isCompatible(sourceInputType.get(i), targetInputType.get(i), passByValue)) { + if (!isCompatible(sourceInputType.get(i), targetInputType.get(i), passByValue, audit)) { + if (audit != null){ + audit.append(" input types"); + } return false; } } @@ -190,13 +293,16 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { boolean found = true; for (DataType sourceFaultType : source.getFaultTypes()) { found = false; - if (isCompatible(targetFaultType, sourceFaultType, passByValue)) { + if (isCompatible(targetFaultType, sourceFaultType, passByValue, audit)) { // Target fault type can be covered by the source fault type found = true; break; } } if (!found) { + if (audit != null){ + audit.append("Fault types incompatible"); + } return false; } } @@ -226,6 +332,7 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { Compatibility compatibility, boolean ignoreCallback, boolean silent) throws IncompatibleInterfaceContractException { + if (source == target) { // Shortcut for performance return true; @@ -268,18 +375,20 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { return false; } } - if (!source.getInterface().isRemotable()) { - // FIXME: for remotable operation, only compare name for now + + if (!silent) { + StringBuffer audit = new StringBuffer(); + if (!isCompatible(operation, targetOperation, Compatibility.SUBSET, true, audit)){ + throw new IncompatibleInterfaceContractException("Operations called " + + operation.getName() + + " are not compatible " + + audit, + source, + target); + } + } else { if (!isCompatible(operation, targetOperation, Compatibility.SUBSET)) { - if (!silent) { - throw new IncompatibleInterfaceContractException("Target operations called " + - operation.getName() + - " are not compatible", - source, - target); - } else { - return false; - } + return false; } } } @@ -294,7 +403,7 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { } if (source.getCallbackInterface() == null || target.getCallbackInterface() == null) { if (!silent) { - throw new IncompatibleInterfaceContractException("Callback interface doesn't match", source, target); + throw new IncompatibleInterfaceContractException("Callback interface doesn't match as one of the callback interfaces is null", source, target); } else { return false; } @@ -386,7 +495,30 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { } return null; } - } + + /** + * In various places in the process of an SCA application we match one interface against + * another. Sometimes the two interfaces can be presented using different IDLs, for example + * Java and WSDL. In this case interfaces are converted so that they are both WSDL1.1 interfaces + * and they are then compared. The generated WSDL is cached on the interface object for + * any subsequent matching + * + * @param interfaceA + * @param interfaceB + */ +/* + public void normalizeContractsForComparison(InterfaceContract interfaceA, InterfaceContract interfaceB){ + // normalize interfaces + if (interfaceA.getInterface().getClass() != interfaceB.getInterface().getClass()) { + this.contractBuilder = builders.getContractBuilder(); + if (interfaceA.getInterface() instanceof Interface){ + contractBuilder.build(interfaceA, null); + } else { + contractBuilder.build(interfaceB, null); + } + } + } +*/ } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties b/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties index 4a62d074c7..fe92f5eab3 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties +++ b/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties @@ -79,3 +79,5 @@ CompositeReferencePromotesNonOverridableReference = [ASM50042] Composite referen PropertyValueDoesNotMatchSimpleType = [ASM50027] The property {0} on component {1} has a value which does not match the simple type {2} with which it is associated PropertyValueDoesNotMatchComplexType = [ASM50038] The property {0} on component {1} has a value which does not match the complex type {2} with which it is associated. Validation reported {3} PropertyValueDoesNotMatchElement = [ASM50029] The property {0} on component {1} has a value which does not match the element {2} with which it is associated. Validation reported {3} +EPRIncompatibleInterface = [BWS20007] The reference interface is incompatible with the interface of the reference binding {0} +EPIncompatibleInterface = [BWS20007] The service interface is incompatible with the interface of the service binding {0} diff --git a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterfaceContract.java b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterfaceContract.java index d691705955..6ac4c1ff2b 100644 --- a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterfaceContract.java +++ b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterfaceContract.java @@ -54,5 +54,18 @@ public class TestInterfaceContract implements InterfaceContract { public Object clone() { return null; } + + // By default there is no normailized contract + // as only Java needs it + public InterfaceContract getNormalizedWSDLContract() { + return null; + } + + // By default there is no normailized contract + // as only Java needs it + public void setNormailizedWSDLContract( + InterfaceContract wsdlInterfaceContract) { + // do nothing + } } diff --git a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeWire.java b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeWire.java index e68f4dee72..616282abfb 100644 --- a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeWire.java +++ b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeWire.java @@ -288,5 +288,18 @@ public class TestRuntimeWire implements RuntimeEndpoint { // TODO Auto-generated method stub } + + public void setGeneratedWSDLContract(InterfaceContract wsdlContract){ + + } + + public InterfaceContract getGeneratedWSDLContract(){ + return null; + } + + public void validateServiceInterfaceCompatibility() { + // TODO Auto-generated method stub + + } } diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java index ef70b5f5c0..516a62a556 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java @@ -266,27 +266,64 @@ public class BindingWSDLGenerator { /** * Create a WSDLInterfaceContract from a JavaInterfaceContract */ - protected static WSDLInterfaceContract createWSDLInterfaceContract(JavaInterfaceContract contract, - boolean requiresSOAP12, - ModelResolver resolver, - DataBindingExtensionPoint dataBindings, - WSDLFactory wsdlFactory, - XSDFactory xsdFactory, - DocumentBuilderFactory documentBuilderFactory, - Monitor monitor) { + public static WSDLInterfaceContract createWSDLInterfaceContract(JavaInterfaceContract contract, + boolean requiresSOAP12, + ModelResolver resolver, + DataBindingExtensionPoint dataBindings, + WSDLFactory wsdlFactory, + XSDFactory xsdFactory, + DocumentBuilderFactory documentBuilderFactory, + Monitor monitor) { WSDLInterfaceContract wsdlContract = wsdlFactory.createWSDLInterfaceContract(); - WSDLInterface wsdlInterface = wsdlFactory.createWSDLInterface(); - wsdlContract.setInterface(wsdlInterface); + + if (contract.getInterface() != null){ + WSDLInterface wsdlInterface = createWSDLInterface((JavaInterface)contract.getInterface(), + requiresSOAP12, + resolver, + dataBindings, + wsdlFactory, + xsdFactory, + documentBuilderFactory, + monitor); + wsdlContract.setInterface(wsdlInterface); + } + + if (contract.getCallbackInterface() != null){ + WSDLInterface wsdlInterface = createWSDLInterface((JavaInterface)contract.getCallbackInterface(), + requiresSOAP12, + resolver, + dataBindings, + wsdlFactory, + xsdFactory, + documentBuilderFactory, + monitor); + wsdlContract.setCallbackInterface(wsdlInterface); + } + return wsdlContract; + } + + /** + * Create a WSDLInterface from a JavaInterface + */ + public static WSDLInterface createWSDLInterface(JavaInterface javaInterface, + boolean requiresSOAP12, + ModelResolver resolver, + DataBindingExtensionPoint dataBindings, + WSDLFactory wsdlFactory, + XSDFactory xsdFactory, + DocumentBuilderFactory documentBuilderFactory, + Monitor monitor) { + + WSDLInterface wsdlInterface = wsdlFactory.createWSDLInterface(); WSDLDefinition wsdlDefinition = wsdlFactory.createWSDLDefinition(); - JavaInterface iface = (JavaInterface)contract.getInterface(); Definition def = null; try { Interface2WSDLGenerator wsdlGenerator = new Interface2WSDLGenerator(requiresSOAP12, resolver, dataBindings, xsdFactory, documentBuilderFactory, monitor); - def = wsdlGenerator.generate(iface, wsdlDefinition); + def = wsdlGenerator.generate(javaInterface, wsdlDefinition); } catch (WSDLException e) { throw new WSDLGenerationException(e); } @@ -294,7 +331,7 @@ public class BindingWSDLGenerator { // for debugging if (printWSDL) { try { - System.out.println("Generated WSDL for Java interface " + iface.getName() + " class " + iface.getJavaClass().getName()); + System.out.println("Generated WSDL for Java interface " + javaInterface.getName() + " class " + javaInterface.getJavaClass().getName()); WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter(); writer.writeWSDL(def, System.out); } catch (WSDLException e) { @@ -316,7 +353,7 @@ public class BindingWSDLGenerator { throw new WSDLGenerationException(e); } - return wsdlContract; - } + return wsdlInterface; + } } diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java index 7509f2ab57..a072b31322 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java @@ -797,10 +797,20 @@ public class Interface2WSDLGenerator { } helpers.put(db, helper); } - TypeInfo typeInfo = helper.getTypeInfo(javaType.isArray() ? javaType.getComponentType() : javaType, - dataType.getLogical()); - ElementInfo element = new ElementInfo(name, typeInfo); - element.setMany(byte[].class != javaType && javaType.isArray()); + // TUSCANY-3616 - don't revert a byte[] to a byte type but retain the mapping to base64Binary + // which is carried in the dataType and the original javaType + TypeInfo typeInfo = null; + ElementInfo element = null; + if (byte[].class == javaType){ + typeInfo = helper.getTypeInfo(javaType, dataType.getLogical()); + element = new ElementInfo(name, typeInfo); + element.setMany(false); + } else { + typeInfo = helper.getTypeInfo(javaType.isArray() ? javaType.getComponentType() : javaType, dataType.getLogical()); + element = new ElementInfo(name, typeInfo); + element.setMany(javaType.isArray()); + } + element.setNillable(!javaType.isPrimitive()); return element; } diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLContractBuilder.java b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLContractBuilder.java new file mode 100644 index 0000000000..25a566bd24 --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLContractBuilder.java @@ -0,0 +1,90 @@ +/* + * 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.tuscany.sca.binding.ws.wsdlgen; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.builder.BindingBuilder; +import org.apache.tuscany.sca.assembly.builder.BuilderContext; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ResolverExtension; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; +import org.apache.tuscany.sca.xsd.XSDFactory; + +/** + * Created WSDL contracts for Endpoints or EndpointReferences for use during + * interface contract mapping. The assmebly spec defines WSDL as the lowest + * common denominator for contract mapping. + */ +public class WSDLContractBuilder implements ContractBuilder { + + private ExtensionPointRegistry extensionPoints; + private FactoryExtensionPoint modelFactories; + private DataBindingExtensionPoint dataBindings; + private WSDLFactory wsdlFactory; + private XSDFactory xsdFactory; + private DocumentBuilderFactory documentBuilderFactory; + + public WSDLContractBuilder(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + + modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); + wsdlFactory = modelFactories.getFactory(WSDLFactory.class); + xsdFactory = modelFactories.getFactory(XSDFactory.class); + documentBuilderFactory = modelFactories.getFactory(DocumentBuilderFactory.class); + + } + + public boolean build(InterfaceContract interfaceContract, BuilderContext context){ +// Uncomment the printWSDL = lines to see the WSDL that is generated +// for interface matching purposes +// BindingWSDLGenerator.printWSDL = true; + JavaInterfaceContract javaContract = (JavaInterfaceContract)interfaceContract; + WSDLInterfaceContract wsdlContract = + BindingWSDLGenerator.createWSDLInterfaceContract(javaContract, + false, + null, + dataBindings, + wsdlFactory, + xsdFactory, + documentBuilderFactory, + null); + javaContract.setNormailizedWSDLContract(wsdlContract); +// BindingWSDLGenerator.printWSDL = false; + return true; + } + +} diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ContractBuilder b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ContractBuilder new file mode 100644 index 0000000000..01333bf670 --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ContractBuilder @@ -0,0 +1,18 @@ +# 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. +org.apache.tuscany.sca.binding.ws.wsdlgen.WSDLContractBuilder + diff --git a/sca-java-2.x/trunk/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java b/sca-java-2.x/trunk/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java index 34a269b2f2..8e3c9262a2 100644 --- a/sca-java-2.x/trunk/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java +++ b/sca-java-2.x/trunk/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java @@ -73,10 +73,10 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySubject, Extensi private String portName; private QName serviceName; private String endpointName; - private WSDLDefinition wsdlDefinition; - private String wsdlNamespace; private InterfaceContract bindingInterfaceContract; private Element endPointReference; + private String wsdlNamespace; + private WSDLDefinition userSpecifiedWSDLDefinition; private Definition generatedWSDLDocument; private boolean isDocumentStyle; private boolean isLiteralEncoding; @@ -140,8 +140,8 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySubject, Extensi public Binding getBinding() { if (binding == null) { - if (getUserSpecifiedWSDLDefinition() != null && wsdlDefinition.getBinding() != null) { - binding = wsdlDefinition.getBinding(); + if (getUserSpecifiedWSDLDefinition() != null && userSpecifiedWSDLDefinition.getBinding() != null) { + binding = userSpecifiedWSDLDefinition.getBinding(); determineWSDLCharacteristics(); } } @@ -247,17 +247,17 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySubject, Extensi } public WSDLDefinition getUserSpecifiedWSDLDefinition() { - if (wsdlDefinition == null) { + if (userSpecifiedWSDLDefinition == null) { Interface iface = bindingInterfaceContract.getInterface(); if (iface instanceof WSDLInterface) { - wsdlDefinition = ((WSDLInterface) iface).getWsdlDefinition(); + userSpecifiedWSDLDefinition = ((WSDLInterface) iface).getWsdlDefinition(); } } - return wsdlDefinition; + return userSpecifiedWSDLDefinition; } public void setUserSpecifiedWSDLDefinition(WSDLDefinition wsdlDefinition) { - this.wsdlDefinition = wsdlDefinition; + this.userSpecifiedWSDLDefinition = wsdlDefinition; } public String getNamespace() { @@ -335,7 +335,7 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySubject, Extensi } /** - * Some items get calculated and cached as they are used are runtime + * Some items get calculated and cached as they are used at runtime * to decide what message processing is required */ protected void determineWSDLCharacteristics() { @@ -347,8 +347,8 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySubject, Extensi protected void setIsDocumentStyle() { if (binding == null){ - if (wsdlDefinition != null && wsdlDefinition.getDefinition() != null){ - Message firstMessage = (Message)wsdlDefinition.getDefinition().getMessages().values().iterator().next(); + if (userSpecifiedWSDLDefinition != null && userSpecifiedWSDLDefinition.getDefinition() != null){ + Message firstMessage = (Message)userSpecifiedWSDLDefinition.getDefinition().getMessages().values().iterator().next(); Part firstPart = (Part)firstMessage.getParts().values().iterator().next(); if (firstPart.getTypeName() != null){ isDocumentStyle = false; diff --git a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java index 32ebc71348..694ece2d6c 100644 --- a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java +++ b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java @@ -61,6 +61,7 @@ import org.apache.tuscany.sca.assembly.SCABindingFactory; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.builder.BuilderContext; import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; import org.apache.tuscany.sca.assembly.builder.ImplementationBuilder; import org.apache.tuscany.sca.assembly.builder.Messages; import org.apache.tuscany.sca.assembly.xsd.Constants; @@ -75,9 +76,12 @@ import org.apache.tuscany.sca.definitions.Definitions; import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; +import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; import org.apache.tuscany.sca.interfacedef.util.XMLType; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.policy.ExtensionType; @@ -106,6 +110,7 @@ public class ComponentBuilderImpl { private InterfaceContractMapper interfaceContractMapper; private BuilderExtensionPoint builders; private Mediator mediator; + private ContractBuilder contractBuilder; public ComponentBuilderImpl(ExtensionPointRegistry registry) { UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); @@ -120,6 +125,7 @@ public class ComponentBuilderImpl { policyBuilder = new ComponentPolicyBuilderImpl(registry); builders = registry.getExtensionPoint(BuilderExtensionPoint.class); mediator = new MediatorImpl(registry); + contractBuilder = builders.getContractBuilder(); } public void setComponentTypeBuilder(CompositeComponentTypeBuilderImpl componentTypeBuilder) { @@ -1297,7 +1303,8 @@ public class ComponentBuilderImpl { boolean isCompatible = true; String incompatibilityReason = ""; try{ - isCompatible = interfaceContractMapper.checkCompatibility(topInterfaceContract, bottomInterfaceContract, Compatibility.SUBSET, false, false); + isCompatible = checkSubsetCompatibility(topInterfaceContract, + bottomInterfaceContract); } catch (IncompatibleInterfaceContractException ex){ isCompatible = false; incompatibilityReason = ex.getMessage(); @@ -1311,6 +1318,24 @@ public class ComponentBuilderImpl { topContract.getName(), incompatibilityReason); } + + // TODO - there is an issue with the following code if the + // contracts of of different types. Need to use the + // normalized form + + // fix up the forward interface based on the promoted component + // Someone might have manually specified a callback interface but + // left out the forward interface + if (topInterfaceContract.getInterface() == null){ + topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); + } + + // fix up the callback interface based on the promoted component + // Someone might have manually specified a forward interface but + // left out the callback interface + if (topInterfaceContract.getCallbackInterface() == null){ + topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); + } } } @@ -1337,7 +1362,8 @@ public class ComponentBuilderImpl { boolean isCompatible = true; String incompatibilityReason = ""; try{ - isCompatible = interfaceContractMapper.checkCompatibility(bottomInterfaceContract, topInterfaceContract, Compatibility.SUBSET, false, false); + isCompatible = checkSubsetCompatibility(bottomInterfaceContract, + topInterfaceContract); } catch (IncompatibleInterfaceContractException ex){ isCompatible = false; incompatibilityReason = ex.getMessage(); @@ -1351,6 +1377,24 @@ public class ComponentBuilderImpl { topContract.getName(), incompatibilityReason); } + + // TODO - there is an issue with the following code if the + // contracts of of different types. Need to use the + // normalized form + + // fix up the forward interface based on the promoted component + // Someone might have manually specified a callback interface but + // left out the forward interface + if (topInterfaceContract.getInterface() == null){ + topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); + } + + // fix up the callback interface based on the promoted component + // Someone might have manually specified a forward interface but + // left out the callback interface + if (topInterfaceContract.getCallbackInterface() == null){ + topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); + } } } @@ -1418,6 +1462,43 @@ public class ComponentBuilderImpl { } else if (componentReference.getCallback().getBindings().isEmpty() && componentTypeReference.getCallback() != null) { componentReference.getCallback().getBindings().addAll(componentTypeReference.getCallback().getBindings()); } - } + } + + /** + * A local wrapper for the interace contract mapper as we need to normalize the + * interface contracts if appropriate and the mapper doesn't have the right + * dependencies to be able to do it. + * + * Sometimes the two interfaces can be presented using different IDLs, for example + * Java and WSDL. In this case interfaces are converted so that they are both WSDL1.1 interfaces + * and they are then compared. The generated WSDL is cached on the interface object for + * any subsequent matching + * + * @param contractA + * @param contractB + * @return true if the interface contracts match + */ + private boolean checkSubsetCompatibility(InterfaceContract contractA, InterfaceContract contractB) + throws IncompatibleInterfaceContractException { + + if (contractA.getClass() != contractB.getClass()) { + + if (contractA instanceof JavaInterfaceContract){ + contractBuilder.build(contractA, null); + contractA = ((JavaInterfaceContract)contractA).getNormalizedWSDLContract(); + } + + if (contractB instanceof JavaInterfaceContract){ + contractBuilder.build(contractB, null); + contractB = ((JavaInterfaceContract)contractB).getNormalizedWSDLContract(); + } + } + + return interfaceContractMapper.checkCompatibility(contractA, + contractB, + Compatibility.SUBSET, + false, + false); + } } diff --git a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeComponentTypeBuilderImpl.java b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeComponentTypeBuilderImpl.java index 2ea35ffb9b..1deec1b5e2 100644 --- a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeComponentTypeBuilderImpl.java +++ b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeComponentTypeBuilderImpl.java @@ -42,6 +42,7 @@ import org.apache.tuscany.sca.assembly.SCABindingFactory; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.builder.BuilderContext; import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; import org.apache.tuscany.sca.assembly.builder.Messages; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; @@ -51,6 +52,7 @@ import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.policy.ExtensionType; import org.apache.tuscany.sca.policy.PolicySubject; @@ -73,6 +75,7 @@ public class CompositeComponentTypeBuilderImpl { private SCABindingFactory scaBindingFactory; private InterfaceContractMapper interfaceContractMapper; private BuilderExtensionPoint builders; + private ContractBuilder contractBuilder; public CompositeComponentTypeBuilderImpl(ExtensionPointRegistry registry) { UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); @@ -83,6 +86,7 @@ public class CompositeComponentTypeBuilderImpl { interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class); builders = registry.getExtensionPoint(BuilderExtensionPoint.class); + contractBuilder = builders.getContractBuilder(); } public void setComponentBuilder(ComponentBuilderImpl componentBuilder) { @@ -434,7 +438,7 @@ public class CompositeComponentTypeBuilderImpl { boolean isCompatible = true; String incompatibilityReason = ""; try{ - isCompatible = interfaceContractMapper.checkCompatibility(topInterfaceContract, bottomInterfaceContract, Compatibility.SUBSET, false, false); + isCompatible = checkSubsetCompatibility(topInterfaceContract, bottomInterfaceContract); } catch (IncompatibleInterfaceContractException ex){ isCompatible = false; incompatibilityReason = ex.getMessage(); @@ -447,6 +451,24 @@ public class CompositeComponentTypeBuilderImpl { topContract.getName(), incompatibilityReason); } + + // TODO - there is an issue with the following code if the + // contracts of of different types. Need to use the + // normalized form + + // fix up the forward interface based on the promoted component + // Someone might have manually specified a callback interface but + // left out the forward interface + if (topInterfaceContract.getInterface() == null){ + topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); + } + + // fix up the callback interface based on the promoted component + // Someone might have manually specified a forward interface but + // left out the callback interface + if (topInterfaceContract.getCallbackInterface() == null){ + topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); + } } } @@ -472,7 +494,7 @@ public class CompositeComponentTypeBuilderImpl { boolean isCompatible = true; String incompatibilityReason = ""; try{ - isCompatible = interfaceContractMapper.checkCompatibility(bottomInterfaceContract, topInterfaceContract, Compatibility.SUBSET, false, false); + isCompatible = checkSubsetCompatibility(bottomInterfaceContract, topInterfaceContract); } catch (IncompatibleInterfaceContractException ex){ isCompatible = false; incompatibilityReason = ex.getMessage(); @@ -485,6 +507,24 @@ public class CompositeComponentTypeBuilderImpl { topContract.getName(), incompatibilityReason); } + + // TODO - there is an issue with the following code if the + // contracts of of different types. Need to use the + // normalized form + + // fix up the forward interface based on the promoted component + // Someone might have manually specified a callback interface but + // left out the forward interface + if (topInterfaceContract.getInterface() == null){ + topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); + } + + // fix up the callback interface based on the promoted component + // Someone might have manually specified a forward interface but + // left out the callback interface + if (topInterfaceContract.getCallbackInterface() == null){ + topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); + } } } @@ -616,4 +656,41 @@ public class CompositeComponentTypeBuilderImpl { } } + /** + * A local wrapper for the interace contract mapper as we need to normalize the + * interface contracts if appropriate and the mapper doesn't have the right + * dependencies to be able to do it. + * + * Sometimes the two interfaces can be presented using different IDLs, for example + * Java and WSDL. In this case interfaces are converted so that they are both WSDL1.1 interfaces + * and they are then compared. The generated WSDL is cached on the interface object for + * any subsequent matching + * + * @param contractA + * @param contractB + * @return true if the interface contracts match + */ + private boolean checkSubsetCompatibility(InterfaceContract contractA, InterfaceContract contractB) + throws IncompatibleInterfaceContractException { + + if (contractA.getClass() != contractB.getClass()) { + + if (contractA instanceof JavaInterfaceContract){ + contractBuilder.build(contractA, null); + contractA = ((JavaInterfaceContract)contractA).getNormalizedWSDLContract(); + } + + if (contractB instanceof JavaInterfaceContract){ + contractBuilder.build(contractB, null); + contractB = ((JavaInterfaceContract)contractB).getNormalizedWSDLContract(); + } + } + + return interfaceContractMapper.checkCompatibility(contractA, + contractB, + Compatibility.SUBSET, + false, + false); + } + } //end class diff --git a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpoint.java b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpoint.java index 6712b71efd..928880214d 100644 --- a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpoint.java +++ b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpoint.java @@ -58,10 +58,34 @@ public interface RuntimeEndpoint extends Endpoint, Invocable, Serializable { */ InterfaceContract getComponentTypeServiceInterfaceContract(); + + /** + * Check that endpoint has compatible interface at the component and binding ends. + * The user can specify the interfaces at both ends so there is a danger that they won't be compatible. + */ + void validateServiceInterfaceCompatibility(); + /** * Get the composite context for the composite that contains this endpoint. This * is useful for accessing various composite level objects from within the * runtime code */ CompositeContext getCompositeContext(); + + /** + * to allow for remote interface comparison we convert a Endpoint's Java interface + * to WSDL at build time. + * + * @param wsdlContract + */ +// void setGeneratedWSDLContract(InterfaceContract wsdlContract); + + /** + * to allow for remote interface comparison we convert a Endpoint's Java interface + * to WSDL at build time. + * + * @preturn wsdlContract + */ +// InterfaceContract getGeneratedWSDLContract(); + } diff --git a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpointReference.java b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpointReference.java index e852a47cf8..fb9b9992c6 100644 --- a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpointReference.java +++ b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/RuntimeEndpointReference.java @@ -49,6 +49,7 @@ public interface RuntimeEndpointReference extends EndpointReference, Invocable, */ InterfaceContract getBindingInterfaceContract(); + /** * Get the interface contract of the reference of the source component type, i.e., the * componentType.reference.interfaceContract. This represents the data types that the @@ -57,6 +58,30 @@ public interface RuntimeEndpointReference extends EndpointReference, Invocable, */ InterfaceContract getComponentTypeReferenceInterfaceContract(); + /** + * Check that endpoint reference has compatible interface at the component and binding ends. + * The user can specify the interfaces at both ends so there is a danger that they won't be compatible. + * There is checking in the activator but of course endpoint references may not have a binding assigned + * until final resolution. + */ + public void validateReferenceInterfaceCompatibility(); + + /** + * to allow for remote interface comparison we convert a Endpoint Reference's Java interface + * to WSDL at build time. + * + * @param wsdlContract + */ +// void setGeneratedWSDLContract(InterfaceContract wsdlContract); + + /** + * to allow for remote interface comparison we convert a Endpoint Reference's Java interface + * to WSDL at build time. + * + * @preturn wsdlContract + */ +// InterfaceContract getGeneratedWSDLContract(); + boolean isOutOfDate(); void rebuild(); boolean isStarted(); diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java index afd62edb8b..db345826d1 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java @@ -247,6 +247,10 @@ public class CompositeActivatorImpl implements CompositeActivator { public void activate(CompositeContext compositeContext, RuntimeEndpoint ep) { ep.bind(compositeContext); + + // Check that the service binding interface is compatible with the + // service interface + ep.validateServiceInterfaceCompatibility(); } public void deactivate(RuntimeComponent component, RuntimeComponentService service) { @@ -309,6 +313,13 @@ public class CompositeActivatorImpl implements CompositeActivator { } // endpointReference.setInterfaceContract(sourceContract.makeUnidirectional(false)); + + // if the reference already has a binding we can check the reference binding interface + // and reference interfaces for compatibility. If we can't check now compatibility + // will be checked when the endpoint reference is resolved. + if (epr.getStatus() == EndpointReference.Status.RESOLVED_BINDING){ + epr.validateReferenceInterfaceCompatibility(); + } } public void deactivate(RuntimeEndpointReference endpointReference) { diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java index eeadfef9c1..4809241432 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java @@ -187,6 +187,8 @@ public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint this.phaseManager = utilities.getUtility(PhaseManager.class); this.serializer = utilities.getUtility(EndpointSerializer.class); this.providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class); + this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class); + this.contractBuilder = builders.getContractBuilder(); } public void unbind() { @@ -224,7 +226,11 @@ public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint for (InvocationChain chain : getInvocationChains()) { Operation op = chain.getTargetOperation(); - if (interfaceContractMapper.isCompatible(operation, op, Compatibility.SUBSET)) { + // We used to check compatibility here but this is now validated when the + // chain is created. As the chain operations are the real interface types + // they may be incompatible just because they are described in different + // IDLs + if (operation.getName().equals(op.getName())) { invocationChainMap.put(operation, chain); return chain; } @@ -304,6 +310,7 @@ public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint // TODO - EPR - why is this looking at the component types. The endpoint should have the right interface contract by this time InterfaceContract targetContract = getComponentTypeServiceInterfaceContract(); // setInterfaceContract(targetContract); + validateServiceInterfaceCompatibility(); for (Operation operation : sourceContract.getInterface().getOperations()) { Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation); if (targetOperation == null) { @@ -463,6 +470,47 @@ public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); return (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class); } // end method RuntimeAssemblyFactory + + /** + * Check that endpoint has compatible interface at the component and binding ends. + * The user can specify the interfaces at both ends so there is a danger that they won't be compatible. + */ + public void validateServiceInterfaceCompatibility() { + + InterfaceContract serviceContract = getComponentServiceInterfaceContract(); + InterfaceContract bindingContract = getBindingInterfaceContract(); + + if ((serviceContract != null) && + (bindingContract != null)){ + try { + if ((serviceContract.getClass() != bindingContract.getClass()) && + (serviceContract instanceof JavaInterfaceContract)) { + interfaceContractMapper.checkCompatibility(getGeneratedWSDLContract(serviceContract), + bindingContract, + Compatibility.SUBSET, + true, // we ignore callbacks as binding iface won't have one + false); + } else { + interfaceContractMapper.checkCompatibility(serviceContract, + bindingContract, + Compatibility.SUBSET, + true, // we ignore callbacks as binding iface won't have one + false); + } + } catch (Exception ex){ + throw new ServiceRuntimeException("Component " + + this.getComponent().getName() + + " Service " + + getService().getName() + + " interface is incompatible with the interface of the reference binding - " + + getBinding().getName() + + " - " + + ex.getMessage() + + " - [" + this.toString() + "]"); + } + } + + } private void initServiceBindingInvocationChains() { @@ -744,5 +792,17 @@ public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint } } } + public InterfaceContract getGeneratedWSDLContract(InterfaceContract interfaceContract) { + if ( interfaceContract.getNormalizedWSDLContract() == null){ + if (getComponentServiceInterfaceContract() instanceof JavaInterfaceContract){ + if (contractBuilder == null){ + throw new ServiceRuntimeException("Contract builder not found while calculating WSDL contract for " + this.toString()); + } + contractBuilder.build(getComponentServiceInterfaceContract(), null); + } + } + + return interfaceContract.getNormalizedWSDLContract(); + } } diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java index 9ef0d8e728..531e4634e1 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java @@ -37,6 +37,8 @@ import org.apache.tuscany.sca.assembly.CompositeReference; import org.apache.tuscany.sca.assembly.CompositeService; import org.apache.tuscany.sca.assembly.Contract; import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.ContractBuilder; import org.apache.tuscany.sca.assembly.impl.EndpointReferenceImpl; import org.apache.tuscany.sca.context.CompositeContext; import org.apache.tuscany.sca.core.ExtensionPointRegistry; @@ -51,12 +53,15 @@ import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.InvocationChain; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.provider.BindingProviderFactory; import org.apache.tuscany.sca.provider.EndpointReferenceProvider; import org.apache.tuscany.sca.provider.PolicyProvider; @@ -99,6 +104,9 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen protected InterfaceContract bindingInterfaceContract; protected InterfaceContract referenceInterfaceContract; + + //protected InterfaceContract generatedReferenceWSDLInterfaceContract; + private String xml; private boolean started; @@ -169,6 +177,9 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen this.phaseManager = utilities.getUtility(PhaseManager.class); this.serializer = utilities.getUtility(EndpointSerializer.class); this.providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class); + + this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class); + this.contractBuilder = builders.getContractBuilder(); } public synchronized List getInvocationChains() { @@ -191,7 +202,12 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen if (cached == null) { for (InvocationChain chain : getInvocationChains()) { Operation op = chain.getSourceOperation(); - if (interfaceContractMapper.isCompatible(operation, op, Compatibility.SUBSET)) { + + // We used to check compatibility here but this is now validated when the + // chain is created. As the chain operations are the real interface types + // they may be incompatible just because they are described in different + // IDLs + if (operation.getName().equals(op.getName())) { invocationChainMap.put(operation, chain); return chain; } @@ -266,6 +282,8 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen throw new IllegalStateException(e); } } + + validateReferenceInterfaceCompatibility(); List chainList = new ArrayList(); if(sourceContract != null && targetContract != null) { @@ -293,6 +311,51 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen chains = chainList; wireProcessor.process(this); } + + /** + * Check that endpoint reference has compatible interface at the component and binding ends. + * The user can specify the interfaces at both ends so there is a danger that they won't be compatible. + * There is checking in the activator but of course endpoint references may not have a binding assigned + * until final resolution. + */ + public void validateReferenceInterfaceCompatibility() { + + InterfaceContract referenceContract = getComponentReferenceInterfaceContract(); + InterfaceContract bindingContract = getBindingInterfaceContract(); + + if ((referenceContract != null) && + (bindingContract != null)){ + + try { + + if ((referenceContract.getClass() != bindingContract.getClass()) && + (referenceContract instanceof JavaInterfaceContract)) { + interfaceContractMapper.checkCompatibility(getGeneratedWSDLContract(referenceContract), + bindingContract, + Compatibility.SUBSET, + true, // we ignore callbacks as binding iface won't have one + false); + } else { + interfaceContractMapper.checkCompatibility(referenceContract, + bindingContract, + Compatibility.SUBSET, + true, // we ignore callbacks as binding iface won't have one + false); + } + + } catch (Exception ex){ + throw new ServiceRuntimeException("Component " + + this.getComponent().getName() + + " Reference " + + getReference().getName() + + " interface is incompatible with the interface of the reference binding " + + getBinding().getName() + + " - " + + ex.getMessage() + + " - [" + this.toString() + "]"); + } + } + } /** * This code used to be in the activator but has moved here as @@ -535,5 +598,18 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen public boolean isStarted() { return started; } + + public InterfaceContract getGeneratedWSDLContract(InterfaceContract interfaceContract) { + if ( interfaceContract.getNormalizedWSDLContract() == null){ + if (getComponentReferenceInterfaceContract() instanceof JavaInterfaceContract){ + if (contractBuilder == null){ + throw new ServiceRuntimeException("Contract builder not found while calculating WSDL contract for " + this.toString()); + } + contractBuilder.build(getComponentReferenceInterfaceContract(), null); + } + } + + return interfaceContract.getNormalizedWSDLContract(); + } } diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java index 7e49d45fe3..3349456044 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java @@ -29,21 +29,26 @@ import javax.xml.namespace.QName; import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentReference; import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.assembly.builder.BindingBuilder; import org.apache.tuscany.sca.assembly.builder.BuilderContext; import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; +import org.apache.tuscany.sca.assembly.builder.Messages; import org.apache.tuscany.sca.assembly.builder.PolicyBuilder; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointReferenceImpl; import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.MonitorFactory; @@ -56,6 +61,7 @@ import org.apache.tuscany.sca.runtime.CompositeActivator; import org.apache.tuscany.sca.runtime.EndpointReferenceBinder; import org.apache.tuscany.sca.runtime.EndpointRegistry; import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; import org.oasisopen.sca.ServiceRuntimeException; /** @@ -292,7 +298,11 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { throw new ServiceRuntimeException("Unable to bind " + monitor.getLastProblem().toString()); } - } + + // Now the endpoint reference is resolved check that the binding interfaces contract + // and the reference contract are compatible + ((RuntimeEndpointReference)endpointReference).validateReferenceInterfaceCompatibility(); + } /** * Returns true if the reference has a callback diff --git a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceContract.java b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceContract.java index 69891225e7..25875dbd6a 100644 --- a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceContract.java +++ b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceContract.java @@ -29,5 +29,5 @@ import org.apache.tuscany.sca.interfacedef.InterfaceContract; * @tuscany.spi.extension.asclient */ public interface JavaInterfaceContract extends InterfaceContract { - + } diff --git a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceContractImpl.java b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceContractImpl.java index d43ebe558b..cb0d5f3b27 100644 --- a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceContractImpl.java +++ b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceContractImpl.java @@ -18,6 +18,7 @@ */ package org.apache.tuscany.sca.interfacedef.java.impl; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractImpl; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; @@ -28,6 +29,10 @@ import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; */ public class JavaInterfaceContractImpl extends InterfaceContractImpl implements JavaInterfaceContract { + // A cached WSDL version of the Java contract use during normalized + // interface comparison + private InterfaceContract normailizedWSDLInterfaceContract; + protected JavaInterfaceContractImpl() { } @@ -36,4 +41,13 @@ public class JavaInterfaceContractImpl extends InterfaceContractImpl implements return (JavaInterfaceContractImpl) super.clone(); } + @Override + public InterfaceContract getNormalizedWSDLContract() { + return normailizedWSDLInterfaceContract; + } + + @Override + public void setNormailizedWSDLContract(InterfaceContract wsdlInterfaceContract) { + normailizedWSDLInterfaceContract = wsdlInterfaceContract; + } } diff --git a/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLInterfaceContractImpl.java b/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLInterfaceContractImpl.java index e10bc0d178..201aecca40 100644 --- a/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLInterfaceContractImpl.java +++ b/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLInterfaceContractImpl.java @@ -18,6 +18,7 @@ */ package org.apache.tuscany.sca.interfacedef.wsdl.impl; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractImpl; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract; @@ -44,4 +45,12 @@ public class WSDLInterfaceContractImpl extends InterfaceContractImpl implements public WSDLInterfaceContractImpl clone() throws CloneNotSupportedException { return (WSDLInterfaceContractImpl) super.clone(); } + + public InterfaceContract getNormalizedWSDLContract() { + return this; + } + + public void setNormailizedWSDLContract(InterfaceContract wsdlInterfaceContract) { + // do nothing as this already is a WSDL contract + } } -- cgit v1.2.3