summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java176
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java212
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java130
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java146
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java129
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java77
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java70
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java68
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java59
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java91
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java91
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java53
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java93
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java44
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java67
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java66
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java151
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java54
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java112
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java75
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java163
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java55
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java167
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java57
24 files changed, 2406 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAGenericApplicationContext.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SCAParentApplicationContext.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringContextTie.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/context/tie/SpringImplementationStub.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringBeanElement.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringConstructorArgElement.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringElementTie.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringPropertyElement.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAPropertyElement.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java
new file mode 100644
index 0000000000..0bcbb73583
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAReferenceElement.java
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import javax.xml.namespace.QName;
+
+
+/**
+ * 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<QName> intentNames = new ArrayList<QName>();
+ private List<QName> policySetNames = new ArrayList<QName>();
+
+
+ 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<QName> getIntentNames() {
+ return intentNames;
+ }
+
+ public List<QName> getPolicySetNames() {
+ return policySetNames;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAReferenceElement [name=").append(name).append(", type=").append(type)
+ .append(", defaultBean=").append(defaultBean).append(", intentNames=").append(intentNames)
+ .append(", policySetNames=").append(policySetNames).append("]");
+ return builder.toString();
+ }
+
+
+} // end class SpringSCAReferenceElement
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java
new file mode 100644
index 0000000000..2322d19e1f
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/elements/tie/SpringSCAServiceElement.java
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import javax.xml.namespace.QName;
+
+
+/**
+ * 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<QName> intentNames = new ArrayList<QName>();
+ private List<QName> policySetNames = new ArrayList<QName>();
+
+
+ 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<QName> getIntentNames() {
+ return intentNames;
+ }
+
+ public List<QName> getPolicySetNames() {
+ return policySetNames;
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpringSCAServiceElement [name=").append(name).append(", type=").append(type)
+ .append(", target=").append(target).append(", intentNames=").append(intentNames)
+ .append(", policySetNames=").append(policySetNames).append("]");
+ return builder.toString();
+ }
+
+} // end class SpringSCAServiceElement
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/SCANamespaceHandlerResolver.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java
new file mode 100644
index 0000000000..27b1811b86
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaNamespaceHandler.java
@@ -0,0 +1,93 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.namespace.QName;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * 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());
+ }
+
+ private static String getNamespaceURI(Element element, String prefix) {
+ if (element == null) {
+ return null;
+ }
+ String name = ("".equals(prefix)) ? "xmlns" : "xmlns:" + prefix;
+ String ns = element.getAttribute(name);
+ if (ns != null && !"".equals(ns)) {
+ return ns;
+ }
+ Node parent = element.getParentNode();
+ if (parent instanceof Element) {
+ return getNamespaceURI((Element)parent, prefix);
+ } else {
+ return null;
+ }
+ }
+
+ public static List<QName> resolve(Element element, String listOfNames) {
+ List<QName> qnames = new ArrayList<QName>();
+ StringTokenizer tokenizer = new StringTokenizer(listOfNames);
+ while (tokenizer.hasMoreTokens()) {
+ String qname = tokenizer.nextToken();
+ String prefix = "";
+ String local = qname;
+ int index = qname.indexOf(':');
+ if (index != -1) {
+ local = qname.substring(index + 1);
+ prefix = qname.substring(0, index);
+ }
+ String ns = getNamespaceURI(element, prefix);
+ if (ns != null) {
+ qnames.add(new QName(ns, local, prefix));
+ } else {
+ throw new IllegalArgumentException("Prefix " + prefix + "is not bound to a namespace");
+ }
+ }
+ return qnames;
+ }
+
+ public static String getAttribute(Element element, String name) {
+ String attr = element.getAttributeNS(null, name);
+ if ("".equals(attr)) {
+ return null;
+ } else {
+ return attr;
+ }
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaPropertyBeanDefinitionParser.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java
new file mode 100644
index 0000000000..8470d2ffd5
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaReferenceBeanDefinitionParser.java
@@ -0,0 +1,67 @@
+/*
+ * 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 static org.apache.tuscany.sca.implementation.spring.namespace.tie.ScaNamespaceHandler.getAttribute;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+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(getAttribute(element, "name"), getAttribute(element, "type"));
+ referenceElement.setDefaultBean(getAttribute(element, "default"));
+
+ String requires = getAttribute(element, "requires");
+ if (requires != null) {
+ List<QName> qnames = ScaNamespaceHandler.resolve(element, requires);
+ referenceElement.getIntentNames().addAll(qnames);
+ }
+
+ String policySets = getAttribute(element, "policySets");
+ if (policySets != null) {
+ List<QName> qnames = ScaNamespaceHandler.resolve(element, policySets);
+ referenceElement.getPolicySetNames().addAll(qnames);
+ }
+
+ context.addSCAReferenceElement(referenceElement);
+ }
+
+ // do nothing, this is handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java
new file mode 100644
index 0000000000..900356698d
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/tie/ScaServiceBeanDefinitionParser.java
@@ -0,0 +1,66 @@
+/*
+ * 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 static org.apache.tuscany.sca.implementation.spring.namespace.tie.ScaNamespaceHandler.getAttribute;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+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(getAttribute(element, "name"), getAttribute(element, "target"));
+ serviceElement.setType(getAttribute(element, "type"));
+
+ String requires = getAttribute(element, "requires");
+ if (requires != null) {
+ List<QName> qnames = ScaNamespaceHandler.resolve(element, requires);
+ serviceElement.getIntentNames().addAll(qnames);
+ }
+
+ String policySets = getAttribute(element, "policySets");
+ if (policySets != null) {
+ List<QName> qnames = ScaNamespaceHandler.resolve(element, policySets);
+ serviceElement.getPolicySetNames().addAll(qnames);
+ }
+
+ context.addSCAServiceElement(serviceElement);
+ }
+ // do nothing, handled by Tuscany
+ return null;
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentNameAnnotationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ComponentStub.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ConstructorAnnotationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/InitDestroyAnnotationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyAnnotationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/PropertyValueStub.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/ReferenceAnnotationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-spring-tie/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/tie/SpringXMLLoaderTie.java b/sca-java-2.x/tags/2.0.1-RC1/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/sca-java-2.x/tags/2.0.1-RC1/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;
+
+ }
+
+}