summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main')
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java43
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java49
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java96
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java72
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/databinding/PropertyDataTypeProcessor.java80
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.java54
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java32
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java86
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java47
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java40
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java43
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java371
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java50
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java83
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java44
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java46
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java47
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java86
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java43
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java47
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java34
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java45
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java131
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java125
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java40
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java399
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java40
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java243
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java169
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java108
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java204
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java56
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java33
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/ResponseDispatchImpl.java224
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.context.PropertyValueFactory17
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions17
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor20
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory20
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.RuntimeWireProcessor17
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/org/apache/tuscany/sca/implementation/java/definitions/definitions.xml30
40 files changed, 3431 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java
new file mode 100644
index 0000000000..e2d99852d8
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.java.context;
+
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+
+/**
+ * Interface for a factory that returns an injected component instance.
+ * This is used by a Component implementation to create new instances of
+ * application implementation objects as determined by the component scope's
+ * lifecycle.
+ * <p/>
+ * The implementation of this interface may be supplied by the user,
+ * may be generated during deployment, or may be dynamic.
+ *
+ * @version $Rev$ $Date$
+ * @param <T> Type of the instance generated by the factory.
+ */
+public interface InstanceFactory<T> {
+ /**
+ * Creates a new instance of the component.
+ * All injected values must be set but any @Init methods must not have been invoked.
+ *
+ * @return A wrapper for the created component instance.
+ */
+ InstanceWrapper<T> newInstance();
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java
new file mode 100644
index 0000000000..df21e013f1
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.java.context;
+
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface InstanceFactoryProvider<T> {
+ /**
+ * Return the implementation class.
+ *
+ * @return the implementation class.
+ */
+ Class<T> getImplementationClass();
+
+ /**
+ * Sets an object factory for an injection site
+ *
+ * @param element the injection site name
+ * @param objectFactory the object factory
+ */
+ void setObjectFactory(JavaElementImpl element, ObjectFactory<?> objectFactory);
+
+ /**
+ * Create an instance factory that can be used to create component instances.
+ *
+ * @return a new instance factory
+ */
+ InstanceFactory<T> createFactory();
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java
new file mode 100644
index 0000000000..f5d9860130
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java
@@ -0,0 +1,96 @@
+/*
+ * 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.java.context;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.implementation.java.injection.Injector;
+import org.apache.tuscany.sca.implementation.java.invocation.EventInvoker;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReflectiveInstanceFactory<T> implements InstanceFactory<T> {
+ private final Constructor<T> ctr;
+ private final ObjectFactory<?>[] ctrArgs;
+ private final Injector<T>[] injectors;
+ private final EventInvoker<T> initInvoker;
+ private final EventInvoker<T> destroyInvoker;
+ private final Injector<T>[] callbackInjectors;
+
+ public ReflectiveInstanceFactory(Constructor<T> ctr,
+ ObjectFactory<?>[] ctrArgs,
+ Injector<T>[] injectors,
+ Injector<T>[] callbackInjectors,
+ EventInvoker<T> initInvoker,
+ EventInvoker<T> destroyInvoker) {
+ this.ctr = ctr;
+ this.ctrArgs = ctrArgs;
+ this.injectors = injectors;
+ this.callbackInjectors = callbackInjectors;
+ this.initInvoker = initInvoker;
+ this.destroyInvoker = destroyInvoker;
+ }
+
+ public InstanceWrapper<T> newInstance() {
+ T instance;
+ try {
+ if (ctrArgs != null) {
+ Object[] args = new Object[ctrArgs.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = ctrArgs[i].getInstance();
+ }
+ instance = ctr.newInstance(args);
+ } else {
+ instance = ctr.newInstance();
+ }
+ } catch (InstantiationException e) {
+ String name = ctr.getDeclaringClass().getName();
+ throw new AssertionError("Class is not instantiable [" + name + "]");
+ } catch (IllegalAccessException e) {
+ String name = ctr.getName();
+ throw new AssertionError("Constructor is not accessible [" + name + "]");
+ } catch (
+ InvocationTargetException e) {
+ String name = ctr.getName();
+ throw new ObjectCreationException("Exception thrown by constructor: " + name, e);
+ }
+
+ if (injectors != null) {
+ for (Injector<T> injector : injectors) {
+ //FIXME Injectors should never be null
+ if (injector != null)
+ try {
+ injector.inject(instance);
+ } catch (Exception e) {
+ if (destroyInvoker != null) {
+ destroyInvoker.invokeEvent(instance);
+ }
+ throw new ObjectCreationException("Exception invoking injector - " + e.getMessage(), e);
+ }
+ }
+ }
+
+ return new ReflectiveInstanceWrapper<T>(instance, initInvoker, destroyInvoker, callbackInjectors);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java
new file mode 100644
index 0000000000..a3ed16dde5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java
@@ -0,0 +1,72 @@
+/*
+ * 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.java.context;
+
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+import org.apache.tuscany.sca.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetInitializationException;
+import org.apache.tuscany.sca.implementation.java.injection.Injector;
+import org.apache.tuscany.sca.implementation.java.invocation.EventInvoker;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReflectiveInstanceWrapper<T> implements InstanceWrapper<T> {
+ private final EventInvoker<T> initInvoker;
+ private final EventInvoker<T> destroyInvoker;
+ private final T instance;
+ private final Injector<T>[] callbackInjectors;
+
+ public ReflectiveInstanceWrapper(T instance, EventInvoker<T> initInvoker, EventInvoker<T> destroyInvoker, Injector<T>[] callbackInjectors) {
+ this.instance = instance;
+ this.initInvoker = initInvoker;
+ this.destroyInvoker = destroyInvoker;
+ this.callbackInjectors = callbackInjectors;
+ }
+
+ public T getInstance() {
+ return instance;
+ }
+
+ public void start() throws TargetInitializationException {
+ if (initInvoker != null) {
+ try {
+ initInvoker.invokeEvent(instance);
+ } catch (Exception e) {
+ try {
+ stop();
+ } catch (TargetDestructionException e1) {
+ throw new TargetInitializationException("TargetDestructionException while handling init exception", e);
+ }
+ throw new TargetInitializationException(e);
+ }
+ }
+ }
+
+ public void stop() throws TargetDestructionException {
+ if (destroyInvoker != null) {
+ destroyInvoker.invokeEvent(instance);
+ }
+ }
+
+ public Injector<T>[] getCallbackInjectors() {
+ return this.callbackInjectors;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/databinding/PropertyDataTypeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/databinding/PropertyDataTypeProcessor.java
new file mode 100644
index 0000000000..16de5bbefb
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/databinding/PropertyDataTypeProcessor.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.databinding;
+
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+
+/**
+ *
+ */
+public class PropertyDataTypeProcessor extends BaseJavaClassVisitor {
+ private Mediator mediator;
+
+ /**
+ * @param registry
+ */
+ public PropertyDataTypeProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ UtilityExtensionPoint utilityExtensionPoint = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.mediator = utilityExtensionPoint.getUtility(Mediator.class);
+ }
+
+ /**
+ * Introspect the property
+ * @param javaElement
+ * @return
+ */
+ private void introspect(Property property, JavaElementImpl javaElement) {
+ // XMLType xmlType = new XMLType(property.getXSDElement(), property.getXSDType());
+ // property.getDataType().setLogical(xmlType);
+ mediator.getDataBindings().introspectType(property.getDataType(), null);
+ }
+
+ @Override
+ public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+ for (Property property : type.getProperties()) {
+ String name = property.getName();
+ JavaElementImpl element = type.getPropertyMembers().get(name);
+ introspect(property, element);
+ DataType dt = property.getDataType();
+ if (dt.getLogical() instanceof XMLType) {
+ XMLType xmlType = (XMLType)dt.getLogical();
+ property.setXSDType(xmlType.getTypeName());
+ property.setXSDElement(xmlType.getElementName());
+ } else {
+ Class<?> baseType = JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType());
+ property.setXSDType(JavaXMLMapper.getXMLType(baseType));
+ }
+ }
+ super.visitEnd(clazz, type);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.java
new file mode 100644
index 0000000000..2513c63e38
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.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.java.injection;
+
+import java.lang.reflect.Array;
+import java.util.List;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>Array</code>
+ * containing object instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class ArrayMultiplicityObjectFactory implements ObjectFactory<Object> {
+
+ private ObjectFactory[] factories;
+
+ private Class interfaceType;
+
+ public ArrayMultiplicityObjectFactory(Class interfaceType, List<ObjectFactory<?>> factories) {
+ assert interfaceType != null : "Interface type was null";
+ assert factories != null : "Object factories were null";
+ this.interfaceType = interfaceType;
+ this.factories = factories.toArray(new ObjectFactory[factories.size()]);
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ Object array = Array.newInstance(interfaceType, factories.length);
+ for (int i = 0; i < factories.length; i++) {
+ Array.set(array, i, factories[i].getInstance());
+ }
+ return array;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java
new file mode 100644
index 0000000000..d8eef18c74
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java
@@ -0,0 +1,32 @@
+/*
+ * 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.java.injection;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+
+/**
+ * Implementations inject a pre-configured context type (interface) on an instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ContextInjector<S, T> extends Injector<T> {
+
+ void setContext(S context) throws ObjectCreationException;
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java
new file mode 100644
index 0000000000..4d97e72bd0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java
@@ -0,0 +1,86 @@
+/*
+ * 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.java.injection;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link org.apache.tuscany.sca.core.factory.ObjectFactory} on a given field
+ *
+ * @version $Rev$ $Date$
+ */
+public class FieldInjector<T> implements Injector<T> {
+
+ private final Field field;
+
+ private final ObjectFactory<?> objectFactory;
+
+ /**
+ * Create an injector and have it use the given <code>ObjectFactory</code> to inject a value on the instance using
+ * the reflected <code>Field</code>
+ */
+ public FieldInjector(Field pField, ObjectFactory<?> objectFactory) {
+ field = pField;
+ // Allow privileged access to set accessibility. Requires ReflectPermission
+ // in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ field.setAccessible(true); // ignore Java accessibility
+ return null;
+ }
+ });
+
+ this.objectFactory = objectFactory;
+ }
+
+ /**
+ * Inject a new value on the given instance
+ */
+ public void inject(T instance) throws ObjectCreationException {
+ inject(instance, objectFactory.getInstance());
+ }
+
+ public void inject(T instance, Object value) {
+ try {
+ field.set(instance, value);
+ } catch (IllegalAccessException e) {
+ throw new ObjectCreationException("Field is not accessible [" + field + "]", e);
+ }
+ }
+
+ public Class<?> getType() {
+ return field.getType();
+ }
+
+ public Type getGenericType() {
+ return field.getGenericType();
+ }
+
+ public void injectNull(T instance) throws ObjectCreationException {
+ inject(instance, null);
+ }
+
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java
new file mode 100644
index 0000000000..8bc2dce76c
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java
@@ -0,0 +1,47 @@
+/*
+ * 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.java.injection;
+
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.inheritfrom
+ */
+public abstract class InjectionRuntimeException extends RuntimeException {
+ private static final long serialVersionUID = -2264137603099898773L;
+
+ public InjectionRuntimeException() {
+ super();
+ }
+
+ public InjectionRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InjectionRuntimeException(String message) {
+ super(message);
+ }
+
+ public InjectionRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java
new file mode 100644
index 0000000000..f0208c4e71
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import java.lang.reflect.Type;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+
+/**
+ * Implementations inject a pre-configured value on an instance
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Injector<T> {
+
+ /**
+ * Inject a value on the given instance
+ */
+ void inject(T instance) throws ObjectCreationException;
+ void injectNull(T instance) throws ObjectCreationException;
+ Class<?> getType();
+ Type getGenericType();
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java
new file mode 100644
index 0000000000..5aeebcca36
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.java.injection;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InvalidAccessorException extends InjectionRuntimeException {
+ private static final long serialVersionUID = 9196299279363310978L;
+
+ public InvalidAccessorException() {
+ super();
+ }
+
+ public InvalidAccessorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidAccessorException(String message) {
+ super(message);
+ }
+
+ public InvalidAccessorException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java
new file mode 100644
index 0000000000..acacd23d8f
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java
@@ -0,0 +1,371 @@
+/*
+ * 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.java.injection;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.common.xml.dom.DOMHelper;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.SimpleTypeMapper;
+import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
+import org.apache.tuscany.sca.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaPropertyValueObjectFactory implements PropertyValueFactory {
+ private Mediator mediator = null;
+ private SimpleTypeMapper simpleTypeMapper;
+ private boolean isSimpleType;
+
+ public JavaPropertyValueObjectFactory(ExtensionPointRegistry registry) {
+ UtilityExtensionPoint utilityExtensionPoint = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.mediator = utilityExtensionPoint.getUtility(Mediator.class);
+ this.simpleTypeMapper = utilityExtensionPoint.getUtility(SimpleTypeMapper.class);
+ }
+
+ public JavaPropertyValueObjectFactory(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ public ObjectFactory createValueFactory(Property property, Object propertyValue, JavaElementImpl javaElement) {
+ Document doc = (Document)propertyValue;
+ List<Node> nodes = getValues(doc);
+ Class<?> javaType = JavaIntrospectionHelper.getBaseType(javaElement.getType(), javaElement.getGenericType());
+ if (property.isMany()) {
+ if (javaElement.getType().isArray()) {
+ return new ArrayObjectFactoryImpl(property, nodes, javaType);
+ } else {
+ return new ListObjectFactoryImpl(property, nodes, javaType);
+ }
+ } else {
+ Object value = null;
+ if (!nodes.isEmpty()) {
+ value = nodes.get(0);
+ }
+ return new ObjectFactoryImpl(property, value, javaType);
+
+ }
+ }
+
+ public ObjectFactory createValueFactory(Property property, Object propertyValue, Class<?> javaType) {
+ Document doc = (Document)propertyValue;
+ List<Node> nodes = getValues(doc);
+ if (property.isMany()) {
+ return new ListObjectFactoryImpl(property, nodes, javaType);
+ } else {
+ Object value = null;
+ if (!nodes.isEmpty()) {
+ value = nodes.get(0);
+ }
+ return new ObjectFactoryImpl(property, value, javaType);
+ }
+ }
+
+ public <B> B createPropertyValue(ComponentProperty property, Class<B> type) {
+
+ validateTypes(property, type);
+
+ ObjectFactory<B> factory = this.createValueFactory(property, property.getValue(), type);
+ return factory.getInstance();
+ }
+
+ private <B> void validateTypes(ComponentProperty property, Class<B> type) {
+ // JAXB seems to do some strange things with conversions, so
+ // we can't rely on the databinding conversion from Node->Java to catch
+ // incompatible types.
+
+ DataType prop1 = property.getProperty().getDataType();
+
+ if ( (prop1 != null) && (type.isAssignableFrom(prop1.getPhysical())) ) {
+ return;
+ } else if ( simpleTypeMapper.getXMLType(type) != null ) {
+ if ( simpleTypeMapper.getXMLType(type).getQName().equals(property.getXSDType()))
+ return;
+ } else if ( isSimpleType(property) ) {
+ if ( type.isAssignableFrom(simpleTypeMapper.getJavaType(property.getXSDType())))
+ return;
+ }
+
+ throw new IllegalArgumentException("Property type " + prop1.getPhysical().getName() + " is not compatible with " + type.getName());
+
+ }
+
+ abstract class ObjectFactoryImplBase implements ObjectFactory {
+ protected SimpleTypeMapper simpleTypeMapper = new SimpleTypeMapperImpl();
+ protected Property property;
+ protected Object propertyValue;
+ protected Class<?> javaType;
+ protected DataType<XMLType> sourceDataType;
+ protected DataType<?> targetDataType;
+
+ public ObjectFactoryImplBase(Property property, Object propertyValue, Class<?> javaType) {
+ this.property = property;
+ this.propertyValue = propertyValue;
+ this.javaType = javaType;
+ sourceDataType =
+ new DataTypeImpl<XMLType>(DOMDataBinding.NAME, Node.class,
+ new XMLType(null, this.property.getXSDType()));
+
+ targetDataType = property.getDataType();
+ if (targetDataType == null) {
+ TypeInfo typeInfo = null;
+ if (this.property.getXSDType() != null) {
+ if (simpleTypeMapper.isSimpleXSDType(this.property.getXSDType())) {
+ typeInfo = new TypeInfo(property.getXSDType(), true, null);
+ } else {
+ typeInfo = new TypeInfo(property.getXSDType(), false, null);
+ }
+ } else {
+ typeInfo = new TypeInfo(property.getXSDType(), false, null);
+ }
+
+ XMLType xmlType = new XMLType(typeInfo);
+ String dataBinding = null; // (String)property.getExtensions().get(DataBinding.class.getName());
+ if (dataBinding != null) {
+ targetDataType = new DataTypeImpl<XMLType>(dataBinding, javaType, xmlType);
+ } else {
+ targetDataType = new DataTypeImpl<XMLType>(dataBinding, javaType, xmlType);
+ mediator.getDataBindings().introspectType(targetDataType, null);
+ }
+ }
+ }
+ }
+
+ class ObjectFactoryImpl extends ObjectFactoryImplBase {
+ private Object result = null;
+
+ public ObjectFactoryImpl(Property property, Object propertyValue, Class<?> javaType) {
+ super(property, propertyValue, javaType);
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ // TUSCANY-3791
+ if (result != null){
+ return result;
+ }
+
+ if (isSimpleType) {
+ try {
+ result = simpleTypeMapper.toJavaObject(property.getXSDType(), (String)propertyValue, null);
+ } catch (NumberFormatException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property.getName()
+ + " with value "
+ + propertyValue, ex);
+ } catch (IllegalArgumentException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property.getName()
+ + " with value "
+ + propertyValue, ex);
+ }
+ } else {
+ result = mediator.mediate(propertyValue, sourceDataType, targetDataType, null);
+ }
+ return result;
+ }
+ }
+
+ class ListObjectFactoryImpl extends ObjectFactoryImplBase {
+ private List result = null;
+
+ public ListObjectFactoryImpl(Property property, List<?> propertyValues, Class<?> javaType) {
+ super(property, propertyValues, javaType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<?> getInstance() throws ObjectCreationException {
+ // TUSCANY-3791
+ if (result != null){
+ return result;
+ }
+
+ if (isSimpleType) {
+ List<Object> values = new ArrayList<Object>();
+ for (String aValue : (List<String>)propertyValue) {
+ try {
+ values.add(simpleTypeMapper.toJavaObject(property.getXSDType(), aValue, null));
+ } catch (NumberFormatException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property
+ .getName()
+ + " with value "
+ + aValue
+ + " from value list of "
+ + propertyValue, ex);
+ } catch (IllegalArgumentException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property
+ .getName()
+ + " with value "
+ + aValue
+ + " from value list of "
+ + propertyValue, ex);
+ }
+ }
+ result = values;
+ } else {
+ List instances = new ArrayList();
+ for (Node aValue : (List<Node>)propertyValue) {
+ instances.add(mediator.mediate(aValue, sourceDataType, targetDataType, null));
+ }
+ result = instances;
+ }
+
+ return result;
+ }
+ }
+
+ class ArrayObjectFactoryImpl extends ObjectFactoryImplBase {
+ private Object result = null;
+
+ public ArrayObjectFactoryImpl(Property property, List<?> propertyValues, Class<?> javaType) {
+ super(property, propertyValues, javaType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getInstance() throws ObjectCreationException {
+ // TUSCANY-3791
+ if (result != null){
+ return result;
+ }
+
+ if (isSimpleType) {
+ int count = 0;
+ Object values = Array.newInstance(javaType, ((List<Object>)propertyValue).size());
+ for (String aValue : (List<String>)propertyValue) {
+ try {
+ Array.set(values, count++, simpleTypeMapper.toJavaObject(property.getXSDType(), aValue, null));
+ } catch (NumberFormatException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property
+ .getName()
+ + " with value "
+ + aValue
+ + " from value list of "
+ + propertyValue, ex);
+ } catch (IllegalArgumentException ex) {
+ throw new ObjectCreationException("Failed to create instance for property " + property
+ .getName()
+ + " with value "
+ + aValue
+ + " from value list of "
+ + propertyValue, ex);
+ }
+ }
+ result = values;
+ } else {
+ Object instances = Array.newInstance(javaType, ((List<Object>)propertyValue).size());
+ int count = 0;
+ for (Node aValue : (List<Node>)propertyValue) {
+ Array.set(instances, count++, mediator.mediate(aValue, sourceDataType, targetDataType, null));
+ }
+ result = instances;
+ }
+
+ return result;
+ }
+ }
+
+ /**
+ * Utility methods
+ */
+
+ /**
+ *
+ * @param property
+ * @return
+ */
+ private boolean isSimpleType(Property property) {
+ if (property.getXSDType() != null) {
+ return simpleTypeMapper.isSimpleXSDType(property.getXSDType());
+ } else {
+ if (property instanceof Document) {
+ Document doc = (Document)property;
+ Element element = doc.getDocumentElement();
+ if (element.getChildNodes().getLength() == 1 && element.getChildNodes().item(0).getNodeType() == Element.TEXT_NODE) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve list of simple property values
+ * @param concatenatedValue
+ * @param javaType
+ * @return
+ */
+ private static List<String> getSimplePropertyValues(String concatenatedValue, Class<?> javaType) {
+ List<String> propValues = new ArrayList<String>();
+ StringTokenizer st = null;
+ if (javaType.getName().equals("java.lang.String")) {
+ st = new StringTokenizer(concatenatedValue, "\"");
+ } else {
+ st = new StringTokenizer(concatenatedValue);
+ }
+ String aToken = null;
+ while (st.hasMoreTokens()) {
+ aToken = st.nextToken();
+ if (aToken.trim().length() > 0) {
+ propValues.add(aToken);
+ }
+ }
+ return propValues;
+ }
+
+ /**
+ * Retrieve the list of complex property values
+ * @param document
+ * @return
+ */
+ private static List<Node> getValues(Document document) {
+ List<Node> propValues = new ArrayList<Node>();
+ if ( document == null )
+ return propValues;
+ // The root is the property element
+ Element rootElement = document.getDocumentElement();
+
+ NodeList nodes = rootElement.getChildNodes();
+ for (int count = 0; count < nodes.getLength(); ++count) {
+ Node node = nodes.item(count);
+ if (node.getNodeType() == Document.ELEMENT_NODE) {
+ propValues.add(DOMHelper.promote(node));
+ }
+ }
+ return propValues;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java
new file mode 100644
index 0000000000..2906897e96
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>List</code>
+ * containing object instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class ListMultiplicityObjectFactory implements ObjectFactory<List<?>> {
+
+ private ObjectFactory[] factories;
+
+ public ListMultiplicityObjectFactory(List<ObjectFactory<?>> factories) {
+ assert factories != null : "Object factories were null";
+ this.factories = factories.toArray(new ObjectFactory[factories.size()]);
+ }
+
+ public List<?> getInstance() throws ObjectCreationException {
+ List<Object> list = new ArrayList<Object>();
+ for (ObjectFactory factory : factories) {
+ list.add(factory.getInstance());
+ }
+ return list;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java
new file mode 100644
index 0000000000..cd43a60ab6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java
@@ -0,0 +1,83 @@
+/*
+ * 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.java.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link org.apache.tuscany.sca.core.factory.ObjectFactory} using a given method
+ *
+ * @version $Rev$ $Date$
+ */
+public class MethodInjector<T> implements Injector<T> {
+ private final Method method;
+ private final ObjectFactory<?> objectFactory;
+
+ public MethodInjector(Method aMethod, ObjectFactory<?> objectFactory) {
+ assert aMethod != null;
+ assert objectFactory != null;
+ this.method = aMethod;
+ // Allow privileged access to set accessibility. Requires ReflectPermission in security
+ // policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ method.setAccessible(true);
+ return null;
+ }
+ });
+ this.objectFactory = objectFactory;
+ }
+
+ public void inject(T instance) throws ObjectCreationException {
+ inject(instance, objectFactory.getInstance());
+ }
+
+ private void inject(T instance, Object value) {
+ try {
+ method.invoke(instance, value);
+ } catch (IllegalAccessException e) {
+ throw new ObjectCreationException("Method is not accessible [" + method + "]", e);
+ } catch (IllegalArgumentException e) {
+ throw new ObjectCreationException("Exception thrown by setter: " + method.getName(), e);
+ } catch (InvocationTargetException e) {
+ throw new ObjectCreationException("Exception thrown by setter: " + method.getName(), e);
+ }
+ }
+
+ public Class<?> getType() {
+ return method.getParameterTypes()[0];
+ }
+
+ public Type getGenericType() {
+ return method.getGenericParameterTypes()[0];
+ }
+
+ public void injectNull(T instance) throws ObjectCreationException {
+ inject(instance, null);
+ }
+
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java
new file mode 100644
index 0000000000..43fb5d6170
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.java.injection;
+
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.oasisopen.sca.RequestContext;
+
+/**
+ * Creates instances of RequestContext for injection on component implementation instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestContextObjectFactory implements ObjectFactory<RequestContext> {
+ private RequestContextFactory factory;
+ private RuntimeComponent component;
+
+ public RequestContextObjectFactory(RequestContextFactory factory, RuntimeComponent component) {
+ this.factory = factory;
+ this.component = component;
+ }
+
+ public RequestContext getInstance() throws ObjectCreationException {
+ return factory.createRequestContext(component);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java
new file mode 100644
index 0000000000..70c368a0e6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java
@@ -0,0 +1,46 @@
+/*
+ * 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.java.injection;
+
+/**
+ * Interface implemented by host environments that allow for resolution of component implementation resources, e.g.
+ * items bound in a JNDI tree.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ResourceHost {
+
+ /**
+ * Resolve a resource matching the given type
+ *
+ * @param type the type of the resources
+ * @throws ResourceResolutionException if an error is encountered during resolution
+ */
+ <T> T resolveResource(Class<T> type) throws ResourceResolutionException;
+
+ /**
+ * Resolve a resource matching the given type and name
+ *
+ * @param type the type of the resources
+ * @param mappedName the mapped name of the resource
+ * @throws ResourceResolutionException if an error is encountered during resolution
+ */
+ <T> T resolveResource(Class<T> type, String mappedName) throws ResourceResolutionException;
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java
new file mode 100644
index 0000000000..d5c1c7b69e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java
@@ -0,0 +1,47 @@
+/*
+ * 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.java.injection;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+
+/**
+ * Denotes an exception thrown when a runtime resource is not found
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceNotFoundException extends ObjectCreationException {
+ private static final long serialVersionUID = 1L;
+
+ public ResourceNotFoundException() {
+ super();
+ }
+
+ public ResourceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+
+ public ResourceNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java
new file mode 100644
index 0000000000..8f55eb18bc
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.java.injection;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Resolves a runtime resource to be injected on a field or method of a Java component type marked with {@link
+ * javax.annotation.Resource}. If the mapped name of the resource is an absolute URI such as
+ * <code>sca://localhost</code> or <code>jndi://localhost</code> the host container namespace is searched; otherwise the
+ * URI is assumed to be relative and the parent composite is searched. If a mapped name is not provided, i.e. resolution
+ * is by type, the parent composite is first searched followed by the host namespace.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceObjectFactory<T> implements ObjectFactory<T> {
+
+ private Class<T> type;
+ private String mappedName;
+ private ResourceHost host;
+ private boolean optional;
+
+ /**
+ * Instantiates a factory that resolves resources by type
+ *
+ * @param type the type of the resource to inject
+ * @param optional true if an error should be thrown if the resource is not found
+ * @param host the runtime resource provider
+ */
+ public ResourceObjectFactory(Class<T> type, boolean optional, ResourceHost host) {
+ this(type, null, optional, host);
+ }
+
+ /**
+ * Instantiates a factory that resolves resources by mapped name
+ *
+ * @param type the type of the resource to inject
+ * @param mappedName the resource name
+ * @param optional true if an error should be thrown if the resource is not found
+ * @param host the runtime resource provider
+ */
+ public ResourceObjectFactory(Class<T> type, String mappedName, boolean optional, ResourceHost host) {
+ this.type = type;
+ this.host = host;
+ this.mappedName = mappedName;
+ this.optional = optional;
+ }
+
+ public T getInstance() throws ObjectCreationException {
+ try {
+ T resource;
+ if (mappedName == null) {
+ resource = host.resolveResource(type);
+ if (!optional && resource == null) {
+ throw new ResourceNotFoundException("Resource not found: " + type.getName());
+ }
+ } else {
+ resource = host.resolveResource(type, mappedName);
+ if (!optional && resource == null) {
+ throw new ResourceNotFoundException("Resource not found: " + mappedName);
+ }
+ }
+ return resource;
+ } catch (ResourceResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java
new file mode 100644
index 0000000000..f94b24762a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.java.injection;
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResourceResolutionException extends Exception {
+ private static final long serialVersionUID = 13421352711315479L;
+
+ public ResourceResolutionException() {
+ super();
+ }
+
+ public ResourceResolutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ResourceResolutionException(String message) {
+ super(message);
+ }
+
+ public ResourceResolutionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java
new file mode 100644
index 0000000000..25c09231c5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java
@@ -0,0 +1,47 @@
+/*
+ * 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.java.invocation;
+
+import org.apache.tuscany.sca.implementation.java.injection.InjectionRuntimeException;
+
+/**
+ * Denotes an error when invoking an event on an object
+ *
+ * @version $Rev$ $Date$
+ */
+public class EventInvocationException extends InjectionRuntimeException {
+ private static final long serialVersionUID = 1480018831708211581L;
+
+ public EventInvocationException() {
+ super();
+ }
+
+ public EventInvocationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EventInvocationException(String message) {
+ super(message);
+ }
+
+ public EventInvocationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java
new file mode 100644
index 0000000000..e6ebb5abc3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java
@@ -0,0 +1,34 @@
+/*
+ * 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.java.invocation;
+
+/**
+ * Performs an invocation on an instance
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EventInvoker<T> {
+
+ /**
+ * Performs the invocation on a given instance
+ *
+ * @throws EventInvocationException
+ */
+ void invokeEvent(T instance) throws EventInvocationException;
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java
new file mode 100644
index 0000000000..1c330ea913
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java
@@ -0,0 +1,45 @@
+/*
+ * 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.java.invocation;
+
+
+/**
+ * Denotes an unknown operation sequence in a conversation
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConversationSequenceException extends Exception {
+ private static final long serialVersionUID = -5744028391493899147L;
+
+ public InvalidConversationSequenceException() {
+ super();
+ }
+
+ public InvalidConversationSequenceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidConversationSequenceException(String message) {
+ super(message);
+ }
+
+ public InvalidConversationSequenceException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java
new file mode 100644
index 0000000000..97b7570faa
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java
@@ -0,0 +1,131 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.invocation.AsyncResponseException;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.oasisopen.sca.ResponseDispatch;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Responsible for asynchronously dispatching an invocation to a Java component
+ * implementation instance
+ *
+ */
+public class JavaAsyncImplementationInvoker extends JavaImplementationInvoker {
+
+ public JavaAsyncImplementationInvoker(Operation operation, Method method, RuntimeComponent component,
+ InterfaceContract interfaceContract) {
+ super( operation, method, component, interfaceContract);
+ assert method != null : "Operation method cannot be null";
+ assert ((JavaOperation) operation).isAsyncServer() : "Operation must be async";
+ } // end constructor
+
+ public Message invoke(Message msg) {
+ Operation op = this.operation;
+
+ Object payload = msg.getBody();
+
+ Object contextId = null;
+
+ // store the current thread context classloader
+ // - replace it with the class loader used to load the java class as per SCA Spec
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+
+ try {
+ // The following call might create a new conversation, as a result, the msg.getConversationID() might
+ // return a new value
+ InstanceWrapper wrapper = scopeContainer.getWrapper(contextId);
+
+ Object instance = wrapper.getInstance();
+
+ // Set the TCCL to the classloader used to load the implementation class
+ Thread.currentThread().setContextClassLoader(instance.getClass().getClassLoader());
+
+ // For an async server method, there is an extra input parameter, which is a DispatchResponse instance
+ // which is typed by the type of the response
+ Class<?> responseType = op.getOutputType().getPhysical();
+ ResponseDispatch<?> dispatch = ResponseDispatchImpl.newInstance(responseType, msg );
+
+ Object ret;
+ Object[] payload2;
+ if (payload != null && !payload.getClass().isArray()) {
+ payload2 = new Object[2];
+ payload2[0] = payload;
+ } else {
+ payload2 = new Object[ ((Object[])payload).length + 1 ];
+ for( int i = 0; i < ((Object[])payload).length; i++) {
+ payload2[i] = ((Object[])payload)[i];
+ } // end for
+ }
+ payload2[ payload2.length - 1 ] = dispatch;
+
+ ret = method.invoke(instance, (Object[])payload2);
+
+ //ret = ((ResponseDispatchImpl<?>)dispatch).get(50, TimeUnit.SECONDS);
+ throw new InvocationTargetException( new AsyncResponseException("AsyncResponse") );
+
+ //scopeContainer.returnWrapper(wrapper, contextId);
+
+ //msg.setBody(ret);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getTargetException();
+ boolean isChecked = false;
+ for (DataType<?> d : operation.getFaultTypes()) {
+ if (d.getPhysical().isInstance(cause)) {
+ isChecked = true;
+ msg.setFaultBody(cause);
+ break;
+ }
+ }
+
+ if (!isChecked) {
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException)cause;
+ }
+ if (cause instanceof Error) {
+ throw (Error)cause;
+ } else {
+ throw new ServiceRuntimeException(cause.getMessage(), cause);
+ }
+ }
+
+ } catch (ObjectCreationException e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ } catch (Exception e) {
+ msg.setFaultBody(e);
+ } finally {
+ // set the tccl
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ return msg;
+ } // end method invoke
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java
new file mode 100644
index 0000000000..6cd16202ba
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.CallbackInterfaceInterceptor;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaCallbackRuntimeWireProcessor implements RuntimeWireProcessor {
+ private static final Logger logger = Logger.getLogger(JavaCallbackRuntimeWireProcessor.class.getName());
+ private InterfaceContractMapper interfaceContractMapper;
+ private JavaInterfaceFactory javaInterfaceFactory;
+
+ public JavaCallbackRuntimeWireProcessor(ExtensionPointRegistry registry) {
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
+
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+ }
+
+ /**
+ * @param interfaceContractMapper
+ * @param javaInterfaceFactory
+ */
+ protected JavaCallbackRuntimeWireProcessor(InterfaceContractMapper interfaceContractMapper,
+ JavaInterfaceFactory javaInterfaceFactory) {
+ super();
+ this.interfaceContractMapper = interfaceContractMapper;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ }
+
+
+ private boolean supportsCallbackInterface(Interface iface, JavaImplementation impl) {
+ if (iface instanceof JavaInterface) {
+ Class<?> ifaceClass = ((JavaInterface)iface).getJavaClass();
+ if (ifaceClass.isAssignableFrom(impl.getJavaClass())) {
+ return true;
+ }
+ }
+ try {
+ Interface implType = javaInterfaceFactory.createJavaInterface(impl.getJavaClass());
+ // Ignore the remotable/conversational testing
+ implType.setRemotable(iface.isRemotable());
+ return interfaceContractMapper.isCompatibleSubset(iface, implType);
+ } catch (InvalidInterfaceException e) {
+ logger.log(Level.WARNING, e.getMessage(), e);
+ return false;
+ }
+ }
+
+ public void process(RuntimeEndpoint endpoint) {
+ // No operation
+ }
+
+ public void process(RuntimeEndpointReference endpointReference) {
+ if(!(endpointReference instanceof RuntimeEndpointReference)) {
+ return;
+ }
+ RuntimeEndpointReference epr = (RuntimeEndpointReference) endpointReference;
+ Contract contract = epr.getReference();
+ if (!(contract instanceof RuntimeComponentReference)) {
+ return;
+ }
+ RuntimeComponent component = (RuntimeComponent) epr.getComponent();
+ if (component == null) {
+ return;
+ }
+ Implementation implementation = component.getImplementation();
+ if (!(implementation instanceof JavaImplementation)) {
+ return;
+ }
+ JavaImplementation javaImpl = (JavaImplementation)implementation;
+ Endpoint callbackEndpoint = epr.getCallbackEndpoint();
+ if (callbackEndpoint != null) {
+ Interface iface = callbackEndpoint.getService().getInterfaceContract().getInterface();
+ if (!supportsCallbackInterface(iface, javaImpl)) {
+ // callback to this impl is not possible, so ensure a callback object is set
+ for (InvocationChain chain : epr.getInvocationChains()) {
+ chain.addInterceptor(Phase.REFERENCE, new CallbackInterfaceInterceptor());
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java
new file mode 100644
index 0000000000..f2a0d576db
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.oasisopen.sca.ComponentContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentContextFactory implements ObjectFactory<ComponentContext> {
+ private final JavaComponentContextProvider component;
+
+
+ public JavaComponentContextFactory(JavaComponentContextProvider component) {
+ this.component = component;
+ }
+
+
+ public ComponentContext getInstance() throws ObjectCreationException {
+ return component.getComponent().getComponentContext();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java
new file mode 100644
index 0000000000..1fa51315c3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java
@@ -0,0 +1,399 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.CallableReferenceObjectFactory;
+import org.apache.tuscany.sca.core.invocation.CallbackReferenceObjectFactory;
+import org.apache.tuscany.sca.core.invocation.CallbackWireObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.invocation.WireObjectFactory;
+import org.apache.tuscany.sca.core.scope.ScopeContainer;
+import org.apache.tuscany.sca.core.scope.TargetResolutionException;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.JavaScopeImpl;
+import org.apache.tuscany.sca.implementation.java.context.InstanceFactory;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.oasisopen.sca.ServiceReference;
+
+/**
+ * The runtime instantiation of Java component implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentContextProvider {
+ private JavaPropertyValueObjectFactory propertyValueFactory;
+ private RuntimeComponent component;
+ private JavaInstanceFactoryProvider<?> instanceFactoryProvider;
+ private ProxyFactory proxyFactory;
+ private InstanceFactory instanceFactory;
+ private JavaScopeImpl scope;
+
+ public JavaComponentContextProvider(RuntimeComponent component,
+ JavaInstanceFactoryProvider configuration,
+ DataBindingExtensionPoint dataBindingExtensionPoint,
+ PropertyValueFactory propertyValueObjectFactory,
+ ComponentContextFactory componentContextFactory,
+ RequestContextFactory requestContextFactory) {
+ super();
+ this.instanceFactoryProvider = configuration;
+ this.proxyFactory = configuration.getProxyFactory();
+ // if (componentContextFactory != null) {
+ // this.componentContext = componentContextFactory.createComponentContext(component, requestContextFactory);
+ // } else {
+ // this.componentContext = new ComponentContextImpl(this, requestContextFactory, this.proxyService);
+ // }
+ this.component = component;
+ this.propertyValueFactory = (JavaPropertyValueObjectFactory) propertyValueObjectFactory;
+ this.scope = ((JavaImplementation)component.getImplementation()).getJavaScope();
+ }
+
+ InstanceWrapper<?> createInstanceWrapper() throws ObjectCreationException {
+ if (instanceFactory == null) {
+ start();
+ }
+ return instanceFactory.newInstance();
+ }
+
+ void configureProperties(List<ComponentProperty> definedProperties) {
+ for (ComponentProperty p : definedProperties) {
+ configureProperty(p);
+ }
+ }
+
+ private void configureProperty(ComponentProperty configuredProperty) {
+ JavaElementImpl element =
+ instanceFactoryProvider.getImplementation().getPropertyMembers().get(configuredProperty.getName());
+
+ if (element != null && configuredProperty.getValue() != null) {
+ if (!(element.getAnchor() instanceof Constructor)) {
+ if(element.getElementType() == ElementType.FIELD) {
+ // Field field = (Field)element.getAnchor();
+ instanceFactoryProvider.getInjectionSites().add(element);
+ /*
+ if(Modifier.isPublic(field.getModifiers())) {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ } else if(field.getAnnotation(org.oasisopen.sca.annotation.Property.class) != null) {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ */
+ } else {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ }
+
+ //Class propertyJavaType = JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType());
+ ObjectFactory<?> propertyObjectFactory =
+ createPropertyValueFactory(configuredProperty, configuredProperty.getValue(), element);
+ instanceFactoryProvider.setObjectFactory(element, propertyObjectFactory);
+
+ JavaConstructorImpl<?> constructor = instanceFactoryProvider.getImplementation().getConstructor();
+ for(JavaElementImpl p: constructor.getParameters()){
+ if(element.getName().equals(p.getName())) {
+ instanceFactoryProvider.setObjectFactory(p, propertyObjectFactory);
+ }
+ }
+ }
+ }
+
+ void start() {
+ List<JavaElementImpl> callbackInjectionList = null;
+
+ // If the component implementation is stateless, we need to inject the callbacks on service invocation
+ // rather than doing it once at the component level.
+ if ( scope.equals(JavaScopeImpl.STATELESS)) {
+ callbackInjectionList = instanceFactoryProvider.getCallbackInjectionSites();
+ } else {
+ callbackInjectionList = instanceFactoryProvider.getInjectionSites();
+ }
+
+ if (!instanceFactoryProvider.getImplementation().getCallbackMembers().isEmpty()) {
+ Map<String, List<EndpointReference>> callbackWires = new HashMap<String, List<EndpointReference>>();
+ for (ComponentService service : component.getServices()) {
+
+ RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference();
+ if (callbackReference != null) {
+ List<EndpointReference> wires = callbackReference.getEndpointReferences();
+ if (!wires.isEmpty()) {
+ RuntimeEndpointReference epr = (RuntimeEndpointReference) wires.get(0);
+ callbackWires.put(epr.getComponentTypeReferenceInterfaceContract().getInterface().toString(),
+ wires);
+ }
+ }
+ }
+
+ for (Map.Entry<String, Collection<JavaElementImpl>> entry : instanceFactoryProvider.getImplementation()
+ .getCallbackMembers().entrySet()) {
+ List<EndpointReference> wires = callbackWires.get(entry.getKey());
+ if (wires == null) {
+ // this can happen when there are no client wires to a
+ // component that has a callback
+ continue;
+ }
+ for(JavaElementImpl element : entry.getValue()) {
+ Class<?> businessInterface = element.getType();
+ ObjectFactory<?> factory = null;
+ if (ServiceReference.class.isAssignableFrom(element.getType())) {
+ businessInterface =
+ JavaIntrospectionHelper.getBusinessInterface(element.getType(), element.getGenericType());
+ factory =
+ new CallbackReferenceObjectFactory(businessInterface, proxyFactory, wires);
+ } else {
+ factory = new CallbackWireObjectFactory(businessInterface, proxyFactory, wires);
+ }
+ if (!(element.getAnchor() instanceof Constructor)) {
+ callbackInjectionList.add(element);
+ }
+ instanceFactoryProvider.setObjectFactory(element, factory);
+ }
+ }
+ }
+ for (Reference ref : instanceFactoryProvider.getImplementation().getReferences()) {
+ JavaElementImpl element =
+ instanceFactoryProvider.getImplementation().getReferenceMembers().get(ref.getName());
+ if (element != null) {
+ if (!(element.getAnchor() instanceof Constructor)) {
+ if(element.getElementType() == ElementType.FIELD) {
+ Field field = (Field)element.getAnchor();
+ if(Modifier.isPublic(field.getModifiers())) {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ } else if(field.getAnnotation(org.oasisopen.sca.annotation.Reference.class) != null) {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ } else {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ }
+ ComponentReference componentReference = null;
+ List<EndpointReference> wireList = null;
+ for (ComponentReference reference : component.getReferences()) {
+ if (reference.getName().equals(ref.getName())) {
+ wireList = ((RuntimeComponentReference)reference).getEndpointReferences();
+ componentReference = reference;
+ break;
+ }
+ }
+ if (ref.getMultiplicity() == Multiplicity.ONE_N || ref.getMultiplicity() == Multiplicity.ZERO_N) {
+ List<ObjectFactory<?>> factories = new ArrayList<ObjectFactory<?>>();
+ Class<?> baseType =
+ JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType());
+ for (int i = 0; i < wireList.size(); i++) {
+ ObjectFactory<?> factory = null;
+ if (ServiceReference.class.isAssignableFrom(baseType)) {
+ Type callableRefType = JavaIntrospectionHelper.getParameterType(element.getGenericType());
+ // Type businessType = JavaIntrospectionHelper.getParameterType(callableRefType);
+ Class<?> businessInterface =
+ JavaIntrospectionHelper.getBusinessInterface(baseType, callableRefType);
+ factory = new CallableReferenceObjectFactory(businessInterface, (RuntimeEndpointReference) wireList.get(i));
+ } else {
+ factory = createObjectFactory(baseType, wireList.get(i));
+ }
+ factories.add(factory);
+ }
+ instanceFactoryProvider.setObjectFactories(element, factories);
+ JavaConstructorImpl<?> constructor = instanceFactoryProvider.getImplementation().getConstructor();
+ for(JavaElementImpl p: constructor.getParameters()){
+ if(element.getName().equals(p.getName())) {
+ instanceFactoryProvider.setObjectFactories(p, factories);
+ }
+ }
+ } else {
+ if (wireList == null && ref.getMultiplicity() == Multiplicity.ONE_ONE) {
+ throw new IllegalStateException("Required reference is missing: " + ref.getName());
+ }
+ if (wireList != null && !wireList.isEmpty()) {
+ ObjectFactory<?> factory = null;
+ if (ServiceReference.class.isAssignableFrom(element.getType())) {
+ Class<?> businessInterface =
+ JavaIntrospectionHelper.getBusinessInterface(element.getType(), element
+ .getGenericType());
+ factory =
+ new CallableReferenceObjectFactory(businessInterface, (RuntimeEndpointReference) wireList.get(0));
+ } else {
+ factory = createObjectFactory(element.getType(), wireList.get(0));
+ }
+ instanceFactoryProvider.setObjectFactory(element, factory);
+ JavaConstructorImpl<?> constructor = instanceFactoryProvider.getImplementation().getConstructor();
+ for(JavaElementImpl p: constructor.getParameters()){
+ if(element.getName().equals(p.getName())) {
+ instanceFactoryProvider.setObjectFactory(p, factory);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //setUpPolicyHandlers();
+ this.instanceFactory = instanceFactoryProvider.createFactory();
+
+ }
+
+ void addResourceFactory(String name, ObjectFactory<?> factory) {
+ JavaResourceImpl resource = instanceFactoryProvider.getImplementation().getResources().get(name);
+
+ if (resource != null && !(resource.getElement().getAnchor() instanceof Constructor)) {
+ instanceFactoryProvider.getInjectionSites().add(resource.getElement());
+ }
+
+ instanceFactoryProvider.setObjectFactory(resource.getElement(), factory);
+ }
+
+ Object createInstance() throws ObjectCreationException {
+ return createInstanceWrapper().getInstance();
+ }
+
+ JavaInstanceFactoryProvider<?> getInstanceFactoryProvider() {
+ return instanceFactoryProvider;
+ }
+
+ void stop() {
+ //cleanUpPolicyHandlers();
+ }
+
+ Invoker createInvoker(Operation operation, InterfaceContract interfaceContract) throws NoSuchMethodException {
+ Class<?> implClass = instanceFactoryProvider.getImplementationClass();
+
+ Method method = JavaInterfaceUtil.findMethod(implClass, operation);
+ if (operation instanceof JavaOperation &&
+ ((JavaOperation) operation).isAsyncServer() ) {
+ return new JavaAsyncImplementationInvoker(operation, method, component, interfaceContract);
+ } else {
+ return new JavaImplementationInvoker(operation, method, component, interfaceContract);
+ } // end if
+ } // end
+
+ private static class OptimizedObjectFactory<T> implements ObjectFactory<T> {
+ private ScopeContainer scopeContainer;
+
+ public OptimizedObjectFactory(ScopeContainer scopeContainer) {
+ super();
+ this.scopeContainer = scopeContainer;
+ }
+
+ public T getInstance() throws ObjectCreationException {
+ try {
+ return (T)scopeContainer.getWrapper(null).getInstance();
+ } catch (TargetResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+
+ }
+
+ private <B> ObjectFactory<B> createObjectFactory(Class<B> interfaze, EndpointReference wire) {
+ // FIXME: [rfeng] Disable the optimization for new as it needs more discussions
+ /*
+ boolean conversational = wire.getSource().getInterfaceContract().getInterface().isConversational();
+ Binding binding = wire.getSource().getBinding();
+ // Check if it's wireable binding for optimization
+ if (!conversational && binding instanceof OptimizableBinding) {
+ OptimizableBinding optimizableBinding = (OptimizableBinding)binding;
+ Component component = optimizableBinding.getTargetComponent();
+ if (component != null) {
+ Implementation implementation = component.getImplementation();
+ // Check if the target component is java component
+ if (implementation instanceof JavaImplementation) {
+ JavaImplementation javaImplementation = (JavaImplementation)implementation;
+ if (interfaze.isAssignableFrom(javaImplementation.getJavaClass())) {
+ ScopedRuntimeComponent scopedComponent = (ScopedRuntimeComponent)component;
+ ScopeContainer scopeContainer = scopedComponent.getScopeContainer();
+ Scope scope = scopeContainer.getScope();
+ if (scope == Scope.COMPOSITE || scope == Scope.STATELESS || scope == Scope.SYSTEM) {
+ boolean optimizable = true;
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ if (chain.getHeadInvoker() != chain.getTailInvoker()) {
+ optimizable = false;
+ break;
+ }
+ }
+ if (optimizable) {
+ return new OptimizedObjectFactory<B>(scopeContainer);
+ }
+ }
+ }
+ }
+ }
+ }
+ */
+ return new WireObjectFactory<B>(interfaze, (RuntimeEndpointReference) wire, proxyFactory);
+ }
+
+ private ObjectFactory<?> createPropertyValueFactory(ComponentProperty property,
+ Object propertyValue,
+ JavaElementImpl javaElement) {
+ return propertyValueFactory.createValueFactory(property, propertyValue, javaElement);
+ }
+
+ /**
+ * @return the component
+ */
+ RuntimeComponent getComponent() {
+ return component;
+ }
+
+ /*private void setUpPolicyHandlers() {
+ for (PolicyHandler policyHandler : policyHandlers.values()) {
+ policyHandler.setUp(component.getImplementation());
+ }
+ }
+
+ private void cleanUpPolicyHandlers() {
+ for (PolicyHandler policyHandler : policyHandlers.values() ) {
+ policyHandler.cleanUp(this);
+ }
+ }*/
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java
new file mode 100644
index 0000000000..4a5ad98e5b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentNameFactory implements ObjectFactory<String> {
+ private final JavaComponentContextProvider componentContextProvider;
+
+
+ public JavaComponentNameFactory(JavaComponentContextProvider component) {
+ this.componentContextProvider = component;
+ }
+
+
+ public String getInstance() throws ObjectCreationException {
+ String uri = componentContextProvider.getComponent().getURI();
+ return uri.substring(uri.lastIndexOf('/')+1);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
new file mode 100644
index 0000000000..69da9019a8
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
@@ -0,0 +1,243 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.ws.Holder;
+
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.scope.Scope;
+import org.apache.tuscany.sca.core.scope.ScopeContainer;
+import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.context.ReflectiveInstanceWrapper;
+import org.apache.tuscany.sca.implementation.java.injection.Injector;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Responsible for synchronously dispatching an invocation to a Java component
+ * implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationInvoker implements Invoker {
+ protected Operation operation;
+ protected Method method;
+ protected boolean allowsPBR;
+
+ @SuppressWarnings("unchecked")
+ protected final ScopeContainer scopeContainer;
+ private final InterfaceContract interfaze;
+
+ public JavaImplementationInvoker(Operation operation, Method method, RuntimeComponent component, InterfaceContract intf) {
+ assert method != null : "Operation method cannot be null";
+ this.method = method;
+ this.operation = operation;
+ this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer();
+ this.allowsPBR = ((JavaImplementation)component.getImplementation()).isAllowsPassByReference(method);
+ this.interfaze = intf;
+ }
+
+ public JavaImplementationInvoker(Operation operation, RuntimeComponent component, InterfaceContract intf) {
+ // used if the method can't be computed statically in advance
+ this.operation = operation;
+ this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer();
+ this.interfaze = intf;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Message invoke(Message msg) {
+
+ Operation op = msg.getOperation();
+ if (op == null) {
+ op = this.operation;
+ }
+ Object payload = msg.getBody();
+
+ Object contextId = null;
+
+ EndpointReference from = msg.getFrom();
+
+ // store the current thread context classloader
+ // as we need to replace it with the class loader
+ // used to load the java class as per SCA Spec
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+
+ try {
+ // The following call might create a new conversation, as a result, the msg.getConversationID() might
+ // return a new value
+ ReflectiveInstanceWrapper wrapper = (ReflectiveInstanceWrapper) scopeContainer.getWrapper(contextId);
+
+ // If there is a callback interface and the implementation is stateless, we need to
+ // inject callbacks at invocation time. For Composite scope, this has already been done.
+ if (( interfaze.getCallbackInterface() != null ) && (scopeContainer.getScope().equals(Scope.STATELESS))){
+ injectCallbacks(wrapper, (JavaInterface)interfaze.getCallbackInterface());
+ }
+
+ Object instance = wrapper.getInstance();
+
+ // If the method couldn't be computed statically, or the instance being
+ // invoked is a user-specified callback object that doesn't implement
+ // the service interface from which the reflective method was obtained,
+ // compute the method object dynamically for this invocation.
+ Method imethod = method;
+ if (imethod == null || !imethod.getDeclaringClass().isInstance(instance)) {
+ try {
+ imethod = JavaInterfaceUtil.findMethod(instance.getClass(), operation);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("Callback object does not provide method " + e.getMessage());
+ }
+ }
+
+ // Set the thread context classloader of the thread used to invoke an operation
+ // of a Java POJO component implementation is the class loader of the contribution
+ // that contains the POJO implementation class.
+
+ Thread.currentThread().setContextClassLoader(instance.getClass().getClassLoader());
+
+ int argumentHolderCount = 0;
+
+ // Holder pattern. Any payload parameters <T> which are should be in holders are placed in Holder<T>.
+ // Only check Holder for remotable interfaces
+ if (imethod != null && op.getInterface().isRemotable()) {
+ List<DataType> inputTypes = op.getInputType().getLogical();
+ for (int i = 0, size = inputTypes.size(); i < size; i++) {
+ if (ParameterMode.IN != op.getParameterModes().get(i)) {
+ // Promote array params from [<T>] to [Holder<T>]
+ Object[] payloadArray = (Object[])payload;
+
+ if ( ParameterMode.INOUT == op.getParameterModes().get(i)) {
+ Object item = payloadArray[i];
+ payloadArray[i] = new Holder(item);
+ } else {
+ // Create an empty Holder since we should not pass values for OUT parameters
+ payloadArray[i] = new Holder();
+ }
+
+ argumentHolderCount++;
+ }
+ }
+ }
+
+ Object ret;
+ if (payload != null && !payload.getClass().isArray()) {
+ ret = imethod.invoke(instance, payload);
+ } else {
+ ret = imethod.invoke(instance, (Object[])payload);
+ }
+
+ scopeContainer.returnWrapper(wrapper, contextId);
+
+
+ if (argumentHolderCount > 0) {
+
+ // Holder pattern. Any payload Holder<T> types are returned as part of the message body.
+ Object[] payloadArray = (Object[])payload;
+ ArrayList<Object> result = new ArrayList<Object>();
+ if (imethod != null) {
+
+ result.add(ret);
+ for (int i = 0, size = op.getParameterModes().size(); i < size; i++) {
+ if (ParameterMode.IN != op.getParameterModes().get(i)) {
+ // Demote array params from Holder<T> to <T>.
+ Holder<Object> item = (Holder<Object>)payloadArray[i];
+ payloadArray[i] = item.value;
+ result.add(payloadArray[i]);
+ }
+ }
+ }
+
+ msg.setBody(result.toArray());
+
+ } else {
+ msg.setBody(ret);
+ }
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getTargetException();
+ boolean isChecked = false;
+ for (DataType<?> d : operation.getFaultTypes()) {
+ if (d.getPhysical().isInstance(cause)) {
+ isChecked = true;
+ msg.setFaultBody(cause);
+ break;
+ }
+ }
+ if (!isChecked) {
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException)cause;
+ }
+ if (cause instanceof Error) {
+ throw (Error)cause;
+ } else {
+ throw new ServiceRuntimeException(cause.getMessage(), cause);
+ }
+ }
+
+ } catch (ObjectCreationException e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ } catch (Exception e) {
+ msg.setFaultBody(e);
+ } finally {
+ // set the tccl
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ return msg;
+ }
+
+ private void injectCallbacks(ReflectiveInstanceWrapper wrapper,
+ JavaInterface callbackInterface) {
+
+ for (Injector injector : wrapper.getCallbackInjectors()) {
+ if (injector != null) {
+ try {
+ if (ServiceReference.class.isAssignableFrom(injector.getType())) {
+ Class<?> intf = JavaIntrospectionHelper.getBusinessInterface(injector.getType(), injector.getGenericType());
+ if ( intf.isAssignableFrom(callbackInterface.getJavaClass())) {
+ injector.inject(wrapper.getInstance());
+ }
+ } else if (injector.getType().isAssignableFrom(callbackInterface.getJavaClass())) {
+ injector.inject(wrapper.getInstance());
+ } else {
+ injector.injectNull(wrapper.getInstance());
+ }
+ } catch (Exception e) {
+ throw new ObjectCreationException("Exception invoking injector - " + e.getMessage(), e);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java
new file mode 100644
index 0000000000..d7abd021f6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java
@@ -0,0 +1,169 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.factory.InstanceWrapper;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.Scope;
+import org.apache.tuscany.sca.core.scope.ScopedImplementationProvider;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.injection.RequestContextObjectFactory;
+import org.apache.tuscany.sca.implementation.java.injection.ResourceHost;
+import org.apache.tuscany.sca.implementation.java.injection.ResourceObjectFactory;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.oasisopen.sca.ComponentContext;
+import org.oasisopen.sca.RequestContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationProvider implements ScopedImplementationProvider {
+ private JavaImplementation implementation;
+ private JavaComponentContextProvider componentContextProvider;
+ private RequestContextFactory requestContextFactory;
+
+ public JavaImplementationProvider(RuntimeComponent component,
+ JavaImplementation implementation,
+ ProxyFactory proxyService,
+ DataBindingExtensionPoint dataBindingRegistry,
+ PropertyValueFactory propertyValueObjectFactory,
+ ComponentContextFactory componentContextFactory,
+ RequestContextFactory requestContextFactory) {
+ super();
+ this.implementation = implementation;
+ this.requestContextFactory = requestContextFactory;
+
+ try {
+ JavaInstanceFactoryProvider configuration = new JavaInstanceFactoryProvider(implementation);
+ configuration.setProxyFactory(proxyService);
+ componentContextProvider =
+ new JavaComponentContextProvider(component,
+ configuration,
+ dataBindingRegistry,
+ propertyValueObjectFactory,
+ componentContextFactory,
+ requestContextFactory);
+
+ Scope scope = getScope();
+
+ componentContextProvider.configureProperties(component.getProperties());
+ handleResources(implementation, proxyService);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ }
+
+ private void handleResources(JavaImplementation componentType, ProxyFactory proxyService) {
+ for (JavaResourceImpl resource : componentType.getResources().values()) {
+ String name = resource.getName();
+
+ ObjectFactory<?> objectFactory =
+ (ObjectFactory<?>)componentContextProvider.getInstanceFactoryProvider().getFactories().get(resource.getElement());
+ if (objectFactory == null) {
+ Class<?> type = resource.getElement().getType();
+ if (ComponentContext.class.equals(type)) {
+ objectFactory = new JavaComponentContextFactory(componentContextProvider);
+ } else if (RequestContext.class.equals(type)) {
+ objectFactory = new RequestContextObjectFactory(requestContextFactory, componentContextProvider.getComponent());
+ } else if (String.class.equals(type)) {
+ objectFactory = new JavaComponentNameFactory(componentContextProvider);
+ } else {
+ boolean optional = resource.isOptional();
+ String mappedName = resource.getMappedName();
+ objectFactory = createResourceObjectFactory(type, mappedName, optional, null);
+ }
+ }
+ componentContextProvider.addResourceFactory(name, objectFactory);
+ }
+ }
+
+ private <T> ResourceObjectFactory<T> createResourceObjectFactory(Class<T> type,
+ String mappedName,
+ boolean optional,
+ ResourceHost host) {
+ return new ResourceObjectFactory<T>(type, mappedName, optional, host);
+ }
+
+ public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
+ try {
+ return componentContextProvider.createInvoker(operation, service.getInterfaceContract());
+ } catch (NoSuchMethodException e) {
+ // It's possible that the instance being invoked is a user-specified
+ // callback object that isn't an instance of the component implementation
+ // class. As an attempt to deal with this, look up a method object from
+ // the service interface. This isn't foolproof, as it's possible that
+ // the service interface isn't a Java interface, or that the callback
+ // object has the right method signature without implementing the
+ // callback interface. There is code in JavaImplementationInvoker
+ // to deal with these possibilities.
+ Interface iface = service.getInterfaceContract().getInterface();
+ if (iface instanceof JavaInterface) {
+ try {
+ Method method = JavaInterfaceUtil.findMethod(((JavaInterface)iface).getJavaClass(), operation);
+ return new JavaImplementationInvoker(operation, method, componentContextProvider.getComponent(), service.getInterfaceContract());
+ } catch (NoSuchMethodException e1) {
+ throw new IllegalArgumentException(e1);
+ }
+ } else {
+ return new JavaImplementationInvoker(operation, componentContextProvider.getComponent(), service.getInterfaceContract());
+ }
+ }
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ public Scope getScope() {
+ return new Scope(implementation.getJavaScope().getScope());
+ }
+
+ public void start() {
+ componentContextProvider.start();
+ }
+
+ public void stop() {
+ componentContextProvider.stop();
+ }
+
+ public InstanceWrapper<?> createInstanceWrapper() {
+ return componentContextProvider.createInstanceWrapper();
+ }
+
+ public boolean isEagerInit() {
+ return implementation.isEagerInit();
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java
new file mode 100644
index 0000000000..b59966a39e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java
@@ -0,0 +1,108 @@
+/*
+ * 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.java.invocation;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.context.PropertyValueFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.CglibProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationProviderFactory implements ImplementationProviderFactory<JavaImplementation> {
+ private static final Logger logger = Logger.getLogger(JavaImplementationProviderFactory.class.getName());
+ private PropertyValueFactory propertyValueFactory;
+ private DataBindingExtensionPoint databindings;
+ private ProxyFactory proxyFactory;
+ private ComponentContextFactory componentContextFactory;
+ private RequestContextFactory requestContextFactory;
+
+ public JavaImplementationProviderFactory(ExtensionPointRegistry registry) {
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ MessageFactory messageFactory = factories.getFactory(MessageFactory.class);
+
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ InterfaceContractMapper interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+
+ ProxyFactoryExtensionPoint proxyFactories = registry.getExtensionPoint(ProxyFactoryExtensionPoint.class);
+ try {
+ proxyFactories.setClassProxyFactory(new CglibProxyFactory(messageFactory, interfaceContractMapper));
+ } catch (NoClassDefFoundError e) {
+ logger.log(Level.WARNING, "Class-based proxy is not supported", e);
+ }
+
+ databindings = registry.getExtensionPoint(DataBindingExtensionPoint.class);
+ propertyValueFactory = factories.getFactory(PropertyValueFactory.class);
+
+ ContextFactoryExtensionPoint contextFactories = registry.getExtensionPoint(ContextFactoryExtensionPoint.class);
+ componentContextFactory = contextFactories.getFactory(ComponentContextFactory.class);
+ requestContextFactory = contextFactories.getFactory(RequestContextFactory.class);
+
+ proxyFactory = ExtensibleProxyFactory.getInstance(registry);
+ }
+
+ /*
+ public JavaImplementationProviderFactory(ProxyFactory proxyService,
+ DataBindingExtensionPoint dataBindingRegistry,
+ PropertyValueFactory propertyValueObjectFactory,
+ ComponentContextFactory componentContextFactory,
+ RequestContextFactory requestContextFactory) {
+ super();
+ this.proxyFactory = proxyService;
+ this.databindings = dataBindingRegistry;
+ this.propertyValueFactory = propertyValueObjectFactory;
+ this.componentContextFactory = componentContextFactory;
+ this.requestContextFactory = requestContextFactory;
+ }
+ */
+
+ public ImplementationProvider createImplementationProvider(RuntimeComponent component,
+ JavaImplementation implementation) {
+ return new JavaImplementationProvider(component,
+ implementation,
+ proxyFactory,
+ databindings,
+ propertyValueFactory,
+ componentContextFactory,
+ requestContextFactory);
+ }
+
+ public Class<JavaImplementation> getModelType() {
+ return JavaImplementation.class;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java
new file mode 100644
index 0000000000..1f1f1eefdc
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java
@@ -0,0 +1,204 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.context.InstanceFactory;
+import org.apache.tuscany.sca.implementation.java.context.InstanceFactoryProvider;
+import org.apache.tuscany.sca.implementation.java.context.ReflectiveInstanceFactory;
+import org.apache.tuscany.sca.implementation.java.injection.ArrayMultiplicityObjectFactory;
+import org.apache.tuscany.sca.implementation.java.injection.FieldInjector;
+import org.apache.tuscany.sca.implementation.java.injection.Injector;
+import org.apache.tuscany.sca.implementation.java.injection.InvalidAccessorException;
+import org.apache.tuscany.sca.implementation.java.injection.ListMultiplicityObjectFactory;
+import org.apache.tuscany.sca.implementation.java.injection.MethodInjector;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+
+/**
+ * Encapsulates configuration for a Java-based atomic component
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T> {
+ private JavaImplementation definition;
+ private ProxyFactory proxyService;
+
+ private final List<JavaElementImpl> injectionSites;
+ private final EventInvoker<T> initInvoker;
+ private final EventInvoker<T> destroyInvoker;
+ private final Map<JavaElementImpl, Object> factories = new HashMap<JavaElementImpl, Object>();
+ private final List<JavaElementImpl> callbackInjectionSites;
+
+ public JavaInstanceFactoryProvider(JavaImplementation definition) {
+ this.definition = definition;
+ this.initInvoker = definition.getInitMethod() == null ? null : new MethodEventInvoker<T>(definition
+ .getInitMethod());
+ this.destroyInvoker = definition.getDestroyMethod() == null ? null : new MethodEventInvoker<T>(definition
+ .getDestroyMethod());
+ injectionSites = new ArrayList<JavaElementImpl>();
+ callbackInjectionSites = new ArrayList<JavaElementImpl>();
+ }
+
+ ProxyFactory getProxyFactory() {
+ return proxyService;
+ }
+
+ void setProxyFactory(ProxyFactory proxyService) {
+ this.proxyService = proxyService;
+ }
+
+ /**
+ * @return the definition
+ */
+ JavaImplementation getImplementation() {
+ return definition;
+ }
+
+ @SuppressWarnings("unchecked")
+ public InstanceFactory<T> createFactory() {
+ ObjectFactory<?>[] initArgs = getConstructorArgs();
+ Injector<T>[] injectors = getInjectors(false);
+ Injector<T>[] callbackInjectors = getInjectors(true);
+ return new ReflectiveInstanceFactory<T>((Constructor<T>)definition.getConstructor().getConstructor(),
+ initArgs, injectors, callbackInjectors, initInvoker, destroyInvoker);
+ }
+
+
+
+ private ObjectFactory<?>[] getConstructorArgs() {
+ JavaConstructorImpl<?> constructor = definition.getConstructor();
+ ObjectFactory<?>[] initArgs = new ObjectFactory<?>[constructor.getParameters().length];
+ for (int i = 0; i < initArgs.length; i++) {
+ ObjectFactory<?> factory = (ObjectFactory<?>)factories.get(constructor.getParameters()[i]);
+ assert factory != null;
+ initArgs[i] = factory;
+ }
+ return initArgs;
+ }
+
+
+
+ @SuppressWarnings("unchecked")
+ private Injector<T>[] getInjectors(boolean callback) {
+ List<JavaElementImpl> sites = null;
+ if ( callback )
+ sites = callbackInjectionSites;
+ else
+ sites = injectionSites;
+
+ // work around JDK1.5 issue with allocating generic arrays
+ Injector<T>[] injectors = new Injector[sites.size()];
+
+ int i = 0;
+ for (JavaElementImpl element : sites) {
+ Object obj = factories.get(element);
+ if (obj != null) {
+ if (obj instanceof ObjectFactory) {
+ ObjectFactory<?> factory = (ObjectFactory<?>)obj;
+ Member member = (Member)element.getAnchor();
+ if (element.getElementType() == ElementType.FIELD) {
+ injectors[i++] = new FieldInjector<T>((Field)member, factory);
+ } else if (element.getElementType() == ElementType.PARAMETER && member instanceof Method) {
+ injectors[i++] = new MethodInjector<T>((Method)member, factory);
+ } else if (member instanceof Constructor) {
+ // Ignore
+ } else {
+ throw new AssertionError(String.valueOf(element));
+ }
+ } else {
+ injectors[i++] = createMultiplicityInjector(element, (List<ObjectFactory<?>>)obj);
+ }
+ }
+ }
+ return injectors;
+ }
+
+ private Injector<T> createMultiplicityInjector(JavaElementImpl element, List<ObjectFactory<?>> factories) {
+ Class<?> interfaceType = JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType());
+
+ if (element.getAnchor() instanceof Field) {
+ Field field = (Field)element.getAnchor();
+ if (field.getType().isArray()) {
+ return new FieldInjector<T>(field, new ArrayMultiplicityObjectFactory(interfaceType, factories));
+ } else {
+ return new FieldInjector<T>(field, new ListMultiplicityObjectFactory(factories));
+ }
+ } else if (element.getAnchor() instanceof Method) {
+ Method method = (Method)element.getAnchor();
+ if (method.getParameterTypes()[0].isArray()) {
+ return new MethodInjector<T>(method, new ArrayMultiplicityObjectFactory(interfaceType, factories));
+ } else {
+ return new MethodInjector<T>(method, new ListMultiplicityObjectFactory(factories));
+ }
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method: " + element.getName());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class<T> getImplementationClass() {
+ return (Class<T>)definition.getJavaClass();
+ }
+
+ public void setObjectFactory(JavaElementImpl element, ObjectFactory<?> objectFactory) {
+ factories.put(element, objectFactory);
+ }
+
+ public void setObjectFactories(JavaElementImpl element, List<ObjectFactory<?>> objectFactory) {
+ factories.put(element, objectFactory);
+ }
+
+ /**
+ * @return the injectionSites
+ */
+ List<JavaElementImpl> getInjectionSites() {
+ return injectionSites;
+ }
+
+ /**
+ * @return the callbackInjectionSites
+ */
+ public List<JavaElementImpl> getCallbackInjectionSites() {
+ return callbackInjectionSites;
+ }
+
+ /**
+ * @return the factories
+ */
+ Map<JavaElementImpl, Object> getFactories() {
+ return factories;
+ }
+
+
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java
new file mode 100644
index 0000000000..515a7c8a43
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java
@@ -0,0 +1,56 @@
+/*
+ * 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.java.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+/**
+ * Performs an wire on a method of a given instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class MethodEventInvoker<T> implements EventInvoker<T> {
+ private final Method method;
+
+ /**
+ * Instantiates an invoker for the given method
+ */
+ public MethodEventInvoker(Method method) {
+ assert method != null;
+ this.method = method;
+ }
+
+ public void invokeEvent(T instance) throws EventInvocationException {
+ try {
+ method.invoke(instance, (Object[]) null);
+ } catch (IllegalArgumentException e) {
+ String name = method.getName();
+ throw new EventInvocationException("Exception thrown by event method [" + name + "]", e.getCause());
+ } catch (IllegalAccessException e) {
+ String name = method.getName();
+ throw new EventInvocationException("Method is not accessible [" + name + "]");
+ } catch (InvocationTargetException e) {
+ String name = method.getName();
+ throw new EventInvocationException("Exception thrown by event method [" + name + "]", e.getCause());
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java
new file mode 100644
index 0000000000..dbc5c6b640
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.java.invocation;
+
+
+/**
+ * Raised when a component has conversational scope but no conversational contract
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoConversationalContractException extends Exception {
+ private static final long serialVersionUID = -1157790036638157539L;
+
+ public NoConversationalContractException(String message) {
+ super(message);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/ResponseDispatchImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/ResponseDispatchImpl.java
new file mode 100644
index 0000000000..dc0bb94bde
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/ResponseDispatchImpl.java
@@ -0,0 +1,224 @@
+/*
+ * 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.java.invocation;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.context.CompositeContext;
+import org.apache.tuscany.sca.context.ThreadMessageContext;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.AsyncFaultWrapper;
+import org.apache.tuscany.sca.core.invocation.AsyncResponseHandler;
+import org.apache.tuscany.sca.core.invocation.CallbackReferenceObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.oasisopen.sca.ResponseDispatch;
+import org.oasisopen.sca.ServiceReference;
+
+/**
+ * Implementation of the ResponseDispatch interface of the OASIS SCA Java API
+ *
+ * This is used for invocations of asynchronous services, where it is passed as a parameter on async service operations
+ * and it provides the path by which the service implementation returns the response to the request, or a Fault
+ *
+ * Note that this class is serializable and can be serialized, stored and deserialized by the service implementation
+ *
+ * @param <T> - type of the response message
+ */
+public class ResponseDispatchImpl<T> implements ResponseDispatch<T>, Serializable {
+
+ /**
+ * Generated serialVersionUID value
+ */
+ private static final long serialVersionUID = 300158355992568592L;
+ private static String WS_MESSAGE_ID = "WS_MESSAGE_ID";
+ private static String MESSAGE_ID = "MESSAGE_ID";
+
+ // A latch used to ensure that the sendResponse() and sendFault() operations are used at most once
+ // The latch is initialized with the value "false"
+ private AtomicBoolean latch = new AtomicBoolean();
+
+ private final Lock lock = new ReentrantLock();
+ private final Condition completed = lock.newCondition();
+
+ // The result
+ private volatile T response = null;
+ private volatile Throwable fault = null;
+
+ private ExtensionPointRegistry registry;
+
+ // Service Reference used for the callback
+ private ServiceReference<AsyncResponseHandler<?>> callbackRef;
+ private String callbackAddress;
+ private String messageID;
+
+ public ResponseDispatchImpl( Message msg ) {
+ super();
+ callbackRef = getAsyncCallbackRef( msg );
+
+ callbackAddress = msg.getFrom().getCallbackEndpoint().getURI();
+
+ // TODO - why is WS stuff bleeding into general code?
+ messageID = (String) msg.getHeaders().get(MESSAGE_ID);
+ if (messageID == null){
+ messageID = (String) msg.getHeaders().get(WS_MESSAGE_ID);
+ }
+
+ } // end constructor
+
+ public static <T> ResponseDispatchImpl<T> newInstance( Class<T> type, Message msg ) {
+ return new ResponseDispatchImpl<T>( msg );
+ }
+
+ /**
+ * Provide Context data for this ResponseDispatch that the service implementation can use
+ */
+ public Map<String, Object> getContext() {
+ return null;
+ }
+
+ /**
+ * Send a Fault. Must only be invoked once for this ResponseDispatch object
+ * @param e - the Fault to send
+ * @throws IllegalStateException if either the sendResponse method or the sendFault method have been called previously
+ */
+ public void sendFault(Throwable e) {
+ if( sendOK() ) {
+ lock.lock();
+ try {
+ fault = e;
+ completed.signalAll();
+ } finally {
+ lock.unlock();
+ } // end try
+ } else {
+ throw new IllegalStateException("sendResponse() or sendFault() has been called previously");
+ } // end if
+ // Now dispatch the response to the callback...
+ AsyncResponseHandler<T> handler = (AsyncResponseHandler<T>) callbackRef.getService();
+ setResponseHeaders();
+ handler.setFault(new AsyncFaultWrapper(e));
+ } // end method sendFault
+
+ /**
+ * Send the response message. Must only be invoked once for this ResponseDispatch object
+ * @throws IllegalStateException if either the sendResponse method or the sendFault method have been called previously
+ * @param res - the response message, which is of type T
+ */
+ public void sendResponse(T res) {
+ if( sendOK() ) {
+ lock.lock();
+ try {
+ response = res;
+ completed.signalAll();
+ } finally {
+ lock.unlock();
+ } // end try
+ } else {
+ throw new IllegalStateException("sendResponse() or sendFault() has been called previously");
+ } // end if
+ // Now dispatch the response to the callback...
+ AsyncResponseHandler<T> handler = (AsyncResponseHandler<T>) callbackRef.getService();
+ setResponseHeaders();
+ handler.setResponse(res);
+ } // end method sendResponse
+
+ public T get(long timeout, TimeUnit unit) throws Throwable {
+ lock.lock();
+ try {
+ // wait for result to be available
+ if( response == null && fault == null ) completed.await( timeout, unit);
+ if( response != null ) return response;
+ if( fault != null ) throw fault;
+ } finally {
+ lock.unlock();
+ } // end try
+
+ return null;
+ } // end method get
+
+ /**
+ * Indicates that sending a response is OK - this is a transactional
+ * query in that it also updates the state of this ResponseDispatch, so
+ * that it will return true once and once only
+ * @return - true if it is OK to send the response, false otherwise
+ */
+ private boolean sendOK() {
+ return latch.compareAndSet(false, true);
+ }
+
+ /**
+ * Creates a service reference for the async callback, based on information contained in the supplied message
+ * @param msg - the incoming message
+ * @return - a CallBackServiceReference
+ */
+ @SuppressWarnings("unchecked")
+ private ServiceReference<AsyncResponseHandler<?>> getAsyncCallbackRef( Message msg ) {
+ RuntimeEndpointReference callbackEPR = (RuntimeEndpointReference) msg.getHeaders().get("ASYNC_CALLBACK");
+ if( callbackEPR == null ) return null;
+
+ CompositeContext compositeContext = callbackEPR.getCompositeContext();
+ registry = compositeContext.getExtensionPointRegistry();
+ ProxyFactory proxyFactory = ExtensibleProxyFactory.getInstance(registry);
+ List<EndpointReference> eprList = new ArrayList<EndpointReference>();
+ eprList.add(callbackEPR);
+ ObjectFactory<?> factory = new CallbackReferenceObjectFactory(AsyncResponseHandler.class, proxyFactory, eprList);
+
+ return (ServiceReference<AsyncResponseHandler<?>>) factory.getInstance();
+
+ } // end method getAsyncCallbackEPR
+
+ /**
+ * Sets the values of various headers in the response message
+ */
+ private void setResponseHeaders() {
+ // Is there an existing message context?
+ Message msgContext = ThreadMessageContext.getMessageContext();
+ if( msgContext == null ) {
+ // Create a message context
+ msgContext = getMessageFactory().createMessage();
+ } // end if
+
+ // Add in the header for the RelatesTo Message ID
+ msgContext.getHeaders().put(WS_MESSAGE_ID, messageID);
+ msgContext.getHeaders().put(MESSAGE_ID, messageID);
+
+ ThreadMessageContext.setMessageContext(msgContext);
+ } // end method setResponseHeaders
+
+ private MessageFactory getMessageFactory() {
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ return modelFactories.getFactory(MessageFactory.class);
+ } // end method getMessageFactory
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.context.PropertyValueFactory b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.context.PropertyValueFactory
new file mode 100644
index 0000000000..9d5f943f46
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.context.PropertyValueFactory
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions
new file mode 100644
index 0000000000..2b67aa59ca
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org/apache/tuscany/sca/implementation/java/definitions/definitions.xml
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor
new file mode 100644
index 0000000000..e649b68466
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation
+# 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
+# "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.
+#
+# NOTE: The ranking attribute is important for the JavaClassVistors
+# Some visitors need to be called after the others
+org.apache.tuscany.sca.implementation.java.databinding.PropertyDataTypeProcessor;ranking=750
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
new file mode 100644
index 0000000000..1c2626706b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Implementation class for the implementation extension
+org.apache.tuscany.sca.implementation.java.invocation.JavaImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.java.JavaImplementation
+
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.RuntimeWireProcessor b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.RuntimeWireProcessor
new file mode 100644
index 0000000000..07008049e8
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.RuntimeWireProcessor
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org.apache.tuscany.sca.implementation.java.invocation.JavaCallbackRuntimeWireProcessor
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/org/apache/tuscany/sca/implementation/java/definitions/definitions.xml b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/org/apache/tuscany/sca/implementation/java/definitions/definitions.xml
new file mode 100644
index 0000000000..e790317458
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/implementation-java-runtime/src/main/resources/org/apache/tuscany/sca/implementation/java/definitions/definitions.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<sca:definitions xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
+
+ <sca:implementationType type="sca:implementation.java" mayProvide="" alwaysProvides=""/>
+
+ </sca:definitions>