summaryrefslogtreecommitdiffstats
path: root/sandbox/sebastien/java/extend/contrib/modules
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-29 02:55:29 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-29 02:55:29 +0000
commit88bf2a256b02e1858993bf097f4dc743d389e3f0 (patch)
tree298073eb40da33624a95f820e576e049c279e463 /sandbox/sebastien/java/extend/contrib/modules
parent490374326cf57b0161d053aea3a9f0cedd7d2228 (diff)
Sandbox to experiment and extend the runtime.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@990479 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sandbox/sebastien/java/extend/contrib/modules')
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/META-INF/MANIFEST.MF21
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/pom.xml64
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/InputStream2Protobuf.java65
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/Protobuf2OutputStream.java60
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufDatabinding.java107
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding20
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer20
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer17
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/com/example/tutorial/AddressBookProtos.java1375
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufTransformationTestCase.java63
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/resources/addressbook.proto48
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/LICENSE205
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/META-INF/MANIFEST.MF33
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/NOTICE6
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/pom.xml69
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/ServletWrapper.java58
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatDefaultServlet.java114
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java701
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/resources/META-INF/services/org.apache.tuscany.sca.host.http.ServletHost18
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java372
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/content/test.html21
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/tuscany.keyStorebin0 -> 1265 bytes
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/LICENSE205
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/META-INF/MANIFEST.MF63
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/NOTICE6
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/pom.xml81
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAGenericApplicationContext.java145
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAParentApplicationContext.java213
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringApplicationContextAccessor.java41
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringContextWrapper.java130
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java53
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java38
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java44
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java49
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java48
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java151
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java112
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java75
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java164
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java168
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/SpringXMLBeanDefinitionLoaderImpl.java78
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java38
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java50
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java81
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java78
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java158
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java40
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java126
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader17
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory20
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.handlers1
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.schemas1
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/org/springframework/sca/xml/spring-sca.xsd84
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/LICENSE205
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/META-INF/MANIFEST.MF25
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/NOTICE6
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/README9
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/pom.xml50
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/stub/SpringXMLBeanDefinitionLoaderStub.java92
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/ComponentTie.java41
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/PropertyValueTie.java53
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringApplicationContextAccessor.java39
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringContextStub.java142
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProvider.java80
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProviderFactory.java75
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationTie.java156
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvocationException.java40
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvoker.java125
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader17
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory20
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/LICENSE205
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/META-INF/MANIFEST.MF25
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/NOTICE6
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/README9
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/pom.xml70
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java176
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java212
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java130
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java146
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java129
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java77
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java70
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java68
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java59
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java73
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java73
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java53
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java38
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java44
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java49
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java48
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java151
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java54
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java112
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java75
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java163
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java55
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java167
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java57
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.handlers1
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.schemas1
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/org/springframework/sca/xml/spring-sca.xsd84
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/LICENSE205
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/META-INF/MANIFEST.MF50
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/NOTICE6
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/pom.xml59
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java132
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java90
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java259
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationBuilder.java41
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java73
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java71
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java63
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java92
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java92
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java95
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java917
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java244
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLBeanDefinitionLoader.java50
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ImplementationBuilder18
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor20
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions17
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties28
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/org/apache/tuscany/sca/implementation/spring/definitions.xml30
-rw-r--r--sandbox/sebastien/java/extend/contrib/modules/pom.xml91
125 files changed, 12613 insertions, 0 deletions
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..2789db18ee
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Data Binding for Google ProtocolBuffers
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Data Binding for JSON
+Import-Package: javax.xml.namespace,
+ javax.xml.stream,
+ org.apache.tuscany.sca.common.xml.stax;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.databinding;version="2.0.0",
+ org.apache.tuscany.sca.databinding.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.impl;version="2.0.0";resolution:=optional,
+ org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0"
+Bundle-SymbolicName: org.apache.tuscany.sca.databinding.protobuf
+Bundle-DocURL: http://www.apache.org/
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/pom.xml
new file mode 100644
index 0000000000..90b5ba1c68
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-databinding-protobuf</artifactId>
+ <name>Apache Tuscany SCA Data Binding for Google ProtocolBuffers</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core-spi</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-common-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-databinding</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>2.3.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/InputStream2Protobuf.java b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/InputStream2Protobuf.java
new file mode 100644
index 0000000000..7953e4e5b3
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/InputStream2Protobuf.java
@@ -0,0 +1,65 @@
+/*
+ * 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.databinding.protobuf;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+
+import com.google.protobuf.Message;
+
+/**
+ *
+ */
+public class InputStream2Protobuf implements PullTransformer<InputStream, Message> {
+
+ @Override
+ public String getSourceDataBinding() {
+ return "application/x-protobuf" + "#" + InputStream.class.getName();
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ // TODO Auto-generated method stub
+ return ProtobufDatabinding.NAME;
+ }
+
+ @Override
+ public int getWeight() {
+ // TODO Auto-generated method stub
+ return 10;
+ }
+
+ @Override
+ public Message transform(InputStream source, TransformationContext context) {
+ try {
+ Class<?> type = context.getTargetDataType().getPhysical();
+ Method method = type.getMethod("parseFrom", InputStream.class);
+ Object result = method.invoke(null, source);
+ return (Message)result;
+ } catch (Throwable e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/Protobuf2OutputStream.java b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/Protobuf2OutputStream.java
new file mode 100644
index 0000000000..6892287f67
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/Protobuf2OutputStream.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.databinding.protobuf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.tuscany.sca.databinding.PushTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+
+import com.google.protobuf.Message;
+
+/**
+ *
+ */
+public class Protobuf2OutputStream implements PushTransformer<Message, OutputStream> {
+ @Override
+ public String getSourceDataBinding() {
+ return ProtobufDatabinding.NAME;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return "application/x-protobuf" + "#" + OutputStream.class.getName();
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+ @Override
+ public void transform(Message source, OutputStream sink, TransformationContext context) {
+ try {
+ if (source != null) {
+ source.writeTo(sink);
+ }
+ } catch (IOException e) {
+ throw new TransformationException(e);
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufDatabinding.java b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufDatabinding.java
new file mode 100644
index 0000000000..ad148c7499
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufDatabinding.java
@@ -0,0 +1,107 @@
+/*
+ * 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.databinding.protobuf;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.WrapperHandler;
+import org.apache.tuscany.sca.databinding.XMLTypeHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+
+import com.google.protobuf.Message;
+
+/**
+ * Google ProtocolBuffers databinding
+ */
+public class ProtobufDatabinding implements DataBinding {
+
+ public static final String NAME = "ProtocolBuffers";
+
+ /**
+ *
+ */
+ public ProtobufDatabinding() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#getName()
+ */
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#introspect(org.apache.tuscany.sca.interfacedef.DataType, org.apache.tuscany.sca.interfacedef.Operation)
+ */
+ @Override
+ public boolean introspect(DataType dataType, Operation operation) {
+ if (Message.class.isAssignableFrom(dataType.getPhysical())) {
+ dataType.setDataBinding(NAME);
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#introspect(java.lang.Object, org.apache.tuscany.sca.interfacedef.Operation)
+ */
+ @Override
+ public DataType introspect(Object value, Operation operation) {
+ if (value instanceof Message) {
+ DataType dt = new DataTypeImpl(value.getClass(), null);
+ dt.setDataBinding(NAME);
+ return dt;
+ } else {
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#getWrapperHandler()
+ */
+ @Override
+ public WrapperHandler getWrapperHandler() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#copy(java.lang.Object, org.apache.tuscany.sca.interfacedef.DataType, org.apache.tuscany.sca.interfacedef.DataType, org.apache.tuscany.sca.interfacedef.Operation, org.apache.tuscany.sca.interfacedef.Operation)
+ */
+ @Override
+ public Object copy(Object object,
+ DataType sourceDataType,
+ DataType targetDataType,
+ Operation sourceOperation,
+ Operation targetOperation) {
+ Message msg = (Message)object;
+ return ((Message.Builder)msg.toBuilder().clone()).build();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.tuscany.sca.databinding.DataBinding#getXMLTypeHelper()
+ */
+ @Override
+ public XMLTypeHelper getXMLTypeHelper() {
+ return null;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding
new file mode 100644
index 0000000000..35f7932ff9
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding
@@ -0,0 +1,20 @@
+# 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.
+
+# implementation classes for the databindings
+org.apache.tuscany.sca.databinding.protobuf.ProtobufDatabinding;name=ProtocolBuffers
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer
new file mode 100644
index 0000000000..0f60373c30
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer
@@ -0,0 +1,20 @@
+# 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.
+
+# Implementation classes for the transformers
+org.apache.tuscany.sca.databinding.protobuf.InputStream2Protobuf;source=application/x-protobuf#java.io.InputStream;target=ProtocolBuffers,weight=10,public=true
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer
new file mode 100644
index 0000000000..cc1989eb7b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PushTransformer
@@ -0,0 +1,17 @@
+# 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.databinding.protobuf.Protobuf2OutputStream;source=ProtocolBuffers;target=application/x-protobuf#java.io.OutputStream,weight=10,public=true
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/com/example/tutorial/AddressBookProtos.java b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/com/example/tutorial/AddressBookProtos.java
new file mode 100644
index 0000000000..8219fe1099
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/com/example/tutorial/AddressBookProtos.java
@@ -0,0 +1,1375 @@
+/*
+ * 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.
+ */
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: addressbook.proto
+
+package com.example.tutorial;
+
+public final class AddressBookProtos {
+ private AddressBookProtos() {
+ }
+
+ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
+ }
+
+ public static final class Person extends com.google.protobuf.GeneratedMessage {
+ // Use Person.newBuilder() to construct.
+ private Person() {
+ initFields();
+ }
+
+ private Person(boolean noInit) {
+ }
+
+ private static final Person defaultInstance;
+
+ public static Person getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public Person getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_fieldAccessorTable;
+ }
+
+ public enum PhoneType implements com.google.protobuf.ProtocolMessageEnum {
+ MOBILE(0, 0), HOME(1, 1), WORK(2, 2), ;
+
+ public final int getNumber() {
+ return value;
+ }
+
+ public static PhoneType valueOf(int value) {
+ switch (value) {
+ case 0:
+ return MOBILE;
+ case 1:
+ return HOME;
+ case 2:
+ return WORK;
+ default:
+ return null;
+ }
+ }
+
+ public static com.google.protobuf.Internal.EnumLiteMap<PhoneType> internalGetValueMap() {
+ return internalValueMap;
+ }
+
+ private static com.google.protobuf.Internal.EnumLiteMap<PhoneType> internalValueMap =
+ new com.google.protobuf.Internal.EnumLiteMap<PhoneType>() {
+ public PhoneType findValueByNumber(int number) {
+ return PhoneType.valueOf(number);
+ }
+ };
+
+ public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+
+ public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
+ return getDescriptor();
+ }
+
+ public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
+ return com.example.tutorial.AddressBookProtos.Person.getDescriptor().getEnumTypes().get(0);
+ }
+
+ private static final PhoneType[] VALUES = {MOBILE, HOME, WORK,};
+
+ public static PhoneType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private PhoneType(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ static {
+ com.example.tutorial.AddressBookProtos.getDescriptor();
+ }
+
+ // @@protoc_insertion_point(enum_scope:tutorial.Person.PhoneType)
+ }
+
+ public static final class PhoneNumber extends com.google.protobuf.GeneratedMessage {
+ // Use PhoneNumber.newBuilder() to construct.
+ private PhoneNumber() {
+ initFields();
+ }
+
+ private PhoneNumber(boolean noInit) {
+ }
+
+ private static final PhoneNumber defaultInstance;
+
+ public static PhoneNumber getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public PhoneNumber getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable;
+ }
+
+ // required string number = 1;
+ public static final int NUMBER_FIELD_NUMBER = 1;
+ private boolean hasNumber;
+ private java.lang.String number_ = "";
+
+ public boolean hasNumber() {
+ return hasNumber;
+ }
+
+ public java.lang.String getNumber() {
+ return number_;
+ }
+
+ // optional .tutorial.Person.PhoneType type = 2 [default = HOME];
+ public static final int TYPE_FIELD_NUMBER = 2;
+ private boolean hasType;
+ private com.example.tutorial.AddressBookProtos.Person.PhoneType type_;
+
+ public boolean hasType() {
+ return hasType;
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneType getType() {
+ return type_;
+ }
+
+ private void initFields() {
+ type_ = com.example.tutorial.AddressBookProtos.Person.PhoneType.HOME;
+ }
+
+ public final boolean isInitialized() {
+ if (!hasNumber)
+ return false;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ getSerializedSize();
+ if (hasNumber()) {
+ output.writeString(1, getNumber());
+ }
+ if (hasType()) {
+ output.writeEnum(2, getType().getNumber());
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1)
+ return size;
+
+ size = 0;
+ if (hasNumber()) {
+ size += com.google.protobuf.CodedOutputStream.computeStringSize(1, getNumber());
+ }
+ if (hasType()) {
+ size += com.google.protobuf.CodedOutputStream.computeEnumSize(2, getType().getNumber());
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseDelimitedFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static Builder newBuilder() {
+ return Builder.create();
+ }
+
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public static Builder newBuilder(com.example.tutorial.AddressBookProtos.Person.PhoneNumber prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+
+ public Builder toBuilder() {
+ return newBuilder(this);
+ }
+
+ public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> {
+ private com.example.tutorial.AddressBookProtos.Person.PhoneNumber result;
+
+ // Construct using com.example.tutorial.AddressBookProtos.Person.PhoneNumber.newBuilder()
+ private Builder() {
+ }
+
+ private static Builder create() {
+ Builder builder = new Builder();
+ builder.result = new com.example.tutorial.AddressBookProtos.Person.PhoneNumber();
+ return builder;
+ }
+
+ protected com.example.tutorial.AddressBookProtos.Person.PhoneNumber internalGetResult() {
+ return result;
+ }
+
+ public Builder clear() {
+ if (result == null) {
+ throw new IllegalStateException("Cannot call clear() after build().");
+ }
+ result = new com.example.tutorial.AddressBookProtos.Person.PhoneNumber();
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(result);
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+ return com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDescriptor();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getDefaultInstanceForType() {
+ return com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance();
+ }
+
+ public boolean isInitialized() {
+ return result.isInitialized();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneNumber build() {
+ if (result != null && !isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return buildPartial();
+ }
+
+ private com.example.tutorial.AddressBookProtos.Person.PhoneNumber buildParsed()
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ if (!isInitialized()) {
+ throw newUninitializedMessageException(result).asInvalidProtocolBufferException();
+ }
+ return buildPartial();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneNumber buildPartial() {
+ if (result == null) {
+ throw new IllegalStateException("build() has already been called on this Builder.");
+ }
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber returnMe = result;
+ result = null;
+ return returnMe;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.example.tutorial.AddressBookProtos.Person.PhoneNumber) {
+ return mergeFrom((com.example.tutorial.AddressBookProtos.Person.PhoneNumber)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.example.tutorial.AddressBookProtos.Person.PhoneNumber other) {
+ if (other == com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance())
+ return this;
+ if (other.hasNumber()) {
+ setNumber(other.getNumber());
+ }
+ if (other.hasType()) {
+ setType(other.getType());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder(this.getUnknownFields());
+ while (true) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ default: {
+ if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ }
+ break;
+ }
+ case 10: {
+ setNumber(input.readString());
+ break;
+ }
+ case 16: {
+ int rawValue = input.readEnum();
+ com.example.tutorial.AddressBookProtos.Person.PhoneType value =
+ com.example.tutorial.AddressBookProtos.Person.PhoneType.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(2, rawValue);
+ } else {
+ setType(value);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // required string number = 1;
+ public boolean hasNumber() {
+ return result.hasNumber();
+ }
+
+ public java.lang.String getNumber() {
+ return result.getNumber();
+ }
+
+ public Builder setNumber(java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.hasNumber = true;
+ result.number_ = value;
+ return this;
+ }
+
+ public Builder clearNumber() {
+ result.hasNumber = false;
+ result.number_ = getDefaultInstance().getNumber();
+ return this;
+ }
+
+ // optional .tutorial.Person.PhoneType type = 2 [default = HOME];
+ public boolean hasType() {
+ return result.hasType();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneType getType() {
+ return result.getType();
+ }
+
+ public Builder setType(com.example.tutorial.AddressBookProtos.Person.PhoneType value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.hasType = true;
+ result.type_ = value;
+ return this;
+ }
+
+ public Builder clearType() {
+ result.hasType = false;
+ result.type_ = com.example.tutorial.AddressBookProtos.Person.PhoneType.HOME;
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:tutorial.Person.PhoneNumber)
+ }
+
+ static {
+ defaultInstance = new PhoneNumber(true);
+ com.example.tutorial.AddressBookProtos.internalForceInit();
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:tutorial.Person.PhoneNumber)
+ }
+
+ // required string name = 1;
+ public static final int NAME_FIELD_NUMBER = 1;
+ private boolean hasName;
+ private java.lang.String name_ = "";
+
+ public boolean hasName() {
+ return hasName;
+ }
+
+ public java.lang.String getName() {
+ return name_;
+ }
+
+ // required int32 id = 2;
+ public static final int ID_FIELD_NUMBER = 2;
+ private boolean hasId;
+ private int id_ = 0;
+
+ public boolean hasId() {
+ return hasId;
+ }
+
+ public int getId() {
+ return id_;
+ }
+
+ // optional string email = 3;
+ public static final int EMAIL_FIELD_NUMBER = 3;
+ private boolean hasEmail;
+ private java.lang.String email_ = "";
+
+ public boolean hasEmail() {
+ return hasEmail;
+ }
+
+ public java.lang.String getEmail() {
+ return email_;
+ }
+
+ // repeated .tutorial.Person.PhoneNumber phone = 4;
+ public static final int PHONE_FIELD_NUMBER = 4;
+ private java.util.List<com.example.tutorial.AddressBookProtos.Person.PhoneNumber> phone_ =
+ java.util.Collections.emptyList();
+
+ public java.util.List<com.example.tutorial.AddressBookProtos.Person.PhoneNumber> getPhoneList() {
+ return phone_;
+ }
+
+ public int getPhoneCount() {
+ return phone_.size();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getPhone(int index) {
+ return phone_.get(index);
+ }
+
+ private void initFields() {
+ }
+
+ public final boolean isInitialized() {
+ if (!hasName)
+ return false;
+ if (!hasId)
+ return false;
+ for (com.example.tutorial.AddressBookProtos.Person.PhoneNumber element : getPhoneList()) {
+ if (!element.isInitialized())
+ return false;
+ }
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ getSerializedSize();
+ if (hasName()) {
+ output.writeString(1, getName());
+ }
+ if (hasId()) {
+ output.writeInt32(2, getId());
+ }
+ if (hasEmail()) {
+ output.writeString(3, getEmail());
+ }
+ for (com.example.tutorial.AddressBookProtos.Person.PhoneNumber element : getPhoneList()) {
+ output.writeMessage(4, element);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1)
+ return size;
+
+ size = 0;
+ if (hasName()) {
+ size += com.google.protobuf.CodedOutputStream.computeStringSize(1, getName());
+ }
+ if (hasId()) {
+ size += com.google.protobuf.CodedOutputStream.computeInt32Size(2, getId());
+ }
+ if (hasEmail()) {
+ size += com.google.protobuf.CodedOutputStream.computeStringSize(3, getEmail());
+ }
+ for (com.example.tutorial.AddressBookProtos.Person.PhoneNumber element : getPhoneList()) {
+ size += com.google.protobuf.CodedOutputStream.computeMessageSize(4, element);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseDelimitedFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.Person parseFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static Builder newBuilder() {
+ return Builder.create();
+ }
+
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public static Builder newBuilder(com.example.tutorial.AddressBookProtos.Person prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+
+ public Builder toBuilder() {
+ return newBuilder(this);
+ }
+
+ public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> {
+ private com.example.tutorial.AddressBookProtos.Person result;
+
+ // Construct using com.example.tutorial.AddressBookProtos.Person.newBuilder()
+ private Builder() {
+ }
+
+ private static Builder create() {
+ Builder builder = new Builder();
+ builder.result = new com.example.tutorial.AddressBookProtos.Person();
+ return builder;
+ }
+
+ protected com.example.tutorial.AddressBookProtos.Person internalGetResult() {
+ return result;
+ }
+
+ public Builder clear() {
+ if (result == null) {
+ throw new IllegalStateException("Cannot call clear() after build().");
+ }
+ result = new com.example.tutorial.AddressBookProtos.Person();
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(result);
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+ return com.example.tutorial.AddressBookProtos.Person.getDescriptor();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person getDefaultInstanceForType() {
+ return com.example.tutorial.AddressBookProtos.Person.getDefaultInstance();
+ }
+
+ public boolean isInitialized() {
+ return result.isInitialized();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person build() {
+ if (result != null && !isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return buildPartial();
+ }
+
+ private com.example.tutorial.AddressBookProtos.Person buildParsed()
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ if (!isInitialized()) {
+ throw newUninitializedMessageException(result).asInvalidProtocolBufferException();
+ }
+ return buildPartial();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person buildPartial() {
+ if (result == null) {
+ throw new IllegalStateException("build() has already been called on this Builder.");
+ }
+ if (result.phone_ != java.util.Collections.EMPTY_LIST) {
+ result.phone_ = java.util.Collections.unmodifiableList(result.phone_);
+ }
+ com.example.tutorial.AddressBookProtos.Person returnMe = result;
+ result = null;
+ return returnMe;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.example.tutorial.AddressBookProtos.Person) {
+ return mergeFrom((com.example.tutorial.AddressBookProtos.Person)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.example.tutorial.AddressBookProtos.Person other) {
+ if (other == com.example.tutorial.AddressBookProtos.Person.getDefaultInstance())
+ return this;
+ if (other.hasName()) {
+ setName(other.getName());
+ }
+ if (other.hasId()) {
+ setId(other.getId());
+ }
+ if (other.hasEmail()) {
+ setEmail(other.getEmail());
+ }
+ if (!other.phone_.isEmpty()) {
+ if (result.phone_.isEmpty()) {
+ result.phone_ =
+ new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person.PhoneNumber>();
+ }
+ result.phone_.addAll(other.phone_);
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder(this.getUnknownFields());
+ while (true) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ default: {
+ if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ }
+ break;
+ }
+ case 10: {
+ setName(input.readString());
+ break;
+ }
+ case 16: {
+ setId(input.readInt32());
+ break;
+ }
+ case 26: {
+ setEmail(input.readString());
+ break;
+ }
+ case 34: {
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder subBuilder =
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber.newBuilder();
+ input.readMessage(subBuilder, extensionRegistry);
+ addPhone(subBuilder.buildPartial());
+ break;
+ }
+ }
+ }
+ }
+
+ // required string name = 1;
+ public boolean hasName() {
+ return result.hasName();
+ }
+
+ public java.lang.String getName() {
+ return result.getName();
+ }
+
+ public Builder setName(java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.hasName = true;
+ result.name_ = value;
+ return this;
+ }
+
+ public Builder clearName() {
+ result.hasName = false;
+ result.name_ = getDefaultInstance().getName();
+ return this;
+ }
+
+ // required int32 id = 2;
+ public boolean hasId() {
+ return result.hasId();
+ }
+
+ public int getId() {
+ return result.getId();
+ }
+
+ public Builder setId(int value) {
+ result.hasId = true;
+ result.id_ = value;
+ return this;
+ }
+
+ public Builder clearId() {
+ result.hasId = false;
+ result.id_ = 0;
+ return this;
+ }
+
+ // optional string email = 3;
+ public boolean hasEmail() {
+ return result.hasEmail();
+ }
+
+ public java.lang.String getEmail() {
+ return result.getEmail();
+ }
+
+ public Builder setEmail(java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.hasEmail = true;
+ result.email_ = value;
+ return this;
+ }
+
+ public Builder clearEmail() {
+ result.hasEmail = false;
+ result.email_ = getDefaultInstance().getEmail();
+ return this;
+ }
+
+ // repeated .tutorial.Person.PhoneNumber phone = 4;
+ public java.util.List<com.example.tutorial.AddressBookProtos.Person.PhoneNumber> getPhoneList() {
+ return java.util.Collections.unmodifiableList(result.phone_);
+ }
+
+ public int getPhoneCount() {
+ return result.getPhoneCount();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getPhone(int index) {
+ return result.getPhone(index);
+ }
+
+ public Builder setPhone(int index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.phone_.set(index, value);
+ return this;
+ }
+
+ public Builder setPhone(int index,
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder builderForValue) {
+ result.phone_.set(index, builderForValue.build());
+ return this;
+ }
+
+ public Builder addPhone(com.example.tutorial.AddressBookProtos.Person.PhoneNumber value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ if (result.phone_.isEmpty()) {
+ result.phone_ =
+ new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person.PhoneNumber>();
+ }
+ result.phone_.add(value);
+ return this;
+ }
+
+ public Builder addPhone(com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder builderForValue) {
+ if (result.phone_.isEmpty()) {
+ result.phone_ =
+ new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person.PhoneNumber>();
+ }
+ result.phone_.add(builderForValue.build());
+ return this;
+ }
+
+ public Builder addAllPhone(java.lang.Iterable<? extends com.example.tutorial.AddressBookProtos.Person.PhoneNumber> values) {
+ if (result.phone_.isEmpty()) {
+ result.phone_ =
+ new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person.PhoneNumber>();
+ }
+ super.addAll(values, result.phone_);
+ return this;
+ }
+
+ public Builder clearPhone() {
+ result.phone_ = java.util.Collections.emptyList();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:tutorial.Person)
+ }
+
+ static {
+ defaultInstance = new Person(true);
+ com.example.tutorial.AddressBookProtos.internalForceInit();
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:tutorial.Person)
+ }
+
+ public static final class AddressBook extends com.google.protobuf.GeneratedMessage {
+ // Use AddressBook.newBuilder() to construct.
+ private AddressBook() {
+ initFields();
+ }
+
+ private AddressBook(boolean noInit) {
+ }
+
+ private static final AddressBook defaultInstance;
+
+ public static AddressBook getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public AddressBook getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
+ return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_fieldAccessorTable;
+ }
+
+ // repeated .tutorial.Person person = 1;
+ public static final int PERSON_FIELD_NUMBER = 1;
+ private java.util.List<com.example.tutorial.AddressBookProtos.Person> person_ = java.util.Collections
+ .emptyList();
+
+ public java.util.List<com.example.tutorial.AddressBookProtos.Person> getPersonList() {
+ return person_;
+ }
+
+ public int getPersonCount() {
+ return person_.size();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person getPerson(int index) {
+ return person_.get(index);
+ }
+
+ private void initFields() {
+ }
+
+ public final boolean isInitialized() {
+ for (com.example.tutorial.AddressBookProtos.Person element : getPersonList()) {
+ if (!element.isInitialized())
+ return false;
+ }
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ getSerializedSize();
+ for (com.example.tutorial.AddressBookProtos.Person element : getPersonList()) {
+ output.writeMessage(1, element);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1)
+ return size;
+
+ size = 0;
+ for (com.example.tutorial.AddressBookProtos.Person element : getPersonList()) {
+ size += com.google.protobuf.CodedOutputStream.computeMessageSize(1, element);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseDelimitedFrom(java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+
+ public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ public static Builder newBuilder() {
+ return Builder.create();
+ }
+
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public static Builder newBuilder(com.example.tutorial.AddressBookProtos.AddressBook prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+
+ public Builder toBuilder() {
+ return newBuilder(this);
+ }
+
+ public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> {
+ private com.example.tutorial.AddressBookProtos.AddressBook result;
+
+ // Construct using com.example.tutorial.AddressBookProtos.AddressBook.newBuilder()
+ private Builder() {
+ }
+
+ private static Builder create() {
+ Builder builder = new Builder();
+ builder.result = new com.example.tutorial.AddressBookProtos.AddressBook();
+ return builder;
+ }
+
+ protected com.example.tutorial.AddressBookProtos.AddressBook internalGetResult() {
+ return result;
+ }
+
+ public Builder clear() {
+ if (result == null) {
+ throw new IllegalStateException("Cannot call clear() after build().");
+ }
+ result = new com.example.tutorial.AddressBookProtos.AddressBook();
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(result);
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+ return com.example.tutorial.AddressBookProtos.AddressBook.getDescriptor();
+ }
+
+ public com.example.tutorial.AddressBookProtos.AddressBook getDefaultInstanceForType() {
+ return com.example.tutorial.AddressBookProtos.AddressBook.getDefaultInstance();
+ }
+
+ public boolean isInitialized() {
+ return result.isInitialized();
+ }
+
+ public com.example.tutorial.AddressBookProtos.AddressBook build() {
+ if (result != null && !isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return buildPartial();
+ }
+
+ private com.example.tutorial.AddressBookProtos.AddressBook buildParsed()
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ if (!isInitialized()) {
+ throw newUninitializedMessageException(result).asInvalidProtocolBufferException();
+ }
+ return buildPartial();
+ }
+
+ public com.example.tutorial.AddressBookProtos.AddressBook buildPartial() {
+ if (result == null) {
+ throw new IllegalStateException("build() has already been called on this Builder.");
+ }
+ if (result.person_ != java.util.Collections.EMPTY_LIST) {
+ result.person_ = java.util.Collections.unmodifiableList(result.person_);
+ }
+ com.example.tutorial.AddressBookProtos.AddressBook returnMe = result;
+ result = null;
+ return returnMe;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.example.tutorial.AddressBookProtos.AddressBook) {
+ return mergeFrom((com.example.tutorial.AddressBookProtos.AddressBook)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.example.tutorial.AddressBookProtos.AddressBook other) {
+ if (other == com.example.tutorial.AddressBookProtos.AddressBook.getDefaultInstance())
+ return this;
+ if (!other.person_.isEmpty()) {
+ if (result.person_.isEmpty()) {
+ result.person_ = new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person>();
+ }
+ result.person_.addAll(other.person_);
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder(this.getUnknownFields());
+ while (true) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ default: {
+ if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+ this.setUnknownFields(unknownFields.build());
+ return this;
+ }
+ break;
+ }
+ case 10: {
+ com.example.tutorial.AddressBookProtos.Person.Builder subBuilder =
+ com.example.tutorial.AddressBookProtos.Person.newBuilder();
+ input.readMessage(subBuilder, extensionRegistry);
+ addPerson(subBuilder.buildPartial());
+ break;
+ }
+ }
+ }
+ }
+
+ // repeated .tutorial.Person person = 1;
+ public java.util.List<com.example.tutorial.AddressBookProtos.Person> getPersonList() {
+ return java.util.Collections.unmodifiableList(result.person_);
+ }
+
+ public int getPersonCount() {
+ return result.getPersonCount();
+ }
+
+ public com.example.tutorial.AddressBookProtos.Person getPerson(int index) {
+ return result.getPerson(index);
+ }
+
+ public Builder setPerson(int index, com.example.tutorial.AddressBookProtos.Person value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ result.person_.set(index, value);
+ return this;
+ }
+
+ public Builder setPerson(int index, com.example.tutorial.AddressBookProtos.Person.Builder builderForValue) {
+ result.person_.set(index, builderForValue.build());
+ return this;
+ }
+
+ public Builder addPerson(com.example.tutorial.AddressBookProtos.Person value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ if (result.person_.isEmpty()) {
+ result.person_ = new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person>();
+ }
+ result.person_.add(value);
+ return this;
+ }
+
+ public Builder addPerson(com.example.tutorial.AddressBookProtos.Person.Builder builderForValue) {
+ if (result.person_.isEmpty()) {
+ result.person_ = new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person>();
+ }
+ result.person_.add(builderForValue.build());
+ return this;
+ }
+
+ public Builder addAllPerson(java.lang.Iterable<? extends com.example.tutorial.AddressBookProtos.Person> values) {
+ if (result.person_.isEmpty()) {
+ result.person_ = new java.util.ArrayList<com.example.tutorial.AddressBookProtos.Person>();
+ }
+ super.addAll(values, result.person_);
+ return this;
+ }
+
+ public Builder clearPerson() {
+ result.person_ = java.util.Collections.emptyList();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:tutorial.AddressBook)
+ }
+
+ static {
+ defaultInstance = new AddressBook(true);
+ com.example.tutorial.AddressBookProtos.internalForceInit();
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:tutorial.AddressBook)
+ }
+
+ private static com.google.protobuf.Descriptors.Descriptor internal_static_tutorial_Person_descriptor;
+ private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_tutorial_Person_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor internal_static_tutorial_Person_PhoneNumber_descriptor;
+ private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor internal_static_tutorial_AddressBook_descriptor;
+ private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_tutorial_AddressBook_fieldAccessorTable;
+
+ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
+ static {
+ java.lang.String[] descriptorData =
+ {"\n\021addressbook.proto\022\010tutorial\"\332\001\n\006Person" + "\022\014\n\004name\030\001 \002(\t\022\n\n\002id\030\002 \002(\005\022\r\n\005email\030\003 \001("
+ + "\t\022+\n\005phone\030\004 \003(\0132\034.tutorial.Person.Phone"
+ + "Number\032M\n\013PhoneNumber\022\016\n\006number\030\001 \002(\t\022.\n"
+ + "\004type\030\002 \001(\0162\032.tutorial.Person.PhoneType:"
+ + "\004HOME\"+\n\tPhoneType\022\n\n\006MOBILE\020\000\022\010\n\004HOME\020\001"
+ + "\022\010\n\004WORK\020\002\"/\n\013AddressBook\022 \n\006person\030\001 \003("
+ + "\0132\020.tutorial.PersonB)\n\024com.example.tutor"
+ + "ialB\021AddressBookProtos"};
+ com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+ new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+ public com.google.protobuf.ExtensionRegistry assignDescriptors(com.google.protobuf.Descriptors.FileDescriptor root) {
+ descriptor = root;
+ internal_static_tutorial_Person_descriptor = getDescriptor().getMessageTypes().get(0);
+ internal_static_tutorial_Person_fieldAccessorTable =
+ new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_tutorial_Person_descriptor,
+ new java.lang.String[] {"Name",
+ "Id",
+ "Email",
+ "Phone",},
+ com.example.tutorial.AddressBookProtos.Person.class,
+ com.example.tutorial.AddressBookProtos.Person.Builder.class);
+ internal_static_tutorial_Person_PhoneNumber_descriptor =
+ internal_static_tutorial_Person_descriptor.getNestedTypes().get(0);
+ internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable =
+ new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_tutorial_Person_PhoneNumber_descriptor,
+ new java.lang.String[] {"Number",
+ "Type",},
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber.class,
+ com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder.class);
+ internal_static_tutorial_AddressBook_descriptor = getDescriptor().getMessageTypes().get(1);
+ internal_static_tutorial_AddressBook_fieldAccessorTable =
+ new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_tutorial_AddressBook_descriptor,
+ new java.lang.String[] {"Person",},
+ com.example.tutorial.AddressBookProtos.AddressBook.class,
+ com.example.tutorial.AddressBookProtos.AddressBook.Builder.class);
+ return null;
+ }
+ };
+ com.google.protobuf.Descriptors.FileDescriptor
+ .internalBuildGeneratedFileFrom(descriptorData,
+ new com.google.protobuf.Descriptors.FileDescriptor[] {},
+ assigner);
+ }
+
+ public static void internalForceInit() {
+ }
+
+ // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufTransformationTestCase.java b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufTransformationTestCase.java
new file mode 100644
index 0000000000..9fc6f30794
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/java/org/apache/tuscany/sca/databinding/protobuf/ProtobufTransformationTestCase.java
@@ -0,0 +1,63 @@
+/*
+ * 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.databinding.protobuf;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.impl.TransformationContextImpl;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.junit.Test;
+
+import com.example.tutorial.AddressBookProtos.AddressBook;
+import com.example.tutorial.AddressBookProtos.Person;
+
+/**
+ *
+ */
+public class ProtobufTransformationTestCase {
+ @Test
+ public void testTransform() throws Exception {
+ Protobuf2OutputStream t1 = new Protobuf2OutputStream();
+ TransformationContext context = new TransformationContextImpl();
+ DataType dt1 = new DataTypeImpl(AddressBook.class, null);
+ context.setSourceDataType(dt1);
+
+ AddressBook addressBook =
+ AddressBook.newBuilder()
+ .addPerson(Person.newBuilder().setId(1).setEmail("abc@example.com").setName("John Smith").build())
+ .build();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ t1.transform(addressBook, bos, context);
+
+ InputStream2Protobuf t2 = new InputStream2Protobuf();
+ context.setSourceDataType(null);
+ context.setTargetDataType(dt1);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ AddressBook addressBook2 = (AddressBook)t2.transform(bis, context);
+ Assert.assertEquals(addressBook, addressBook2);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/resources/addressbook.proto b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/resources/addressbook.proto
new file mode 100644
index 0000000000..395320fb22
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/databinding-protobuf/src/test/resources/addressbook.proto
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+// See README.txt for information and build instructions.
+
+package tutorial;
+
+option java_package = "com.example.tutorial";
+option java_outer_classname = "AddressBookProtos";
+
+message Person {
+ required string name = 1;
+ required int32 id = 2; // Unique ID number for this person.
+ optional string email = 3;
+
+ enum PhoneType {
+ MOBILE = 0;
+ HOME = 1;
+ WORK = 2;
+ }
+
+ message PhoneNumber {
+ required string number = 1;
+ optional PhoneType type = 2 [default = HOME];
+ }
+
+ repeated PhoneNumber phone = 4;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+ repeated Person person = 1;
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/LICENSE b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..cab6b5057e
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/META-INF/MANIFEST.MF
@@ -0,0 +1,33 @@
+Manifest-Version: 1.0
+Private-Package: org.apache.tuscany.sca.http.tomcat;version="2.0.0",org.
+ apache.tuscany.sca.http.tomcat.module;version="2.0.0"
+Tool: Bnd-0.0.255
+Bundle-Name: Apache Tuscany SCA Tomcat Servlet Host Extension
+Created-By: 1.6.0_07 (Sun Microsystems Inc.)
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bnd-LastModified: 1222833663765
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Tomcat Servlet Host Extension
+Import-Package: javax.naming,
+ javax.naming.directory,
+ javax.servlet,
+ javax.servlet.http,
+ org.apache.catalina,
+ org.apache.catalina.connector,
+ org.apache.catalina.core,
+ org.apache.catalina.servlets,
+ org.apache.catalina.startup,
+ org.apache.coyote,
+ org.apache.coyote.http11,
+ org.apache.naming.resources,
+ org.apache.tomcat.util.buf,
+ org.apache.tomcat.util.http.mapper,
+ org.apache.tomcat.util.net,
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.host.http;version="2.0.0",
+ org.apache.tuscany.sca.work;version="2.0.0"
+Bundle-SymbolicName: org.apache.tuscany.sca.host.tomcat
+Bundle-DocURL: http://www.apache.org/
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/NOTICE b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/pom.xml
new file mode 100644
index 0000000000..6f49551591
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-host-tomcat</artifactId>
+ <name>Apache Tuscany SCA Tomcat Servlet Host Extension</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-host-http</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>catalina</artifactId>
+ <version>6.0.26</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>coyote</artifactId>
+ <version>6.0.26</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/ServletWrapper.java b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/ServletWrapper.java
new file mode 100644
index 0000000000..a0b384d554
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/ServletWrapper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.http.tomcat;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.core.StandardWrapper;
+
+/**
+ * A Servlet wrapper.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServletWrapper extends StandardWrapper {
+ private static final long serialVersionUID = 1L;
+
+ private final Servlet servlet;
+
+ public ServletWrapper(Servlet servlet) {
+ this.servlet = servlet;
+ }
+
+ @Override
+ public synchronized Servlet loadServlet() {
+ return servlet;
+ }
+
+ @Override
+ public Servlet getServlet() {
+ return servlet;
+ }
+
+ public void initServlet() throws ServletException {
+ servlet.init(facade);
+ }
+
+ public void destroyServlet() {
+ servlet.destroy();
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatDefaultServlet.java b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatDefaultServlet.java
new file mode 100644
index 0000000000..5d9b65503a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatDefaultServlet.java
@@ -0,0 +1,114 @@
+/*
+ * 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.http.tomcat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Hashtable;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.naming.resources.FileDirContext;
+import org.apache.naming.resources.ProxyDirContext;
+import org.apache.naming.resources.Resource;
+
+/**
+ * DefaultServlet implementation for Tomcat.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TomcatDefaultServlet extends DefaultServlet {
+ private static final long serialVersionUID = -7503581551326796573L;
+
+ private String documentRoot;
+ private ProxyDirContext proxyDirContext;
+
+ public TomcatDefaultServlet(String servletPath, String documentRoot) {
+ this.documentRoot = documentRoot;
+
+ DirContext dirContext;
+ URI uri = URI.create(documentRoot);
+ if (!"file".equals(uri.getScheme())) {
+
+ dirContext = new FileDirContext() {
+ @Override
+ public Attributes getAttributes(String name) throws NamingException {
+ return new BasicAttributes();
+ }
+
+ @Override
+ public Object lookup(String name) throws NamingException {
+
+ try {
+ final URL url = new URL(TomcatDefaultServlet.this.documentRoot + name);
+ return new Resource() {
+ @Override
+ public InputStream streamContent() throws IOException {
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ return connection.getInputStream();
+ }
+ };
+ } catch (MalformedURLException e) {
+ throw new NamingException(e.toString());
+ }
+ }
+ };
+
+ } else {
+ dirContext = new FileDirContext();
+ ((FileDirContext)dirContext).setDocBase(uri.getPath());
+ }
+ proxyDirContext = new ProxyDirContext(new Hashtable(), dirContext);
+ resources = proxyDirContext;
+ }
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ resources = proxyDirContext;
+ }
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+ super.init(servletConfig);
+ resources = proxyDirContext;
+ }
+
+ @Override
+ protected String getRelativePath(HttpServletRequest request) {
+ String path = request.getPathInfo();
+ if (path == null || path.length() == 0) {
+ path = "/";
+ }
+ return path;
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java
new file mode 100644
index 0000000000..d1a2e5d283
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java
@@ -0,0 +1,701 @@
+/*
+ * 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.http.tomcat;
+
+import java.beans.PropertyChangeListener;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.KeyStore;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Loader;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.core.StandardEngine;
+import org.apache.catalina.startup.ContextConfig;
+import org.apache.catalina.startup.Embedded;
+import org.apache.coyote.http11.Http11Protocol;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.mapper.MappingData;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.LifeCycleListener;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.host.http.DefaultResourceServlet;
+import org.apache.tuscany.sca.host.http.SecurityContext;
+import org.apache.tuscany.sca.host.http.ServletHost;
+import org.apache.tuscany.sca.host.http.ServletMappingException;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ * A Tomcat based implementation of ServletHost.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TomcatServer implements ServletHost, LifeCycleListener {
+ private static final Logger logger = Logger.getLogger(TomcatServer.class.getName());
+
+ private WorkScheduler workScheduler;
+ private Embedded embedded;
+ private Map<Integer, Port> ports = new HashMap<Integer, Port>();
+ private String contextPath = "/";
+ private int defaultPort = 8080;
+ private int defaultSSLPort = 8443;
+
+ private final class TuscanyLoader implements Loader {
+ private final ClassLoader tccl;
+ private boolean delegate;
+ private boolean reloadable;
+ private Container container;
+ private List<String> repos = new ArrayList<String>();
+ private List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+ private TuscanyLoader(ClassLoader tccl) {
+ this.tccl = tccl;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ public void addRepository(String repository) {
+ repos.add(repository);
+ }
+
+ public void backgroundProcess() {
+ }
+
+ public String[] findRepositories() {
+ return repos.toArray(new String[repos.size()]);
+ }
+
+ public Container getContainer() {
+ return container;
+ }
+
+ public boolean getDelegate() {
+ return delegate;
+ }
+
+ public String getInfo() {
+ return "Tuscany Loader for Embedded Tomcat";
+ }
+
+ public boolean getReloadable() {
+ return reloadable;
+ }
+
+ public boolean modified() {
+ return false;
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ public void setContainer(Container container) {
+ this.container = container;
+ }
+
+ public void setDelegate(boolean delegate) {
+ this.delegate = delegate;
+ }
+
+ public void setReloadable(boolean reloadable) {
+ this.reloadable = reloadable;
+ }
+
+ public ClassLoader getClassLoader() {
+ return tccl;
+ }
+ }
+
+ /**
+ * Represents a port and the server that serves it.
+ */
+ private class Port {
+ private Engine engine;
+ private Host host;
+ private Connector connector;
+
+ private Port(Engine engine, Host host, Connector connector) {
+ this.engine = engine;
+ this.host = host;
+ this.connector = connector;
+ }
+
+ public Engine getEngine() {
+ return engine;
+ }
+
+ public Host getHost() {
+ return host;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
+ }
+
+ /**
+ * Constructs a new embedded Tomcat server.
+ *
+ */
+ public TomcatServer(ExtensionPointRegistry registry, Map<String, String> attributes) {
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.workScheduler = utilities.getUtility(WorkScheduler.class);
+ String port = attributes.get("defaultPort");
+ if (port != null) {
+ defaultPort = Integer.parseInt(port);
+ }
+ String sslPort = attributes.get("defaultSSLPort");
+ if (sslPort != null) {
+ defaultPort = Integer.parseInt(sslPort);
+ }
+ if (attributes.containsKey("contextPath")) {
+ contextPath = attributes.get("contextPath");
+ }
+ }
+
+ protected TomcatServer(WorkScheduler workScheduler) {
+ this.workScheduler = workScheduler;
+ }
+
+ public void setDefaultPort(int port) {
+ defaultPort = port;
+ }
+
+ public int getDefaultPort() {
+ return defaultPort;
+ }
+
+ /**
+ * Stop all the started servers.
+ */
+ public void stop() {
+ if (embedded != null) {
+ try {
+ // embedded.stop();
+ embedded.destroy();
+ for (Port port : ports.values()) {
+ port.connector.stop();
+ }
+ } catch (LifecycleException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ public synchronized String addServletMapping(String suri, Servlet servlet) {
+ init();
+ URI uri = URI.create(suri);
+
+ // Get the URI scheme and port
+ String scheme = uri.getScheme();
+ if (scheme == null) {
+ scheme = "http";
+ }
+ final int portNumber = (uri.getPort() == -1 ? defaultPort : uri.getPort());
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+
+ port = createInstance(scheme, portNumber);
+ ports.put(portNumber, port);
+ }
+
+ // Register the Servlet mapping
+ String path = uri.getPath();
+
+ if (!path.startsWith("/")) {
+ path = '/' + path;
+ }
+
+ if (!path.startsWith(contextPath)) {
+ path = contextPath + path;
+ }
+
+ ServletWrapper wrapper;
+ if (servlet instanceof DefaultResourceServlet) {
+ String defaultServletPath = path;
+
+ // Optimize the handling of resource requests, use the Tomcat default Servlet
+ // instead of our default resource Servlet
+ if (defaultServletPath.endsWith("*")) {
+ defaultServletPath = defaultServletPath.substring(0, defaultServletPath.length() - 1);
+ }
+ if (defaultServletPath.endsWith("/")) {
+ defaultServletPath = defaultServletPath.substring(0, defaultServletPath.length() - 1);
+ }
+ DefaultResourceServlet resourceServlet = (DefaultResourceServlet)servlet;
+ TomcatDefaultServlet defaultServlet =
+ new TomcatDefaultServlet(defaultServletPath, resourceServlet.getDocumentRoot());
+ wrapper = new ServletWrapper(defaultServlet);
+
+ } else {
+ wrapper = new ServletWrapper(servlet);
+ }
+ Context context = port.getHost().map(path);
+ wrapper.setName(path);
+ wrapper.addMapping(path);
+ context.addChild(wrapper);
+ context.addServletMapping(path, path);
+ port.getConnector().getMapper().addWrapper("localhost", "", path, wrapper);
+
+ // Initialize the Servlet
+ try {
+ wrapper.initServlet();
+ } catch (ServletException e) {
+ throw new ServletMappingException(e);
+ }
+
+ // Compute the complete URL
+ String host;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ host = "localhost";
+ }
+ URL addedURL;
+ try {
+ addedURL = new URL(scheme, host, portNumber, path);
+ } catch (MalformedURLException e) {
+ throw new ServletMappingException(e);
+ }
+ logger.info("Added Servlet mapping: " + addedURL);
+ return addedURL.toString();
+ }
+
+ private Port createInstance(String scheme, final int portNumber) {
+ Port port;
+ // Create an engine
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ final Engine engine = AccessController.doPrivileged(new PrivilegedAction<Engine>() {
+ public Engine run() {
+ return embedded.createEngine();
+ }
+ });
+
+ ((StandardEngine)engine).setBaseDir("");
+ engine.setDefaultHost("localhost");
+ engine.setName("engine/" + portNumber);
+
+ // Create a host
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ final Host host = AccessController.doPrivileged(new PrivilegedAction<Host>() {
+ public Host run() {
+ Host host = embedded.createHost("localhost", "");
+ engine.addChild(host);
+ return host;
+ }
+ });
+
+ // Create the root context
+ Context context = embedded.createContext("", "");
+ final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ context.setLoader(new TuscanyLoader(tccl));
+ // context.setParentClassLoader(tccl.getParent());
+ ContextConfig config = new ContextConfig();
+ ((Lifecycle)context).addLifecycleListener(config);
+ host.addChild(context);
+
+ embedded.addEngine(engine);
+
+ // Install an HTTP connector
+
+ Connector connector;
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ try {
+ final String protocol = scheme;
+ connector = AccessController.doPrivileged(new PrivilegedExceptionAction<Connector>() {
+ public Connector run() throws Exception {
+ Connector customConnector = new Connector();
+ customConnector.setPort(portNumber);
+
+ if ("https".equalsIgnoreCase(protocol)) {
+ configureSSL(customConnector);
+ ((Http11Protocol)customConnector.getProtocolHandler()).setSSLEnabled(true);
+ }
+ return customConnector;
+ }
+
+ private void configureSSL(Connector customConnector) {
+ String trustStore = System.getProperty("javax.net.ssl.trustStore");
+ String trustStorePass = System.getProperty("javax.net.ssl.trustStorePassword");
+ String keyStore = System.getProperty("javax.net.ssl.keyStore");
+ String keyStorePass = System.getProperty("javax.net.ssl.keyStorePassword");
+
+ customConnector.setProperty("protocol", "TLS");
+
+ customConnector.setProperty("keystore", keyStore);
+ customConnector.setProperty("keypass", keyStorePass);
+ String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
+ String trustStoreType =
+ System.getProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType());
+ customConnector.setProperty("keytype", keyStoreType);
+ customConnector.setProperty("trusttype", trustStoreType);
+ customConnector.setProperty("truststore", trustStore);
+ customConnector.setProperty("trustpass", trustStorePass);
+
+ customConnector.setProperty("clientauth", "false");
+ customConnector.setProtocol("HTTP/1.1");
+ customConnector.setScheme(protocol);
+ customConnector.setProperty("backlog", "10");
+ customConnector.setSecure(true);
+ }
+ });
+ } catch (Exception e) {
+ throw new ServletMappingException(e);
+ }
+
+ embedded.addConnector(connector);
+ try {
+ connector.start();
+ } catch (LifecycleException e) {
+ throw new ServletMappingException(e);
+ }
+
+ // Keep track of the running server
+ port = new Port(engine, host, connector);
+ return port;
+ }
+
+ private synchronized void init() {
+ if (embedded != null) {
+ return;
+ }
+ embedded = new Embedded();
+ embedded.setAwait(true);
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws LifecycleException {
+ embedded.start();
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ // throw (LifecycleException)e.getException();
+ throw new ServletMappingException(e);
+ }
+ }
+
+ public URL getURLMapping(String suri) throws ServletMappingException {
+ URI uri = URI.create(suri);
+
+ // Get the URI scheme and port
+ String scheme = uri.getScheme();
+ if (scheme == null) {
+ scheme = "http";
+ }
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = defaultPort;
+ }
+
+ // Get the host
+ String host;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ host = "localhost";
+ }
+
+ // Construct the URL
+ String path = uri.getPath();
+
+ if (!path.startsWith("/")) {
+ path = '/' + path;
+ }
+
+ if (!path.startsWith(contextPath)) {
+ path = contextPath + path;
+ }
+ URL url;
+ try {
+ url = new URL(scheme, host, portNumber, path);
+ } catch (MalformedURLException e) {
+ throw new ServletMappingException(e);
+ }
+ return url;
+ }
+
+ public Servlet getServletMapping(String suri) throws ServletMappingException {
+
+ if (suri == null) {
+ return null;
+ }
+
+ URI uri = URI.create(suri);
+
+ // Get the URI port
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = defaultPort;
+ }
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+ return null;
+ }
+
+ String mapping = uri.getPath();
+
+ if (!mapping.startsWith("/")) {
+ mapping = '/' + mapping;
+ }
+
+ if (!mapping.startsWith(contextPath)) {
+ mapping = contextPath + mapping;
+ }
+
+ final Context context = port.getHost().map(mapping);
+ final MappingData md = new MappingData();
+ final MessageBytes mb = MessageBytes.newInstance();
+ mb.setString(mapping);
+ try {
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ context.getMapper().map(mb, md);
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ return null;
+ }
+ if (md.wrapper instanceof ServletWrapper) {
+ ServletWrapper servletWrapper = (ServletWrapper)md.wrapper;
+ return servletWrapper.getServlet();
+ } else {
+ return null;
+ }
+ }
+
+ public synchronized Servlet removeServletMapping(String suri) {
+ URI uri = URI.create(suri);
+
+ // Get the URI port
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = defaultPort;
+ }
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+ throw new IllegalStateException("No servlet registered at this URI: " + suri);
+ }
+
+ String mapping = uri.getPath();
+
+ if (!mapping.startsWith("/")) {
+ mapping = '/' + mapping;
+ }
+
+ if (!mapping.startsWith(contextPath)) {
+ mapping = contextPath + mapping;
+ }
+
+ final Context context = port.getHost().map(mapping);
+ final MappingData md = new MappingData();
+ final MessageBytes mb = MessageBytes.newInstance();
+ mb.setString(mapping);
+ try {
+ // Allow privileged access to read properties. Requires PropertiesPermission read in
+ // security policy.
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ context.getMapper().map(mb, md);
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ return null;
+ }
+ if (md.wrapper instanceof ServletWrapper) {
+ ServletWrapper servletWrapper = (ServletWrapper)md.wrapper;
+
+ port.getConnector().getMapper().removeWrapper("localhost", "", mapping);
+
+ try {
+ context.removeServletMapping(mapping);
+ } catch (NegativeArraySizeException e) {
+ // JIRA TUSCANY-1599
+ // FIXME Looks like a bug in Tomcat when removing the last
+ // Servlet in the list, catch the exception for now as it doesn't
+ // seem harmful, will find a better solution for the next release
+ }
+ context.removeChild(servletWrapper);
+ try {
+ servletWrapper.destroyServlet();
+ } catch (Exception ex) {
+ // Hack to handle destruction of Servlets without Servlet context
+ }
+
+ logger.info("Removed Servlet mapping: " + suri);
+
+ // Stop the port if there's no servlets on it anymore
+ String[] contextNames = port.getConnector().getMapper().getContextNames();
+ if (contextNames == null || contextNames.length == 0) {
+ try {
+ port.getConnector().stop();
+ ((StandardEngine)port.getEngine()).stop();
+ embedded.removeEngine(port.getEngine());
+ embedded.removeConnector(port.getConnector());
+ ports.remove(portNumber);
+ } catch (LifecycleException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ return servletWrapper.getServlet();
+ } else {
+ logger.warning("Trying to Remove servlet mapping: " + mapping + " where mapping is not registered");
+ return null;
+ }
+ }
+
+ public RequestDispatcher getRequestDispatcher(String suri) throws ServletMappingException {
+ //FIXME implement this later
+ return null;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public void setContextPath(String path) {
+ this.contextPath = path;
+ }
+
+ public void start() {
+
+ }
+
+ public String addServletMapping(String uri, Servlet servlet, SecurityContext securityContext)
+ throws ServletMappingException {
+ return addServletMapping(uri, servlet);
+ }
+
+ public String getName() {
+ return "tomcat";
+ }
+
+ public URL getURLMapping(String arg0, SecurityContext arg1) {
+ return null;
+ }
+
+ public void setAttribute(String arg0, Object arg1) {
+ }
+
+ private URL map(String suri, SecurityContext securityContext, boolean resolve) throws ServletMappingException {
+ URI uri = URI.create(suri);
+
+ // Get the URI scheme and port
+ String scheme = null;
+ if (securityContext != null && securityContext.isSSLEnabled()) {
+ scheme = "https";
+ } else {
+ scheme = uri.getScheme();
+ if (scheme == null) {
+ scheme = "http";
+ }
+ }
+
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ if ("http".equals(scheme)) {
+ portNumber = defaultPort;
+ } else {
+ portNumber = defaultSSLPort;
+ }
+ }
+
+ // Get the host
+ String host = uri.getHost();
+ if (host == null) {
+ host = "0.0.0.0";
+ if (resolve) {
+ try {
+ host = InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ host = "localhost";
+ }
+ }
+ }
+
+ // Construct the URL
+ String path = uri.getPath();
+
+ if (!path.startsWith("/")) {
+ path = '/' + path;
+ }
+
+ if (!path.startsWith(contextPath)) {
+ path = contextPath + path;
+ }
+
+ URL url;
+ try {
+ url = new URL(scheme, host, portNumber, path);
+ } catch (MalformedURLException e) {
+ throw new ServletMappingException(e);
+ }
+ return url;
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ if (ports.isEmpty()) {
+ return null;
+ } else {
+ Port port = ports.values().iterator().next();
+ return port.getHost().map(getContextPath()).getServletContext();
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/resources/META-INF/services/org.apache.tuscany.sca.host.http.ServletHost b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/resources/META-INF/services/org.apache.tuscany.sca.host.http.ServletHost
new file mode 100644
index 0000000000..00350bbf6b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/main/resources/META-INF/services/org.apache.tuscany.sca.host.http.ServletHost
@@ -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.
+# Implementation class for the ServletHost
+org.apache.tuscany.sca.http.tomcat.TomcatServer;name=tomcat,ranking=50,defaultPort=8085
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java
new file mode 100644
index 0000000000..4bcf0623e8
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java
@@ -0,0 +1,372 @@
+/*
+ * 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.http.tomcat;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.URL;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.host.http.DefaultResourceServlet;
+import org.apache.tuscany.sca.host.http.ExtensibleServletHost;
+import org.apache.tuscany.sca.host.http.ServletHost;
+import org.apache.tuscany.sca.work.NotificationListener;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TomcatServerTestCase extends TestCase {
+
+ private static final String REQUEST1_HEADER =
+ "GET /foo HTTP/1.0\n" + "Host: localhost\n"
+ + "Content-Type: text/xml\n"
+ + "Connection: close\n"
+ + "Content-Length: ";
+ private static final String REQUEST1_CONTENT = "";
+ private static final String REQUEST1 =
+ REQUEST1_HEADER + REQUEST1_CONTENT.getBytes().length + "\n\n" + REQUEST1_CONTENT;
+
+ private static final String REQUEST2_HEADER =
+ "GET /webcontent/test.html HTTP/1.0\n" + "Host: localhost\n"
+ + "Content-Type: text/xml\n"
+ + "Connection: close\n"
+ + "Content-Length: ";
+ private static final String REQUEST2_CONTENT = "";
+ private static final String REQUEST2 =
+ REQUEST2_HEADER + REQUEST2_CONTENT.getBytes().length + "\n\n" + REQUEST2_CONTENT;
+
+ private static final int HTTP_PORT = 8085;
+
+ private WorkScheduler workScheduler = new WorkScheduler() {
+
+ public <T extends Runnable> void scheduleWork(T work) {
+ Thread thread = new Thread(work);
+ thread.start();
+ }
+
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+ scheduleWork(work);
+ }
+
+ public void destroy() {
+ }
+ };
+
+ /**
+ * Verifies requests are properly routed according to the Servlet mapping
+ */
+ public void testRegisterServletMapping() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ ServletContext servletContext = service.getServletContext();
+ Assert.assertNotNull(servletContext);
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.stop();
+ assertTrue(servlet.invoked);
+ }
+
+ /**
+ * Verifies requests are properly routed according to the Servlet mapping
+ */
+ public void testRegisterServletMappingSSL() throws Exception {
+ System.setProperty("javax.net.ssl.keyStore", "target/test-classes/tuscany.keyStore");
+ System.setProperty("javax.net.ssl.keyStorePassword", "apache");
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ try {
+ service.addServletMapping("https://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ } finally {
+ System.clearProperty("javax.net.ssl.keyStore");
+ System.clearProperty("javax.net.ssl.keyStorePassword");
+ }
+ System.setProperty("javax.net.ssl.trustStore", "target/test-classes/tuscany.keyStore");
+ System.setProperty("javax.net.ssl.trustStorePassword", "apache");
+ URL url = new URL("https://127.0.0.1:8085/foo");
+ HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+ conn.setHostnameVerifier(new HostnameVerifier() {
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }}
+ );
+
+ conn.connect();
+ read(conn.getInputStream());
+
+ service.stop();
+ assertTrue(servlet.invoked);
+
+ }
+ /**
+ * Verifies that Servlets can be registered with multiple ports
+ */
+ public void testRegisterMultiplePorts() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/", servlet);
+ TestServlet servlet2 = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + (HTTP_PORT + 1) + "/", servlet2);
+ {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ }
+ {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT + 1);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ }
+
+ service.stop();
+ assertTrue(servlet.invoked);
+ assertTrue(servlet2.invoked);
+ }
+
+ public void testUnregisterMapping() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ service.removeServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo");
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.stop();
+ assertFalse(servlet.invoked);
+
+ }
+
+ public void testRegisterUnregisterMapping() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ }
+ assertTrue(servlet.invoked);
+ service.removeServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo");
+ {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ }
+ servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ }
+ assertTrue(servlet.invoked);
+ service.stop();
+ }
+
+ public void testRequestSession() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.stop();
+ assertTrue(servlet.invoked);
+ assertNotNull(servlet.sessionId);
+ }
+
+ public void testRestart() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ service.stop();
+ service.stop();
+ }
+
+ public void testNoMappings() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+ Exception ex = null;
+ try {
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ } catch (Exception e) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ service.stop();
+ }
+
+ public void testResourceServlet() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+
+ String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
+ documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
+ DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
+ TestResourceServlet servlet = new TestResourceServlet(resourceServlet);
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", servlet);
+
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST2.getBytes());
+ os.flush();
+
+ String document = read(client);
+ assertTrue(document.indexOf("<body><p>hello</body>") != -1);
+
+ service.stop();
+ }
+
+ public void testDefaultServlet() throws Exception {
+ TomcatServer service = new TomcatServer(workScheduler);
+
+ String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
+ documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
+ DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", resourceServlet);
+
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST2.getBytes());
+ os.flush();
+
+ String document = read(client);
+ assertTrue(document.indexOf("<body><p>hello</body>") != -1);
+
+ service.stop();
+ }
+
+ private static String read(Socket socket) throws IOException {
+ InputStream is = socket.getInputStream();
+ return read(is);
+ }
+
+ private static String read(InputStream is) throws IOException {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(is));
+ StringBuffer sb = new StringBuffer();
+ String str;
+ while ((str = reader.readLine()) != null) {
+ sb.append(str);
+ }
+ return sb.toString();
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+ private class TestServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+ boolean invoked;
+ String sessionId;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ invoked = true;
+ sessionId = req.getSession().getId();
+ OutputStream writer = resp.getOutputStream();
+ try {
+ writer.write("result".getBytes());
+ } finally {
+ writer.close();
+ }
+ }
+
+ }
+
+ private class TestResourceServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+ private HttpServlet delegate;
+
+ public TestResourceServlet(HttpServlet delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ delegate.init();
+ }
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ super.init();
+ delegate.init(config);
+ }
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ delegate.service(req, resp);
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ delegate.destroy();
+ }
+ }
+
+ @Test
+ public void testDiscovery() {
+ ExtensionPointRegistry registry = new DefaultExtensionPointRegistry();
+ ExtensibleServletHost host = ExtensibleServletHost.getInstance(registry);
+ ServletHost me = host.getDefaultServletHost();
+ Assert.assertEquals("tomcat", me.getName());
+ Assert.assertEquals(8085, me.getDefaultPort());
+ registry.stop();
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/content/test.html b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/content/test.html
new file mode 100644
index 0000000000..f4b79d7f01
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/content/test.html
@@ -0,0 +1,21 @@
+<html>
+<!--
+ * 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.
+-->
+<body><p>hello</body>
+</html> \ No newline at end of file
diff --git a/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/tuscany.keyStore b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/tuscany.keyStore
new file mode 100644
index 0000000000..7ea23f7ff4
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/host-tomcat/src/test/resources/tuscany.keyStore
Binary files differ
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/LICENSE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..b598607625
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/META-INF/MANIFEST.MF
@@ -0,0 +1,63 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-SymbolicName: org.apache.tuscany.sca.implementation.spring.runtime
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
+Import-Package: org.oasisopen.sca;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0",
+ javax.xml.namespace,
+ org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.assembly.builder;version="2.0.0",
+ org.apache.tuscany.sca.assembly.impl;version="2.0.0",
+ org.apache.tuscany.sca.assembly.xml;version="2.0.0",
+ org.apache.tuscany.sca.context;version="2.0.0",
+ org.apache.tuscany.sca.contribution;version="2.0.0",
+ org.apache.tuscany.sca.contribution.processor;version="2.0.0",
+ org.apache.tuscany.sca.contribution.resolver;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.core.factory;version="2.0.0",
+ org.apache.tuscany.sca.core.invocation;version="2.0.0",
+ org.apache.tuscany.sca.databinding;version="2.0.0",
+ org.apache.tuscany.sca.databinding.impl;version="2.0.0",
+ org.apache.tuscany.sca.implementation.spring;version="2.0.0",
+ org.apache.tuscany.sca.implementation.spring.xml;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.injection;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.introspect;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.introspect.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
+ org.apache.tuscany.sca.invocation;version="2.0.0",
+ org.apache.tuscany.sca.monitor;version="2.0.0",
+ org.apache.tuscany.sca.policy;version="2.0.0",
+ org.apache.tuscany.sca.provider;version="2.0.0",
+ org.apache.tuscany.sca.runtime;version="2.0.0",
+ org.springframework.beans;version="3.0.2.RELEASE",
+ org.springframework.beans.factory;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.annotation;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.config;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.support;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.xml;version="3.0.2.RELEASE",
+ org.springframework.context;version="3.0.2.RELEASE",
+ org.springframework.context.support;version="3.0.2.RELEASE",
+ org.springframework.core;version="3.0.2.RELEASE",
+ org.springframework.core.io;version="3.0.2.RELEASE",
+ org.springframework.util;version="3.0.2.RELEASE"
+Export-Package: org.apache.tuscany.sca.implementation.spring.context;version="2.0.0";
+ uses:="org.springframework.beans.factory.support,
+ org.springframework.context.support,
+ org.springframework.core.io,
+ org.apache.tuscany.sca.implementation.spring,
+ org.springframework.context,
+ org.apache.tuscany.sca.implementation.spring.provider,
+ org.springframework.beans.factory.config,
+ org.springframework.beans.factory"
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/NOTICE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/NOTICE
new file mode 100644
index 0000000000..1325efd8bf
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/pom.xml
new file mode 100644
index 0000000000..b08e1c8930
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-implementation-spring-runtime</artifactId>
+ <name>Apache Tuscany SCA Spring Implementation Runtime Model</name>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-spring</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-java-runtime</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core-spi</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Spring dependencies... -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAGenericApplicationContext.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAGenericApplicationContext.java
new file mode 100644
index 0000000000..44a3ee2b88
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAGenericApplicationContext.java
@@ -0,0 +1,145 @@
+/*
+ * 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.implementation.spring.context;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement;
+import org.apache.tuscany.sca.implementation.spring.SpringPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanReference;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
+import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+
+public class SCAGenericApplicationContext extends GenericApplicationContext {
+
+ private ClassLoader classloader = null;
+ private List<SpringSCAPropertyElement> propertyElements = new ArrayList<SpringSCAPropertyElement>();
+ private List<SpringSCAServiceElement> serviceElements = new ArrayList<SpringSCAServiceElement>();
+ private List<SpringSCAReferenceElement> referenceElements = new ArrayList<SpringSCAReferenceElement>();
+ private List<SpringBeanElement> beanElements;
+
+ public SCAGenericApplicationContext(DefaultListableBeanFactory beanFactory,
+ ApplicationContext parent,
+ ClassLoader classloader) {
+ super(beanFactory, parent);
+ this.classloader = classloader;
+ }
+
+ public SCAGenericApplicationContext(ApplicationContext parent, ClassLoader classloader) {
+ super(parent);
+ this.classloader = classloader;
+ }
+
+ @Override
+ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
+ beanFactory.setBeanClassLoader(classloader);
+ }
+
+ public void addSCAPropertyElement(SpringSCAPropertyElement propertyElement) {
+ propertyElements.add(propertyElement);
+ }
+
+ public void addSCAServiceElement(SpringSCAServiceElement serviceElement) {
+ serviceElements.add(serviceElement);
+ }
+
+ public void addSCAReferenceElement(SpringSCAReferenceElement referenceElement) {
+ referenceElements.add(referenceElement);
+ }
+
+ public synchronized List<SpringBeanElement> getBeanElements() {
+ if (beanElements == null) {
+ beanElements = new ArrayList<SpringBeanElement>();
+ for (String name : getBeanDefinitionNames()) {
+ BeanDefinition def = getBeanDefinition(name);
+ SpringBeanElement beanElement = new SpringBeanElement(name, def.getBeanClassName());
+ beanElements.add(beanElement);
+ beanElement.setAbstractBean(def.isAbstract());
+ beanElement.setFactoryBeanAttribute(def.getFactoryBeanName() != null);
+ beanElement.setFactoryMethodAttribute(def.getFactoryMethodName() != null);
+ beanElement.setParentAttribute(def.getParentName() != null);
+ beanElement.setInnerBean(beanElement.getId() == null);
+
+ ConstructorArgumentValues args = def.getConstructorArgumentValues();
+ for (Map.Entry<Integer, ValueHolder> e: args.getIndexedArgumentValues().entrySet()) {
+ ValueHolder holder = e.getValue();
+ SpringConstructorArgElement arg = new SpringConstructorArgElement(holder.getType());
+ arg.setIndex(e.getKey());
+ beanElement.addCustructorArgs(arg);
+ }
+
+ MutablePropertyValues values = def.getPropertyValues();
+ for (PropertyValue p : values.getPropertyValueList()) {
+ SpringPropertyElement propertyElement = new SpringPropertyElement(p.getName());
+ Object value = p.getValue();
+ configurePropertyElement(propertyElement, value);
+ beanElement.getProperties().add(propertyElement);
+ }
+ }
+ }
+ return beanElements;
+ }
+
+ public void configurePropertyElement(SpringPropertyElement propertyElement, Object value) {
+ if (value instanceof BeanReference) {
+ BeanReference beanRef = (BeanReference)value;
+ propertyElement.addRef(beanRef.getBeanName());
+ } else if (value instanceof Collection) {
+ Collection collection = (Collection)value;
+ for (Object item : collection) {
+ configurePropertyElement(propertyElement, item);
+ }
+ } else if (value instanceof TypedStringValue) {
+ TypedStringValue stringValue = (TypedStringValue)value;
+ propertyElement.addValue(stringValue.getValue());
+ } else {
+ if (value != null) {
+ propertyElement.addValue(value.toString());
+ }
+ }
+ }
+
+ public List<SpringSCAPropertyElement> getPropertyElements() {
+ return propertyElements;
+ }
+
+ public List<SpringSCAServiceElement> getServiceElements() {
+ return serviceElements;
+ }
+
+ public List<SpringSCAReferenceElement> getReferenceElements() {
+ return referenceElements;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAParentApplicationContext.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAParentApplicationContext.java
new file mode 100644
index 0000000000..cd81facc3d
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SCAParentApplicationContext.java
@@ -0,0 +1,213 @@
+/*
+ * 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.implementation.spring.context;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tuscany.sca.implementation.spring.provider.SpringImplementationWrapper;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.MessageSourceResolvable;
+import org.springframework.context.NoSuchMessageException;
+import org.springframework.core.io.Resource;
+
+/**
+ * A Spring ParentApplicationContext for a given Spring Implementation
+ *
+ * The Parent application context is responsible for handling those entities within a Spring
+ * application context that actually belong to SCA rather than to Spring. The principal things
+ * are Properties and References. These may be present either through explicit <sca:property/>
+ * and <sca:reference/> elements in the application context or they may be implicit through
+ * unresolved Spring bean <property.../> elements. In either case, it is the Parent application
+ * context that must provide Spring beans that correspond to the property or reference, as derived
+ * from the SCA composite in which the Spring application context is an implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCAParentApplicationContext implements ApplicationContext {
+
+ // The Spring implementation for which this is the parent application context
+ private SpringImplementationWrapper implementation;
+
+ private static final String[] EMPTY_ARRAY = new String[0];
+
+ public SCAParentApplicationContext(SpringImplementationWrapper implementation) {
+ this.implementation = implementation;
+ } // end constructor
+
+ public Object getBean(String name) throws BeansException {
+ return getBean(name, (Class)null);
+ }
+
+ /**
+ * Get a Bean for a reference or for a property.
+ *
+ * @param name - the name of the Bean required
+ * @param requiredType - the required type of the Bean (either a Java class or a Java interface)
+ * @return Object - a Bean which matches the requested bean
+ */
+ public Object getBean(String name, Class requiredType) throws BeansException {
+ Object bean = implementation.getBean(name, requiredType);
+ if (bean == null && getParent() != null) {
+ bean = getParent().getBean(name, requiredType);
+ }
+ if (bean == null) {
+ throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name);
+ } else {
+ return bean;
+ }
+ } // end method getBean( String, Class )
+
+ public Object getBean(String name, Object[] args) throws BeansException {
+ return getBean(name, ((Class)null));
+ }
+
+ public <T> T getBean(Class<T> clazz) throws BeansException {
+ return clazz.cast(getBean(clazz.getName(), clazz));
+ }
+
+ public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> clazz) throws BeansException {
+ return null;
+ }
+
+ public <A extends Annotation> A findAnnotationOnBean(String arg0, Class<A> clazz) {
+ return null;
+ }
+
+ public boolean containsBean(String name) {
+ // TODO
+ return false;
+ }
+
+ public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+ // TODO
+ return false;
+ }
+
+ public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Class getType(String name) throws NoSuchBeanDefinitionException {
+ return null;
+ }
+
+ public String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+ return EMPTY_ARRAY;
+ }
+
+ public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
+ return null;
+ }
+
+ public String getId() {
+ return this.toString();
+ }
+
+ public String getDisplayName() {
+ return implementation.getURI();
+ }
+
+ public long getStartupDate() {
+ return 0;
+ }
+
+ public boolean containsBeanDefinition(String beanName) {
+ return false;
+ }
+
+ public int getBeanDefinitionCount() {
+ return 0;
+ }
+
+ public String[] getBeanDefinitionNames() {
+ return new String[0];
+ }
+
+ public String[] getBeanNamesForType(Class type) {
+ return new String[0];
+ }
+
+ public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) {
+ return new String[0];
+ }
+
+ public Map getBeansOfType(Class type) throws BeansException {
+ return null;
+ }
+
+ public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException {
+ return null;
+ }
+
+ public boolean isPrototype(String theString) {
+ return false;
+ }
+
+ public BeanFactory getParentBeanFactory() {
+ return null;
+ }
+
+ public boolean containsLocalBean(String name) {
+ return false;
+ }
+
+ public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
+ return null;
+ }
+
+ public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
+ return null;
+ }
+
+ public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
+ return null;
+ }
+
+ public void publishEvent(ApplicationEvent event) {
+
+ }
+
+ public Resource[] getResources(String locationPattern) throws IOException {
+ return new Resource[0];
+ }
+
+ public Resource getResource(String location) {
+ return null;
+ }
+
+ public ClassLoader getClassLoader() {
+ // REVIEW: this is almost certainly flawed, but it's not clear how the SCA runtime's
+ // resource loading mechanism is exposed right now.
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ public ApplicationContext getParent() {
+ return implementation.getParentApplicationContext();
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringApplicationContextAccessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringApplicationContextAccessor.java
new file mode 100644
index 0000000000..2d18b5aa6c
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringApplicationContextAccessor.java
@@ -0,0 +1,41 @@
+/*
+ * 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.implementation.spring.context;
+
+import org.springframework.context.ApplicationContext;
+
+/**
+ * A utility to receive the parent Spring application context
+ */
+public interface SpringApplicationContextAccessor {
+ /**
+ * Get the parent Spring application context for the hosting environment. This will be used as the parent
+ * application context for implementation.spring components
+ * @return The parent application context
+ */
+ ApplicationContext getParentApplicationContext();
+
+ /**
+ * Set the root Spring application context. This is particually useful for Spring web integration where Spring
+ * creates WebApplicationContext and keeps it in the ServletContext
+ * @param parentApplicationContext The parent application context
+ */
+ void setParentApplicationContext(ApplicationContext parentApplicationContext);
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringContextWrapper.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringContextWrapper.java
new file mode 100644
index 0000000000..4b0ad72972
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/context/SpringContextWrapper.java
@@ -0,0 +1,130 @@
+/*
+ * 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.implementation.spring.context;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.implementation.spring.processor.ComponentNameAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.ConstructorAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.InitDestroyAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.PropertyAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.ReferenceAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.provider.ComponentWrapper;
+import org.apache.tuscany.sca.implementation.spring.provider.PropertyValueWrapper;
+import org.apache.tuscany.sca.implementation.spring.provider.SpringImplementationWrapper;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.UrlResource;
+
+/**
+ * This is the runtime side tie for the corresponding tuscany side stub class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the SpringContextStub class
+ * in the implementation-spring module for what the stub does.
+ */
+public class SpringContextWrapper {
+
+ private GenericApplicationContext springContext;
+ private SpringImplementationWrapper implementation;
+
+ public SpringContextWrapper(SpringImplementationWrapper implementation, List<URL> resource) {
+ this.implementation = implementation;
+ SCAParentApplicationContext scaParentContext = new SCAParentApplicationContext(implementation);
+ springContext = createApplicationContext(scaParentContext, resource);
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return springContext;
+ }
+
+ public void start() {
+ // Do refresh here to ensure that Spring Beans are not touched before the SCA config process is complete...
+ springContext.refresh();
+ springContext.start();
+ }
+
+ public void close() {
+ springContext.close();
+ if (springContext instanceof GenericApplicationContext) {
+ springContext.stop();
+ }
+ }
+
+ /**
+ * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean
+ */
+ private GenericApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext,
+ List<URL> resources) {
+
+ GenericApplicationContext appCtx =
+ new SCAGenericApplicationContext(scaParentContext, implementation.getClassLoader());
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx);
+
+ // REVIEW: [rfeng] How do we control the schema validation
+ xmlReader.setValidating(false);
+
+ for (URL resource : resources) {
+ xmlReader.loadBeanDefinitions(new UrlResource(resource));
+ }
+ xmlReader.setBeanClassLoader(implementation.getClassLoader());
+ includeAnnotationProcessors(appCtx.getBeanFactory());
+ return appCtx;
+
+ }
+
+ public Object getBean(String id) throws BeansException {
+ return springContext.getBean(id);
+ }
+
+ /**
+ * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean
+ */
+ private void includeAnnotationProcessors(ConfigurableListableBeanFactory beanFactory) {
+
+ // Processor to deal with @Init and @Destroy SCA Annotations
+ BeanPostProcessor initDestroyProcessor = new InitDestroyAnnotationProcessor();
+ beanFactory.addBeanPostProcessor(initDestroyProcessor);
+
+ // Processor to deal with @Reference SCA Annotations
+ ComponentWrapper component = implementation.getComponentWrapper();
+ BeanPostProcessor referenceProcessor = new ReferenceAnnotationProcessor(component);
+ beanFactory.addBeanPostProcessor(referenceProcessor);
+
+ // Processor to deal with @Property SCA Annotations
+ PropertyValueWrapper pvs = implementation.getPropertyValueWrapper();
+ BeanPostProcessor propertyProcessor = new PropertyAnnotationProcessor(pvs);
+ beanFactory.addBeanPostProcessor(propertyProcessor);
+
+ // Processor to deal with @ComponentName SCA Annotations
+ BeanPostProcessor componentNameProcessor =
+ new ComponentNameAnnotationProcessor(implementation.getComponentName());
+ beanFactory.addBeanPostProcessor(componentNameProcessor);
+
+ // Processor to deal with @Constructor SCA Annotations
+ BeanPostProcessor constructorProcessor = new ConstructorAnnotationProcessor();
+ beanFactory.addBeanPostProcessor(constructorProcessor);
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java
new file mode 100644
index 0000000000..75e00007f6
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java
@@ -0,0 +1,53 @@
+/*
+ * 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.implementation.spring.namespace;
+
+import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver;
+import org.springframework.beans.factory.xml.NamespaceHandler;
+
+/**
+ * Overrides the default Spring namespace resolver to automatically register
+ * {@link ScaNamespaceHandler} instead of requiring a value to be supplied in a
+ * Spring configuration
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCANamespaceHandlerResolver extends DefaultNamespaceHandlerResolver {
+ private static final String SCA_NAMESPACE = "http://www.springframework.org/schema/sca";
+
+ private ScaNamespaceHandler handler;
+
+ public SCANamespaceHandlerResolver(ClassLoader classLoader) {
+ super(classLoader);
+ handler = new ScaNamespaceHandler(/*componentType*/);
+ }
+
+ public SCANamespaceHandlerResolver(String handlerMappingsLocation, ClassLoader classLoader) {
+ super(classLoader, handlerMappingsLocation);
+ handler = new ScaNamespaceHandler(/*componentType*/);
+ }
+
+ @Override
+ public NamespaceHandler resolve(String namespaceUri) {
+ if (SCA_NAMESPACE.equals(namespaceUri)) {
+ return handler;
+ }
+ return super.resolve(namespaceUri);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java
new file mode 100644
index 0000000000..89c87ad1d1
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+/**
+ * Handler for the &lt;sca:&gt; namespace in an application context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaNamespaceHandler extends NamespaceHandlerSupport {
+
+ public ScaNamespaceHandler() {
+ }
+
+ @Override
+ public void init() {
+ registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser());
+ registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser());
+ registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser());
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java
new file mode 100644
index 0000000000..bff0aa84e0
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace;
+
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.context.SCAGenericApplicationContext;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:reference&gt; element
+ * @version $Rev$ $Date$
+ */
+public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAPropertyElement propertyElement =
+ new SpringSCAPropertyElement(element.getAttributeNS(null, "name"), element.getAttributeNS(null, "type"));
+ context.addSCAPropertyElement(propertyElement);
+ }
+ // do nothing, this is handled by Tuscany
+ return null;
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java
new file mode 100644
index 0000000000..6cb4978a47
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace;
+
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.context.SCAGenericApplicationContext;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:reference&gt; element
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAReferenceElement referenceElement =
+ new SpringSCAReferenceElement(element.getAttributeNS(null, "name"),
+ element.getAttributeNS(null, "type"));
+ referenceElement.setDefaultBean(element.getAttributeNS(null, "default"));
+ context.addSCAReferenceElement(referenceElement);
+ }
+
+ // do nothing, this is handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java
new file mode 100644
index 0000000000..e5eabd2a4b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace;
+
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+import org.apache.tuscany.sca.implementation.spring.context.SCAGenericApplicationContext;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:service/&gt; element
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAServiceElement serviceElement =
+ new SpringSCAServiceElement(element.getAttributeNS(null, "name"),
+ element.getAttributeNS(null, "target"));
+ serviceElement.setType(element.getAttributeNS(null, "type"));
+ context.addSCAServiceElement(serviceElement);
+ }
+ // do nothing, handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java
new file mode 100644
index 0000000000..68d49bbc24
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java
@@ -0,0 +1,151 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.ref.Reference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.oasisopen.sca.annotation.ComponentName;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class ComponentNameAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> componentNameAnnotationType = ComponentName.class;
+
+ private String componentName;
+
+ public ComponentNameAnnotationProcessor(String componentName) {
+ this.componentName = componentName;
+ }
+
+ /**
+ * Gets componentName annotation type.
+ */
+ protected Class<? extends Annotation> getComponentNameAnnotationType() {
+ return this.componentNameAnnotationType;
+ }
+
+ /**
+ * Sets componentName annotation type.
+ */
+ public void setComponentNameAnnotationType(Class<? extends Annotation> componentNameAnnotationType) {
+ Assert.notNull(componentNameAnnotationType, "'componentNameAnnotationType' type must not be null.");
+ this.componentNameAnnotationType = componentNameAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+ Annotation annotation = field.getAnnotation(getComponentNameAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on static fields");
+ }
+
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on private fields");
+ }
+
+ ReflectionUtils.makeAccessible(field);
+
+ if (field.getType().getName().equals("java.lang.String")) {
+ Object nameObj = componentName;
+ if (nameObj != null)
+ ReflectionUtils.setField(field, bean, nameObj);
+ } else {
+ throw new IllegalStateException(
+ "ComponentName annotation is supported only on java.lang.String field type.");
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+ Annotation annotation = method.getAnnotation(getComponentNameAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on static methods");
+ }
+
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on private methods");
+ }
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException(
+ "ComponentName annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+
+ if (pd.getPropertyType().getName().equals("java.lang.String")) {
+ Object nameObj = componentName;
+ if (nameObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {nameObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e);
+ }
+ }
+ } else {
+ throw new IllegalStateException(
+ "ComponentName annotation is supported only on java.lang.String field type.");
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java
new file mode 100644
index 0000000000..a52a85ff3a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java
@@ -0,0 +1,112 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
+import org.springframework.util.Assert;
+
+public class ConstructorAnnotationProcessor extends InstantiationAwareBeanPostProcessorAdapter {
+
+ private Class<? extends Annotation> constructorAnnotationType = org.oasisopen.sca.annotation.Constructor.class;
+
+ private Class<? extends Annotation> autowiredAnnotationType = Autowired.class;
+
+ public ConstructorAnnotationProcessor() {
+ // Default constructor.
+ }
+
+ /**
+ * Set the 'autowired' annotation type, to be used on constructors, fields,
+ * setter methods and arbitrary config methods.
+ */
+ public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
+ Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
+ this.autowiredAnnotationType = autowiredAnnotationType;
+ }
+
+ /**
+ * Return the 'autowired' annotation type.
+ */
+ protected Class<? extends Annotation> getAutowiredAnnotationType() {
+ return this.autowiredAnnotationType;
+ }
+
+ /**
+ * Return the 'constructor' annotation type.
+ */
+ protected Class<? extends Annotation> getConstructorAnnotationType() {
+ return this.constructorAnnotationType;
+ }
+
+ /**
+ * Sets the 'constructor' annotation type.
+ */
+ public void setConstructorAnnotationType(Class<? extends Annotation> constructorAnnotationType) {
+ Assert.notNull(constructorAnnotationType, "'constructorAnnotationType' type must not be null.");
+ this.constructorAnnotationType = constructorAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException {
+ /*Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
+ Method[] declaredMethods = beanClass.getDeclaredMethods();
+ List candidates = new ArrayList(declaredConstructors.length);
+
+ for (int i = 0; i < declaredMethods.length; i++) {
+ Method method = declaredMethods[i];
+ Annotation annotation = method.getAnnotation(getConstructorAnnotationType());
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Constructor annotation is not supported on static methods");
+ }
+
+ if (candidates.size() == 1) {
+ throw new IllegalStateException("Only one method is allowed to have constructor annotation in a bean: " + method);
+ }
+
+ candidates.add(method);
+ }
+ }
+
+ return (Constructor[]) candidates.toArray(new Constructor[candidates.size()]);*/
+ return null;
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java
new file mode 100644
index 0000000000..477582b1d3
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.lang.annotation.Annotation;
+
+import org.oasisopen.sca.annotation.Destroy;
+import org.oasisopen.sca.annotation.Init;
+import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
+
+public class InitDestroyAnnotationProcessor extends InitDestroyAnnotationBeanPostProcessor {
+
+ private static final long serialVersionUID = 0;
+
+ private Class<? extends Annotation> initAnnotationType = Init.class;
+ private Class<? extends Annotation> destroyAnnotationType = Destroy.class;
+
+ /**
+ * Gets init annotation type.
+ */
+ protected Class<? extends Annotation> getInitAnnotationType() {
+ return this.initAnnotationType;
+ }
+
+ /**
+ * Sets init annotation type.
+ */
+ /*
+ * public void setInitAnnotationType(Class<? extends Annotation>
+ * initAnnotationType) { Assert.notNull(initAnnotationType,
+ * "Init annotation type must not be null."); this.initAnnotationType =
+ * initAnnotationType; }
+ */
+
+ /**
+ * Gets destroy annotation type.
+ */
+ protected Class<? extends Annotation> getDestroyAnnotationType() {
+ return this.destroyAnnotationType;
+ }
+
+ /**
+ * Sets destroy annotation type.
+ */
+ /*
+ * public void setDestroyAnnotationType(Class<? extends Annotation>
+ * destroyAnnotationType) { Assert.notNull(destroyAnnotationType,
+ * "Destroy annotation type must not be null."); this.destroyAnnotationType
+ * = destroyAnnotationType; }
+ */
+
+ public InitDestroyAnnotationProcessor() {
+ // Set the @Init annotation type
+ setInitAnnotationType(initAnnotationType);
+
+ // Set the @Destroy annotation type
+ setDestroyAnnotationType(destroyAnnotationType);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java
new file mode 100644
index 0000000000..4763714a38
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java
@@ -0,0 +1,164 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tuscany.sca.implementation.spring.provider.PropertyValueWrapper;
+import org.oasisopen.sca.annotation.Property;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class PropertyAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> propertyAnnotationType = Property.class;
+
+ private PropertyValueWrapper propertyValue;
+
+ public PropertyAnnotationProcessor(PropertyValueWrapper propertyValue) {
+ this.propertyValue = propertyValue;
+ }
+
+ /**
+ * Gets property annotation type.
+ */
+ protected Class<? extends Annotation> getPropertyAnnotationType() {
+ return this.propertyAnnotationType;
+ }
+
+ /**
+ * Sets property annotation type.
+ */
+ public void setPropertyAnnotationType(Class<? extends Annotation> propertyAnnotationType) {
+ Assert.notNull(propertyAnnotationType, "'propertyAnnotationType' type must not be null.");
+ this.propertyAnnotationType = propertyAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Property} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+
+ Property annotation = (Property)method.getAnnotation(getPropertyAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on static methods");
+ }
+
+ /*
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on private methods");
+ }
+ */
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException("Property annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+ if (pd != null) {
+ String propName = annotation.name();
+ if ("".equals(propName)) {
+ injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), pd.getName()));
+ } else {
+ injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), propName));
+ }
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+
+ Property annotation = (Property)field.getAnnotation(getPropertyAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on static fields");
+ }
+
+ /*
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on private fields");
+ }
+ */
+
+ ReflectionUtils.makeAccessible(field);
+
+ Object propertyObj = null;
+ String propName = annotation.name();
+ if ("".equals(propName)) {
+ propertyObj = propertyValue.getPropertyObj(field.getType(), field.getName());
+ } else {
+ propertyObj = propertyValue.getPropertyObj(field.getType(), propName);
+ }
+
+ if (propertyObj != null)
+ ReflectionUtils.setField(field, bean, propertyObj);
+ }
+ }
+ });
+ }
+
+ public void injectProperty(Object bean, PropertyDescriptor pd, Object propertyObj) {
+
+ if (propertyObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {propertyObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting property: " + e.getMessage(), e);
+ }
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java
new file mode 100644
index 0000000000..ad79db840e
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java
@@ -0,0 +1,168 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tuscany.sca.implementation.spring.provider.ComponentWrapper;
+import org.oasisopen.sca.annotation.Reference;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class ReferenceAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> referenceAnnotationType = Reference.class;
+ private ComponentWrapper component;
+
+ public ReferenceAnnotationProcessor(ComponentWrapper component) {
+ this.component = component;
+ }
+
+ /**
+ * Gets referece annotation type.
+ */
+ protected Class<? extends Annotation> getReferenceAnnotationType() {
+ return this.referenceAnnotationType;
+ }
+
+ /**
+ * Sets referece annotation type.
+ */
+ public void setReferenceAnnotationType(Class<? extends Annotation> referenceAnnotationType) {
+ Assert.notNull(referenceAnnotationType, "'referenceAnnotationType' type must not be null.");
+ this.referenceAnnotationType = referenceAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+
+ Reference annotation = (Reference)method.getAnnotation(getReferenceAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on static methods");
+ }
+
+ /*
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on private methods");
+ }
+ */
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException(
+ "Reference annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+ if (pd != null) {
+ String refName = annotation.name();
+ if ("".equals(refName)) {
+ injectReference(bean, pd, pd.getName());
+ } else {
+ injectReference(bean, pd, refName);
+ }
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+
+ Reference annotation = (Reference)field.getAnnotation(getReferenceAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on static fields");
+ }
+
+ /*
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on private fields");
+ }
+ */
+
+ ReflectionUtils.makeAccessible(field);
+
+ Object referenceObj = null;
+ String refName = annotation.name();
+ if ("".equals(refName)) {
+ referenceObj = component.getService(field.getType(), field.getName());
+ } else {
+ referenceObj = component.getService(field.getType(), refName);
+ }
+
+ if (referenceObj != null)
+ ReflectionUtils.setField(field, bean, referenceObj);
+ }
+ }
+ });
+ }
+
+ /**
+ * Processes a property descriptor to inject a service.
+ */
+ public void injectReference(Object bean, PropertyDescriptor pd, String name) {
+
+ Object referenceObj = component.getService(pd.getPropertyType(), name);
+
+ if (referenceObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {referenceObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e);
+ }
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/SpringXMLBeanDefinitionLoaderImpl.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/SpringXMLBeanDefinitionLoaderImpl.java
new file mode 100644
index 0000000000..71feddb9f5
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/SpringXMLBeanDefinitionLoaderImpl.java
@@ -0,0 +1,78 @@
+/*
+ * 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.implementation.spring.processor;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+import org.apache.tuscany.sca.implementation.spring.context.SCAGenericApplicationContext;
+import org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.UrlResource;
+
+/**
+ * A tie that allows Tuscany to call Spring library to load the application context for the purpose of introspection
+ */
+public class SpringXMLBeanDefinitionLoaderImpl implements SpringXMLBeanDefinitionLoader {
+
+ private static SCAGenericApplicationContext createApplicationContext(Object scaParentContext,
+ ClassLoader classLoader,
+ List<URL> resources) {
+ if (classLoader == null) {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+
+ SCAGenericApplicationContext appCtx =
+ new SCAGenericApplicationContext((ApplicationContext)scaParentContext, classLoader);
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx);
+
+ // REVIEW: [rfeng] How do we control the schema validation
+ xmlReader.setValidating(false);
+
+ for (URL resource : resources) {
+ xmlReader.loadBeanDefinitions(new UrlResource(resource));
+ }
+
+ return appCtx;
+
+ }
+
+ @Override
+ public Object load(List<URL> resources,
+ List<SpringSCAServiceElement> serviceElements,
+ List<SpringSCAReferenceElement> referenceElements,
+ List<SpringSCAPropertyElement> propertyElements,
+ List<SpringBeanElement> beanElements,
+ ProcessorContext context) {
+ SCAGenericApplicationContext applicationContext = createApplicationContext(null, null, resources);
+ serviceElements.addAll(applicationContext.getServiceElements());
+ referenceElements.addAll(applicationContext.getReferenceElements());
+ propertyElements.addAll(applicationContext.getPropertyElements());
+ beanElements.addAll(applicationContext.getBeanElements());
+ return applicationContext;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java
new file mode 100644
index 0000000000..5bddd8a006
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/ComponentWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * 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.implementation.spring.provider;
+
+/**
+ * Wrapper for the Component
+ */
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+public class ComponentWrapper {
+
+ private RuntimeComponent component;
+
+ public ComponentWrapper(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ public Object getService(Class<?> type, String name) {
+ return component.getComponentContext().getService(type, name);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java
new file mode 100644
index 0000000000..eca1492081
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/PropertyValueWrapper.java
@@ -0,0 +1,50 @@
+/*
+ * 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.implementation.spring.provider;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Wrapper for PropertyValue
+ */
+public class PropertyValueWrapper {
+
+ private RuntimeComponent component;
+ private PropertyValueFactory propertyFactory;
+
+ public PropertyValueWrapper(RuntimeComponent component, PropertyValueFactory propertyFactory) {
+ this.component = component;
+ this.propertyFactory = propertyFactory;
+ }
+
+ public Object getPropertyObj(Class<?> type, String name) {
+ List<ComponentProperty> props = component.getProperties();
+ for (ComponentProperty prop : props) {
+ if (prop.getName().equals(name)) {
+ return propertyFactory.createPropertyValue(prop, type);
+ }
+ }
+ return null; // property name not found
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java
new file mode 100644
index 0000000000..db7831322a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProvider.java
@@ -0,0 +1,81 @@
+/*
+ * 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.implementation.spring.provider;
+
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.spring.context.SpringContextWrapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * A provider class for runtime Spring implementation instances
+ * @version $Rev$ $Date$
+ */
+public class SpringImplementationProvider implements ImplementationProvider {
+ private RuntimeComponent component;
+
+ // A Spring application context object
+ private SpringContextWrapper springContext;
+
+ /**
+ * Constructor for the provider - takes a component definition and a Spring implementation
+ * description
+ * @param component - the component in the assembly
+ * @param implementation - the implementation
+ */
+ public SpringImplementationProvider(RuntimeComponent component,
+ SpringImplementationWrapper implementation,
+ ApplicationContext parentApplicationContext,
+ ProxyFactory proxyService,
+ PropertyValueFactory propertyValueObjectFactory) {
+ super();
+ this.component = component;
+
+ springContext = new SpringContextWrapper(implementation, implementation.getResource());
+
+ } // end constructor
+
+ public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
+ return new SpringInvoker(component, springContext, service, operation);
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ /**
+ * Start this Spring implementation instance
+ */
+ public void start() {
+ springContext.start();
+ }
+
+ /**
+ * Stop this implementation instance
+ */
+ public void stop() {
+ springContext.close();
+ }
+
+} // end class SpringImplementationProvider
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java
new file mode 100644
index 0000000000..be16fb3251
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationProviderFactory.java
@@ -0,0 +1,78 @@
+/*
+ * 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.implementation.spring.provider;
+
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.implementation.spring.context.SpringApplicationContextAccessor;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * ImplementationProviderFactory for Spring implementation type
+ * @version $Rev$ $Date$
+ *
+ */
+public class SpringImplementationProviderFactory implements ImplementationProviderFactory<SpringImplementation> {
+ private ProxyFactory proxyFactory;
+ private PropertyValueFactory propertyFactory;
+ private SpringApplicationContextAccessor contextAccessor;
+
+ /**
+ * Simple constructor
+ *
+ */
+ public SpringImplementationProviderFactory(ExtensionPointRegistry registry) {
+ super();
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ contextAccessor = utilities.getUtility(SpringApplicationContextAccessor.class);
+ proxyFactory = ExtensibleProxyFactory.getInstance(registry);
+ propertyFactory = utilities.getUtility(PropertyValueFactory.class);
+ }
+
+ /**
+ * Returns a SpringImplementationProvider for a given component and Spring implementation
+ * @param component the component for which implementation instances are required
+ * @param implementation the Spring implementation with details of the component
+ * implementation
+ * @return the SpringImplementationProvider for the specified component
+ */
+ public ImplementationProvider createImplementationProvider(RuntimeComponent component,
+ SpringImplementation implementation) {
+ ApplicationContext parentApplicationContext =
+ (contextAccessor != null) ? contextAccessor.getParentApplicationContext() : null;
+ SpringImplementationWrapper tie =
+ new SpringImplementationWrapper(implementation, parentApplicationContext, component, propertyFactory);
+ return new SpringImplementationProvider(component, tie, parentApplicationContext, proxyFactory, propertyFactory);
+ }
+
+ /**
+ * Returns the class of the Spring implementation
+ */
+ public Class<SpringImplementation> getModelType() {
+ return SpringImplementation.class;
+ }
+
+} // end class SpringImplementationProviderFactory
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java
new file mode 100644
index 0000000000..e5593f5eaa
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringImplementationWrapper.java
@@ -0,0 +1,158 @@
+/*
+ * 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.implementation.spring.provider;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * Wrapper for SpringImplementation
+ */
+public class SpringImplementationWrapper {
+
+ private SpringImplementation implementation;
+ private ApplicationContext parentApplicationContext;
+ private RuntimeComponent component;
+ private PropertyValueFactory propertyFactory;
+
+ public SpringImplementationWrapper(SpringImplementation implementation,
+ ApplicationContext parentApplicationContext,
+ RuntimeComponent component,
+ PropertyValueFactory propertyFactory) {
+ this.implementation = implementation;
+ this.component = component;
+ this.propertyFactory = propertyFactory;
+ this.parentApplicationContext = parentApplicationContext;
+ }
+
+ public String getURI() {
+ return implementation.getURI();
+ }
+
+ public List<URL> getResource() {
+ return implementation.getResource();
+ }
+
+ public String getComponentName() {
+ return component.getName();
+ }
+
+ /**
+ * Method to create a Java Bean for a Property value
+ * @param <B> the class type of the Bean
+ * @param requiredType - a Class object for the required type
+ * @param name - the Property name
+ * @return - a Bean of the specified property, with value set
+ */
+ private <B> B getPropertyBean(Class<?> requiredType, String name) {
+ B propertyObject = null;
+ // Get the component's list of properties
+ List<ComponentProperty> props = component.getProperties();
+ for (ComponentProperty prop : props) {
+ if (prop.getName().equals(name)) {
+ // On finding the property, create a factory for it and create a Bean using
+ // the factory
+ propertyObject = (B)propertyFactory.createPropertyValue(prop, requiredType);
+ } // end if
+ } // end for
+
+ return propertyObject;
+ }
+
+ /**
+ * Creates a proxy Bean for a reference
+ * @param <B> the Business interface type for the reference
+ * @param businessInterface - the business interface as a Class
+ * @param referenceName - the name of the Reference
+ * @return an Bean of the type defined by <B>
+ */
+ private <B> B getService(Class<B> businessInterface, String referenceName) {
+ return component.getComponentContext().getService(businessInterface, referenceName);
+ }
+
+ /**
+ * Get a Bean for a reference or for a property.
+ *
+ * @param name - the name of the Bean required
+ * @param requiredType - the required type of the Bean (either a Java class or a Java interface)
+ * @return Object - a Bean which matches the requested bean
+ */
+ public Object getBean(String name, Class<?> requiredType) {
+ // The expectation is that the requested Bean is either a reference or a property
+ // from the Spring context
+ for (Reference reference : implementation.getReferences()) {
+ if (reference.getName().equals(name)) {
+ // Extract the Java interface for the reference (it can't be any other interface type
+ // for a Spring application context)
+ if (requiredType == null) {
+ JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface();
+ requiredType = javaInterface.getJavaClass();
+ }
+ // Create and return the proxy for the reference
+ return getService(requiredType, reference.getName());
+ } // end if
+ } // end for
+
+ // For a property, get the name and the required Java type and create a Bean
+ // of that type with the value inserted.
+ for (Property property : implementation.getProperties()) {
+ if (property.getName().equals(name)) {
+ if (requiredType == null) {
+ // The following code only deals with a subset of types and was superceded
+ // by the information from the implementation (which uses Classes as found
+ // in the Spring implementation itself.
+ //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() );
+ requiredType = implementation.getPropertyClass(name);
+ }
+ return getPropertyBean(requiredType, property.getName());
+ } // end if
+ } // end for
+ // TODO: NoSuchBeanException
+ // throw new RuntimeException("Unable to find Bean with name " + name);
+ return null;
+
+ } // end method getBean( String, Class )
+
+ public ComponentWrapper getComponentWrapper() {
+ return new ComponentWrapper(component);
+ }
+
+ public PropertyValueWrapper getPropertyValueWrapper() {
+ return new PropertyValueWrapper(component, propertyFactory);
+ }
+
+ public ClassLoader getClassLoader() {
+ return implementation.getClassLoader();
+ }
+
+ public ApplicationContext getParentApplicationContext() {
+ return parentApplicationContext;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java
new file mode 100644
index 0000000000..0e1d3f5b5a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvocationException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.implementation.spring.provider;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SpringInvocationException extends Exception {
+
+ private static final long serialVersionUID = -1157790036638157513L;
+
+ public SpringInvocationException(String msg) {
+ super(msg);
+ }
+
+ public SpringInvocationException(Throwable e) {
+ super(e);
+ }
+
+ public SpringInvocationException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java
new file mode 100644
index 0000000000..ea1d6e6755
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/SpringInvoker.java
@@ -0,0 +1,126 @@
+/*
+ * 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.implementation.spring.provider;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.implementation.spring.context.SpringContextWrapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Initial implementation of a Spring bean invoker
+ * @version $Rev$ $Date$
+ */
+public class SpringInvoker implements Invoker {
+
+ private Method theMethod = null;
+ private Object bean;
+ private SpringBeanElement beanElement;
+ private boolean badInvoker = false;
+
+ private SpringContextWrapper springContext;
+ private Operation operation;
+
+ /**
+ * SpringInvoker constructor
+ * @param component - the Spring component to invoke
+ * @param service - the service to invoke
+ * @param operation - the operation to invoke
+ */
+ public SpringInvoker(RuntimeComponent component,
+ SpringContextWrapper springContext,
+ RuntimeComponentService service,
+ Operation operation) {
+
+ this.springContext = springContext;
+ this.operation = operation;
+
+ // From the component and the service, identify the Spring Bean which is the target
+ SpringImplementation theImplementation = (SpringImplementation)component.getImplementation();
+ beanElement = theImplementation.getBeanFromService(service.getService());
+
+ if (beanElement == null) {
+ badInvoker = true;
+ return;
+ }
+
+ } // end constructor SpringInvoker
+
+ // Lazy-load the method to avoid timing problems with the Spring Context
+ private void setupMethod() throws SpringInvocationException {
+ try {
+ bean = springContext.getBean(beanElement.getId());
+ Class<?> beanClass = bean.getClass();
+ theMethod = JavaInterfaceUtil.findMethod(beanClass, operation);
+ //System.out.println("SpringInvoker - found method " + theMethod.getName() );
+ } catch (NoSuchMethodException e) {
+ throw new SpringInvocationException(e);
+ }
+ }
+
+ private Object doInvoke(Object payload) throws SpringInvocationException {
+ if (theMethod == null)
+ setupMethod();
+
+ if (badInvoker)
+ throw new SpringInvocationException("Spring invoker incorrectly configured");
+ // Invoke the method on the Spring bean using the payload, returning the results
+ try {
+ Object ret;
+
+ if (payload != null && !payload.getClass().isArray()) {
+ ret = theMethod.invoke(bean, payload);
+ } else {
+ ret = theMethod.invoke(bean, (Object[])payload);
+ }
+ return ret;
+ } catch (InvocationTargetException e) {
+ throw new SpringInvocationException("Spring invoker invoke method '" + theMethod.getName() + "' error.",
+ e.getCause());
+ } catch (Exception e) {
+ throw new SpringInvocationException("Spring invoker invoke method '" + theMethod.getName() + "' error.", e);
+ }
+
+ } // end method doInvoke
+
+ /**
+ * @param msg the message to invoke on the target bean
+ */
+ public Message invoke(Message msg) {
+ try {
+ Object resp = doInvoke(msg.getBody());
+ msg.setBody(resp);
+ } catch (SpringInvocationException e) {
+ msg.setFaultBody(e.getCause());
+ } catch (Throwable e) {
+ msg.setFaultBody(e);
+ }
+ //System.out.println("Spring Invoker - invoke called");
+ return msg;
+ } // end method invoke
+
+} // end class SpringInvoker
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader
new file mode 100644
index 0000000000..4c8fa09951
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader
@@ -0,0 +1,17 @@
+# 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.implementation.spring.processor.SpringXMLBeanDefinitionLoaderImpl;ranking=100 \ No newline at end of file
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
new file mode 100644
index 0000000000..e6c8d70fe1
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
@@ -0,0 +1,20 @@
+# 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.
+
+# Implementation class for the implementation extension
+org.apache.tuscany.sca.implementation.spring.provider.SpringImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.spring.SpringImplementation;ranking=100
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.handlers b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 0000000000..6d29e21024
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://www.springframework.org/schema/sca=org.apache.tuscany.sca.implementation.spring.namespace.ScaNamespaceHandler
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.schemas b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 0000000000..249cc21c13
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1 @@
+http\://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd=org/springframework/sca/xml/spring-sca.xsd
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/org/springframework/sca/xml/spring-sca.xsd b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/org/springframework/sca/xml/spring-sca.xsd
new file mode 100644
index 0000000000..dfa0b931f6
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-runtime/src/main/resources/org/springframework/sca/xml/spring-sca.xsd
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<xsd:schema xmlns="http://www.springframework.org/schema/sca" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ attributeFormDefault="unqualified" elementFormDefault="qualified"
+ targetNamespace="http://www.springframework.org/schema/sca">
+
+ <xsd:element name="reference">
+ <xsd:complexType>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="default" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="property">
+ <xsd:complexType>
+ <xsd:attribute name="id" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="service">
+ <xsd:complexType>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="target" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/LICENSE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..a41644caa8
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Spring Implementation Model
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Spring Implementation Model
+Import-Package: org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.assembly.impl;version="2.0.0",
+ org.apache.tuscany.sca.context;version="2.0.0",
+ org.apache.tuscany.sca.contribution.processor;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.core.invocation;version="2.0.0",
+ org.apache.tuscany.sca.implementation.spring;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java.impl;version="2.0.0",
+ org.apache.tuscany.sca.invocation;version="2.0.0",
+ org.apache.tuscany.sca.provider;version="2.0.0",
+ org.apache.tuscany.sca.runtime;version="2.0.0",
+ org.oasisopen.sca;version="2.0.0"
+Bundle-SymbolicName: org.apache.tuscany.sca.implementation.spring.stub
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/NOTICE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/NOTICE
new file mode 100644
index 0000000000..1325efd8bf
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/README b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/README
new file mode 100644
index 0000000000..e1b1f98fe0
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/README
@@ -0,0 +1,9 @@
+Note that the implementation spring modules have a different structure from other extensions.
+
+The aim is to have the Tuscany runtime embedded in a container with the Tuscany classes hidden
+from user applications and the Spring jar's packaged with the application. That means that the
+Tuscany code has no visibilty of the Spring classes and visa-versa. To implement that the
+implementation-spring module has no dependencies on Spring and the implementation-spring-runtime
+module has no dependencies on Tuscany (other than the sca-api), and reflection is used to call
+methods between the modules.
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/pom.xml
new file mode 100644
index 0000000000..f459f1755c
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-implementation-spring-stub</artifactId>
+ <name>Apache Tuscany SCA Spring Implementation Runtime Stub</name>
+
+ <dependencies>
+
+ <!-- **************************************** -->
+ <!-- * * -->
+ <!-- * DONT ADD ANY SPRING DEPENDENCIES!!! * -->
+ <!-- * * -->
+ <!-- * See the README for details why not * -->
+ <!-- * * -->
+ <!-- * * -->
+ <!-- **************************************** -->
+
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-spring</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/stub/SpringXMLBeanDefinitionLoaderStub.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/stub/SpringXMLBeanDefinitionLoaderStub.java
new file mode 100644
index 0000000000..f34dfb8ceb
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/stub/SpringXMLBeanDefinitionLoaderStub.java
@@ -0,0 +1,92 @@
+/*
+ * 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.implementation.spring.processor.stub;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+import org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * This is the Tuscany side stub for the corresponding runtime tie class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the SpringContextTie class
+ * in the implementation-spring-runtime module for what the tie does.
+ */
+public class SpringXMLBeanDefinitionLoaderStub implements SpringXMLBeanDefinitionLoader {
+ private final static String TIE = "org.apache.tuscany.sca.implementation.spring.processor.tie.SpringXMLLoaderTie";
+
+ private static Method createApplicationContext;
+
+ public SpringXMLBeanDefinitionLoaderStub() throws Exception {
+ synchronized (SpringXMLBeanDefinitionLoaderStub.class) {
+ if (createApplicationContext == null) {
+ Class<?> tieClass = Class.forName(TIE, false, Thread.currentThread().getContextClassLoader());
+ createApplicationContext =
+ tieClass.getMethod("createApplicationContext", Object.class, ClassLoader.class, List.class);
+ }
+ }
+ }
+
+ public Object createApplicationContext(Object scaParentContext, ClassLoader classLoader, List<URL> resources)
+ throws Exception {
+ return createApplicationContext.invoke(null, scaParentContext, classLoader, resources);
+ }
+
+ public Object load(List<URL> resources,
+ List<SpringSCAServiceElement> serviceElements,
+ List<SpringSCAReferenceElement> referenceElements,
+ List<SpringSCAPropertyElement> propertyElements,
+ List<SpringBeanElement> beanElements,
+ ProcessorContext context) {
+ try {
+ Object appContext =
+ createApplicationContext(null, Thread.currentThread().getContextClassLoader(), resources);
+ Class<?> cls = appContext.getClass();
+ Method method = cls.getMethod("getElements", Class.class);
+ SpringSCAServiceElement[] serviceArray =
+ (SpringSCAServiceElement[])method.invoke(appContext, SpringSCAServiceElement.class);
+ serviceElements.addAll(Arrays.asList(serviceArray));
+
+ SpringSCAReferenceElement[] referenceArray =
+ (SpringSCAReferenceElement[])method.invoke(appContext, SpringSCAReferenceElement.class);
+ referenceElements.addAll(Arrays.asList(referenceArray));
+
+ SpringSCAPropertyElement[] propertyArray =
+ (SpringSCAPropertyElement[])method.invoke(appContext, SpringSCAPropertyElement.class);
+ propertyElements.addAll(Arrays.asList(propertyArray));
+
+ SpringBeanElement[] beanArray = (SpringBeanElement[])method.invoke(appContext, SpringBeanElement.class);
+ beanElements.addAll(Arrays.asList(beanArray));
+
+ return appContext;
+ } catch (Throwable e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/ComponentTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/ComponentTie.java
new file mode 100644
index 0000000000..882aa587e5
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/ComponentTie.java
@@ -0,0 +1,41 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+/**
+ * This is the Tuscany side tie for the corresponding Spring runtime side stub class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the ComponentStub class
+ * in the implementation-spring-runtime module for what the stub does.
+ */
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+public class ComponentTie {
+
+ private RuntimeComponent component;
+
+ public ComponentTie(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ public Object getService(Class<?> type, String name) {
+ return component.getComponentContext().getService(type, name);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/PropertyValueTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/PropertyValueTie.java
new file mode 100644
index 0000000000..5e0c5263c2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/PropertyValueTie.java
@@ -0,0 +1,53 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * This is the Tuscany side tie for the corresponding Spring runtime side stub class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the PropertyValueStub class
+ * in the implementation-spring-runtime module for what the stub does.
+ */
+public class PropertyValueTie {
+
+ private RuntimeComponent component;
+ private PropertyValueFactory propertyFactory;
+
+ public PropertyValueTie(RuntimeComponent component, PropertyValueFactory propertyFactory) {
+ this.component = component;
+ this.propertyFactory = propertyFactory;
+ }
+
+ public Object getPropertyObj(Class<?> type, String name) {
+ List<ComponentProperty> props = component.getProperties();
+ for (ComponentProperty prop : props) {
+ if (prop.getName().equals(name)) {
+ return propertyFactory.createPropertyValue(prop, type);
+ }
+ }
+ return null; // property name not found
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringApplicationContextAccessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringApplicationContextAccessor.java
new file mode 100644
index 0000000000..84a65bcf17
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringApplicationContextAccessor.java
@@ -0,0 +1,39 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+/**
+ * A utility to receive the parent Spring application context
+ */
+public interface SpringApplicationContextAccessor {
+ /**
+ * Get the parent Spring application context for the hosting environment. This will be used as the parent
+ * application context for implementation.spring components
+ * @return The parent application context
+ */
+ Object getParentApplicationContext();
+
+ /**
+ * Set the root Spring application context. This is particually useful for Spring web integration where Spring
+ * creates WebApplicationContext and keeps it in the ServletContext
+ * @param parentApplicationContext The parent application context
+ */
+ void setParentApplicationContext(Object parentApplicationContext);
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringContextStub.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringContextStub.java
new file mode 100644
index 0000000000..062da4b2d2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringContextStub.java
@@ -0,0 +1,142 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * This is the Tuscany side stub for the corresponding runtime tie class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the SpringContextTie class
+ * in the implementation-spring-runtime module for what the tie does.
+ */
+public class SpringContextStub {
+
+ private static final String SPRING_IMPLEMENTATION_STUB =
+ "org.apache.tuscany.sca.implementation.spring.context.tie.SpringImplementationStub";
+ private static final String SPRING_CONTEXT_TIE =
+ "org.apache.tuscany.sca.implementation.spring.context.tie.SpringContextTie";
+ private Object tie;
+ private Method startMethod;
+ private Method closeMethod;
+ private Method getBeanMethod;
+
+ public SpringContextStub(RuntimeComponent component,
+ SpringImplementation implementation,
+ Object parentApplicationContext,
+ ProxyFactory proxyService,
+ PropertyValueFactory propertyValueObjectFactory) {
+
+ initTie(component, implementation, parentApplicationContext, propertyValueObjectFactory);
+
+ }
+
+ private void initTie(RuntimeComponent component,
+ SpringImplementation implementation,
+ Object parentApplicationContext,
+ PropertyValueFactory propertyValueObjectFactory) {
+
+ // TODO: what class loader to use?
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ try {
+
+ Class<?> stubClass = Class.forName(SPRING_IMPLEMENTATION_STUB, true, cl);
+ Constructor<?> stubConstructor = stubClass.getConstructor(new Class<?>[] {Object.class});
+ Object stub =
+ stubConstructor.newInstance(new SpringImplementationTie(implementation, parentApplicationContext,
+ component, propertyValueObjectFactory));
+
+ Class<?> tieClass = Class.forName(SPRING_CONTEXT_TIE, true, cl);
+ Constructor<?> tieConstructor = tieClass.getConstructor(new Class<?>[] {stubClass, List.class});
+ this.tie = tieConstructor.newInstance(stub, implementation.getResource());
+
+ this.startMethod = tieClass.getMethod("start");
+ this.closeMethod = tieClass.getMethod("close");
+ this.getBeanMethod = tieClass.getMethod("getBean", String.class);
+
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (SecurityException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void start() {
+ try {
+ startMethod.invoke(tie);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void close() {
+ try {
+ closeMethod.invoke(tie);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getBean(String id) throws SpringInvocationException {
+ try {
+
+ return getBeanMethod.invoke(tie, id);
+
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProvider.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProvider.java
new file mode 100644
index 0000000000..e0207b9f12
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProvider.java
@@ -0,0 +1,80 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * A provider class for runtime Spring implementation instances
+ * @version $Rev$ $Date$
+ */
+public class SpringImplementationProvider implements ImplementationProvider {
+ private RuntimeComponent component;
+
+ // A Spring application context object
+ private SpringContextStub springContext;
+
+ /**
+ * Constructor for the provider - takes a component definition and a Spring implementation
+ * description
+ * @param component - the component in the assembly
+ * @param implementation - the implementation
+ */
+ public SpringImplementationProvider(RuntimeComponent component,
+ SpringImplementation implementation,
+ Object parentApplicationContext,
+ ProxyFactory proxyService,
+ PropertyValueFactory propertyValueObjectFactory) {
+ super();
+ this.component = component;
+
+ springContext = new SpringContextStub(component, implementation, parentApplicationContext, proxyService, propertyValueObjectFactory);
+
+ } // end constructor
+
+ public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
+ return new SpringInvoker(component, springContext, service, operation);
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ /**
+ * Start this Spring implementation instance
+ */
+ public void start() {
+ springContext.start();
+ }
+
+ /**
+ * Stop this implementation instance
+ */
+ public void stop() {
+ springContext.close();
+ }
+
+} // end class SpringImplementationProvider
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProviderFactory.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProviderFactory.java
new file mode 100644
index 0000000000..d402ff2eb6
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationProviderFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * ImplementationProviderFactory for Spring implementation type
+ * @version $Rev$ $Date$
+ *
+ */
+public class SpringImplementationProviderFactory implements ImplementationProviderFactory<SpringImplementation> {
+ private ProxyFactory proxyFactory;
+ private PropertyValueFactory propertyFactory;
+ private SpringApplicationContextAccessor contextAccessor;
+
+ /**
+ * Simple constructor
+ *
+ */
+ public SpringImplementationProviderFactory(ExtensionPointRegistry registry) {
+ super();
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ contextAccessor = utilities.getUtility(SpringApplicationContextAccessor.class);
+ proxyFactory = ExtensibleProxyFactory.getInstance(registry);
+ propertyFactory = utilities.getUtility(PropertyValueFactory.class);
+ }
+
+ /**
+ * Returns a SpringImplementationProvider for a given component and Spring implementation
+ * @param component the component for which implementation instances are required
+ * @param implementation the Spring implementation with details of the component
+ * implementation
+ * @return the SpringImplementationProvider for the specified component
+ */
+ public ImplementationProvider createImplementationProvider(RuntimeComponent component,
+ SpringImplementation implementation) {
+ Object parentApplicationContext =
+ (contextAccessor != null) ? contextAccessor.getParentApplicationContext() : null;
+ return new SpringImplementationProvider(component, implementation, parentApplicationContext, proxyFactory,
+ propertyFactory);
+ }
+
+ /**
+ * Returns the class of the Spring implementation
+ */
+ public Class<SpringImplementation> getModelType() {
+ return SpringImplementation.class;
+ }
+
+} // end class SpringImplementationProviderFactory
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationTie.java
new file mode 100644
index 0000000000..fc75faed21
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringImplementationTie.java
@@ -0,0 +1,156 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * This is the Tuscany side tie for the corresponding runtime stub class.
+ * It enables the Sping code in the runtime module to invoke methods on a
+ * Tuscany SpringImplementation without the Spring runtime module
+ * needing to know about any Tuscany classes. See the SpringImplementationStub class
+ * in the implementation-spring-runtime module for what the stub does.
+ */
+public class SpringImplementationTie {
+
+ private SpringImplementation implementation;
+ private Object parentApplicationContext;
+ private RuntimeComponent component;
+ private PropertyValueFactory propertyFactory;
+
+ public SpringImplementationTie(SpringImplementation implementation,
+ Object parentApplicationContext,
+ RuntimeComponent component,
+ PropertyValueFactory propertyFactory) {
+ this.implementation = implementation;
+ this.component = component;
+ this.propertyFactory = propertyFactory;
+ this.parentApplicationContext = parentApplicationContext;
+ }
+
+ public String getURI() {
+ return implementation.getURI();
+ }
+
+ public String getComponentName() {
+ return component.getName();
+ }
+
+ /**
+ * Method to create a Java Bean for a Property value
+ * @param <B> the class type of the Bean
+ * @param requiredType - a Class object for the required type
+ * @param name - the Property name
+ * @return - a Bean of the specified property, with value set
+ */
+ private <B> B getPropertyBean(Class<?> requiredType, String name) {
+ B propertyObject = null;
+ // Get the component's list of properties
+ List<ComponentProperty> props = component.getProperties();
+ for (ComponentProperty prop : props) {
+ if (prop.getName().equals(name)) {
+ // On finding the property, create a factory for it and create a Bean using
+ // the factory
+ propertyObject = (B) propertyFactory.createPropertyValue(prop, requiredType);
+ } // end if
+ } // end for
+
+ return propertyObject;
+ }
+
+ /**
+ * Creates a proxy Bean for a reference
+ * @param <B> the Business interface type for the reference
+ * @param businessInterface - the business interface as a Class
+ * @param referenceName - the name of the Reference
+ * @return an Bean of the type defined by <B>
+ */
+ private <B> B getService(Class<B> businessInterface, String referenceName) {
+ return component.getComponentContext().getService(businessInterface, referenceName);
+ }
+
+ /**
+ * Get a Bean for a reference or for a property.
+ *
+ * @param name - the name of the Bean required
+ * @param requiredType - the required type of the Bean (either a Java class or a Java interface)
+ * @return Object - a Bean which matches the requested bean
+ */
+ public Object getBean(String name, Class<?> requiredType) {
+ // The expectation is that the requested Bean is either a reference or a property
+ // from the Spring context
+ for (Reference reference : implementation.getReferences()) {
+ if (reference.getName().equals(name)) {
+ // Extract the Java interface for the reference (it can't be any other interface type
+ // for a Spring application context)
+ if (requiredType == null) {
+ JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface();
+ requiredType = javaInterface.getJavaClass();
+ }
+ // Create and return the proxy for the reference
+ return getService(requiredType, reference.getName());
+ } // end if
+ } // end for
+
+ // For a property, get the name and the required Java type and create a Bean
+ // of that type with the value inserted.
+ for (Property property : implementation.getProperties()) {
+ if (property.getName().equals(name)) {
+ if (requiredType == null) {
+ // The following code only deals with a subset of types and was superceded
+ // by the information from the implementation (which uses Classes as found
+ // in the Spring implementation itself.
+ //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() );
+ requiredType = implementation.getPropertyClass(name);
+ }
+ return getPropertyBean(requiredType, property.getName());
+ } // end if
+ } // end for
+ // TODO: NoSuchBeanException
+ // throw new RuntimeException("Unable to find Bean with name " + name);
+ return null;
+
+ } // end method getBean( String, Class )
+
+ public Object getComponentTie() {
+ return new ComponentTie(component);
+ }
+
+ public Object getPropertyValueTie() {
+ return new PropertyValueTie(component, propertyFactory);
+ }
+
+ public ClassLoader getClassLoader() {
+ return implementation.getClassLoader();
+ }
+
+ public Object getParentApplicationContext() {
+ return parentApplicationContext;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvocationException.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvocationException.java
new file mode 100644
index 0000000000..909a640563
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvocationException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SpringInvocationException extends Exception {
+
+ private static final long serialVersionUID = -1157790036638157513L;
+
+ public SpringInvocationException(String msg) {
+ super(msg);
+ }
+
+ public SpringInvocationException(Throwable e) {
+ super(e);
+ }
+
+ public SpringInvocationException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvoker.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvoker.java
new file mode 100644
index 0000000000..7d73eb5e6a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/java/org/apache/tuscany/sca/implementation/spring/provider/stub/SpringInvoker.java
@@ -0,0 +1,125 @@
+/*
+ * 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.implementation.spring.provider.stub;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Initial implementation of a Spring bean invoker
+ * @version $Rev$ $Date$
+ */
+public class SpringInvoker implements Invoker {
+
+ private Method theMethod = null;
+ private Object bean;
+ private SpringBeanElement beanElement;
+ private boolean badInvoker = false;
+
+ private SpringContextStub springContext;
+ private Operation operation;
+
+ /**
+ * SpringInvoker constructor
+ * @param component - the Spring component to invoke
+ * @param service - the service to invoke
+ * @param operation - the operation to invoke
+ */
+ public SpringInvoker(RuntimeComponent component,
+ SpringContextStub springContext,
+ RuntimeComponentService service,
+ Operation operation) {
+
+ this.springContext = springContext;
+ this.operation = operation;
+
+ // From the component and the service, identify the Spring Bean which is the target
+ SpringImplementation theImplementation = (SpringImplementation)component.getImplementation();
+ beanElement = theImplementation.getBeanFromService(service.getService());
+
+ if (beanElement == null) {
+ badInvoker = true;
+ return;
+ }
+
+ } // end constructor SpringInvoker
+
+ // Lazy-load the method to avoid timing problems with the Spring Context
+ private void setupMethod() throws SpringInvocationException {
+ try {
+ bean = springContext.getBean(beanElement.getId());
+ Class<?> beanClass = bean.getClass();
+ theMethod = JavaInterfaceUtil.findMethod(beanClass, operation);
+ //System.out.println("SpringInvoker - found method " + theMethod.getName() );
+ } catch (NoSuchMethodException e) {
+ throw new SpringInvocationException(e);
+ }
+ }
+
+ private Object doInvoke(Object payload) throws SpringInvocationException {
+ if (theMethod == null)
+ setupMethod();
+
+ if (badInvoker)
+ throw new SpringInvocationException("Spring invoker incorrectly configured");
+ // Invoke the method on the Spring bean using the payload, returning the results
+ try {
+ Object ret;
+
+ if (payload != null && !payload.getClass().isArray()) {
+ ret = theMethod.invoke(bean, payload);
+ } else {
+ ret = theMethod.invoke(bean, (Object[])payload);
+ }
+ return ret;
+ } catch (InvocationTargetException e) {
+ throw new SpringInvocationException("Spring invoker invoke method '" + theMethod.getName() + "' error.",
+ e.getCause());
+ } catch (Exception e) {
+ throw new SpringInvocationException("Spring invoker invoke method '" + theMethod.getName() + "' error.", e);
+ }
+
+ } // end method doInvoke
+
+ /**
+ * @param msg the message to invoke on the target bean
+ */
+ public Message invoke(Message msg) {
+ try {
+ Object resp = doInvoke(msg.getBody());
+ msg.setBody(resp);
+ } catch (SpringInvocationException e) {
+ msg.setFaultBody(e.getCause());
+ } catch (Throwable e) {
+ msg.setFaultBody(e);
+ }
+ //System.out.println("Spring Invoker - invoke called");
+ return msg;
+ } // end method invoke
+
+} // end class SpringInvoker
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader
new file mode 100644
index 0000000000..0a46baa13b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader
@@ -0,0 +1,17 @@
+# 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.implementation.spring.processor.stub.SpringXMLBeanDefinitionLoaderStub;ranking=50 \ No newline at end of file
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
new file mode 100644
index 0000000000..e037ea60f5
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-stub/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
@@ -0,0 +1,20 @@
+# 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.
+
+# Implementation class for the implementation extension
+org.apache.tuscany.sca.implementation.spring.provider.stub.SpringImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.spring.SpringImplementation;ranking=50
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/LICENSE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..5d452244d2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-SymbolicName: org.apache.tuscany.sca.implementation.spring.tie
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
+Import-Package: org.oasisopen.sca;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0",
+ org.springframework.beans;version="3.0.2.RELEASE",
+ org.springframework.beans.factory;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.annotation;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.config;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.support;version="3.0.2.RELEASE",
+ org.springframework.beans.factory.xml;version="3.0.2.RELEASE",
+ org.springframework.context;version="3.0.2.RELEASE",
+ org.springframework.context.support;version="3.0.2.RELEASE",
+ org.springframework.core;version="3.0.2.RELEASE",
+ org.springframework.core.io;version="3.0.2.RELEASE",
+ org.springframework.util;version="3.0.2.RELEASE"
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/NOTICE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/NOTICE
new file mode 100644
index 0000000000..1325efd8bf
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/README b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/README
new file mode 100644
index 0000000000..e1b1f98fe0
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/README
@@ -0,0 +1,9 @@
+Note that the implementation spring modules have a different structure from other extensions.
+
+The aim is to have the Tuscany runtime embedded in a container with the Tuscany classes hidden
+from user applications and the Spring jar's packaged with the application. That means that the
+Tuscany code has no visibilty of the Spring classes and visa-versa. To implement that the
+implementation-spring module has no dependencies on Spring and the implementation-spring-runtime
+module has no dependencies on Tuscany (other than the sca-api), and reflection is used to call
+methods between the modules.
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/pom.xml
new file mode 100644
index 0000000000..a30109d442
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-implementation-spring-tie</artifactId>
+ <name>Apache Tuscany SCA Spring Implementation Runtime Tie</name>
+
+ <dependencies>
+
+ <!-- **************************************** -->
+ <!-- * * -->
+ <!-- * DONT ADD ANY TUSCANY DEPENDENCIES!!! * -->
+ <!-- * * -->
+ <!-- * See the README for details why not * -->
+ <!-- * * -->
+ <!-- * * -->
+ <!-- **************************************** -->
+
+ <!-- SCA API dependency -->
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-sca-api</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Spring dependencies... -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java
new file mode 100644
index 0000000000..69e2ee2865
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java
@@ -0,0 +1,176 @@
+/*
+ * 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.implementation.spring.context.tie;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringConstructorArgElement;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringElementTie;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAServiceElement;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanReference;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
+import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+
+public class SCAGenericApplicationContext extends GenericApplicationContext {
+
+ private ClassLoader classloader = null;
+ private List<SpringSCAPropertyElement> propertyElements = new ArrayList<SpringSCAPropertyElement>();
+ private List<SpringSCAServiceElement> serviceElements = new ArrayList<SpringSCAServiceElement>();
+ private List<SpringSCAReferenceElement> referenceElements = new ArrayList<SpringSCAReferenceElement>();
+ private List<SpringBeanElement> beanElements;
+
+ public SCAGenericApplicationContext(DefaultListableBeanFactory beanFactory,
+ ApplicationContext parent,
+ ClassLoader classloader) {
+ super(beanFactory, parent);
+ this.classloader = classloader;
+ }
+
+ public SCAGenericApplicationContext(ApplicationContext parent, ClassLoader classloader) {
+ super(parent);
+ this.classloader = classloader;
+ }
+
+ @Override
+ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
+ beanFactory.setBeanClassLoader(classloader);
+ }
+
+ public void addSCAPropertyElement(SpringSCAPropertyElement propertyElement) {
+ propertyElements.add(propertyElement);
+ }
+
+ public void addSCAServiceElement(SpringSCAServiceElement serviceElement) {
+ serviceElements.add(serviceElement);
+ }
+
+ public void addSCAReferenceElement(SpringSCAReferenceElement referenceElement) {
+ referenceElements.add(referenceElement);
+ }
+
+ public synchronized List<SpringBeanElement> getBeanElements() {
+ if (beanElements == null) {
+ beanElements = new ArrayList<SpringBeanElement>();
+ for (String name : getBeanDefinitionNames()) {
+ BeanDefinition def = getBeanDefinition(name);
+ SpringBeanElement beanElement = new SpringBeanElement(name, def.getBeanClassName());
+ beanElements.add(beanElement);
+ beanElement.setAbstractBean(def.isAbstract());
+ beanElement.setFactoryBeanAttribute(def.getFactoryBeanName() != null);
+ beanElement.setFactoryMethodAttribute(def.getFactoryMethodName() != null);
+ beanElement.setParentAttribute(def.getParentName() != null);
+ beanElement.setInnerBean(beanElement.getId() == null);
+
+ ConstructorArgumentValues args = def.getConstructorArgumentValues();
+ for (Map.Entry<Integer, ValueHolder> e: args.getIndexedArgumentValues().entrySet()) {
+ ValueHolder holder = e.getValue();
+ SpringConstructorArgElement arg = new SpringConstructorArgElement(holder.getType());
+ arg.setIndex(e.getKey());
+ beanElement.addCustructorArgs(arg);
+ }
+
+ MutablePropertyValues values = def.getPropertyValues();
+ for (PropertyValue p : values.getPropertyValueList()) {
+ SpringPropertyElement propertyElement = new SpringPropertyElement(p.getName());
+ Object value = p.getValue();
+ configurePropertyElement(propertyElement, value);
+ beanElement.getProperties().add(propertyElement);
+ }
+ }
+ }
+ return beanElements;
+ }
+
+ public void configurePropertyElement(SpringPropertyElement propertyElement, Object value) {
+ if (value instanceof BeanReference) {
+ BeanReference beanRef = (BeanReference)value;
+ propertyElement.addRef(beanRef.getBeanName());
+ } else if (value instanceof Collection) {
+ Collection collection = (Collection)value;
+ for (Object item : collection) {
+ configurePropertyElement(propertyElement, item);
+ }
+ } else if (value instanceof TypedStringValue) {
+ TypedStringValue stringValue = (TypedStringValue)value;
+ propertyElement.addValue(stringValue.getValue());
+ } else {
+ if (value != null) {
+ propertyElement.addValue(value.toString());
+ }
+ }
+ }
+
+ public List<SpringSCAPropertyElement> getPropertyElements() {
+ return propertyElements;
+ }
+
+ public List<SpringSCAServiceElement> getServiceElements() {
+ return serviceElements;
+ }
+
+ public List<SpringSCAReferenceElement> getReferenceElements() {
+ return referenceElements;
+ }
+
+ public <T> T[] getElements(Class<T> type) {
+ if (type.getSimpleName().equals(SpringSCAPropertyElement.class.getSimpleName())) {
+ T[] elements = (T[])Array.newInstance(type, getPropertyElements().size());
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = SpringElementTie.copy(getPropertyElements().get(i), type, type);
+ }
+ return elements;
+ } else if (type.getSimpleName().equals(SpringSCAReferenceElement.class.getSimpleName())) {
+ T[] elements = (T[])Array.newInstance(type, getReferenceElements().size());
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = SpringElementTie.copy(getReferenceElements().get(i), type, type);
+ }
+ return elements;
+ } else if (type.getSimpleName().equals(SpringSCAServiceElement.class.getSimpleName())) {
+ T[] elements = (T[])Array.newInstance(type, getServiceElements().size());
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = SpringElementTie.copy(getServiceElements().get(i), type, type);
+ }
+ return elements;
+ } else if (type.getSimpleName().equals(SpringBeanElement.class.getSimpleName())) {
+ T[] elements = (T[])Array.newInstance(type, getBeanElements().size());
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = SpringElementTie.copy(getBeanElements().get(i), type, type);
+ }
+ return elements;
+ } else {
+ throw new IllegalArgumentException(type + " is not supported");
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java
new file mode 100644
index 0000000000..d2b35ce74e
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java
@@ -0,0 +1,212 @@
+/*
+ * 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.implementation.spring.context.tie;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+import java.util.Map;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.MessageSourceResolvable;
+import org.springframework.context.NoSuchMessageException;
+import org.springframework.core.io.Resource;
+
+/**
+ * A Spring ParentApplicationContext for a given Spring Implementation
+ *
+ * The Parent application context is responsible for handling those entities within a Spring
+ * application context that actually belong to SCA rather than to Spring. The principal things
+ * are Properties and References. These may be present either through explicit <sca:property/>
+ * and <sca:reference/> elements in the application context or they may be implicit through
+ * unresolved Spring bean <property.../> elements. In either case, it is the Parent application
+ * context that must provide Spring beans that correspond to the property or reference, as derived
+ * from the SCA composite in which the Spring application context is an implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCAParentApplicationContext implements ApplicationContext {
+
+ // The Spring implementation for which this is the parent application context
+ private SpringImplementationStub implementation;
+
+ private static final String[] EMPTY_ARRAY = new String[0];
+
+ public SCAParentApplicationContext(SpringImplementationStub implementation) {
+ this.implementation = implementation;
+ } // end constructor
+
+ public Object getBean(String name) throws BeansException {
+ return getBean(name, (Class)null);
+ }
+
+ /**
+ * Get a Bean for a reference or for a property.
+ *
+ * @param name - the name of the Bean required
+ * @param requiredType - the required type of the Bean (either a Java class or a Java interface)
+ * @return Object - a Bean which matches the requested bean
+ */
+ public Object getBean(String name, Class requiredType) throws BeansException {
+ Object bean = implementation.getBean(name, requiredType);
+ if (bean == null && getParent() != null) {
+ bean = getParent().getBean(name, requiredType);
+ }
+ if (bean == null) {
+ throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name);
+ } else {
+ return bean;
+ }
+ } // end method getBean( String, Class )
+
+ public Object getBean(String name, Object[] args) throws BeansException {
+ return getBean(name, ((Class)null));
+ }
+
+ public <T> T getBean(Class<T> clazz) throws BeansException {
+ return clazz.cast(getBean(clazz.getName(), clazz));
+ }
+
+ public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> clazz) throws BeansException {
+ return null;
+ }
+
+ public <A extends Annotation> A findAnnotationOnBean(String arg0, Class<A> clazz) {
+ return null;
+ }
+
+ public boolean containsBean(String name) {
+ // TODO
+ return false;
+ }
+
+ public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+ // TODO
+ return false;
+ }
+
+ public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Class getType(String name) throws NoSuchBeanDefinitionException {
+ return null;
+ }
+
+ public String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+ return EMPTY_ARRAY;
+ }
+
+ public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
+ return null;
+ }
+
+ public String getId() {
+ return this.toString();
+ }
+
+ public String getDisplayName() {
+ return implementation.getURI();
+ }
+
+ public long getStartupDate() {
+ return 0;
+ }
+
+ public boolean containsBeanDefinition(String beanName) {
+ return false;
+ }
+
+ public int getBeanDefinitionCount() {
+ return 0;
+ }
+
+ public String[] getBeanDefinitionNames() {
+ return new String[0];
+ }
+
+ public String[] getBeanNamesForType(Class type) {
+ return new String[0];
+ }
+
+ public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) {
+ return new String[0];
+ }
+
+ public Map getBeansOfType(Class type) throws BeansException {
+ return null;
+ }
+
+ public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException {
+ return null;
+ }
+
+ public boolean isPrototype(String theString) {
+ return false;
+ }
+
+ public BeanFactory getParentBeanFactory() {
+ return null;
+ }
+
+ public boolean containsLocalBean(String name) {
+ return false;
+ }
+
+ public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
+ return null;
+ }
+
+ public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
+ return null;
+ }
+
+ public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
+ return null;
+ }
+
+ public void publishEvent(ApplicationEvent event) {
+
+ }
+
+ public Resource[] getResources(String locationPattern) throws IOException {
+ return new Resource[0];
+ }
+
+ public Resource getResource(String location) {
+ return null;
+ }
+
+ public ClassLoader getClassLoader() {
+ // REVIEW: this is almost certainly flawed, but it's not clear how the SCA runtime's
+ // resource loading mechanism is exposed right now.
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ public ApplicationContext getParent() {
+ return implementation.getParentApplicationContext();
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java
new file mode 100644
index 0000000000..8bcdc8108d
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java
@@ -0,0 +1,130 @@
+/*
+ * 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.implementation.spring.context.tie;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.implementation.spring.processor.tie.ComponentNameAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.ComponentStub;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.ConstructorAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.InitDestroyAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.PropertyAnnotationProcessor;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.PropertyValueStub;
+import org.apache.tuscany.sca.implementation.spring.processor.tie.ReferenceAnnotationProcessor;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.UrlResource;
+
+/**
+ * This is the runtime side tie for the corresponding tuscany side stub class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the SpringContextStub class
+ * in the implementation-spring module for what the stub does.
+ */
+public class SpringContextTie {
+
+ private AbstractApplicationContext springContext;
+ private SpringImplementationStub implementation;
+
+ public SpringContextTie(SpringImplementationStub implementation, List<URL> resource) {
+ this.implementation = implementation;
+ SCAParentApplicationContext scaParentContext = new SCAParentApplicationContext(implementation);
+ springContext = createApplicationContext(scaParentContext, resource);
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return springContext;
+ }
+
+ public void start() {
+ // Do refresh here to ensure that Spring Beans are not touched before the SCA config process is complete...
+ springContext.refresh();
+ springContext.start();
+ }
+
+ public void close() {
+ springContext.close();
+ if (springContext instanceof GenericApplicationContext) {
+ springContext.stop();
+ }
+ }
+
+ /**
+ * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean
+ */
+ private AbstractApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext,
+ List<URL> resources) {
+
+ GenericApplicationContext appCtx =
+ new SCAGenericApplicationContext(scaParentContext, implementation.getClassLoader());
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx);
+
+ // REVIEW: [rfeng] How do we control the schema validation
+ xmlReader.setValidating(false);
+
+ for (URL resource : resources) {
+ xmlReader.loadBeanDefinitions(new UrlResource(resource));
+ }
+ xmlReader.setBeanClassLoader(implementation.getClassLoader());
+ includeAnnotationProcessors(appCtx.getBeanFactory());
+ return appCtx;
+
+ }
+
+ public Object getBean(String id) throws BeansException {
+ return springContext.getBean(id);
+ }
+
+ /**
+ * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean
+ */
+ private void includeAnnotationProcessors(ConfigurableListableBeanFactory beanFactory) {
+
+ // Processor to deal with @Init and @Destroy SCA Annotations
+ BeanPostProcessor initDestroyProcessor = new InitDestroyAnnotationProcessor();
+ beanFactory.addBeanPostProcessor(initDestroyProcessor);
+
+ // Processor to deal with @Reference SCA Annotations
+ ComponentStub component = new ComponentStub(implementation.getComponentTie());
+ BeanPostProcessor referenceProcessor = new ReferenceAnnotationProcessor(component);
+ beanFactory.addBeanPostProcessor(referenceProcessor);
+
+ // Processor to deal with @Property SCA Annotations
+ PropertyValueStub pvs = new PropertyValueStub(implementation.getPropertyValueTie());
+ BeanPostProcessor propertyProcessor = new PropertyAnnotationProcessor(pvs);
+ beanFactory.addBeanPostProcessor(propertyProcessor);
+
+ // Processor to deal with @ComponentName SCA Annotations
+ BeanPostProcessor componentNameProcessor =
+ new ComponentNameAnnotationProcessor(implementation.getComponentName());
+ beanFactory.addBeanPostProcessor(componentNameProcessor);
+
+ // Processor to deal with @Constructor SCA Annotations
+ BeanPostProcessor constructorProcessor = new ConstructorAnnotationProcessor();
+ beanFactory.addBeanPostProcessor(constructorProcessor);
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java
new file mode 100644
index 0000000000..5ce52e668c
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java
@@ -0,0 +1,146 @@
+/*
+ * 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.implementation.spring.context.tie;
+
+import java.lang.reflect.Method;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * This is the runtime side stub for the corresponding Tuscany-side stub class.
+ * It enables the Spring code in the runtime module to invoke methods on a
+ * Tuscany SpringImplementation without the Spring runtime module
+ * needing to know about any Tuscany classes. See the SpringImplementationTie class
+ * in the implementation-spring module for what the tie does.
+ */
+public class SpringImplementationStub {
+
+ Object tie;
+ Method getURI;
+ Method getBean;
+ Method getComponentName;
+ Method getComponentTie;
+ Method getPropertyValueTie;
+ Method getClassLoader;
+ Method getParentApplicationContext;
+
+ public SpringImplementationStub(Object tie) {
+ this.tie = tie;
+ Class<?> tieClass = tie.getClass();
+ try {
+ getURI = tieClass.getMethod("getURI", new Class<?>[] {});
+ getBean = tieClass.getMethod("getBean", new Class<?>[] {String.class, Class.class});
+ getComponentName = tieClass.getMethod("getComponentName");
+ getComponentTie = tieClass.getMethod("getComponentTie");
+ getPropertyValueTie = tieClass.getMethod("getPropertyValueTie");
+ getClassLoader = tieClass.getMethod("getClassLoader");
+ getParentApplicationContext = tieClass.getMethod("getParentApplicationContext");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String getURI() {
+ try {
+
+ return (String)getURI.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Get a Bean for a reference or for a property.
+ *
+ * @param name - the name of the Bean required
+ * @param requiredType - the required type of the Bean (either a Java class or a Java interface)
+ * @return Object - a Bean which matches the requested bean
+ */
+ public Object getBean(String name, Class<?> requiredType) throws BeansException {
+ try {
+
+ Object bean = getBean.invoke(tie, new Object[] {name, requiredType});
+// if (bean == null) {
+// throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name);
+// }
+ return bean;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String getComponentName() {
+ try {
+
+ return (String)getComponentName.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getComponentTie() {
+ try {
+
+ return getComponentTie.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getPropertyValueTie() {
+ try {
+
+ return getPropertyValueTie.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public ClassLoader getClassLoader() {
+ try {
+
+ return (ClassLoader)getClassLoader.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Get the parent Spring application context set by the Tuscany runtime
+ * @return
+ */
+ public ApplicationContext getParentApplicationContext() {
+ try {
+
+ return (ApplicationContext)getParentApplicationContext.invoke(tie);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java
new file mode 100644
index 0000000000..020e001a59
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java
@@ -0,0 +1,129 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <bean> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringBeanElement {
+
+ private String id;
+ private String className = null;
+ private boolean innerBean = false;
+ private boolean abstractBean = false;
+ private boolean parentAttribute = false;
+ private boolean factoryBeanAttribute = false;
+ private boolean factoryMethodAttribute = false;
+
+ private List<SpringPropertyElement> properties = new ArrayList<SpringPropertyElement>();
+ private List<SpringConstructorArgElement> constructorargs = new ArrayList<SpringConstructorArgElement>();
+
+ public SpringBeanElement(String id, String className) {
+ this.id = id;
+ this.className = className;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public List<SpringPropertyElement> getProperties() {
+ return properties;
+ }
+
+ public void addProperty(SpringPropertyElement property) {
+ properties.add(property);
+ }
+
+ public List<SpringConstructorArgElement> getCustructorArgs() {
+ return constructorargs;
+ }
+
+ public void addCustructorArgs(SpringConstructorArgElement args) {
+ constructorargs.add(args);
+ }
+
+ public boolean isInnerBean() {
+ return innerBean;
+ }
+
+ public void setInnerBean(boolean innerBean) {
+ this.innerBean = innerBean;
+ }
+
+ public boolean isAbstractBean() {
+ return abstractBean;
+ }
+
+ public void setAbstractBean(boolean abstractBean) {
+ this.abstractBean = abstractBean;
+ }
+
+ public boolean hasParentAttribute() {
+ return parentAttribute;
+ }
+
+ public void setParentAttribute(boolean parentAttribute) {
+ this.parentAttribute = parentAttribute;
+ }
+
+ public boolean hasFactoryBeanAttribute() {
+ return factoryBeanAttribute;
+ }
+
+ public void setFactoryBeanAttribute(boolean factoryBeanAttribute) {
+ this.factoryBeanAttribute = factoryBeanAttribute;
+ }
+
+ public boolean hasFactoryMethodAttribute() {
+ return factoryMethodAttribute;
+ }
+
+ public void setFactoryMethodAttribute(boolean factoryMethodAttribute) {
+ this.factoryMethodAttribute = factoryMethodAttribute;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringBeanElement [id=").append(id).append(", className=").append(className)
+ .append(", innerBean=").append(innerBean).append(", abstractBean=").append(abstractBean)
+ .append(", parentAttribute=").append(parentAttribute).append(", factoryBeanAttribute=")
+ .append(factoryBeanAttribute).append(", factoryMethodAttribute=").append(factoryMethodAttribute)
+ .append(", properties=").append(properties).append(", constructorargs=").append(constructorargs)
+ .append("]");
+ return builder.toString();
+ }
+
+} // end class SpringBeanElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java
new file mode 100644
index 0000000000..53a972b7d8
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java
@@ -0,0 +1,77 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <constructor-arg> element in a Spring application-context
+ * - this has ref attribute
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringConstructorArgElement {
+
+ private String type;
+ private int autoIndex = -1;
+ private int index = -1;
+ private List<String> refs = new ArrayList<String>();
+ private List<String> values = new ArrayList<String>();
+
+ public SpringConstructorArgElement(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public List<String> getRefs() {
+ return this.refs;
+ }
+
+ public void addRef(String ref) {
+ this.refs.add(ref);
+ }
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public int getAutoIndex() {
+ return this.autoIndex;
+ }
+
+ public void setAutoIndex(int index) {
+ this.autoIndex = index;
+ }
+
+ public List<String> getValues() {
+ return this.values;
+ }
+
+ public void addValue(String value) {
+ this.values.add(value);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java
new file mode 100644
index 0000000000..c088e5d0f2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java
@@ -0,0 +1,70 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * A hacking utility to copy beans field by field between two class loaders
+ */
+public class SpringElementTie {
+ public static <T> T copy(Object source, Class<T> cls, Type genericType) {
+ if (source == null) {
+ return null;
+ }
+ if (cls.isPrimitive()) {
+ return (T)source;
+ }
+ if (Collection.class.isAssignableFrom(cls)) {
+ ParameterizedType pType = (ParameterizedType)genericType;
+ Type itemType = pType.getActualTypeArguments()[0];
+ Collection col = (Collection)source;
+ List target = new ArrayList();
+ for (Object item : col) {
+ target.add(copy(item, (Class<?>)itemType, itemType));
+ }
+ return (T)target;
+ }
+ if (cls.isInstance(source)) {
+ return cls.cast(source);
+ }
+ try {
+ Class<?> sourceClass = source.getClass();
+ T target = cls.newInstance();
+ for (Field sourceField : sourceClass.getDeclaredFields()) {
+ sourceField.setAccessible(true);
+ Field targetField = cls.getDeclaredField(sourceField.getName());
+ targetField.setAccessible(true);
+ Object sourceFieldValue = sourceField.get(source);
+ Object targetFieldValue = copy(sourceFieldValue, targetField.getType(), targetField.getGenericType());
+ targetField.set(target, targetFieldValue);
+ }
+ return target;
+ } catch (Throwable e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java
new file mode 100644
index 0000000000..c0a1f2129b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java
@@ -0,0 +1,68 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <property> element in a Spring application-context
+ * - this has name and ref attributes
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringPropertyElement {
+
+ private String name;
+ private List<String> refs = new ArrayList<String>();
+ private List<String> values = new ArrayList<String>();
+
+ public SpringPropertyElement(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List<String> getRefs() {
+ return this.refs;
+ }
+
+ public void addRef(String ref) {
+ this.refs.add(ref);
+ }
+
+ public List<String> getValues() {
+ return this.values;
+ }
+
+ public void addValue(String value) {
+ this.values.add(value);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringPropertyElement [name=").append(name).append(", refs=").append(refs).append(", values=")
+ .append(values).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringPropertyElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java
new file mode 100644
index 0000000000..3f9901abea
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java
@@ -0,0 +1,59 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+/**
+ * Represents an <sca:property> element in a Spring application-context
+ * - this has name and type attributes
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAPropertyElement {
+
+ private String name;
+ private String type;
+
+ public SpringSCAPropertyElement(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAPropertyElement [name=").append(name).append(", type=").append(type).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringPropertyElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java
new file mode 100644
index 0000000000..7569d2996f
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java
@@ -0,0 +1,73 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+
+/**
+ * Represents a <sca:reference> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAReferenceElement {
+
+ private String name;
+ private String type;
+ private String defaultBean;
+
+ public SpringSCAReferenceElement(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setDefaultBean(String defaultBean) {
+ this.defaultBean = defaultBean;
+ }
+
+ public String getDefaultBean() {
+ return defaultBean;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAReferenceElement [name=").append(name).append(", type=").append(type)
+ .append(", defaultBean=").append(defaultBean).append("]");
+ return builder.toString();
+ }
+
+
+} // end class SpringSCAReferenceElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java
new file mode 100644
index 0000000000..737abe7c04
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java
@@ -0,0 +1,73 @@
+/*
+ * 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.implementation.spring.elements.tie;
+
+
+/**
+ * Represents a <sca:service> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAServiceElement {
+
+ private String name;
+ private String type;
+ private String target;
+
+
+ public SpringSCAServiceElement(String name, String target) {
+ this.name = name;
+ this.target = target;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAServiceElement [name=").append(name).append(", type=").append(type)
+ .append(", target=").append(target).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringSCAServiceElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java
new file mode 100644
index 0000000000..07c7c6a454
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java
@@ -0,0 +1,53 @@
+/*
+ * 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.implementation.spring.namespace.tie;
+
+import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver;
+import org.springframework.beans.factory.xml.NamespaceHandler;
+
+/**
+ * Overrides the default Spring namespace resolver to automatically register
+ * {@link ScaNamespaceHandler} instead of requiring a value to be supplied in a
+ * Spring configuration
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCANamespaceHandlerResolver extends DefaultNamespaceHandlerResolver {
+ private static final String SCA_NAMESPACE = "http://www.springframework.org/schema/sca";
+
+ private ScaNamespaceHandler handler;
+
+ public SCANamespaceHandlerResolver(ClassLoader classLoader) {
+ super(classLoader);
+ handler = new ScaNamespaceHandler(/*componentType*/);
+ }
+
+ public SCANamespaceHandlerResolver(String handlerMappingsLocation, ClassLoader classLoader) {
+ super(classLoader, handlerMappingsLocation);
+ handler = new ScaNamespaceHandler(/*componentType*/);
+ }
+
+ @Override
+ public NamespaceHandler resolve(String namespaceUri) {
+ if (SCA_NAMESPACE.equals(namespaceUri)) {
+ return handler;
+ }
+ return super.resolve(namespaceUri);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java
new file mode 100644
index 0000000000..6ed49abb6f
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace.tie;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+/**
+ * Handler for the &lt;sca:&gt; namespace in an application context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaNamespaceHandler extends NamespaceHandlerSupport {
+
+ public ScaNamespaceHandler() {
+ }
+
+ @Override
+ public void init() {
+ registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser());
+ registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser());
+ registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser());
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java
new file mode 100644
index 0000000000..ad11a300ae
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace.tie;
+
+import org.apache.tuscany.sca.implementation.spring.context.tie.SCAGenericApplicationContext;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAPropertyElement;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:reference&gt; element
+ * @version $Rev$ $Date$
+ */
+public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAPropertyElement propertyElement =
+ new SpringSCAPropertyElement(element.getAttributeNS(null, "name"), element.getAttributeNS(null, "type"));
+ context.addSCAPropertyElement(propertyElement);
+ }
+ // do nothing, this is handled by Tuscany
+ return null;
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java
new file mode 100644
index 0000000000..a4fefa70f1
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace.tie;
+
+import org.apache.tuscany.sca.implementation.spring.context.tie.SCAGenericApplicationContext;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAReferenceElement;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:reference&gt; element
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAReferenceElement referenceElement =
+ new SpringSCAReferenceElement(element.getAttributeNS(null, "name"),
+ element.getAttributeNS(null, "type"));
+ referenceElement.setDefaultBean(element.getAttributeNS(null, "default"));
+ context.addSCAReferenceElement(referenceElement);
+ }
+
+ // do nothing, this is handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java
new file mode 100644
index 0000000000..64f4ce20dc
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tuscany.sca.implementation.spring.namespace.tie;
+
+import org.apache.tuscany.sca.implementation.spring.context.tie.SCAGenericApplicationContext;
+import org.apache.tuscany.sca.implementation.spring.elements.tie.SpringSCAServiceElement;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for the &lt;sca:service/&gt; element
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser {
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
+ if (registry instanceof SCAGenericApplicationContext) {
+ SCAGenericApplicationContext context = (SCAGenericApplicationContext)registry;
+ SpringSCAServiceElement serviceElement =
+ new SpringSCAServiceElement(element.getAttributeNS(null, "name"),
+ element.getAttributeNS(null, "target"));
+ serviceElement.setType(element.getAttributeNS(null, "type"));
+ context.addSCAServiceElement(serviceElement);
+ }
+ // do nothing, handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java
new file mode 100644
index 0000000000..77f9f30bfd
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java
@@ -0,0 +1,151 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.ref.Reference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.oasisopen.sca.annotation.ComponentName;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class ComponentNameAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> componentNameAnnotationType = ComponentName.class;
+
+ private String componentName;
+
+ public ComponentNameAnnotationProcessor(String componentName) {
+ this.componentName = componentName;
+ }
+
+ /**
+ * Gets componentName annotation type.
+ */
+ protected Class<? extends Annotation> getComponentNameAnnotationType() {
+ return this.componentNameAnnotationType;
+ }
+
+ /**
+ * Sets componentName annotation type.
+ */
+ public void setComponentNameAnnotationType(Class<? extends Annotation> componentNameAnnotationType) {
+ Assert.notNull(componentNameAnnotationType, "'componentNameAnnotationType' type must not be null.");
+ this.componentNameAnnotationType = componentNameAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+ Annotation annotation = field.getAnnotation(getComponentNameAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on static fields");
+ }
+
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on private fields");
+ }
+
+ ReflectionUtils.makeAccessible(field);
+
+ if (field.getType().getName().equals("java.lang.String")) {
+ Object nameObj = componentName;
+ if (nameObj != null)
+ ReflectionUtils.setField(field, bean, nameObj);
+ } else {
+ throw new IllegalStateException(
+ "ComponentName annotation is supported only on java.lang.String field type.");
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+ Annotation annotation = method.getAnnotation(getComponentNameAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on static methods");
+ }
+
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("ComponentName annotation is not supported on private methods");
+ }
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException(
+ "ComponentName annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+
+ if (pd.getPropertyType().getName().equals("java.lang.String")) {
+ Object nameObj = componentName;
+ if (nameObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {nameObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e);
+ }
+ }
+ } else {
+ throw new IllegalStateException(
+ "ComponentName annotation is supported only on java.lang.String field type.");
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java
new file mode 100644
index 0000000000..7511ac4bd5
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java
@@ -0,0 +1,54 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.lang.reflect.Method;
+
+/**
+ * This is the Spring runtime side stub for the corresponding Tuscany tie class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the ComponentTie class
+ * in the implementation-spring module for what the tie does.
+ */
+public class ComponentStub {
+
+ private Object tie;
+ private Method getService;
+
+ public ComponentStub(Object tie) {
+ this.tie = tie;
+ Class<?> tieClass = tie.getClass();
+ try {
+ getService = tieClass.getMethod("getService", new Class<?>[] {Class.class, String.class});
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getService(Class<?> type, String name) {
+ try {
+
+ return getService.invoke(tie, type, name);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java
new file mode 100644
index 0000000000..503307cfd9
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java
@@ -0,0 +1,112 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
+import org.springframework.util.Assert;
+
+public class ConstructorAnnotationProcessor extends InstantiationAwareBeanPostProcessorAdapter {
+
+ private Class<? extends Annotation> constructorAnnotationType = org.oasisopen.sca.annotation.Constructor.class;
+
+ private Class<? extends Annotation> autowiredAnnotationType = Autowired.class;
+
+ public ConstructorAnnotationProcessor() {
+ // Default constructor.
+ }
+
+ /**
+ * Set the 'autowired' annotation type, to be used on constructors, fields,
+ * setter methods and arbitrary config methods.
+ */
+ public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
+ Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
+ this.autowiredAnnotationType = autowiredAnnotationType;
+ }
+
+ /**
+ * Return the 'autowired' annotation type.
+ */
+ protected Class<? extends Annotation> getAutowiredAnnotationType() {
+ return this.autowiredAnnotationType;
+ }
+
+ /**
+ * Return the 'constructor' annotation type.
+ */
+ protected Class<? extends Annotation> getConstructorAnnotationType() {
+ return this.constructorAnnotationType;
+ }
+
+ /**
+ * Sets the 'constructor' annotation type.
+ */
+ public void setConstructorAnnotationType(Class<? extends Annotation> constructorAnnotationType) {
+ Assert.notNull(constructorAnnotationType, "'constructorAnnotationType' type must not be null.");
+ this.constructorAnnotationType = constructorAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException {
+ /*Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
+ Method[] declaredMethods = beanClass.getDeclaredMethods();
+ List candidates = new ArrayList(declaredConstructors.length);
+
+ for (int i = 0; i < declaredMethods.length; i++) {
+ Method method = declaredMethods[i];
+ Annotation annotation = method.getAnnotation(getConstructorAnnotationType());
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Constructor annotation is not supported on static methods");
+ }
+
+ if (candidates.size() == 1) {
+ throw new IllegalStateException("Only one method is allowed to have constructor annotation in a bean: " + method);
+ }
+
+ candidates.add(method);
+ }
+ }
+
+ return (Constructor[]) candidates.toArray(new Constructor[candidates.size()]);*/
+ return null;
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java
new file mode 100644
index 0000000000..390ee040f2
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.lang.annotation.Annotation;
+
+import org.oasisopen.sca.annotation.Destroy;
+import org.oasisopen.sca.annotation.Init;
+import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
+
+public class InitDestroyAnnotationProcessor extends InitDestroyAnnotationBeanPostProcessor {
+
+ private static final long serialVersionUID = 0;
+
+ private Class<? extends Annotation> initAnnotationType = Init.class;
+ private Class<? extends Annotation> destroyAnnotationType = Destroy.class;
+
+ /**
+ * Gets init annotation type.
+ */
+ protected Class<? extends Annotation> getInitAnnotationType() {
+ return this.initAnnotationType;
+ }
+
+ /**
+ * Sets init annotation type.
+ */
+ /*
+ * public void setInitAnnotationType(Class<? extends Annotation>
+ * initAnnotationType) { Assert.notNull(initAnnotationType,
+ * "Init annotation type must not be null."); this.initAnnotationType =
+ * initAnnotationType; }
+ */
+
+ /**
+ * Gets destroy annotation type.
+ */
+ protected Class<? extends Annotation> getDestroyAnnotationType() {
+ return this.destroyAnnotationType;
+ }
+
+ /**
+ * Sets destroy annotation type.
+ */
+ /*
+ * public void setDestroyAnnotationType(Class<? extends Annotation>
+ * destroyAnnotationType) { Assert.notNull(destroyAnnotationType,
+ * "Destroy annotation type must not be null."); this.destroyAnnotationType
+ * = destroyAnnotationType; }
+ */
+
+ public InitDestroyAnnotationProcessor() {
+ // Set the @Init annotation type
+ setInitAnnotationType(initAnnotationType);
+
+ // Set the @Destroy annotation type
+ setDestroyAnnotationType(destroyAnnotationType);
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java
new file mode 100644
index 0000000000..ce3aafd3ef
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java
@@ -0,0 +1,163 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.oasisopen.sca.annotation.Property;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class PropertyAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> propertyAnnotationType = Property.class;
+
+ private PropertyValueStub propertyValue;
+
+ public PropertyAnnotationProcessor(PropertyValueStub propertyValue) {
+ this.propertyValue = propertyValue;
+ }
+
+ /**
+ * Gets property annotation type.
+ */
+ protected Class<? extends Annotation> getPropertyAnnotationType() {
+ return this.propertyAnnotationType;
+ }
+
+ /**
+ * Sets property annotation type.
+ */
+ public void setPropertyAnnotationType(Class<? extends Annotation> propertyAnnotationType) {
+ Assert.notNull(propertyAnnotationType, "'propertyAnnotationType' type must not be null.");
+ this.propertyAnnotationType = propertyAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Property} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+
+ Property annotation = (Property)method.getAnnotation(getPropertyAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on static methods");
+ }
+
+ /*
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on private methods");
+ }
+ */
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException("Property annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+ if (pd != null) {
+ String propName = annotation.name();
+ if ("".equals(propName)) {
+ injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), pd.getName()));
+ } else {
+ injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), propName));
+ }
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+
+ Property annotation = (Property)field.getAnnotation(getPropertyAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on static fields");
+ }
+
+ /*
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("Property annotation is not supported on private fields");
+ }
+ */
+
+ ReflectionUtils.makeAccessible(field);
+
+ Object propertyObj = null;
+ String propName = annotation.name();
+ if ("".equals(propName)) {
+ propertyObj = propertyValue.getPropertyObj(field.getType(), field.getName());
+ } else {
+ propertyObj = propertyValue.getPropertyObj(field.getType(), propName);
+ }
+
+ if (propertyObj != null)
+ ReflectionUtils.setField(field, bean, propertyObj);
+ }
+ }
+ });
+ }
+
+ public void injectProperty(Object bean, PropertyDescriptor pd, Object propertyObj) {
+
+ if (propertyObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {propertyObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting property: " + e.getMessage(), e);
+ }
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java
new file mode 100644
index 0000000000..5a4b57ce81
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java
@@ -0,0 +1,55 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.lang.reflect.Method;
+
+/**
+ * This is the Spring runtime side stub for the corresponding Tuscany tie class.
+ * It enables the Tuscany code to invoke methods on a Spring context without
+ * needing to know about any Spring classes. See the PropertyValueTie class
+ * in the implementation-spring module for what the tie does.
+ */
+public class PropertyValueStub {
+
+ private Object tie;
+ private Method getPropertyObj;
+
+ public PropertyValueStub(Object tie) {
+ this.tie = tie;
+ Class<?> tieClass = tie.getClass();
+ try {
+ getPropertyObj = tieClass.getMethod("getPropertyObj", new Class<?>[] {Class.class, String.class});
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getPropertyObj(Class<?> propertyType, String name) {
+ try {
+
+ return getPropertyObj.invoke(tie, propertyType, name);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java
new file mode 100644
index 0000000000..24761d2cfa
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java
@@ -0,0 +1,167 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.oasisopen.sca.annotation.Reference;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+public class ReferenceAnnotationProcessor implements BeanPostProcessor {
+
+ private Class<? extends Annotation> referenceAnnotationType = Reference.class;
+ private ComponentStub component;
+
+ public ReferenceAnnotationProcessor(ComponentStub component) {
+ this.component = component;
+ }
+
+ /**
+ * Gets referece annotation type.
+ */
+ protected Class<? extends Annotation> getReferenceAnnotationType() {
+ return this.referenceAnnotationType;
+ }
+
+ /**
+ * Sets referece annotation type.
+ */
+ public void setReferenceAnnotationType(Class<? extends Annotation> referenceAnnotationType) {
+ Assert.notNull(referenceAnnotationType, "'referenceAnnotationType' type must not be null.");
+ this.referenceAnnotationType = referenceAnnotationType;
+ }
+
+ /**
+ * This method is used to execute before a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ processAnnotation(bean);
+ return bean;
+ }
+
+ /**
+ * This method is used to execute after a bean's initialization callback.
+ *
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ /**
+ * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p>
+ */
+ protected void processAnnotation(final Object bean) {
+
+ final Class<?> clazz = bean.getClass();
+
+ ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
+ public void doWith(Method method) {
+
+ Reference annotation = (Reference)method.getAnnotation(getReferenceAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on static methods");
+ }
+
+ /*
+ if (Modifier.isPrivate(method.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on private methods");
+ }
+ */
+
+ if (method.getParameterTypes().length == 0) {
+ throw new IllegalStateException(
+ "Reference annotation requires at least one argument: " + method);
+ }
+
+ PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
+ if (pd != null) {
+ String refName = annotation.name();
+ if ("".equals(refName)) {
+ injectReference(bean, pd, pd.getName());
+ } else {
+ injectReference(bean, pd, refName);
+ }
+ }
+ }
+ }
+ });
+
+ ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
+ public void doWith(Field field) {
+
+ Reference annotation = (Reference)field.getAnnotation(getReferenceAnnotationType());
+
+ if (annotation != null) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on static fields");
+ }
+
+ /*
+ if (Modifier.isPrivate(field.getModifiers())) {
+ throw new IllegalStateException("Reference annotation is not supported on private fields");
+ }
+ */
+
+ ReflectionUtils.makeAccessible(field);
+
+ Object referenceObj = null;
+ String refName = annotation.name();
+ if ("".equals(refName)) {
+ referenceObj = component.getService(field.getType(), field.getName());
+ } else {
+ referenceObj = component.getService(field.getType(), refName);
+ }
+
+ if (referenceObj != null)
+ ReflectionUtils.setField(field, bean, referenceObj);
+ }
+ }
+ });
+ }
+
+ /**
+ * Processes a property descriptor to inject a service.
+ */
+ public void injectReference(Object bean, PropertyDescriptor pd, String name) {
+
+ Object referenceObj = component.getService(pd.getPropertyType(), name);
+
+ if (referenceObj != null) {
+ try {
+ pd.getWriteMethod().invoke(bean, new Object[] {referenceObj});
+ } catch (Throwable e) {
+ throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e);
+ }
+ }
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java
new file mode 100644
index 0000000000..82aa176219
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java
@@ -0,0 +1,57 @@
+/*
+ * 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.implementation.spring.processor.tie;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.implementation.spring.context.tie.SCAGenericApplicationContext;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.UrlResource;
+
+/**
+ * A tie that allows Tuscany to call Spring library to load the application context for the purpose of introspection
+ */
+public class SpringXMLLoaderTie {
+
+ public static ApplicationContext createApplicationContext(Object scaParentContext,
+ ClassLoader classLoader,
+ List<URL> resources) {
+ if (classLoader == null) {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+
+ SCAGenericApplicationContext appCtx =
+ new SCAGenericApplicationContext((ApplicationContext)scaParentContext, classLoader);
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx);
+
+ // REVIEW: [rfeng] How do we control the schema validation
+ xmlReader.setValidating(false);
+
+ for (URL resource : resources) {
+ xmlReader.loadBeanDefinitions(new UrlResource(resource));
+ }
+
+ return appCtx;
+
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.handlers b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 0000000000..e7b61bfe48
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://www.springframework.org/schema/sca=org.apache.tuscany.sca.implementation.spring.namespace.tie.ScaNamespaceHandler
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.schemas b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 0000000000..249cc21c13
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1 @@
+http\://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd=org/springframework/sca/xml/spring-sca.xsd
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/org/springframework/sca/xml/spring-sca.xsd b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/org/springframework/sca/xml/spring-sca.xsd
new file mode 100644
index 0000000000..dfa0b931f6
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring-tie/src/main/resources/org/springframework/sca/xml/spring-sca.xsd
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<xsd:schema xmlns="http://www.springframework.org/schema/sca" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ attributeFormDefault="unqualified" elementFormDefault="qualified"
+ targetNamespace="http://www.springframework.org/schema/sca">
+
+ <xsd:element name="reference">
+ <xsd:complexType>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="default" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="property">
+ <xsd:complexType>
+ <xsd:attribute name="id" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="service">
+ <xsd:complexType>
+ <xsd:attribute name="name" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="target" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string" />
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/LICENSE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/META-INF/MANIFEST.MF b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..9226b047d7
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/META-INF/MANIFEST.MF
@@ -0,0 +1,50 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Spring Implementation Model
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Spring Implementation Model
+Import-Package: javax.jws,
+ javax.xml.namespace,
+ javax.xml.stream,
+ org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.assembly.builder;version="2.0.0",
+ org.apache.tuscany.sca.assembly.impl;version="2.0.0",
+ org.apache.tuscany.sca.assembly.xml;version="2.0.0",
+ org.apache.tuscany.sca.context;version="2.0.0",
+ org.apache.tuscany.sca.contribution;version="2.0.0",
+ org.apache.tuscany.sca.contribution.processor;version="2.0.0",
+ org.apache.tuscany.sca.contribution.resolver;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.core.factory;version="2.0.0",
+ org.apache.tuscany.sca.core.invocation;version="2.0.0",
+ org.apache.tuscany.sca.databinding;version="2.0.0",
+ org.apache.tuscany.sca.databinding.impl;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.injection;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.introspect;version="2.0.0",
+ org.apache.tuscany.sca.implementation.java.introspect.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.java.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
+ org.apache.tuscany.sca.invocation;version="2.0.0",
+ org.apache.tuscany.sca.monitor;version="2.0.0",
+ org.apache.tuscany.sca.policy;version="2.0.0",
+ org.apache.tuscany.sca.provider;version="2.0.0",
+ org.apache.tuscany.sca.runtime;version="2.0.0",
+ org.oasisopen.sca;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0"
+Bundle-SymbolicName: org.apache.tuscany.sca.implementation.spring
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
+Export-Package: org.apache.tuscany.sca.implementation.spring;version="2.0.0",
+ org.apache.tuscany.sca.implementation.spring.xml;version="2.0.0";
+ uses:="javax.xml.stream,
+ org.apache.tuscany.sca.contribution.resolver,
+ org.apache.tuscany.sca.implementation.spring,
+ org.apache.tuscany.sca.contribution.processor,
+ org.apache.tuscany.sca.core,
+ javax.xml.namespace"
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/NOTICE b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/NOTICE
new file mode 100644
index 0000000000..1325efd8bf
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/pom.xml
new file mode 100644
index 0000000000..371bde71b9
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-implementation-spring</artifactId>
+ <name>Apache Tuscany SCA Spring Implementation Model</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-assembly</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-assembly-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-contribution</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-sca-api</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-java</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java
new file mode 100644
index 0000000000..64b36a0a44
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanElement.java
@@ -0,0 +1,132 @@
+/*
+ * 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.implementation.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <bean> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringBeanElement {
+
+ private String id;
+ private String className = null;
+ private boolean innerBean = false;
+ private boolean abstractBean = false;
+ private boolean parentAttribute = false;
+ private boolean factoryBeanAttribute = false;
+ private boolean factoryMethodAttribute = false;
+
+ private List<SpringPropertyElement> properties = new ArrayList<SpringPropertyElement>();
+ private List<SpringConstructorArgElement> constructorargs = new ArrayList<SpringConstructorArgElement>();
+
+ public SpringBeanElement() {
+ }
+
+ public SpringBeanElement(String id, String className) {
+ this.id = id;
+ this.className = className;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public List<SpringPropertyElement> getProperties() {
+ return properties;
+ }
+
+ public void addProperty(SpringPropertyElement property) {
+ properties.add(property);
+ }
+
+ public List<SpringConstructorArgElement> getCustructorArgs() {
+ return constructorargs;
+ }
+
+ public void addCustructorArgs(SpringConstructorArgElement args) {
+ constructorargs.add(args);
+ }
+
+ public boolean isInnerBean() {
+ return innerBean;
+ }
+
+ public void setInnerBean(boolean innerBean) {
+ this.innerBean = innerBean;
+ }
+
+ public boolean isAbstractBean() {
+ return abstractBean;
+ }
+
+ public void setAbstractBean(boolean abstractBean) {
+ this.abstractBean = abstractBean;
+ }
+
+ public boolean hasParentAttribute() {
+ return parentAttribute;
+ }
+
+ public void setParentAttribute(boolean parentAttribute) {
+ this.parentAttribute = parentAttribute;
+ }
+
+ public boolean hasFactoryBeanAttribute() {
+ return factoryBeanAttribute;
+ }
+
+ public void setFactoryBeanAttribute(boolean factoryBeanAttribute) {
+ this.factoryBeanAttribute = factoryBeanAttribute;
+ }
+
+ public boolean hasFactoryMethodAttribute() {
+ return factoryMethodAttribute;
+ }
+
+ public void setFactoryMethodAttribute(boolean factoryMethodAttribute) {
+ this.factoryMethodAttribute = factoryMethodAttribute;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringBeanElement [id=").append(id).append(", className=").append(className)
+ .append(", innerBean=").append(innerBean).append(", abstractBean=").append(abstractBean)
+ .append(", parentAttribute=").append(parentAttribute).append(", factoryBeanAttribute=")
+ .append(factoryBeanAttribute).append(", factoryMethodAttribute=").append(factoryMethodAttribute)
+ .append(", properties=").append(properties).append(", constructorargs=").append(constructorargs)
+ .append("]");
+ return builder.toString();
+ }
+
+} // end class SpringBeanElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.java
new file mode 100644
index 0000000000..1de0595d60
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringConstructorArgElement.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.implementation.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <constructor-arg> element in a Spring application-context
+ * - this has ref attribute
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringConstructorArgElement {
+
+ private String type;
+ private int autoIndex = -1;
+ private int index = -1;
+ private List<String> refs = new ArrayList<String>();
+ private List<String> values = new ArrayList<String>();
+
+ public SpringConstructorArgElement() {
+
+ }
+
+ public SpringConstructorArgElement(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public List<String> getRefs() {
+ return this.refs;
+ }
+
+ public void addRef(String ref) {
+ this.refs.add(ref);
+ }
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public int getAutoIndex() {
+ return this.autoIndex;
+ }
+
+ public void setAutoIndex(int index) {
+ this.autoIndex = index;
+ }
+
+ public List<String> getValues() {
+ return this.values;
+ }
+
+ public void addValue(String value) {
+ this.values.add(value);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringConstructorArgElement [type=").append(type).append(", autoIndex=").append(autoIndex)
+ .append(", index=").append(index).append(", refs=").append(refs).append(", values=").append(values)
+ .append("]");
+ return builder.toString();
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java
new file mode 100644
index 0000000000..a5d4adb1bb
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java
@@ -0,0 +1,259 @@
+/*
+ * 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.implementation.spring;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Extensible;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.impl.ImplementationImpl;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+
+/**
+ * Represents a Spring implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringImplementation extends ImplementationImpl implements Implementation, Extensible {
+ public final static QName TYPE = new QName(SCA11_NS, "implementation.spring");
+ // The location attribute which points to the Spring application-context XML file
+ private String location;
+ // The application-context file as a Spring Resource
+ private List<URL> resource;
+ private ComponentType componentType;
+ // Mapping of Services to Beans
+ private Map<String, SpringBeanElement> serviceMap;
+ // Mapping of property names to Java class
+ private Map<String, Class<?>> propertyMap;
+ // List of unresolved bean property references
+ private Map<String, Reference> unresolvedBeanRef;
+ private ClassLoader classLoader;
+
+ public SpringImplementation() {
+ super(TYPE);
+ this.location = null;
+ this.resource = null;
+ setUnresolved(true);
+ serviceMap = new HashMap<String, SpringBeanElement>();
+ propertyMap = new HashMap<String, Class<?>>();
+ unresolvedBeanRef = new HashMap<String, Reference>();
+ } // end method SpringImplementation
+
+ /* Returns the location attribute for this Spring implementation */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the location attribute for this Spring implementation
+ * location - a URI to the Spring application-context file
+ */
+ public void setLocation(String location) {
+ this.location = location;
+ return;
+ }
+
+ public void setResource(List<URL> resource) {
+ this.resource = resource;
+ }
+
+ public List<URL> getResource() {
+ return resource;
+ }
+
+ /*
+ * Returns the componentType for this Spring implementation
+ */
+ public ComponentType getComponentType() {
+ return componentType;
+ }
+
+ /*
+ * Sets the componentType for this Spring implementation
+ */
+ public void setComponentType(ComponentType componentType) {
+ this.componentType = componentType;
+ }
+
+ @Override
+ public List<Service> getServices() {
+ return componentType.getServices();
+ }
+
+ @Override
+ public List<Reference> getReferences() {
+ return componentType.getReferences();
+ }
+
+ @Override
+ public List<Property> getProperties() {
+ return componentType.getProperties();
+ }
+
+ /**
+ * Returns the Spring Bean which implements a particular service
+ * @param service the service
+ * @return the bean which implements the service, as a SpringBeanElement
+ */
+ public SpringBeanElement getBeanFromService(Service service) {
+ SpringBeanElement theBean = serviceMap.get(service.getName());
+ return theBean;
+ }
+
+ /**
+ * Sets the mapping from a service to the Spring Bean that implements the service
+ * @param service the service
+ * @param theBean a SpringBeanElement for the Bean implementing the service
+ */
+ public void setBeanForService(Service service, SpringBeanElement theBean) {
+ serviceMap.put(service.getName(), theBean);
+ }
+
+ /**
+ * Add a mapping from a SCA property name to a Java class for the property
+ * @param propertyName
+ * @param propertyClass
+ */
+ public void setPropertyClass(String propertyName, Class<?> propertyClass) {
+ if (propertyName == null || propertyClass == null)
+ return;
+ propertyMap.put(propertyName, propertyClass);
+ return;
+ } // end method setPropertyClass
+
+ /**
+ * Gets the Java Class for an SCA property
+ * @param propertyName - the property name
+ * @return - a Class object for the type of the property
+ */
+ public Class<?> getPropertyClass(String propertyName) {
+ return propertyMap.get(propertyName);
+ } // end method getPropertyClass
+
+ public void setUnresolvedBeanRef(String refName, Reference reference) {
+ if (refName == null || reference == null)
+ return;
+ unresolvedBeanRef.put(refName, reference);
+ return;
+ } // end method setUnresolvedBeanRef
+
+ public Reference getUnresolvedBeanRef(String refName) {
+ return unresolvedBeanRef.get(refName);
+ } // end method getUnresolvedBeanRef
+
+ /**
+ * Use preProcess to validate and map the references and properties dynamically
+ */
+ public void build(Component component) {
+
+ for (Reference reference : component.getReferences()) {
+ if (unresolvedBeanRef.containsKey(reference.getName())) {
+ Reference ref = unresolvedBeanRef.get(reference.getName());
+ componentType.getReferences().add(createReference(reference, ref.getInterfaceContract()));
+ unresolvedBeanRef.remove(reference.getName());
+ }
+ }
+
+ for (Property property : component.getProperties()) {
+ if (unresolvedBeanRef.containsKey(property.getName())) {
+ componentType.getProperties().add(createProperty(property));
+ this.setPropertyClass(property.getName(), property.getClass());
+ unresolvedBeanRef.remove(property.getName());
+ }
+ }
+ }
+
+ protected Reference createReference(Reference reference, InterfaceContract interfaze) {
+ Reference newReference;
+ try {
+ newReference = (Reference)reference.clone();
+ if (newReference.getInterfaceContract() == null)
+ newReference.setInterfaceContract(interfaze);
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e); // should not ever happen
+ }
+ return newReference;
+ }
+
+ protected Property createProperty(Property property) {
+ Property newProperty;
+ try {
+ newProperty = (Property)property.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e); // should not ever happen
+ }
+ return newProperty;
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((location == null) ? 0 : location.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (!(obj instanceof SpringImplementation)) {
+ return false;
+ }
+ SpringImplementation other = (SpringImplementation)obj;
+ if (location == null) {
+ if (other.location != null) {
+ return false;
+ }
+ } else if (!location.equals(other.location)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringImplementation [location=").append(location).append(", resource=").append(resource)
+ .append("]");
+ return builder.toString();
+ }
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationBuilder.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationBuilder.java
new file mode 100644
index 0000000000..1a246fa03a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationBuilder.java
@@ -0,0 +1,41 @@
+/*
+ * 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.implementation.spring;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.builder.BuilderContext;
+import org.apache.tuscany.sca.assembly.builder.ImplementationBuilder;
+
+/**
+ *
+ */
+public class SpringImplementationBuilder implements ImplementationBuilder<SpringImplementation> {
+
+ public void build(Component component, SpringImplementation implmentation, BuilderContext context) {
+ implmentation.build(component);
+ }
+
+ public QName getImplementationType() {
+ return SpringImplementation.TYPE;
+ }
+
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java
new file mode 100644
index 0000000000..27c09c1f18
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationConstants.java
@@ -0,0 +1,73 @@
+/*
+ * 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.implementation.spring;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Constants used in Spring Application Context XML files.
+ */
+public interface SpringImplementationConstants {
+
+ String SCA_NS = "http://www.springframework.org/schema/sca";
+ String SPRING_NS = "http://www.springframework.org/schema/beans";
+
+ String PROPERTY = "property";
+ QName SCA_PROPERTY_ELEMENT = new QName(SCA_NS, PROPERTY);
+ QName PROPERTY_ELEMENT = new QName(SPRING_NS, PROPERTY);
+
+ String SCASERVICE = "service";
+ QName SCA_SERVICE_ELEMENT = new QName(SCA_NS, SCASERVICE);
+
+ String SCAREFERENCE = "reference";
+ QName SCA_REFERENCE_ELEMENT = new QName(SCA_NS, SCAREFERENCE);
+
+ String BEANS = "beans";
+ QName BEANS_ELEMENT = new QName(SPRING_NS, BEANS);
+
+ String IMPORT = "import";
+ QName IMPORT_ELEMENT = new QName(SPRING_NS, IMPORT);
+
+ String BEAN = "bean";
+ QName BEAN_ELEMENT = new QName(SPRING_NS, BEAN);
+
+ String CONSTRUCTORARG = "constructor-arg";
+ QName CONSTRUCTORARG_ELEMENT = new QName(SPRING_NS, CONSTRUCTORARG);
+
+ String LIST = "list";
+ QName LIST_ELEMENT = new QName(SPRING_NS, LIST);
+
+ String SET = "set";
+ QName SET_ELEMENT = new QName(SPRING_NS, SET);
+
+ String MAP = "map";
+ QName MAP_ELEMENT = new QName(SPRING_NS, MAP);
+
+ String VALUE = "value";
+ QName VALUE_ELEMENT = new QName(SPRING_NS, VALUE);
+
+ String REF = "ref";
+ QName REF_ELEMENT = new QName(SPRING_NS, REF);
+
+ String ENTRY = "entry";
+ QName ENTRY_ELEMENT = new QName(SPRING_NS, ENTRY);
+
+ String APPLICATION_CONTEXT = "application-context.xml";
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java
new file mode 100644
index 0000000000..8de3a4cbe1
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyElement.java
@@ -0,0 +1,71 @@
+/*
+ * 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.implementation.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a <property> element in a Spring application-context
+ * - this has name and ref attributes
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringPropertyElement {
+
+ private String name;
+ private List<String> refs = new ArrayList<String>();
+ private List<String> values = new ArrayList<String>();
+
+ public SpringPropertyElement() {
+ }
+
+ public SpringPropertyElement(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List<String> getRefs() {
+ return this.refs;
+ }
+
+ public void addRef(String ref) {
+ this.refs.add(ref);
+ }
+
+ public List<String> getValues() {
+ return this.values;
+ }
+
+ public void addValue(String value) {
+ this.values.add(value);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringPropertyElement [name=").append(name).append(", refs=").append(refs).append(", values=")
+ .append(values).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringPropertyElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java
new file mode 100644
index 0000000000..f27506f28b
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAPropertyElement.java
@@ -0,0 +1,63 @@
+/*
+ * 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.implementation.spring;
+
+/**
+ * Represents an <sca:property> element in a Spring application-context
+ * - this has name and type attributes
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAPropertyElement {
+
+ private String name;
+ private String type;
+
+ public SpringSCAPropertyElement() {
+ super();
+ }
+
+ public SpringSCAPropertyElement(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAPropertyElement [name=").append(name).append(", type=").append(type).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringPropertyElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java
new file mode 100644
index 0000000000..74cd3f4290
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAReferenceElement.java
@@ -0,0 +1,92 @@
+/*
+ * 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.implementation.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicySet;
+
+/**
+ * Represents a <sca:reference> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAReferenceElement {
+
+ private String name;
+ private String type;
+ private String defaultBean;
+ private List<Intent> intents = new ArrayList<Intent>();
+ private List<PolicySet> policySets = new ArrayList<PolicySet>();
+
+ public SpringSCAReferenceElement() {
+
+ }
+
+ public SpringSCAReferenceElement(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setDefaultBean(String defaultBean) {
+ this.defaultBean = defaultBean;
+ }
+
+ public String getDefaultBean() {
+ return defaultBean;
+ }
+
+ public List<Intent> getRequiredIntents() {
+ return intents;
+ }
+
+ public List<PolicySet> getPolicySets() {
+ return policySets;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAReferenceElement [name=").append(name).append(", type=").append(type)
+ .append(", defaultBean=").append(defaultBean).append(", intents=").append(intents).append(", policySets=")
+ .append(policySets).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringSCAReferenceElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java
new file mode 100644
index 0000000000..181bd7a787
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringSCAServiceElement.java
@@ -0,0 +1,92 @@
+/*
+ * 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.implementation.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicySet;
+
+/**
+ * Represents a <sca:service> element in a Spring application-context
+ * - this has id and className attributes
+ * - plus zero or more property elements as children
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringSCAServiceElement {
+
+ private String name;
+ private String type;
+ private String target;
+ private List<Intent> intents = new ArrayList<Intent>();
+ private List<PolicySet> policySets = new ArrayList<PolicySet>();
+
+ public SpringSCAServiceElement() {
+
+ }
+
+ public SpringSCAServiceElement(String name, String target) {
+ this.name = name;
+ this.target = target;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public List<Intent> getRequiredIntents() {
+ return intents;
+ }
+
+ public List<PolicySet> getPolicySets() {
+ return policySets;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAServiceElement [name=").append(name).append(", type=").append(type)
+ .append(", target=").append(target).append(", intents=").append(intents).append(", policySets=")
+ .append(policySets).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringSCAServiceElement
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java
new file mode 100644
index 0000000000..5eaf27ab81
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringBeanIntrospector.java
@@ -0,0 +1,95 @@
+/*
+ * 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.implementation.spring.introspect;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory;
+import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+
+/**
+ * Provides introspection functions for Spring beans
+ * This version leans heavily on the implementation-java classes
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringBeanIntrospector {
+
+ private JavaImplementationFactory javaImplementationFactory;
+
+ /**
+ * The constructor sets up the various visitor elements that will be used to introspect
+ * the Spring bean and extract SCA information.
+ *
+ * @param assemblyFactory The Assembly Factory to use
+ * @param javaFactory The Java Interface Factory to use
+ * @param policyFactory The Policy Factory to use.
+ */
+ public SpringBeanIntrospector(ExtensionPointRegistry registry, List<SpringConstructorArgElement> conArgs) {
+
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ javaImplementationFactory = factories.getFactory(JavaImplementationFactory.class);
+ } // end constructor
+
+ /**
+ * Introspect a Spring Bean and extract the features important to SCA
+ * @param beanClass the Spring Bean class to introspect
+ * @param componentType the componentType that is filled in through the introspection
+ * process (assumed empty on invocation, filled on return
+ * @return a Map of property names to JavaElementImpl
+ * @throws ContributionResolveException - if there was a problem resolving the
+ * Spring Bean or its componentType
+ *
+ */
+ public JavaImplementation introspectBean(Class<?> beanClass, ComponentType componentType)
+ throws ContributionResolveException {
+ if (componentType == null)
+ throw new ContributionResolveException("Introspect Spring bean: supplied componentType is null");
+
+ // Create a Java implementation ready for the introspection
+ JavaImplementation javaImplementation = javaImplementationFactory.createJavaImplementation();
+ // Set the type to be implementation.spring to avoid heuristic introspection
+ javaImplementation.setType(SpringImplementation.TYPE);
+
+ try {
+ // Introspect the bean...the results of the introspection are placed into the Java implementation
+ javaImplementationFactory.createJavaImplementation(javaImplementation, beanClass);
+
+ // Extract the services, references & properties found through introspection
+ // put the services, references and properties into the component type
+ componentType.getServices().addAll(javaImplementation.getServices());
+ componentType.getReferences().addAll(javaImplementation.getReferences());
+ componentType.getProperties().addAll(javaImplementation.getProperties());
+
+ } catch (IntrospectionException e) {
+ throw new ContributionResolveException(e);
+ } // end try
+
+ return javaImplementation;
+
+ } // end method introspectBean
+
+} // end class SpringBeanIntrospector
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java
new file mode 100644
index 0000000000..2730ee3146
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/introspect/SpringXMLComponentTypeLoader.java
@@ -0,0 +1,917 @@
+/*
+ * 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.implementation.spring.introspect;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+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.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringConstructorArgElement;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.implementation.spring.SpringPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+import org.apache.tuscany.sca.implementation.spring.xml.SpringXMLBeanDefinitionLoader;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+
+/**
+ * Introspects a Spring XML application-context configuration file to create <implementation-spring../>
+ * component type information.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringXMLComponentTypeLoader {
+ private final static Logger log = Logger.getLogger(SpringXMLComponentTypeLoader.class.getName());
+
+ private ExtensionPointRegistry registry;
+ private ContributionFactory contributionFactory;
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+ private SpringBeanIntrospector beanIntrospector;
+
+ private SpringXMLBeanDefinitionLoader xmlBeanDefinitionLoader;
+
+ public SpringXMLComponentTypeLoader(ExtensionPointRegistry registry) {
+ super();
+ this.registry = registry;
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ this.javaFactory = factories.getFactory(JavaInterfaceFactory.class);
+ this.contributionFactory = factories.getFactory(ContributionFactory.class);
+ this.xmlBeanDefinitionLoader =
+ registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(SpringXMLBeanDefinitionLoader.class);
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-spring-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ protected Class<SpringImplementation> getImplementationClass() {
+ return SpringImplementation.class;
+ }
+
+ /**
+ * Base method which loads the component type from the application-context attached to the
+ * Spring implementation
+ *
+ */
+ public void load(SpringImplementation implementation, ModelResolver resolver, ProcessorContext context)
+ throws ContributionReadException {
+ //System.out.println("Spring TypeLoader - load method start");
+ ComponentType componentType = implementation.getComponentType();
+ /* Check that there is a component type object already set */
+ if (componentType == null) {
+ throw new ContributionReadException("SpringXMLLoader load: implementation has no ComponentType object");
+ }
+ if (componentType.isUnresolved()) {
+ /* Fetch the location of the application-context file from the implementation */
+ loadFromXML(implementation, resolver, context);
+ if (!componentType.isUnresolved())
+ implementation.setUnresolved(false);
+ } // end if
+ //System.out.println("Spring TypeLoader - load method complete");
+ } // end method load
+
+ private Class<?> resolveClass(ModelResolver resolver, String className, ProcessorContext context)
+ throws ClassNotFoundException {
+ ClassReference classReference = new ClassReference(className);
+ classReference = resolver.resolveModel(ClassReference.class, classReference, context);
+ if (classReference.isUnresolved()) {
+ throw new ClassNotFoundException(className);
+ }
+ Class<?> javaClass = classReference.getJavaClass();
+ return javaClass;
+ }
+
+ /**
+ * Method which fills out the component type for a Spring implementation by reading the
+ * Spring application-context.xml file.
+ *
+ * @param implementation SpringImplementation into which to load the component type information
+ * @throws ContributionReadException Failed to read the contribution
+ */
+ private void loadFromXML(SpringImplementation implementation, ModelResolver resolver, ProcessorContext context)
+ throws ContributionReadException {
+ List<SpringBeanElement> beans = new ArrayList<SpringBeanElement>();
+ List<SpringSCAServiceElement> services = new ArrayList<SpringSCAServiceElement>();
+ List<SpringSCAReferenceElement> references = new ArrayList<SpringSCAReferenceElement>();
+ List<SpringSCAPropertyElement> scaproperties = new ArrayList<SpringSCAPropertyElement>();
+
+ URL resource;
+ List<URL> contextResources = new ArrayList<URL>();
+ String contextPath = implementation.getLocation();
+
+ try {
+ resource = resolveLocation(resolver, contextPath, context);
+ contextResources = getApplicationContextResource(resource);
+
+ implementation.setClassLoader(new ContextClassLoader(resolver, context));
+ implementation.setResource(contextResources);
+ // The URI is used to uniquely identify the Implementation
+ implementation.setURI(resource.toString());
+
+ List<SpringBeanElement> appCxtBeans = new ArrayList<SpringBeanElement>();
+ List<SpringSCAServiceElement> appCxtServices = new ArrayList<SpringSCAServiceElement>();
+ List<SpringSCAReferenceElement> appCxtReferences = new ArrayList<SpringSCAReferenceElement>();
+ List<SpringSCAPropertyElement> appCxtProperties = new ArrayList<SpringSCAPropertyElement>();
+
+ if (xmlBeanDefinitionLoader != null) {
+ xmlBeanDefinitionLoader.load(contextResources,
+ appCxtServices,
+ appCxtReferences,
+ appCxtProperties,
+ appCxtBeans,
+ context);
+ }
+ // Validate the beans from individual application context for uniqueness
+ validateBeans(appCxtBeans, appCxtServices, appCxtReferences, appCxtProperties, context.getMonitor());
+ // Add all the validated beans to the generic list
+ beans.addAll(appCxtBeans);
+ services.addAll(appCxtServices);
+ references.addAll(appCxtReferences);
+ scaproperties.addAll(appCxtProperties);
+ } catch (Throwable e) {
+ throw new ContributionReadException(e);
+ }
+
+ /* At this point, the complete application-context.xml file has been read and its contents */
+ /* stored in the lists of beans, services, references. These are now used to generate */
+ /* the implied componentType for the application context */
+ generateComponentType(implementation, resolver, beans, services, references, scaproperties, context);
+
+ return;
+ } // end method loadFromXML
+
+ private URL resolveLocation(ModelResolver resolver, String contextPath, ProcessorContext context)
+ throws MalformedURLException, ContributionReadException {
+ URL resource = null;
+ URI uri = URI.create(contextPath);
+ if (!uri.isAbsolute()) {
+ Artifact parent = context.getArtifact();
+ if (parent != null && parent.getURI() != null) {
+ URI base = URI.create("/" + parent.getURI());
+ uri = base.resolve(uri);
+ // Remove the leading / to make artifact resolver happy
+ if (uri.toString().startsWith("/")) {
+ uri = URI.create(uri.toString().substring(1));
+ }
+ }
+ Artifact artifact = contributionFactory.createArtifact();
+ artifact.setUnresolved(true);
+ artifact.setURI(uri.toString());
+ artifact = resolver.resolveModel(Artifact.class, artifact, context);
+ if (!artifact.isUnresolved()) {
+ resource = new URL(artifact.getLocation());
+ } else {
+ throw new ContributionReadException("Location cannot be resloved: " + contextPath);
+ }
+ } else {
+ resource = new URL(contextPath);
+ }
+ return resource;
+ }
+
+ /**
+ * Generates the Spring implementation component type from the configuration contained in the
+ * lists of beans, services, references and scaproperties derived from the application context
+ */
+ private void generateComponentType(SpringImplementation implementation,
+ ModelResolver resolver,
+ List<SpringBeanElement> beans,
+ List<SpringSCAServiceElement> services,
+ List<SpringSCAReferenceElement> references,
+ List<SpringSCAPropertyElement> scaproperties,
+ ProcessorContext context) throws ContributionReadException {
+ /*
+ * 1. Each sca:service becomes a service in the component type
+ * 2. Each sca:reference becomes a reference in the component type
+ * 3. Each sca:property becomes a property in the component type
+ * 4. IF there are no explicit service elements, each bean becomes a service
+ * 5. Each bean property which is a reference not pointing at another bean in the
+ * application context becomes a reference unless it is pointing at one of the references
+ * 6. Each bean property which is not a reference and which is not pointing
+ * at another bean in the application context becomes a property in the component type
+ */
+
+ JavaImplementation javaImplementation = null;
+ ComponentType componentType = implementation.getComponentType();
+
+ try {
+ // Deal with the services first....
+ Iterator<SpringSCAServiceElement> its = services.iterator();
+ while (its.hasNext()) {
+ SpringSCAServiceElement serviceElement = its.next();
+ Class<?> interfaze = resolveClass(resolver, serviceElement.getType(), context);
+ Service theService = createService(interfaze, serviceElement.getName());
+ // Spring allows duplication of bean definitions in multiple context scenario,
+ // in such cases, the latest bean definition overrides the older ones, hence
+ // we will remove any older definition and use the latest.
+ Service duplicate = null;
+ for (Service service : componentType.getServices()) {
+ if (service.getName().equals(theService.getName()))
+ duplicate = service;
+ }
+ if (duplicate != null)
+ componentType.getServices().remove(duplicate);
+
+ componentType.getServices().add(theService);
+ // Add this service to the Service / Bean map
+ String beanName = serviceElement.getTarget();
+ for (SpringBeanElement beanElement : beans) {
+ if (beanName.equals(beanElement.getId())) {
+ if (isValidBeanForService(beanElement)) {
+ // add the required intents and policySets for the service
+ theService.getRequiredIntents().addAll(serviceElement.getRequiredIntents());
+ theService.getPolicySets().addAll(serviceElement.getPolicySets());
+ implementation.setBeanForService(theService, beanElement);
+ }
+ }
+ } // end for
+ } // end while
+
+ // Next handle the references
+ Iterator<SpringSCAReferenceElement> itr = references.iterator();
+ while (itr.hasNext()) {
+ SpringSCAReferenceElement referenceElement = itr.next();
+ Class<?> interfaze = resolveClass(resolver, referenceElement.getType(), context);
+ Reference theReference = createReference(interfaze, referenceElement.getName());
+ // Override the older bean definition with the latest ones
+ // for the duplicate definitions found.
+ Reference duplicate = null;
+ for (Reference reference : componentType.getReferences()) {
+ if (reference.getName().equals(theReference.getName()))
+ duplicate = reference;
+ }
+ if (duplicate != null)
+ componentType.getReferences().remove(duplicate);
+
+ // add the required intents and policySets for this reference
+ theReference.getRequiredIntents().addAll(referenceElement.getRequiredIntents());
+ theReference.getPolicySets().addAll(referenceElement.getPolicySets());
+ componentType.getReferences().add(theReference);
+ } // end while
+
+ // Next handle the properties
+ Iterator<SpringSCAPropertyElement> itsp = scaproperties.iterator();
+ while (itsp.hasNext()) {
+ SpringSCAPropertyElement scaproperty = itsp.next();
+ // Create a component type property if the SCA property element has a name
+ // and a type declared...
+ if (scaproperty.getType() != null && scaproperty.getName() != null) {
+ Property theProperty = assemblyFactory.createProperty();
+ theProperty.setName(scaproperty.getName());
+ // Get the Java class and then an XSD element type for the property
+ Class<?> propType = Class.forName(scaproperty.getType());
+ theProperty.setXSDType(JavaXMLMapper.getXMLType(propType));
+ // Override the older bean definition with the latest ones
+ // for the duplicate definitions found.
+ Property duplicate = null;
+ for (Property property : componentType.getProperties()) {
+ if (property.getName().equals(theProperty.getName()))
+ duplicate = property;
+ }
+ if (duplicate != null)
+ componentType.getProperties().remove(duplicate);
+
+ componentType.getProperties().add(theProperty);
+ // Remember the Java Class (ie the type) for this property
+ implementation.setPropertyClass(theProperty.getName(), propType);
+ } // end if
+ } // end while
+
+ // Finally deal with the beans
+ Iterator<SpringBeanElement> itb;
+ // If there are no explicit service elements, then expose all the beans
+ if (services.isEmpty()) {
+ itb = beans.iterator();
+ // Loop through all the beans found
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+
+ // If its not a valid bean for service, ignore it
+ if (!isValidBeanForService(beanElement)) {
+ continue;
+ }
+ try {
+ // Load the Spring bean class
+ Class<?> beanClass = resolveClass(resolver, beanElement.getClassName(), context);
+ // Introspect the bean
+ beanIntrospector = new SpringBeanIntrospector(registry, beanElement.getCustructorArgs());
+ ComponentType beanComponentType = assemblyFactory.createComponentType();
+ javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType);
+ // Set the service name as bean name
+ for (Service componentService : beanComponentType.getServices()) {
+ componentService.setName(beanElement.getId());
+ }
+ // Get the service interface defined by this Spring Bean and add to
+ // the component type of the Spring Assembly
+ List<Service> beanServices = beanComponentType.getServices();
+ componentType.getServices().addAll(beanServices);
+ // Add these services to the Service / Bean map
+ for (Service beanService : beanServices) {
+ implementation.setBeanForService(beanService, beanElement);
+ }
+ } catch (Throwable e) {
+ // [rfeng] FIXME: Some Spring beans have constructors that take pararemters injected by Spring and
+ // Tuscany is not happy with that during the introspection
+ log.log(Level.SEVERE, e.getMessage(), e);
+ }
+ } // end while
+ } // end if
+
+ itb = beans.iterator();
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+
+ // If its not a valid bean for service, ignore it
+ if (!isValidBeanForService(beanElement)) {
+ continue;
+ }
+ // Ignore if the bean has no properties and constructor arguments
+ if (beanElement.getProperties().isEmpty() && beanElement.getCustructorArgs().isEmpty())
+ continue;
+
+ ComponentType beanComponentType = assemblyFactory.createComponentType();
+
+ try {
+ Class<?> beanClass = resolveClass(resolver, beanElement.getClassName(), context);
+ // Introspect the bean
+ beanIntrospector = new SpringBeanIntrospector(registry, beanElement.getCustructorArgs());
+ javaImplementation = beanIntrospector.introspectBean(beanClass, beanComponentType);
+ } catch (Exception e) {
+ // [rfeng] FIXME: Some Spring beans have constructors that take pararemters injected by Spring and
+ // Tuscany is not happy with that during the introspection
+ log.log(Level.SEVERE, e.getMessage(), e);
+ continue;
+ }
+ Map<String, JavaElementImpl> propertyMap = javaImplementation.getPropertyMembers();
+ JavaConstructorImpl constructor = javaImplementation.getConstructor();
+ // Get the references by this Spring Bean and add the unresolved ones to
+ // the component type of the Spring Assembly
+ List<Reference> beanReferences = beanComponentType.getReferences();
+ List<Property> beanProperties = beanComponentType.getProperties();
+
+ Set<String> excludedNames = new HashSet<String>();
+ Iterator<SpringPropertyElement> itp = beanElement.getProperties().iterator();
+ while (itp.hasNext()) {
+ SpringPropertyElement propertyElement = itp.next();
+ // Exclude the reference that is also known as a spring property
+ excludedNames.add(propertyElement.getName());
+ for (String propertyRef : propertyElement.getRefs()) {
+ if (propertyRefUnresolved(propertyRef, beans, references, scaproperties)) {
+ // This means an unresolved reference from the spring bean...
+ for (Reference reference : beanReferences) {
+ if (propertyElement.getName().equals(reference.getName())) {
+ // The name of the reference in this case is the string in
+ // the @ref attribute of the Spring property element, NOT the
+ // name of the field in the Spring bean....
+ reference.setName(propertyRef);
+ componentType.getReferences().add(reference);
+ break;
+ } // end if
+ } // end for
+
+ // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type
+ for (Property scaproperty : beanProperties) {
+ if (propertyElement.getName().equals(scaproperty.getName())) {
+ // The name of the reference in this case is the string in
+ // the @ref attribute of the Spring property element, NOT the
+ // name of the field in the Spring bean....
+ Class<?> interfaze =
+ resolveClass(resolver,
+ (propertyMap.get(propertyElement.getName()).getType()).getName(),
+ context);
+ Reference theReference = createReference(interfaze, propertyRef);
+ implementation.setUnresolvedBeanRef(propertyRef, theReference);
+ break;
+ } // end if
+ } // end for
+ } // end if
+ } // end for
+ } // end while
+
+ Iterator<SpringConstructorArgElement> itcr = beanElement.getCustructorArgs().iterator();
+ while (itcr.hasNext()) {
+ SpringConstructorArgElement conArgElement = itcr.next();
+ for (String constructorArgRef : conArgElement.getRefs()) {
+ if (propertyRefUnresolved(constructorArgRef, beans, references, scaproperties)) {
+ for (JavaParameterImpl parameter : constructor.getParameters()) {
+ String paramType = parameter.getType().getName();
+ Class<?> interfaze = resolveClass(resolver, paramType, context);
+ // Create a component type reference/property if the constructor-arg element has a
+ // type attribute OR index attribute declared...
+ if ((conArgElement.getType() != null && paramType.equals(conArgElement.getType())) || (conArgElement
+ .getIndex() != -1 && (conArgElement.getIndex() == parameter.getIndex()))) {
+ // [rfeng] Commenting out the following code as the constructor parameter based SCA
+ // references are added already
+ /*
+ if (parameter.getClassifer() == org.oasisopen.sca.annotation.Reference.class) {
+ Reference theReference = createReference(interfaze, constructorArgRef);
+ componentType.getReferences().add(theReference);
+ }
+ */
+ if (parameter.getClassifer() == org.oasisopen.sca.annotation.Property.class) {
+ // Store the unresolved references as unresolvedBeanRef in the Spring Implementation type
+ // we might need to verify with the component definition later.
+ Reference theReference = createReference(interfaze, constructorArgRef);
+ implementation.setUnresolvedBeanRef(constructorArgRef, theReference);
+ }
+ }
+ } // end for
+ } // end if
+ } // end for
+ } // end while
+
+ // [rfeng] Add the remaining introspected references (w/ @Reference but without Spring property ref)
+ for (Reference ref : beanReferences) {
+ if (!excludedNames.contains(ref.getName()) && componentType.getReference(ref.getName()) == null) {
+ // Only add the ones that not listed by sca:reference
+ componentType.getReferences().add(ref);
+ }
+ }
+
+ } // end while
+
+ } catch (ClassNotFoundException e) {
+ // Means that either an interface class, property class or a bean was not found
+ throw new ContributionReadException(e);
+ } catch (InvalidInterfaceException e) {
+ throw new ContributionReadException(e);
+ } // end try
+
+ // If we get here, the Spring assembly component type is resolved
+ componentType.setUnresolved(false);
+ implementation.setComponentType(componentType);
+ return;
+ } // end method generateComponentType
+
+ /*
+ * Determines whether a reference attribute of a Spring property element is resolved either
+ * by a bean in the application context or by an SCA reference element or by an SCA property
+ * element
+ * @param ref - a String containing the name of the reference - may be null
+ * @param beans - a List of SpringBean elements
+ * @param references - a List of SCA reference elements
+ * @return true if the property is not resolved, false if it is resolved
+ */
+ private boolean propertyRefUnresolved(String ref,
+ List<SpringBeanElement> beans,
+ List<SpringSCAReferenceElement> references,
+ List<SpringSCAPropertyElement> scaproperties) {
+ boolean unresolved = true;
+
+ if (ref != null) {
+ // Scan over the beans looking for a match
+ Iterator<SpringBeanElement> itb = beans.iterator();
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+ // Does the bean name match the ref?
+ if (ref.equals(beanElement.getId())) {
+ unresolved = false;
+ break;
+ } // end if
+ } // end while
+ // Scan over the SCA reference elements looking for a match
+ if (unresolved) {
+ Iterator<SpringSCAReferenceElement> itr = references.iterator();
+ while (itr.hasNext()) {
+ SpringSCAReferenceElement referenceElement = itr.next();
+ if (ref.equals(referenceElement.getName())) {
+ unresolved = false;
+ break;
+ } // end if
+ } // end while
+ } // end if
+ // Scan over the SCA property elements looking for a match
+ if (unresolved) {
+ Iterator<SpringSCAPropertyElement> itsp = scaproperties.iterator();
+ while (itsp.hasNext()) {
+ SpringSCAPropertyElement propertyElement = itsp.next();
+ if (ref.equals(propertyElement.getName())) {
+ unresolved = false;
+ break;
+ } // end if
+ } // end while
+ } // end if
+ } else {
+ // In the case where ref = null, the property is not going to be a reference of any
+ // kind and can be ignored
+ unresolved = false;
+ } // end if
+
+ return unresolved;
+
+ } // end method propertyRefUnresolved
+
+ /**
+ * Validates whether the <sca:service>, <sca:reference> and <sca:property> elements
+ * has unique names within the application context.
+ */
+ private void validateBeans(List<SpringBeanElement> beans,
+ List<SpringSCAServiceElement> services,
+ List<SpringSCAReferenceElement> references,
+ List<SpringSCAPropertyElement> scaproperties,
+ Monitor monitor) throws ContributionReadException {
+
+ // The @target attribute of a <service/> subelement of a <beans/> element
+ // MUST have the value of the @name attribute of one of the <bean/>
+ // subelements of the <beans/> element.
+ Iterator<SpringSCAServiceElement> its = services.iterator();
+ while (its.hasNext()) {
+ SpringSCAServiceElement serviceElement = its.next();
+ boolean targetBeanExists = false;
+ Iterator<SpringBeanElement> itb = beans.iterator();
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+ if (serviceElement.getTarget().equals(beanElement.getId()))
+ targetBeanExists = true;
+ }
+ if (!targetBeanExists)
+ error(monitor, "TargetBeanDoesNotExist", beans);
+ } // end while
+
+ // The value of the @name attribute of an <sca:reference/> subelement of a <beans/>
+ // element MUST be unique amongst the @name attributes of the <sca:property/>
+ // subelements and the <bean/> subelements of the <beans/> element.
+ // AND
+ // The @default attribute of a <sca:reference/> subelement of a <beans/>
+ // element MUST have the value of the @name attribute of one of the <bean/>
+ // subelements of the <beans/> element.
+ Iterator<SpringSCAReferenceElement> itr = references.iterator();
+ while (itr.hasNext()) {
+ SpringSCAReferenceElement referenceElement = itr.next();
+ boolean defaultBeanExists = true;
+ boolean isUniqueReferenceName = true;
+ Iterator<SpringBeanElement> itb = beans.iterator();
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+ if (referenceElement.getDefaultBean() != null)
+ if (referenceElement.getDefaultBean().equals(beanElement.getId()))
+ defaultBeanExists = false;
+ if (referenceElement.getName().equals(beanElement.getId()))
+ isUniqueReferenceName = false;
+ }
+ Iterator<SpringSCAPropertyElement> itp = scaproperties.iterator();
+ while (itp.hasNext()) {
+ SpringSCAPropertyElement propertyElement = itp.next();
+ if (referenceElement.getName().equals(propertyElement.getName()))
+ isUniqueReferenceName = false;
+ }
+ if (!defaultBeanExists)
+ error(monitor, "DefaultBeanDoesNotExist", beans);
+ if (!isUniqueReferenceName)
+ error(monitor, "ScaReferenceNameNotUnique", beans);
+ } // end while
+
+ // The value of the @name attribute of an <sca:property/> subelement of a <beans/>
+ // element MUST be unique amongst the @name attributes of the <sca:reference/>
+ // subelements and the <bean/> subelements of the <beans/> element.
+ Iterator<SpringSCAPropertyElement> itp = scaproperties.iterator();
+ while (itp.hasNext()) {
+ SpringSCAPropertyElement propertyElement = itp.next();
+ boolean isUniquePropertyName = true;
+ Iterator<SpringBeanElement> itb = beans.iterator();
+ while (itb.hasNext()) {
+ SpringBeanElement beanElement = itb.next();
+ if (propertyElement.getName().equals(beanElement.getId()))
+ isUniquePropertyName = false;
+ }
+ Iterator<SpringSCAReferenceElement> itrp = references.iterator();
+ while (itrp.hasNext()) {
+ SpringSCAReferenceElement referenceElement = itrp.next();
+ if (propertyElement.getName().equals(referenceElement.getName()))
+ isUniquePropertyName = false;
+ }
+ if (!isUniquePropertyName)
+ error(monitor, "ScaPropertyNameNotUnique", beans);
+ } // end while
+ }
+
+ /**
+ * Validates whether a bean definition is valid for exposing as service.
+ */
+ private boolean isValidBeanForService(SpringBeanElement beanElement) {
+
+ if (beanElement.isInnerBean())
+ return false;
+ if (beanElement.hasParentAttribute())
+ return false;
+ if (beanElement.hasFactoryMethodAttribute())
+ return false;
+ if (beanElement.hasFactoryBeanAttribute())
+ return false;
+ if (beanElement.getClassName() == null)
+ return false;
+ if (beanElement.getClassName().startsWith("org.springframework"))
+ return false;
+ // return true otherwise
+ return true;
+ }
+
+ /**
+ * Gets hold of the application-context.xml file as a Spring resource
+ * @param locationAttr - the location attribute from the <implementation.spring../> element
+ * @param cl - the ClassLoader for the Spring implementation
+ */
+ protected List<URL> getApplicationContextResource(URL url) throws ContributionReadException {
+ File manifestFile = null;
+ File appXmlFile;
+ File appXmlFolder;
+ File locationFile = null;
+ List<URL> appCtxResources = new ArrayList<URL>();
+
+ if (url != null) {
+ String path = url.getPath();
+ locationFile = new File(path);
+ } else {
+ throw new ContributionReadException(
+ "SpringXMLComponentTypeLoader getApplicationContextResource: " + "unable to find resource file "
+ + url);
+ }
+
+ if (locationFile.isDirectory()) {
+ try {
+ manifestFile = new File(locationFile, "META-INF" + File.separator + "MANIFEST.MF");
+ if (manifestFile.exists()) {
+ Manifest mf = new Manifest(new FileInputStream(manifestFile));
+ Attributes mainAttrs = mf.getMainAttributes();
+ String appCtxPath = mainAttrs.getValue("Spring-Context");
+ if (appCtxPath != null) {
+ String[] cxtPaths = appCtxPath.split(";");
+ for (String path : cxtPaths) {
+ appXmlFile = new File(locationFile, path.trim());
+ if (appXmlFile.exists()) {
+ appCtxResources.add(appXmlFile.toURI().toURL());
+ }
+ }
+ return appCtxResources;
+ }
+ }
+ // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the
+ // xml files available in the META-INF/spring folder.
+ appXmlFolder = new File(locationFile, "META-INF" + File.separator + "spring");
+ if (appXmlFolder.exists()) {
+ File[] files = appXmlFolder.listFiles();
+ for (File appFile : files) {
+ if (appFile.getName().endsWith(".xml")) {
+ appCtxResources.add(appFile.toURI().toURL());
+ }
+ }
+ return appCtxResources;
+ }
+ } catch (IOException e) {
+ throw new ContributionReadException("Error reading manifest " + manifestFile);
+ }
+ } else {
+ if (locationFile.isFile() && locationFile.getName().endsWith(".jar")) {
+ try {
+ JarFile jf = new JarFile(locationFile);
+ JarEntry je;
+ Manifest mf = jf.getManifest();
+ if (mf != null) {
+ Attributes mainAttrs = mf.getMainAttributes();
+ String appCtxPath = mainAttrs.getValue("Spring-Context");
+ if (appCtxPath != null) {
+ String[] cxtPaths = appCtxPath.split(";");
+ for (String path : cxtPaths) {
+ je = jf.getJarEntry(path.trim());
+ if (je != null)
+ appCtxResources.add(new URL("jar:" + locationFile.toURI().toURL()
+ + "!/"
+ + appCtxPath));
+ }
+ return appCtxResources;
+ }
+ }
+ // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the
+ // .xml files available in the META-INF/spring folder.
+ Enumeration<JarEntry> entries = jf.entries();
+ while (entries.hasMoreElements()) {
+ je = entries.nextElement();
+ if (je.getName().startsWith("META-INF/spring/") && je.getName().endsWith(".xml")) {
+ appCtxResources.add(new URL("jar:" + locationFile.toURI().toURL() + "!/" + je.getName()));
+ }
+ }
+ return appCtxResources;
+ } catch (IOException e) {
+ // TODO: create a more appropriate exception type
+ throw new ContributionReadException(
+ "SpringXMLComponentTypeLoader getApplicationContextResource: " + " IO exception reading context file.",
+ e);
+ }
+ } else {
+ if (locationFile.getName().endsWith(".xml")) {
+ appCtxResources.add(url);
+ return appCtxResources;
+ } else {
+ // Deal with the directory inside a jar file, in case the contribution itself is a JAR file.
+ try {
+ if (locationFile.getPath().indexOf(".jar") > 0) {
+ String jarPath = url.getPath().substring(5, url.getPath().indexOf("!"));
+ JarFile jf = new JarFile(jarPath);
+ JarEntry je =
+ jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/") + 2) + "/"
+ + "META-INF"
+ + "/"
+ + "MANIFEST.MF");
+ if (je != null) {
+ Manifest mf = new Manifest(jf.getInputStream(je));
+ Attributes mainAttrs = mf.getMainAttributes();
+ String appCtxPath = mainAttrs.getValue("Spring-Context");
+ if (appCtxPath != null) {
+ String[] cxtPaths = appCtxPath.split(";");
+ for (String path : cxtPaths) {
+ je =
+ jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/") + 2) + "/"
+ + path.trim());
+ if (je != null) {
+ appCtxResources.add(new URL("jar:" + url.getPath() + "/" + path.trim()));
+ }
+ }
+ return appCtxResources;
+ }
+ }
+ // No MANIFEST.MF file OR no manifest-specified Spring context , then read all the
+ // .xml files available in the META-INF/spring folder.
+ Enumeration<JarEntry> entries = jf.entries();
+ while (entries.hasMoreElements()) {
+ je = entries.nextElement();
+ if (je.getName().startsWith("META-INF/spring/") && je.getName().endsWith(".xml")) {
+ appCtxResources.add(new URL("jar:" + url.getPath() + "/" + je.getName()));
+ }
+ }
+ return appCtxResources;
+ }
+ } catch (IOException e) {
+ throw new ContributionReadException("Error reading manifest " + manifestFile);
+ }
+ }
+ }
+ }
+
+ throw new ContributionReadException(
+ "SpringXMLComponentTypeLoader getApplicationContextResource: " + "unable to read resource file "
+ + url);
+ } // end method getApplicationContextResource
+
+ /**
+ * Creates a Service for the component type based on its name and Java interface
+ */
+ public Service createService(Class<?> interfaze, String name) throws InvalidInterfaceException {
+ Service service = assemblyFactory.createService();
+ JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract();
+ service.setInterfaceContract(interfaceContract);
+
+ // Set the name for the service
+ service.setName(name);
+
+ // Set the call interface and, if present, the callback interface
+ JavaInterface callInterface = javaFactory.createJavaInterface(interfaze);
+ service.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass());
+ service.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+ return service;
+ } // end method createService
+
+ /**
+ * Creates a Reference for the component type based on its name and Java interface
+ */
+ private org.apache.tuscany.sca.assembly.Reference createReference(Class<?> interfaze, String name)
+ throws InvalidInterfaceException {
+ org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference();
+ JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract();
+ reference.setInterfaceContract(interfaceContract);
+
+ // Set the name of the reference to the supplied name and the multiplicity of the reference
+ // to 1..1 - for Spring implementations, this is the only multiplicity supported
+ reference.setName(name);
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+
+ // Set the call interface and, if present, the callback interface
+ JavaInterface callInterface = javaFactory.createJavaInterface(interfaze);
+ reference.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass());
+ reference.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+
+ return reference;
+ }
+
+ private class ContextClassLoader extends ClassLoader {
+ public ContextClassLoader(ModelResolver resolver, ProcessorContext context) {
+ super();
+ this.resolver = resolver;
+ this.context = context;
+ }
+
+ private ModelResolver resolver;
+ private ProcessorContext context;
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ return SpringXMLComponentTypeLoader.this.resolveClass(resolver, name, context);
+ }
+
+ @Override
+ protected URL findResource(String name) {
+ try {
+ return resolveLocation(resolver, name, context);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected Enumeration<URL> findResources(String name) throws IOException {
+ URL url = findResource(name);
+ if (url != null) {
+ return Collections.enumeration(Arrays.asList(url));
+ } else {
+ Collection<URL> urls = Collections.emptyList();
+ return Collections.enumeration(urls);
+ }
+ }
+ }
+} // end class SpringXMLComponentTypeLoader
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java
new file mode 100644
index 0000000000..4b4144f0c8
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringImplementationProcessor.java
@@ -0,0 +1,244 @@
+/*
+ * 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.implementation.spring.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor;
+import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.spring.SpringImplementation;
+import org.apache.tuscany.sca.implementation.spring.introspect.SpringXMLComponentTypeLoader;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+
+/**
+ * SpringArtifactProcessor is responsible for processing the XML of an <implementation.spring.../>
+ * element in an SCA SCDL file.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SpringImplementationProcessor extends BaseStAXArtifactProcessor implements
+ StAXArtifactProcessor<SpringImplementation> {
+
+ private static final String LOCATION = "location";
+ private static final String IMPLEMENTATION_SPRING = "implementation.spring";
+ private static final QName IMPLEMENTATION_SPRING_QNAME = new QName(Constants.SCA11_NS, IMPLEMENTATION_SPRING);
+ private static final String MSG_LOCATION_MISSING = "Reading implementation.spring - location attribute missing";
+
+ private ExtensionPointRegistry registry;
+ private AssemblyFactory assemblyFactory;
+ private PolicySubjectProcessor policyProcessor;
+
+ private FactoryExtensionPoint factories;
+
+ public SpringImplementationProcessor(ExtensionPointRegistry registry) {
+ this.registry = registry;
+ this.factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ this.policyProcessor = new PolicySubjectProcessor(registry);
+ }
+
+ /**
+ * Report a exception.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-spring-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-spring-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /*
+ * Read the XML and parse out the attributes.
+ *
+ * <implementation.spring.../> has a single required attribute:
+ * "location" - which is the target URI of of an archive file or a directory that contains the Spring
+ * application context files.
+ * If the resource identified by the location attribute is an archive file, then the file
+ * META-INF/MANIFEST.MF is read from the archive.
+ * If the location URI identifies a directory, then META-INF/MANIFEST.MF must exist
+ * underneath that directory.
+ * If the manifest file contains a header "Spring-Context" of the format:
+ * Spring-Context ::= path ( ';' path )*
+ *
+ * Where path is a relative path with respect to the location URI, then the set of paths
+ * specified in the header identify the context configuration files.
+ * If there is no MANIFEST.MF file or no Spring-Context header within that file,
+ * then the default behaviour is to build an application context using all the *.xml files
+ * in the META-INF/spring directory.
+ */
+ public SpringImplementation read(XMLStreamReader reader, ProcessorContext context)
+ throws ContributionReadException, XMLStreamException {
+
+ // Create the Spring implementation
+ SpringImplementation springImplementation = null;
+
+ // Read the location attribute for the spring implementation
+ String springLocation = getURIString(reader, LOCATION);
+ if (springLocation != null) {
+ springImplementation = new SpringImplementation();
+ springImplementation.setLocation(springLocation);
+ springImplementation.setUnresolved(true);
+ processComponentType(springImplementation);
+ } else {
+ error(context.getMonitor(), "LocationAttributeMissing", reader);
+ //throw new ContributionReadException(MSG_LOCATION_MISSING);
+ }
+
+ // Read policies
+ policyProcessor.readPolicies(springImplementation, reader);
+
+ // Skip to end element
+ while (reader.hasNext()) {
+ if (reader.next() == END_ELEMENT && IMPLEMENTATION_SPRING_QNAME.equals(reader.getName())) {
+ break;
+ }
+ } // end while
+
+ return springImplementation;
+ } // end read
+
+ /*
+ * Handles the component type for the Spring implementation
+ * @param springImplementation - a Spring implementation. The component type information
+ * is created for this implementation
+ *
+ */
+ private void processComponentType(SpringImplementation springImplementation) {
+
+ // Create a ComponentType and mark it unresolved
+ ComponentType componentType = assemblyFactory.createComponentType();
+ componentType.setUnresolved(true);
+ springImplementation.setComponentType(componentType);
+ } // end processComponentType
+
+ /*
+ * Write out the XML representation of the Spring implementation
+ * <implementation.spring location="..." />
+ */
+ public void write(SpringImplementation springImplementation, XMLStreamWriter writer, ProcessorContext context)
+ throws ContributionWriteException, XMLStreamException {
+
+ // Write <implementation.spring>
+ writer.writeStartElement(Constants.SCA11_NS, IMPLEMENTATION_SPRING);
+ policyProcessor.writePolicyAttributes(springImplementation, writer);
+
+ if (springImplementation.getLocation() != null) {
+ writer.writeAttribute(LOCATION, springImplementation.getLocation());
+ }
+
+ writer.writeEndElement();
+
+ } // end write
+
+ /**
+ * Resolves the Spring implementation - loads the Spring application-context XML and
+ * derives the spring implementation componentType from it
+ */
+ public void resolve(SpringImplementation springImplementation, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+
+ if (springImplementation == null)
+ return;
+
+ Monitor monitor = context.getMonitor();
+ /* Load the Spring component type by reading the Spring application context */
+ SpringXMLComponentTypeLoader springLoader = new SpringXMLComponentTypeLoader(registry);
+ try {
+ // Load the Spring Implementation information from its application context file...
+ springLoader.load(springImplementation, resolver, context);
+ } catch (ContributionReadException e) {
+ ContributionResolveException ce = new ContributionResolveException(e);
+ error(monitor, "ContributionResolveException", resolver, ce);
+ throw ce;
+ }
+
+ ComponentType ct = springImplementation.getComponentType();
+ if (ct.isUnresolved()) {
+ // If the introspection fails to resolve, try to find a side file...
+ ComponentType componentType = resolver.resolveModel(ComponentType.class, ct, context);
+ if (componentType.isUnresolved()) {
+ error(monitor, "UnableToResolveComponentType", resolver);
+ //throw new ContributionResolveException("SpringArtifactProcessor: unable to resolve componentType for Spring component");
+ } else {
+ springImplementation.setComponentType(componentType);
+ springImplementation.setUnresolved(false);
+ }
+
+ } // end if
+
+ } // end method resolve
+
+ public QName getArtifactType() {
+ return IMPLEMENTATION_SPRING_QNAME;
+ }
+
+ public Class<SpringImplementation> getModelType() {
+ return SpringImplementation.class;
+ }
+
+} // end class SpringArtifactProcessor
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLBeanDefinitionLoader.java b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLBeanDefinitionLoader.java
new file mode 100644
index 0000000000..a3dc353ffc
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLBeanDefinitionLoader.java
@@ -0,0 +1,50 @@
+/*
+ * 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.implementation.spring.xml;
+
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.implementation.spring.SpringBeanElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAPropertyElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAReferenceElement;
+import org.apache.tuscany.sca.implementation.spring.SpringSCAServiceElement;
+
+/**
+ * The utility interface to load Spring XML bean definitions into an application context
+ */
+public interface SpringXMLBeanDefinitionLoader {
+ /**
+ * @param resources
+ * @param serviceElements
+ * @param referenceElements
+ * @param propertyElements
+ * @param beanElements
+ * @param context
+ * @return
+ */
+ Object load(List<URL> resources,
+ List<SpringSCAServiceElement> serviceElements,
+ List<SpringSCAReferenceElement> referenceElements,
+ List<SpringSCAPropertyElement> propertyElements,
+ List<SpringBeanElement> beanElements,
+ ProcessorContext context);
+}
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ImplementationBuilder b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ImplementationBuilder
new file mode 100644
index 0000000000..7ea615051e
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.ImplementationBuilder
@@ -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.implementation.spring.SpringImplementationBuilder;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#implementation.spring
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..880d6fade0
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,20 @@
+# 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.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.implementation.spring.xml.SpringImplementationProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#implementation.spring,model=org.apache.tuscany.sca.implementation.spring.SpringImplementation
+
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions
new file mode 100644
index 0000000000..4a9270d094
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions
@@ -0,0 +1,17 @@
+# 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/implementation/spring/definitions.xml
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties
new file mode 100644
index 0000000000..28bd31ca11
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties
@@ -0,0 +1,28 @@
+#
+#
+# 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.
+#
+#
+LocationAttributeMissing = Reading implementation.spring - location attribute missing
+ContributionResolveException = ContributionResolveException occured due to:
+UnableToResolveComponentType = SpringArtifactProcessor: unable to resolve componentType for Spring component
+ScaServiceNameNotUnique = The value of the @name attribute of an <sca:service/> element MUST be unique amongst the <sca:service/> subelements of the <beans/> element
+ScaReferenceNameNotUnique = The value of the @name attribute of an <sca:reference/> element MUST be unique amongst the <sca:reference/> subelements of the <beans/> element
+ScaPropertyNameNotUnique = The value of the @name attribute of an <sca:property/> element MUST be unique amongst the <sca:property/> subelements of the <beans/> element
+DefaultBeanDoesNotExist = The @default attribute of a <sca:reference/> element MUST have the value of the @name attribute of one of the <bean/> subelements of the <beans/> element.
+TargetBeanDoesNotExist = The @target attribute of a <sca:service/> element MUST have the value of the @name attribute of one of the <bean/> subelements of the <beans/> element.
diff --git a/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/org/apache/tuscany/sca/implementation/spring/definitions.xml b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/org/apache/tuscany/sca/implementation/spring/definitions.xml
new file mode 100644
index 0000000000..18e7b1e60a
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/implementation-spring/src/main/resources/org/apache/tuscany/sca/implementation/spring/definitions.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<sca:definitions xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
+
+ <sca:implementationType type="sca:implementation.spring" mayProvide="" alwaysProvides=""/>
+
+ </sca:definitions>
diff --git a/sandbox/sebastien/java/extend/contrib/modules/pom.xml b/sandbox/sebastien/java/extend/contrib/modules/pom.xml
new file mode 100644
index 0000000000..238ee4dd06
--- /dev/null
+++ b/sandbox/sebastien/java/extend/contrib/modules/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-sca</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-contrib-modules</artifactId>
+ <packaging>pom</packaging>
+ <name>Apache Tuscany SCA Contributed Modules</name>
+
+ <modules>
+ <module>databinding-protobuf</module>
+ <module>host-tomcat</module>
+ </modules>
+
+ <profiles>
+ <profile>
+ <id>eclipse</id>
+ <build>
+ <defaultGoal>org.apache.tuscany.maven.plugins:maven-bundle-plugin:eclipse</defaultGoal>
+ <!--
+ <plugins>
+ <plugin>
+ <groupId>org.apache.tuscany.maven.plugins</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.0.6</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>generate-pde</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>eclipse</goal>
+ </goals>
+ <configuration>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ -->
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${basedir}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>