summaryrefslogtreecommitdiffstats
path: root/branches/sca-android/modules/implementation-java-runtime/src
diff options
context:
space:
mode:
Diffstat (limited to 'branches/sca-android/modules/implementation-java-runtime/src')
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java43
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java49
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java86
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java56
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.java54
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java32
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ConversationIDObjectFactory.java39
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java67
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java45
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java35
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java43
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java325
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java50
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java64
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java55
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java46
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java51
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java87
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java43
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java47
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java34
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java46
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java106
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java40
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java404
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java40
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java199
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java204
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java76
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java183
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java126
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java56
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java34
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java74
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java103
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator18
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/MultiplicityTestCase.java34
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapperTestCase.java84
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/CallbackWireObjectFactoryTestCase.java54
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjectorTestCase.java49
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactoryTestCase.java449
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodEventInvokerTestCase.java76
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjectorTestCase.java80
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactoryTestCase.java33
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactoryTestCase.java89
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactory.java39
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactoryTestCase.java33
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactory.java120
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactoryTestCase.java77
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean1.java50
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean2.java51
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Entry.java32
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/JavaIntrospectionHelperTestCase.java185
-rw-r--r--branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/SuperBean.java48
54 files changed, 4643 insertions, 0 deletions
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactory.java
new file mode 100644
index 0000000000..ac8af3ed64
--- /dev/null
+++ b/branches/sca-android/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.context.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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/InstanceFactoryProvider.java
new file mode 100644
index 0000000000..a93710d266
--- /dev/null
+++ b/branches/sca-android/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.impl.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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java
new file mode 100644
index 0000000000..b5d3254fa0
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.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.context;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.sca.core.context.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;
+
+ public ReflectiveInstanceFactory(Constructor<T> ctr,
+ ObjectFactory<?>[] ctrArgs,
+ Injector<T>[] injectors,
+ EventInvoker<T> initInvoker,
+ EventInvoker<T> destroyInvoker) {
+ this.ctr = ctr;
+ this.ctrArgs = ctrArgs;
+ this.injectors = injectors;
+ 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)
+ injector.inject(instance);
+ }
+ }
+
+ return new ReflectiveInstanceWrapper<T>(instance, initInvoker, destroyInvoker);
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java
new file mode 100644
index 0000000000..5285caa481
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.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.context;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetInitializationException;
+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;
+
+ public ReflectiveInstanceWrapper(T instance, EventInvoker<T> initInvoker, EventInvoker<T> destroyInvoker) {
+ this.instance = instance;
+ this.initInvoker = initInvoker;
+ this.destroyInvoker = destroyInvoker;
+ }
+
+ public T getInstance() {
+ return instance;
+ }
+
+ public void start() throws TargetInitializationException {
+ if (initInvoker != null) {
+ initInvoker.invokeEvent(instance);
+ }
+ }
+
+
+ public void stop() throws TargetDestructionException {
+ if (destroyInvoker != null) {
+ destroyInvoker.invokeEvent(instance);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ArrayMultiplicityObjectFactory.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ContextInjector.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ConversationIDObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ConversationIDObjectFactory.java
new file mode 100644
index 0000000000..ffce7ce467
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ConversationIDObjectFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
+
+/**
+ * Object Factory that is used to retrieve the ConversationID from the
+ * Message on the ThreadMessageContext.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConversationIDObjectFactory implements ObjectFactory {
+
+ public ConversationIDObjectFactory() {
+ }
+
+ public Object getInstance() {
+ return ThreadMessageContext.getMessageContext().getFrom().getReferenceParameters().getConversationID();
+
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java
new file mode 100644
index 0000000000..dd454be7c5
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjector.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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 {
+ try {
+ field.set(instance, objectFactory.getInstance());
+ } catch (IllegalAccessException e) {
+ throw new ObjectCreationException("Field is not accessible [" + field + "]", e);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.java
new file mode 100644
index 0000000000..4a8c8f31b8
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InjectionRuntimeException.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.injection;
+
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class InjectionRuntimeException extends RuntimeException {
+
+ 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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java
new file mode 100644
index 0000000000..4d062859b9
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/Injector.java
@@ -0,0 +1,35 @@
+/*
+ * 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 value on an instance
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Injector<T> {
+
+ /**
+ * Inject a value on the given instance
+ */
+ void inject(T instance) throws ObjectCreationException;
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/InvalidAccessorException.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java
new file mode 100644
index 0000000000..695dea3343
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactory.java
@@ -0,0 +1,325 @@
+/*
+ * 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.context.PropertyValueFactory;
+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.DOMHelper;
+import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
+import org.apache.tuscany.sca.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.introspect.impl.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 boolean isSimpleType;
+
+ public JavaPropertyValueObjectFactory(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ public ObjectFactory createValueFactory(Property property, Object propertyValue, JavaElementImpl javaElement) {
+ isSimpleType = isSimpleType(property);
+ Document doc = (Document)propertyValue;
+ Class javaType = JavaIntrospectionHelper.getBaseType(javaElement.getType(), javaElement.getGenericType());
+ Element rootElement = doc.getDocumentElement();
+ if (property.isMany()) {
+ if (isSimpleType) {
+ String value = "";
+ if (rootElement.getChildNodes().getLength() > 0) {
+ value = rootElement.getChildNodes().item(0).getTextContent();
+ }
+ List<String> values = getSimplePropertyValues(value, javaType);
+ if ( javaElement.getType().isArray() ) {
+ return new ArrayObjectFactoryImpl(property, values, isSimpleType, javaType);
+ } else {
+ return new ListObjectFactoryImpl(property, values, isSimpleType, javaType);
+ }
+ } else {
+ if ( javaElement.getType().isArray() ) {
+ return new ArrayObjectFactoryImpl(property, getComplexPropertyValues(doc), isSimpleType, javaType);
+ } else {
+ return new ListObjectFactoryImpl(property, getComplexPropertyValues(doc), isSimpleType, javaType);
+ }
+ }
+ } else {
+ if (isSimpleType) {
+ String value = "";
+ if (rootElement.getChildNodes().getLength() > 0) {
+ value = rootElement.getChildNodes().item(0).getTextContent();
+ }
+ return new ObjectFactoryImpl(property, value, isSimpleType, javaType);
+ } else {
+ List<Node> nodes = getComplexPropertyValues(doc);
+ Object value = null;
+ if (!nodes.isEmpty()) {
+ value = nodes.get(0);
+ }
+ return new ObjectFactoryImpl(property, value, isSimpleType, javaType);
+ }
+
+ }
+ }
+
+ public ObjectFactory createValueFactory(Property property, Object propertyValue, Class javaType) {
+ isSimpleType = isSimpleType(property);
+ Document doc = (Document)propertyValue;
+ Element rootElement = doc.getDocumentElement();
+ if (property.isMany()) {
+ if (isSimpleType) {
+ String value = "";
+ if (rootElement.getChildNodes().getLength() > 0) {
+ value = rootElement.getChildNodes().item(0).getTextContent();
+ }
+ List<String> values = getSimplePropertyValues(value, javaType);
+ return new ListObjectFactoryImpl(property, values, isSimpleType, javaType);
+ } else {
+ return new ListObjectFactoryImpl(property, getComplexPropertyValues(doc), isSimpleType, javaType);
+ }
+ } else {
+ if (isSimpleType) {
+ String value = "";
+ if (rootElement.getChildNodes().getLength() > 0) {
+ value = rootElement.getChildNodes().item(0).getTextContent();
+ }
+ return new ObjectFactoryImpl(property, value, isSimpleType, javaType);
+ } else {
+ List<Node> nodes = getComplexPropertyValues(doc);
+ Object value = null;
+ if (!nodes.isEmpty()) {
+ value = nodes.get(0);
+ }
+ return new ObjectFactoryImpl(property, value, isSimpleType, javaType);
+ }
+
+ }
+ }
+
+ private boolean isSimpleType(Property property) {
+ if (property.getXSDType() != null) {
+ return SimpleTypeMapperImpl.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;
+ }
+
+ private 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;
+ }
+
+ private List<Node> getComplexPropertyValues(Document document) {
+ Element rootElement = document.getDocumentElement();
+ List<Node> propValues = new ArrayList<Node>();
+ NodeList nodes = rootElement.getChildNodes();
+ for (int count = 0; count < nodes.getLength(); ++count) {
+ if (nodes.item(count).getNodeType() == Document.ELEMENT_NODE) {
+ propValues.add(DOMHelper.promote(nodes.item(count)));
+ }
+ }
+ return propValues;
+ }
+
+ public 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;
+ boolean isSimpleType;
+
+ public ObjectFactoryImplBase(Property property, Object propertyValue, boolean isSimpleType, Class javaType) {
+ this.isSimpleType = isSimpleType;
+ this.property = property;
+ this.propertyValue = propertyValue;
+ this.javaType = javaType;
+ sourceDataType = new DataTypeImpl<XMLType>(DOMDataBinding.NAME, Node.class, new XMLType(null, this.property
+ .getXSDType()));
+ TypeInfo typeInfo = null;
+ if (this.property.getXSDType() != null) {
+ if (SimpleTypeMapperImpl.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);
+ }
+ }
+ }
+
+ public class ObjectFactoryImpl extends ObjectFactoryImplBase {
+ public ObjectFactoryImpl(Property property, Object propertyValue, boolean isSimpleType, Class javaType) {
+ super(property, propertyValue, isSimpleType, javaType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getInstance() throws ObjectCreationException {
+ if (isSimpleType) {
+ try {
+ return 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 {
+ return mediator.mediate(propertyValue, sourceDataType, targetDataType, null);
+ // return null;
+ }
+ }
+ }
+
+ public class ListObjectFactoryImpl extends ObjectFactoryImplBase {
+ public ListObjectFactoryImpl(Property property, List<?> propertyValues, boolean isSimpleType, Class javaType) {
+ super(property, propertyValues, isSimpleType, javaType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<?> getInstance() throws ObjectCreationException {
+ 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);
+ }
+ }
+ return values;
+ } else {
+ List instances = new ArrayList();
+ for (Node aValue : (List<Node>)propertyValue) {
+ instances.add(mediator.mediate(aValue, sourceDataType, targetDataType, null));
+ }
+ return instances;
+ }
+ }
+ }
+
+ public class ArrayObjectFactoryImpl extends ObjectFactoryImplBase {
+ public ArrayObjectFactoryImpl(Property property, List<?> propertyValues, boolean isSimpleType, Class javaType) {
+ super(property, propertyValues, isSimpleType, javaType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getInstance() throws ObjectCreationException {
+ 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);
+ }
+ }
+ return 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));
+ }
+ return instances;
+ }
+ }
+ }
+
+ /**
+ * This method will create an instance of the value for the specified Property.
+ *
+ * @param property The Property from which to retrieve the property value
+ * @param type The type of the property value being retrieved from the Property
+ * @param <B> Type type of the property value being looked up
+ *
+ * @return the value for the Property
+ */
+ public <B> B createPropertyValue(ComponentProperty property, Class<B> type)
+ {
+ ObjectFactory<B> factory = this.createValueFactory(property, property.getValue(), type);
+ return factory.getInstance();
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ListMultiplicityObjectFactory.java
new file mode 100644
index 0000000000..9f587f58de
--- /dev/null
+++ b/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java
new file mode 100644
index 0000000000..baf9eb9cc1
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjector.java
@@ -0,0 +1,64 @@
+/*
+ * 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.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 {
+ try {
+ method.invoke(instance, objectFactory.getInstance());
+ } 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);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java
new file mode 100644
index 0000000000..ca9c08fe63
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.context.RequestContextImpl;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.osoa.sca.RequestContext;
+
+/**
+ * Creates instances of
+ * {@link org.apache.tuscany.sca.core.context.RequestContextImpl} for
+ * injection on component implementation instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestContextObjectFactory implements ObjectFactory<RequestContext> {
+ private RequestContextFactory factory;
+ private ProxyFactory proxyFactory;
+
+ public RequestContextObjectFactory(RequestContextFactory factory) {
+ this(factory, null);
+ }
+
+ public RequestContextObjectFactory(RequestContextFactory factory, ProxyFactory proxyFactory) {
+ this.factory = factory;
+ this.proxyFactory = proxyFactory;
+ }
+
+ public RequestContext getInstance() throws ObjectCreationException {
+ if (factory != null) {
+ return factory.createRequestContext();
+ } else {
+ return new RequestContextImpl(proxyFactory);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceHost.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java
new file mode 100644
index 0000000000..17450f43cb
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceNotFoundException.java
@@ -0,0 +1,51 @@
+/*
+ * 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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java
new file mode 100644
index 0000000000..5d4d999453
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactory.java
@@ -0,0 +1,87 @@
+/*
+ * 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;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ 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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/injection/ResourceResolutionException.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java
new file mode 100644
index 0000000000..135fde09ff
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.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.invocation;
+
+import org.apache.tuscany.sca.core.invocation.TargetInvocationException;
+
+/**
+ * Denotes an unknown operation sequence in a conversation
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConversationSequenceException extends TargetInvocationException {
+ 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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java
new file mode 100644
index 0000000000..ef4e67d79a
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java
@@ -0,0 +1,106 @@
+/*
+ * 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.Implementation;
+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.EndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+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;
+
+ /**
+ * @param interfaceContractMapper
+ * @param javaInterfaceFactory
+ */
+ public JavaCallbackRuntimeWireProcessor(InterfaceContractMapper interfaceContractMapper,
+ JavaInterfaceFactory javaInterfaceFactory) {
+ super();
+ this.interfaceContractMapper = interfaceContractMapper;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ }
+
+ public void process(RuntimeWire wire) {
+ addCallbackInterfaceInterceptors(wire);
+ }
+
+ private void addCallbackInterfaceInterceptors(RuntimeWire wire) {
+ Contract contract = wire.getSource().getContract();
+ if (!(contract instanceof RuntimeComponentReference)) {
+ return;
+ }
+ RuntimeComponent component = wire.getSource().getComponent();
+ Implementation implementation = component.getImplementation();
+ if (!(implementation instanceof JavaImplementation)) {
+ return;
+ }
+ JavaImplementation javaImpl = (JavaImplementation)implementation;
+ EndpointReference callbackEndpoint = wire.getSource().getCallbackEndpoint();
+ if (callbackEndpoint != null) {
+ Interface iface = callbackEndpoint.getContract().getInterfaceContract().getInterface();
+ if (!supportsCallbackInterface(iface, javaImpl)) {
+ // callback to this impl is not possible, so ensure a callback object is set
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ chain.addInterceptor(Phase.REFERENCE, new CallbackInterfaceInterceptor());
+ }
+ }
+ }
+ }
+
+ 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());
+ implType.setConversational(iface.isConversational());
+ return interfaceContractMapper.isCompatible(iface, implType);
+ } catch (InvalidInterfaceException e) {
+ logger.log(Level.WARNING, e.getMessage(), e);
+ return false;
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java
new file mode 100644
index 0000000000..2903cc6fc8
--- /dev/null
+++ b/branches/sca-android/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.osoa.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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java
new file mode 100644
index 0000000000..e585b3d46f
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java
@@ -0,0 +1,404 @@
+/*
+ * 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.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.Multiplicity;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.context.ComponentContextImpl;
+import org.apache.tuscany.sca.core.context.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.impl.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.impl.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.injection.ConversationIDObjectFactory;
+import org.apache.tuscany.sca.implementation.java.injection.InvalidAccessorException;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.implementation.java.introspect.impl.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.annotations.ConversationID;
+
+/**
+ * The runtime instantiation of Java component implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentContextProvider {
+ private JavaPropertyValueObjectFactory propertyValueFactory;
+ private DataBindingExtensionPoint dataBindingRegistry;
+ private RuntimeComponent component;
+ private JavaInstanceFactoryProvider<?> instanceFactoryProvider;
+ private ProxyFactory proxyFactory;
+
+ public JavaComponentContextProvider(RuntimeComponent component,
+ JavaInstanceFactoryProvider configuration,
+ DataBindingExtensionPoint dataBindingExtensionPoint,
+ JavaPropertyValueObjectFactory 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.dataBindingRegistry = dataBindingExtensionPoint;
+ this.propertyValueFactory = propertyValueObjectFactory;
+ }
+
+ InstanceWrapper<?> createInstanceWrapper() throws ObjectCreationException {
+ return instanceFactoryProvider.createFactory().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.osoa.sca.annotations.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() {
+ if (!instanceFactoryProvider.getImplementation().getCallbackMembers().isEmpty()) {
+ Map<String, List<RuntimeWire>> callbackWires = new HashMap<String, List<RuntimeWire>>();
+ for (ComponentService service : component.getServices()) {
+
+ RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference();
+ if (callbackReference != null) {
+ List<RuntimeWire> wires = callbackReference.getRuntimeWires();
+ if (!wires.isEmpty()) {
+ callbackWires.put(wires.get(0).getSource().getInterfaceContract().getInterface().toString(),
+ wires);
+ }
+ }
+ }
+
+ for (Map.Entry<String, Collection<JavaElementImpl>> entry : instanceFactoryProvider.getImplementation()
+ .getCallbackMembers().entrySet()) {
+ List<RuntimeWire> 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 (CallableReference.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)) {
+ instanceFactoryProvider.getInjectionSites().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.osoa.sca.annotations.Reference.class) != null) {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ } else {
+ instanceFactoryProvider.getInjectionSites().add(element);
+ }
+ }
+ ComponentReference componentReference = null;
+ List<RuntimeWire> wireList = null;
+ for (ComponentReference reference : component.getReferences()) {
+ if (reference.getName().equals(ref.getName())) {
+ wireList = ((RuntimeComponentReference)reference).getRuntimeWires();
+ 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 (CallableReference.class.isAssignableFrom(baseType)) {
+ Type callableRefType = JavaIntrospectionHelper.getParameterType(element.getGenericType());
+ // Type businessType = JavaIntrospectionHelper.getParameterType(callableRefType);
+ Class<?> businessInterface =
+ JavaIntrospectionHelper.getBusinessInterface(baseType, callableRefType);
+ factory =
+ new CallableReferenceObjectFactory(businessInterface, component,
+ (RuntimeComponentReference)wireList.get(i)
+ .getSource().getContract(), wireList.get(i)
+ .getSource().getBinding());
+ } 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 (CallableReference.class.isAssignableFrom(element.getType())) {
+ Class<?> businessInterface =
+ JavaIntrospectionHelper.getBusinessInterface(element.getType(), element
+ .getGenericType());
+ factory =
+ new CallableReferenceObjectFactory(businessInterface, component,
+ (RuntimeComponentReference)componentReference, null);
+ } 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);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // We need to set the PropertyValueFactory on the ComponentContextImpl
+ // so the ComponentContext can "de-marshal" the property type to a value
+ // when the getProperty() method is called
+ ComponentContextImpl ccImpl = (ComponentContextImpl)component.getComponentContext();
+ ccImpl.setPropertyValueFactory(propertyValueFactory);
+
+ //setUpPolicyHandlers();
+ }
+
+ 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);
+ }
+
+ void addConversationIDFactories(List<Member> names) {
+ ObjectFactory<String> factory = new ConversationIDObjectFactory();
+ for (Member name : names) {
+ if (name instanceof Field) {
+ JavaElementImpl element = new JavaElementImpl((Field)name);
+ element.setClassifer(ConversationID.class);
+ instanceFactoryProvider.setObjectFactory(element, factory);
+ } else if (name instanceof Method) {
+ JavaElementImpl element = new JavaElementImpl((Method)name, 0);
+ element.setName(JavaIntrospectionHelper.toPropertyName(name.getName()));
+ element.setClassifer(ConversationID.class);
+ instanceFactoryProvider.setObjectFactory(element, factory);
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method: " + name.getName());
+ }
+ }
+ }
+
+ Object createInstance() throws ObjectCreationException {
+ return createInstanceWrapper().getInstance();
+ }
+
+ JavaInstanceFactoryProvider<?> getInstanceFactoryProvider() {
+ return instanceFactoryProvider;
+ }
+
+ void stop() {
+ //cleanUpPolicyHandlers();
+ }
+
+ Invoker createInvoker(Operation operation) throws NoSuchMethodException {
+ Class<?> implClass = instanceFactoryProvider.getImplementationClass();
+
+ Method method = JavaInterfaceUtil.findMethod(implClass, operation);
+ return new JavaImplementationInvoker(operation, method, component);
+ }
+
+ 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, RuntimeWire 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, 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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
new file mode 100644
index 0000000000..25d538cff4
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
@@ -0,0 +1,199 @@
+/*
+ * 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.context.InstanceWrapper;
+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.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Responsible for synchronously dispatching an invocation to a Java component
+ * implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationInvoker implements Invoker, DataExchangeSemantics {
+ protected Operation operation;
+ protected Method method;
+ protected boolean allowsPBR;
+
+ @SuppressWarnings("unchecked")
+ protected final ScopeContainer scopeContainer;
+
+ public JavaImplementationInvoker(Operation operation, Method method, RuntimeComponent component) {
+ 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);
+ }
+
+ public JavaImplementationInvoker(Operation operation, RuntimeComponent component) {
+ // used if the method can't be computed statically in advance
+ this.operation = operation;
+ this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Message invoke(Message msg) {
+ Operation op = msg.getOperation();
+ if (op == null) {
+ op = this.operation;
+ }
+ ConversationSequence sequence = op.getConversationSequence();
+ Object payload = msg.getBody();
+
+ Object contextId = null;
+
+ EndpointReference from = msg.getFrom();
+ ReferenceParameters parameters = null;
+ if (from != null) {
+ parameters = from.getReferenceParameters();
+ }
+ // check what sort of context is required
+ if (scopeContainer != null) {
+ Scope scope = scopeContainer.getScope();
+ if (scope == Scope.REQUEST) {
+ contextId = Thread.currentThread();
+ } else if (scope == Scope.CONVERSATION && parameters != null) {
+ contextId = parameters.getConversationID();
+ }
+ }
+
+ 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);
+
+ // detects whether the scope container has created a conversation Id. This will
+ // happen in the case that the component has conversational scope but only the
+ // callback interface is conversational. Or in the callback case if the service interface
+ // is conversational and the callback interface isn't. If we are in this situation we need
+ // to get the contextId of this component and remove it after we have invoked the method on
+ // it. It is possible that the component instance will not go away when it is removed below
+ // because a callback conversation will still be holding a reference to it
+ boolean removeTemporaryConversationalComponentAfterCall = false;
+ if (parameters != null && (contextId == null) && (parameters.getConversationID() != null)) {
+ contextId = parameters.getConversationID();
+ removeTemporaryConversationalComponentAfterCall = true;
+ }
+
+ 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());
+ }
+ }
+
+ 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 ((sequence == ConversationSequence.CONVERSATION_END) || (removeTemporaryConversationalComponentAfterCall)) {
+ // if end conversation, or we have the special case where a conversational
+ // object was created to service the stateless half of a stateful component
+ scopeContainer.remove(contextId);
+ parameters.setConversationID(null);
+ }
+ 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 (sequence != ConversationSequence.CONVERSATION_NONE ){
+ try {
+// // If the exception is not a business exception then end the conversation
+// boolean businessException = false;
+//
+// for (DataType dataType : operation.getFaultTypes()){
+// if ((dataType.getPhysical() == e.getCause().getClass()) &&
+// (contextId != null) ){
+// businessException = true;
+// break;
+// }
+// }
+
+ if (!isChecked && contextId != null) {
+ scopeContainer.remove(contextId);
+ parameters.setConversationID(null);
+ }
+ } catch (Exception ex){
+ // TODO - sure what the best course of action is here. We have
+ // a system exception in the middle of a business exception
+ }
+ }
+ if (!isChecked) {
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException)cause;
+ }
+ if (cause instanceof Error) {
+ throw (Error)cause;
+ } else {
+ throw new ServiceRuntimeException(cause.getMessage(), cause);
+ }
+ }
+
+ } catch (Exception e) {
+ msg.setFaultBody(e);
+ }
+ return msg;
+ }
+
+ public boolean allowsPassByReference() {
+ return allowsPBR;
+ }
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java
new file mode 100644
index 0000000000..e9eea607c9
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.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.reflect.Method;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.context.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.impl.JavaResourceImpl;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+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.policy.util.PolicyHandlerTuple;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.osoa.sca.ComponentContext;
+import org.osoa.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,
+ JavaPropertyValueObjectFactory propertyValueObjectFactory,
+ ComponentContextFactory componentContextFactory,
+ RequestContextFactory requestContextFactory,
+ List<PolicyHandlerTuple> policyHandlerClassNames) {
+ super();
+ this.implementation = implementation;
+ this.requestContextFactory = requestContextFactory;
+ this.implementation.setPolicyHandlerClassNames(policyHandlerClassNames);
+
+ try {
+ JavaInstanceFactoryProvider configuration = new JavaInstanceFactoryProvider(implementation);
+ configuration.setProxyFactory(proxyService);
+ componentContextProvider =
+ new JavaComponentContextProvider(component,
+ configuration,
+ dataBindingRegistry,
+ propertyValueObjectFactory,
+ componentContextFactory,
+ requestContextFactory);
+
+ Scope scope = getScope();
+
+ if (scope == Scope.SYSTEM || scope == Scope.COMPOSITE) {
+ // Nothing
+ } else {
+ // Check for conversational contract if conversational scope
+ if (scope == Scope.CONVERSATION) {
+ boolean hasConversationalContract = false;
+ for (Service serviceDef : implementation.getServices()) {
+ if (serviceDef.getInterfaceContract().getInterface().isConversational()) {
+ hasConversationalContract = true;
+ break;
+ }
+ }
+ if (!hasConversationalContract) {
+ String name = implementation.getJavaClass().getName();
+ throw new NoConversationalContractException(name);
+ }
+ }
+ }
+
+ if (implementation.getConversationIDMembers().size() > 0) {
+ componentContextProvider.addConversationIDFactories(implementation.getConversationIDMembers());
+ }
+
+ 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, proxyService);
+ } 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);
+ } 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());
+ } catch (NoSuchMethodException e1) {
+ throw new IllegalArgumentException(e1);
+ }
+ } else {
+ return new JavaImplementationInvoker(operation, componentContextProvider.getComponent());
+ }
+ }
+ }
+
+ 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();
+ }
+
+ public long getMaxAge() {
+ return implementation.getMaxAge();
+ }
+
+ public long getMaxIdleTime() {
+ return implementation.getMaxIdleTime();
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java
new file mode 100644
index 0000000000..9b78439012
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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.List;
+
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple;
+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 JavaPropertyValueObjectFactory propertyValueObjectFactory;
+ private DataBindingExtensionPoint dataBindingRegistry;
+ private ProxyFactory proxyService;
+ private ComponentContextFactory componentContextFactory;
+ private RequestContextFactory requestContextFactory;
+ private List<PolicyHandlerTuple> policyHandlerClassNames = null;
+
+ public JavaImplementationProviderFactory(ProxyFactory proxyService,
+ DataBindingExtensionPoint dataBindingRegistry,
+ JavaPropertyValueObjectFactory propertyValueObjectFactory,
+ ComponentContextFactory componentContextFactory,
+ RequestContextFactory requestContextFactory,
+ List<PolicyHandlerTuple> policyHandlerClassNames) {
+ super();
+ this.proxyService = proxyService;
+ this.dataBindingRegistry = dataBindingRegistry;
+ this.propertyValueObjectFactory = propertyValueObjectFactory;
+ this.componentContextFactory = componentContextFactory;
+ this.requestContextFactory = requestContextFactory;
+ this.policyHandlerClassNames = policyHandlerClassNames;
+ }
+
+ public ImplementationProvider createImplementationProvider(RuntimeComponent component,
+ JavaImplementation implementation) {
+ return new JavaImplementationProvider(component,
+ implementation,
+ proxyService,
+ dataBindingRegistry,
+ propertyValueObjectFactory,
+ componentContextFactory,
+ requestContextFactory,
+ policyHandlerClassNames);
+ }
+
+ public Class<JavaImplementation> getModelType() {
+ return JavaImplementation.class;
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java
new file mode 100644
index 0000000000..95a9f63688
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java
@@ -0,0 +1,183 @@
+/*
+ * 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.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.impl.JavaConstructorImpl;
+import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl;
+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.impl.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>();
+
+ 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>();
+ }
+
+ 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();
+ return new ReflectiveInstanceFactory<T>((Constructor<T>)definition.getConstructor().getConstructor(),
+ initArgs, injectors, 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() {
+ // work around JDK1.5 issue with allocating generic arrays
+ @SuppressWarnings("unchecked")
+ Injector<T>[] injectors = new Injector[injectionSites.size()];
+
+ int i = 0;
+ for (JavaElementImpl element : injectionSites) {
+ 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 factories
+ */
+ Map<JavaElementImpl, Object> getFactories() {
+ return factories;
+ }
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java
new file mode 100644
index 0000000000..ee3507ef80
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ConfiguredOperation;
+import org.apache.tuscany.sca.assembly.OperationsConfigurator;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.PolicySetAttachPoint;
+import org.apache.tuscany.sca.policy.util.PolicyHandler;
+import org.apache.tuscany.sca.policy.util.PolicyHandlerUtils;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+
+/**
+ * Processor to inject policy handling interceptor whenever PolicySets are specified in a Java Implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaPolicyHandlingRuntimeWireProcessor implements RuntimeWireProcessor {
+ private static final Logger logger = Logger.getLogger(JavaPolicyHandlingRuntimeWireProcessor.class.getName());
+
+ public JavaPolicyHandlingRuntimeWireProcessor() {
+ super();
+ }
+
+ public void process(RuntimeWire wire) {
+ /*Contract contract = wire.getSource().getContract();
+ if (!(contract instanceof RuntimeComponentReference)) {
+ return;
+ }*/
+
+ RuntimeComponent component = wire.getTarget().getComponent();
+ if (component != null && component.getImplementation() instanceof JavaImplementation) {
+ JavaImplementation javaImpl = (JavaImplementation)component.getImplementation();
+ if (javaImpl instanceof PolicySetAttachPoint) {
+ PolicyHandler policyHandler = null;
+ List<PolicyHandler> implPolicyHandlers = new ArrayList<PolicyHandler>();
+ PolicySetAttachPoint policiedImpl = (PolicySetAttachPoint)javaImpl;
+
+ try {
+ //for ( PolicySet policySet : policiedImpl.getPolicySets() ) {
+ for (PolicySet policySet : component.getPolicySets()) {
+ policyHandler =
+ PolicyHandlerUtils.findPolicyHandler(policySet, javaImpl.getPolicyHandlerClassNames());
+ if (policyHandler != null) {
+ policyHandler.setUp(javaImpl);
+ implPolicyHandlers.add(policyHandler);
+ } else {
+ //FIXME: to be removed after the PolicyHandler story has crystalized..
+ //maybe replace with exception then...
+ logger.warning("No PolicyHandler registered for PolicySet - " + policySet.getName());
+ }
+ }
+
+ List<PolicyHandler> applicablePolicyHandlers = null;
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ applicablePolicyHandlers = new ArrayList<PolicyHandler>();
+ if (javaImpl instanceof OperationsConfigurator) {
+ String operationName = chain.getTargetOperation().getName();
+ OperationsConfigurator opConfigurator = (OperationsConfigurator)component;
+ for (ConfiguredOperation confOp : opConfigurator.getConfiguredOperations()) {
+ if (confOp.getName().equals(operationName)) {
+ for (PolicySet policySet : confOp.getPolicySets()) {
+ policyHandler =
+ PolicyHandlerUtils.findPolicyHandler(policySet, javaImpl
+ .getPolicyHandlerClassNames());
+ if (policyHandler != null) {
+ policyHandler.setUp(javaImpl);
+ applicablePolicyHandlers.add(policyHandler);
+ } else {
+ logger.warning("No PolicyHandler registered for " + policySet);
+ }
+ }
+ break;
+ }
+ }
+
+ //if no policies have been specified at the operation level then simply
+ //apply whatever is specified for the implementation level
+ if (applicablePolicyHandlers.isEmpty()) {
+ applicablePolicyHandlers = implPolicyHandlers;
+ }
+ }
+
+ if (!applicablePolicyHandlers.isEmpty()) {
+ String phase =
+ (wire.getSource().getContract() instanceof ComponentReference) ? Phase.REFERENCE_POLICY
+ : Phase.SERVICE_POLICY;
+
+ chain.addInterceptor(Phase.IMPLEMENTATION_POLICY, new PolicyHandlingInterceptor(chain.getTargetOperation(),
+ applicablePolicyHandlers));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java b/branches/sca-android/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/branches/sca-android/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/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java
new file mode 100644
index 0000000000..a7b175cf9b
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.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;
+
+
+/**
+ * Raised when a component has conversational scope but no conversational contract
+ *
+ * @version $Rev: 487877 $ $Date: 2006-12-16 15:32:16 -0500 (Sat, 16 Dec 2006) $
+ */
+public class NoConversationalContractException extends Exception {
+
+ private static final long serialVersionUID = -1157790036638157539L;
+
+ public NoConversationalContractException(String message) {
+ super(message);
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java
new file mode 100644
index 0000000000..8c85b46c65
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java
@@ -0,0 +1,74 @@
+/*
+ * 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.List;
+
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.policy.util.PolicyHandler;
+
+/**
+ * An interceptor to invoke policy handlers before and after the invocation of operations on
+ * an implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicyHandlingInterceptor implements Interceptor {
+ private Invoker next;
+ private List<PolicyHandler> policyHandlers = null;
+ private Operation targetOperation = null;
+
+ public PolicyHandlingInterceptor(Operation targetOperation, List<PolicyHandler> policyHandlers) {
+ this.policyHandlers = policyHandlers;
+ this.targetOperation = targetOperation;
+ }
+
+ public Message invoke(Message msg) {
+ try {
+ applyPreInvocationPolicies(targetOperation, msg);
+ msg = next.invoke(msg);
+ } finally {
+ applyPostInvocationPolices(targetOperation, msg);
+ }
+ return msg;
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+ private void applyPreInvocationPolicies(Object... context) {
+ for (PolicyHandler policyHandler : policyHandlers) {
+ policyHandler.beforeInvoke(context);
+ }
+ }
+
+ private void applyPostInvocationPolices(Object... context) {
+ for ( int count = policyHandlers.size() - 1 ; count >= 0 ; --count) {
+ policyHandlers.get(count).afterInvoke(context);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java
new file mode 100644
index 0000000000..111b008b96
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/module/JavaRuntimeModuleActivator.java
@@ -0,0 +1,103 @@
+/*
+ * 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.module;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+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.databinding.TransformerExtensionPoint;
+import org.apache.tuscany.sca.databinding.impl.MediatorImpl;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.implementation.java.invocation.JavaCallbackRuntimeWireProcessor;
+import org.apache.tuscany.sca.implementation.java.invocation.JavaImplementationProviderFactory;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.policy.util.PolicyHandlerDefinitionsLoader;
+import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaRuntimeModuleActivator implements ModuleActivator {
+
+ public JavaRuntimeModuleActivator() {
+ }
+
+ public void start(ExtensionPointRegistry registry) {
+
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.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);
+ proxyFactories.setClassProxyFactory(new CglibProxyFactory(messageFactory, interfaceContractMapper));
+
+ JavaInterfaceFactory javaFactory = factories.getFactory(JavaInterfaceFactory.class);
+
+ DataBindingExtensionPoint dataBindings = registry.getExtensionPoint(DataBindingExtensionPoint.class);
+ TransformerExtensionPoint transformers = registry.getExtensionPoint(TransformerExtensionPoint.class);
+ MediatorImpl mediator = new MediatorImpl(dataBindings, transformers);
+ JavaPropertyValueObjectFactory factory = new JavaPropertyValueObjectFactory(mediator);
+
+ ContextFactoryExtensionPoint contextFactories = registry.getExtensionPoint(ContextFactoryExtensionPoint.class);
+ ComponentContextFactory componentContextFactory = contextFactories.getFactory(ComponentContextFactory.class);
+ RequestContextFactory requestContextFactory = contextFactories.getFactory(RequestContextFactory.class);
+
+ List<PolicyHandlerTuple> policyHandlerClassNames = null;
+ policyHandlerClassNames = PolicyHandlerDefinitionsLoader.loadPolicyHandlerClassnames();
+
+ ProxyFactory proxyFactory = new ExtensibleProxyFactory(proxyFactories);
+
+ JavaImplementationProviderFactory javaImplementationProviderFactory =
+ new JavaImplementationProviderFactory(proxyFactory, dataBindings, factory, componentContextFactory,
+ requestContextFactory, policyHandlerClassNames);
+
+ ProviderFactoryExtensionPoint providerFactories =
+ registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+ providerFactories.addProviderFactory(javaImplementationProviderFactory);
+
+ RuntimeWireProcessorExtensionPoint wireProcessorExtensionPoint =
+ registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class);
+ if (wireProcessorExtensionPoint != null) {
+ wireProcessorExtensionPoint.addWireProcessor(new JavaCallbackRuntimeWireProcessor(interfaceContractMapper,
+ javaFactory));
+ //wireProcessorExtensionPoint.addWireProcessor(new JavaPolicyHandlingRuntimeWireProcessor());
+ }
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator b/branches/sca-android/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
new file mode 100644
index 0000000000..0871ddf4be
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# Implementation class for the ModuleActivator
+org.apache.tuscany.sca.implementation.java.module.JavaRuntimeModuleActivator
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/MultiplicityTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/MultiplicityTestCase.java
new file mode 100644
index 0000000000..ba8da101c6
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/MultiplicityTestCase.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.context;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests wires that are configured with a multiplicity
+ *
+ * @version $Rev$ $Date$
+ */
+public class MultiplicityTestCase extends TestCase {
+
+ public void testMultiplicity() throws Exception {
+ // TODO implement
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapperTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapperTestCase.java
new file mode 100644
index 0000000000..628a308c86
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapperTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * 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 static org.easymock.EasyMock.createMock;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetInitializationException;
+import org.apache.tuscany.sca.implementation.java.invocation.EventInvoker;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReflectiveInstanceWrapperTestCase extends TestCase {
+ private ReflectiveInstanceWrapper<Object> wrapper;
+ private Object instance;
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+
+ public void testWithNoCallbacks() {
+ wrapper = new ReflectiveInstanceWrapper<Object>(instance, null, null);
+ try {
+ wrapper.start();
+ } catch (TargetInitializationException e) {
+ fail();
+ }
+ try {
+ wrapper.stop();
+ } catch (TargetDestructionException e) {
+ fail();
+ }
+ }
+
+ public void testWithStartCallback() {
+ initInvoker.invokeEvent(instance);
+ EasyMock.replay(initInvoker);
+ wrapper = new ReflectiveInstanceWrapper<Object>(instance, initInvoker, null);
+ try {
+ wrapper.start();
+ } catch (TargetInitializationException e) {
+ fail();
+ }
+ EasyMock.verify(initInvoker);
+ }
+
+ public void testWithStopCallback() {
+ destroyInvoker.invokeEvent(instance);
+ EasyMock.replay(destroyInvoker);
+ wrapper = new ReflectiveInstanceWrapper<Object>(instance, null, destroyInvoker);
+ try {
+ wrapper.stop();
+ } catch (TargetDestructionException e) {
+ fail();
+ }
+ EasyMock.verify(destroyInvoker);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ instance = new Object();
+ initInvoker = createMock(EventInvoker.class);
+ destroyInvoker = createMock(EventInvoker.class);
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/CallbackWireObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/CallbackWireObjectFactoryTestCase.java
new file mode 100644
index 0000000000..29dcfa8169
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/CallbackWireObjectFactoryTestCase.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 static org.easymock.EasyMock.createMock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.invocation.CallbackWireObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CallbackWireObjectFactoryTestCase extends TestCase {
+
+ @SuppressWarnings({"unchecked"})
+ public void testCreateInstance() throws Exception {
+ ProxyFactory service = createMock(ProxyFactory.class);
+ Foo foo = new Foo() {
+ };
+ EasyMock.expect(service.createCallbackProxy(EasyMock.eq(Foo.class), EasyMock.isA(List.class))).andReturn(foo);
+ EasyMock.replay(service);
+ List<RuntimeWire> wires = new ArrayList<RuntimeWire>();
+ CallbackWireObjectFactory factory = new CallbackWireObjectFactory(Foo.class, service, wires);
+ assertEquals(foo, factory.getInstance());
+ EasyMock.verify(service);
+ }
+
+ private interface Foo {
+
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjectorTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjectorTestCase.java
new file mode 100644
index 0000000000..cc852cc677
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/FieldInjectorTestCase.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.injection;
+
+import java.lang.reflect.Field;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FieldInjectorTestCase extends TestCase {
+
+ protected Field protectedField;
+
+ public void testIllegalAccess() throws Exception {
+ FieldInjector<Foo> injector = new FieldInjector<Foo>(protectedField, new SingletonObjectFactory<String>("foo"));
+ Foo foo = new Foo();
+ injector.inject(foo);
+ assertEquals("foo", foo.hidden);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ protectedField = Foo.class.getDeclaredField("hidden");
+ }
+
+ private class Foo {
+ private String hidden;
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactoryTestCase.java
new file mode 100644
index 0000000000..d502462688
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/JavaPropertyValueObjectFactoryTestCase.java
@@ -0,0 +1,449 @@
+/*
+ * 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.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.DefaultAssemblyFactory;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.DefaultDataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
+import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This test case will test the JavaPropertyValueObjectFactory.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaPropertyValueObjectFactoryTestCase {
+
+ /**
+ * The factory we should use for testing.
+ */
+ private static JavaPropertyValueObjectFactory factory;
+
+ /**
+ * The assembly factory used to create Properties.
+ */
+ private static AssemblyFactory assemblyFactory;
+
+ /**
+ * Test Setup.
+ */
+ @BeforeClass
+ public static void setup() {
+ // Create the factory
+ Mediator mediator = EasyMock.createNiceMock(Mediator.class);
+ DataBindingExtensionPoint dpep = new DefaultDataBindingExtensionPoint();
+ EasyMock.expect(mediator.getDataBindings()).andReturn(dpep).anyTimes();
+ EasyMock.replay(mediator);
+ factory = new JavaPropertyValueObjectFactory(mediator);
+
+ // Create the AssemblyFactory we should use
+ assemblyFactory = new DefaultAssemblyFactory();
+ }
+
+ /**
+ * A test that will attempt to inject positive, negative and zero into an
+ * int property.
+ */
+ @Test
+ public void testIntegerInjectionValid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedType = Integer.TYPE;
+
+ for (int i = -5; i <= 5; i++) {
+ params.propertyValue = Integer.toString(i);
+ params.expectedValueFromFactory = i;
+ doInjection(params);
+ }
+ }
+
+ /**
+ * A test that will attempt to inject positive, negative and zero into an
+ * int property using a JavaElement.
+ */
+ @Test
+ public void testIntegerInjectionValidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedJavaElement = new JavaElementImpl(int.class);
+
+ for (int i = -5; i <= 5; i++) {
+ params.propertyValue = Integer.toString(i);
+ params.expectedValueFromFactory = i;
+ doInjection(params);
+ }
+ }
+
+ /**
+ * A test that will attempt to inject multiple int values into an
+ * int property.
+ */
+ @Test
+ public void testIntegerArrayInjectionValid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.isMany = true;
+ params.expectedType = int.class;
+ params.propertyValue = "1 2 3 4 5";
+ params.expectedValueFromFactory = Arrays.asList(1, 2, 3, 4, 5);
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject multiple int values into an
+ * int property using a JavaElement.
+ */
+ @Test
+ public void testIntegerArrayInjectionValidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.isMany = true;
+ params.expectedJavaElement = new JavaElementImpl(int[].class);
+ params.propertyValue = "1 2 3 4 5";
+ int[] expected = { 1, 2, 3, 4, 5 };
+ params.expectedValueFromFactory = expected;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject a non-number into an
+ * int property.
+ */
+ @Test
+ public void testIntegerInjectionBadNumberInvalid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedType = Integer.TYPE;
+ params.propertyValue = "a";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject a non-number into an
+ * int property using a JavaElement.
+ */
+ @Test
+ public void testIntegerInjectionBadNumberInvalidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedJavaElement = new JavaElementImpl(Integer.TYPE);
+ params.propertyValue = "a";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject multiple int values into an
+ * int property where one of the property values is not a number.
+ * The injection should throw ObjectCreationException
+ */
+ @Test
+ public void testIntegerArrayInjectionBadNumberInvalid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.isMany = true;
+ params.expectedType = int.class;
+ params.propertyValue = "1 2 aa 4 5";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject multiple int values into an
+ * int property using a JavaElement where one of the property
+ * values is not a number.
+ * The injection should throw ObjectCreationException
+ */
+ @Test
+ public void testIntegerArrayInjectionBadNumberInvalidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.isMany = true;
+ params.expectedJavaElement = new JavaElementImpl(int[].class);
+ params.propertyValue = "1 2 aa 4 5";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject an empty string into an int property.
+ * The injection should throw ObjectCreationException
+ */
+ @Test
+ public void testIntegerInjectionEmptyStringInvalid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedType = Integer.TYPE;
+ params.propertyValue = "";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject an empty string into an int property
+ * using a JavaElement.
+ * The injection should throw ObjectCreationException
+ */
+ @Test
+ public void testIntegerInjectionEmptyStringInvalidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "intField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_INT;
+ params.expectedJavaElement = new JavaElementImpl(Integer.TYPE);
+ params.propertyValue = "";
+ params.exceptionExpected = true;
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject a String into a String
+ * property.
+ */
+ @Test
+ public void testStringInjectionValid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "StringField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_STRING;
+ params.expectedType = String.class;
+
+ params.propertyValue = "Some Test String";
+ params.expectedValueFromFactory = "Some Test String";
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject a String into a String
+ * property using a JavaElement.
+ */
+ @Test
+ public void testStringInjectionValidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "StringField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_STRING;
+ params.expectedJavaElement = new JavaElementImpl(String.class);
+
+ params.propertyValue = "Some Test String";
+ params.expectedValueFromFactory = "Some Test String";
+ doInjection(params);
+ }
+
+ /**
+ * This class defines all the parameters for the Property Injection test.
+ */
+ private class InjectionTestParams {
+ // Input parameters for the test
+ public boolean isMany = false;
+ public String propertyName;
+ public String propertyValue;
+ public QName xsdType;
+
+ // Expected result for test
+ public Object expectedValueFromFactory;
+ public Class<?> expectedType;
+ public JavaElementImpl expectedJavaElement;
+ public boolean exceptionExpected = false;
+ }
+
+ /**
+ * A test that will attempt to inject multiple String values into an
+ * String property.
+ */
+ @Test
+ public void testStringArrayInjectionValid() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "StringField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_STRING;
+ params.isMany = true;
+ params.expectedType = String.class;
+ params.propertyValue = "\"String1\" \"String2\" \"String3\" \"String4\" \"String5\"";
+ params.expectedValueFromFactory = Arrays.asList(
+ "String1", "String2", "String3", "String4", "String5");
+ doInjection(params);
+ }
+
+ /**
+ * A test that will attempt to inject multiple String values into an
+ * String property using a JavaElement.
+ */
+ @Test
+ public void testStringArrayInjectionValidWithJavaElement() {
+ InjectionTestParams params = new InjectionTestParams();
+ params.propertyName = "StringField";
+ params.xsdType = SimpleTypeMapperImpl.XSD_STRING;
+ params.isMany = true;
+ params.expectedJavaElement = new JavaElementImpl(String.class);
+ params.propertyValue = "\"String1\" \"String2\" \"String3\" \"String4\" \"String5\"";
+ params.expectedValueFromFactory = Arrays.asList(
+ "String1", "String2", "String3", "String4", "String5");
+ doInjection(params);
+ }
+
+ /**
+ * Utility method for testing creating properties with the
+ * JavaPropertyValueObjectFactory.
+ *
+ * @param testParams The parameters for the test
+ */
+ private void doInjection(final InjectionTestParams testParams) {
+ // Create the property
+ Property prop = assemblyFactory.createProperty();
+ prop.setMany(testParams.isMany);
+ prop.setName(testParams.propertyName);
+ prop.setXSDType(testParams.xsdType);
+
+ // Mock up the XML that will contain the Property details
+ Document doc = EasyMock.createNiceMock(Document.class);
+ Element rootElement = EasyMock.createMock(Element.class);
+ EasyMock.expect(doc.getDocumentElement()).andReturn(rootElement);
+ NodeList nodeList = EasyMock.createMock(NodeList.class);
+ EasyMock.expect(rootElement.getChildNodes()).andReturn(nodeList).anyTimes();
+ EasyMock.expect(nodeList.getLength()).andReturn(1);
+ Node node = EasyMock.createMock(Node.class);
+ EasyMock.expect(nodeList.item(0)).andReturn(node);
+ EasyMock.expect(node.getTextContent()).andReturn(testParams.propertyValue);
+ EasyMock.replay(doc, rootElement, nodeList, node);
+
+ // Create a factory either using the Class or JavaElementImpl constructor
+ ObjectFactory<?> objectFactory;
+ if (testParams.expectedJavaElement != null) {
+ objectFactory = factory.createValueFactory(prop, doc, testParams.expectedJavaElement);
+ } else {
+ objectFactory = factory.createValueFactory(prop, doc, testParams.expectedType);
+ }
+ Assert.assertNotNull(objectFactory);
+
+ // Lets test the factory
+ try {
+ // Create a new instance with the factory
+ Object value = objectFactory.getInstance();
+
+ // Did we expect an exception to be thrown?
+ if (testParams.exceptionExpected) {
+ Assert.fail("Test should have thrown ObjectCreationException");
+ }
+
+ // Make sure the result is of the correct type
+ if (testParams.expectedValueFromFactory instanceof Collection<?>) {
+ // Make sure the Collections contain the same type
+ Assert.assertTrue(value instanceof Collection<?>);
+ Iterator<?> iter1 = ((Collection<?>) testParams.expectedValueFromFactory).iterator();
+ Iterator<?> iter2 = ((Collection<?>) value).iterator();
+ Assert.assertEquals(iter1.next().getClass(), iter2.next().getClass());
+ } else {
+ Assert.assertEquals(testParams.expectedValueFromFactory.getClass(), value.getClass());
+ }
+
+ // Validate the result
+ Assert.assertNotNull(value);
+ if (testParams.expectedValueFromFactory.getClass().isArray()) {
+ Assert.assertTrue(compareArrays(testParams.expectedValueFromFactory, value));
+ } else {
+ Assert.assertEquals(testParams.expectedValueFromFactory, value);
+ }
+ } catch (ObjectCreationException ex) {
+ // Is this an expected exception?
+ if (testParams.exceptionExpected) {
+ // Make sure the exception error message contains the property name
+ Assert.assertTrue(ex.toString().indexOf(testParams.propertyName) != -1);
+
+ // Make sure the exception error message contains the property value
+ if (testParams.propertyValue != null) {
+ if (testParams.isMany) {
+ // FIXME: No simple way to do this for multi-value properties
+ } else {
+ Assert.assertTrue(ex.toString().indexOf(testParams.propertyValue) != -1);
+ }
+ }
+ } else {
+ // Test failure. We were not expecting an exception
+ ex.printStackTrace();
+ Assert.fail("Unexpected exception " + ex);
+ }
+ }
+ }
+
+ /**
+ * Compares two Objects that are actually arrays to make sure that they are
+ * equal.
+ *
+ * @param array1 The first array
+ * @param array2 The second array
+ * @return True if they are equal. False if they are not
+ */
+ private boolean compareArrays(final Object array1, final Object array2) {
+ // Check for primitive array types
+ if (array1 instanceof boolean[]) {
+ return Arrays.equals((boolean[]) array1, (boolean[]) array2);
+ }
+ if (array1 instanceof byte[]) {
+ return Arrays.equals((byte[]) array1, (byte[]) array2);
+ }
+ if (array1 instanceof char[]) {
+ return Arrays.equals((char[]) array1, (char[]) array2);
+ }
+ if (array1 instanceof double[]) {
+ return Arrays.equals((double[]) array1, (double[]) array2);
+ }
+ if (array1 instanceof float[]) {
+ return Arrays.equals((float[]) array1, (float[]) array2);
+ }
+ if (array1 instanceof int[]) {
+ return Arrays.equals((int[]) array1, (int[]) array2);
+ }
+ if (array1 instanceof long[]) {
+ return Arrays.equals((long[]) array1, (long[]) array2);
+ }
+ if (array1 instanceof short[]) {
+ return Arrays.equals((short[]) array1, (short[]) array2);
+ }
+
+ // Not a primitive so must be an Object[]
+ return Arrays.equals((Object[]) array1, (Object[]) array2);
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodEventInvokerTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodEventInvokerTestCase.java
new file mode 100644
index 0000000000..4de0a4e8c7
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodEventInvokerTestCase.java
@@ -0,0 +1,76 @@
+/*
+ * 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.Method;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.implementation.java.invocation.EventInvocationException;
+import org.apache.tuscany.sca.implementation.java.invocation.MethodEventInvoker;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodEventInvokerTestCase extends TestCase {
+ private Method privateMethod;
+ private Method exceptionMethod;
+
+ public void testIllegalAccess() throws Exception {
+ MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(privateMethod);
+ try {
+ injector.invokeEvent(new Foo());
+ fail();
+ } catch (EventInvocationException e) {
+ // expected
+ }
+ }
+
+ public void testException() throws Exception {
+ MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(exceptionMethod);
+ try {
+ injector.invokeEvent(new Foo());
+ fail();
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ privateMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("hidden");
+ exceptionMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("exception");
+
+ }
+
+ public class Foo {
+
+ public void foo() {
+ }
+
+ private void hidden() {
+ }
+
+ public void exception() {
+ throw new RuntimeException();
+ }
+
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjectorTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjectorTestCase.java
new file mode 100644
index 0000000000..214779ed3f
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/MethodInjectorTestCase.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.injection;
+
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodInjectorTestCase extends TestCase {
+ private Method fooMethod;
+ private Method privateMethod;
+ private Method exceptionMethod;
+
+ public void testIllegalArgument() throws Exception {
+ ObjectFactory<Object> factory = new SingletonObjectFactory<Object>(new Object());
+ MethodInjector<Foo> injector = new MethodInjector<Foo>(fooMethod, factory);
+ try {
+ injector.inject(new Foo());
+ fail();
+ } catch (ObjectCreationException e) {
+ // expected
+ }
+ }
+
+ public void testException() throws Exception {
+ ObjectFactory<Object> factory = new SingletonObjectFactory<Object>("foo");
+ MethodInjector<Foo> injector = new MethodInjector<Foo>(exceptionMethod, factory);
+ try {
+ injector.inject(new Foo());
+ fail();
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ fooMethod = Foo.class.getMethod("foo", String.class);
+ privateMethod = Foo.class.getDeclaredMethod("hidden", String.class);
+ exceptionMethod = Foo.class.getDeclaredMethod("exception", String.class);
+
+ }
+
+ private class Foo {
+
+ public void foo(String bar) {
+ }
+
+ private void hidden(String bar) {
+ }
+
+ public void exception(String bar) {
+ throw new RuntimeException();
+ }
+
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactoryTestCase.java
new file mode 100644
index 0000000000..c470b8cf3d
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/RequestContextObjectFactoryTestCase.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.injection;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RequestContextObjectFactoryTestCase extends TestCase {
+
+ public void testInstanceCreate() {
+ RequestContextObjectFactory factory = new RequestContextObjectFactory(null);
+ assertNotNull(factory.getInstance());
+ }
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactoryTestCase.java
new file mode 100644
index 0000000000..ed7a0e7d03
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/ResourceObjectFactoryTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * 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 junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResourceObjectFactoryTestCase extends TestCase {
+
+ public void testResolveFromHostByType() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("foo");
+ EasyMock.replay(host);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(host);
+ }
+
+ public void testResolveFromHostByName() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class),
+ EasyMock.eq("sca://localhost/bar"))).andReturn("foo");
+ EasyMock.replay(host);
+ ResourceObjectFactory<String> factory =
+ new ResourceObjectFactory<String>(String.class, "sca://localhost/bar", false, host);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(host);
+ }
+
+
+ public void testResolveFromParentThenResolveFromHostNotFound() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(host);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, host);
+ assertNull(factory.getInstance());
+ EasyMock.verify(host);
+ }
+
+ public void testResolveByTypeNotFound() throws Exception {
+// ResourceHost host = EasyMock.createMock(ResourceHost.class);
+// EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+// EasyMock.replay(host);
+//
+// RuntimeWire wire = EasyMock.createMock(RuntimeWire.class);
+// EasyMock.expect(wire.getTargetInstance()).andReturn(null);
+// EasyMock.replay(wire);
+//
+// ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host);
+// try {
+// factory.getInstance();
+// fail();
+// } catch (ResourceNotFoundException e) {
+// //expected
+// }
+// EasyMock.verify(host);
+ }
+
+ public void testResolveByTypeNotFoundOptional() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(host);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, host);
+ assertNull(factory.getInstance());
+ EasyMock.verify(host);
+ }
+
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactory.java
new file mode 100644
index 0000000000..c1650c3a83
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Implementation of ObjectFactory that returns a single instance, typically an immutable type.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SingletonObjectFactory<T> implements ObjectFactory<T> {
+ private final T instance;
+
+ public SingletonObjectFactory(T instance) {
+ this.instance = instance;
+ }
+
+ public T getInstance() {
+ return instance;
+ }
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactoryTestCase.java
new file mode 100644
index 0000000000..40ad1b1e95
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/SingletonObjectFactoryTestCase.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.injection;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SingletonObjectFactoryTestCase extends TestCase {
+
+ public void testSingleton() throws Exception {
+ Object o = new Object();
+ SingletonObjectFactory<Object> factory = new SingletonObjectFactory<Object>(o);
+ assertEquals(o, factory.getInstance());
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactory.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactory.java
new file mode 100644
index 0000000000..de371e09bb
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactory.java
@@ -0,0 +1,120 @@
+/*
+ * 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.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * Creates new instances of a Java class
+ *
+ * @version $Rev$ $Date$
+ * @see org.apache.tuscany.sca.implementation.java.injection.Injector
+ */
+public class TestObjectFactory<T> implements ObjectFactory<T> {
+
+ private final Constructor<T> ctr;
+ private ObjectFactory[] initializerFactories;
+
+ /**
+ * Creates the object factory
+ *
+ * @param ctr the constructor to use when instantiating a new object
+ */
+ public TestObjectFactory(Constructor<T> ctr) {
+ assert ctr != null;
+ this.ctr = ctr;
+ initializerFactories = new ObjectFactory[ctr.getParameterTypes().length];
+ }
+
+ /**
+ * Creates the object factory
+ *
+ * @param ctr the constructor to use when instantiating a new object
+ * @param factories an ordered list of <code>ObjectFactory</code>s to use for returning constructor parameters
+ */
+ public TestObjectFactory(Constructor<T> ctr, List<ObjectFactory> factories) {
+ assert ctr != null;
+ int params = ctr.getParameterTypes().length;
+ assert params == factories.size();
+ this.ctr = ctr;
+ initializerFactories = new ObjectFactory[params];
+ int i = 0;
+ for (ObjectFactory factory : factories) {
+ initializerFactories[i] = factory;
+ i++;
+ }
+ }
+
+ /**
+ * Returns the ordered array of <code>ObjectFactory</code>s use in creating constructor parameters
+ */
+ public ObjectFactory[] getInitializerFactories() {
+ return initializerFactories;
+ }
+
+ /**
+ * Sets an <code>ObjectFactory</code>s to use in creating constructor parameter
+ *
+ * @param pos the constructor parameter position
+ * @param factory the object factory
+ */
+ public void setInitializerFactory(int pos, ObjectFactory factory) {
+ assert pos < initializerFactories.length;
+ initializerFactories[pos] = factory;
+ }
+
+ /**
+ * Creates a new instance of an object
+ */
+ public T getInstance() throws ObjectCreationException {
+ int size = initializerFactories.length;
+ Object[] initargs = new Object[size];
+ // create the constructor arg array
+ for (int i = 0; i < size; i++) {
+ ObjectFactory<?> objectFactory = initializerFactories[i];
+ if (objectFactory == null) {
+ // this can happen if a reference is optional
+ initargs[i] = null;
+ } else {
+ initargs[i] = objectFactory.getInstance();
+ }
+ }
+ try {
+ ctr.setAccessible(true);
+ return ctr.newInstance(initargs);
+ } catch (IllegalArgumentException e) {
+ String name = ctr.getName();
+ throw new ObjectCreationException("Exception thrown by constructor: " + name, e);
+ } 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);
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactoryTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactoryTestCase.java
new file mode 100644
index 0000000000..1fb7abb917
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/injection/TestObjectFactoryTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.injection;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TestObjectFactoryTestCase extends TestCase {
+
+ private Constructor<Foo> ctor;
+
+ public void testConstructorInjection() throws Exception {
+ List<ObjectFactory> initializers = new ArrayList<ObjectFactory>();
+ initializers.add(new SingletonObjectFactory<String>("foo"));
+ TestObjectFactory<Foo> factory = new TestObjectFactory<Foo>(ctor, initializers);
+ Foo foo = factory.getInstance();
+ assertEquals("foo", foo.foo);
+ }
+
+ /**
+ * Verifies null parameters can be passed to a constructor. This is valid when a reference is optional during
+ * constructor injection
+ */
+ public void testConstructorInjectionOptionalParam() throws Exception {
+ List<ObjectFactory> initializers = new ArrayList<ObjectFactory>();
+ initializers.add(null);
+ TestObjectFactory<Foo> factory = new TestObjectFactory<Foo>(ctor, initializers);
+ Foo foo = factory.getInstance();
+ assertNull(foo.foo);
+ }
+
+ public void testConstructorInitializerInjection() throws Exception {
+ TestObjectFactory<Foo> factory = new TestObjectFactory<Foo>(ctor);
+ factory.setInitializerFactory(0, new SingletonObjectFactory<String>("foo"));
+ Foo foo = factory.getInstance();
+ assertEquals("foo", foo.foo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ ctor = Foo.class.getConstructor(String.class);
+ }
+
+ private static class Foo {
+
+ private String foo;
+
+ public Foo(String foo) {
+ this.foo = foo;
+ }
+ }
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean1.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean1.java
new file mode 100644
index 0000000000..e993cdd382
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean1.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.util;
+
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class Bean1 extends SuperBean {
+
+ public static final int ALL_BEAN1_FIELDS = 6 + ALL_SUPER_FIELDS;
+ public static final int ALL_BEAN1_PUBLIC_PROTECTED_FIELDS = 5 + ALL_SUPER_PUBLIC_PROTECTED_FIELDS;
+ public static final int ALL_BEAN1_METHODS = 4 + ALL_SUPER_METHODS - 1;
+ public String field3;
+ protected String field2;
+ private String field1;
+
+ public void setMethod1(String param) {
+ }
+
+ public void setMethod1(int param) {
+ }
+
+ @Override
+ public void override(String param) throws Exception {
+ }
+
+
+ public void noOverride(String param) throws Exception {
+ }
+
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean2.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean2.java
new file mode 100644
index 0000000000..82264c77c9
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Bean2.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class Bean2 {
+
+ private List methodList;
+ private List fieldList;
+
+ public List getMethodList() {
+ return methodList;
+ }
+
+ public void setMethodList(List list) {
+ methodList = list;
+ }
+
+ public List getfieldList() {
+ return fieldList;
+ }
+
+ public void setfieldList(List list) {
+ throw new AssertionFailedError("setter inadvertantly called");
+ }
+
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Entry.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Entry.java
new file mode 100644
index 0000000000..a5e12d181c
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/Entry.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.util;
+
+/**
+ * Implementations are used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Entry {
+
+ String getString();
+
+ void setString(String val);
+}
+
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/JavaIntrospectionHelperTestCase.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/JavaIntrospectionHelperTestCase.java
new file mode 100644
index 0000000000..ed6bf7ddc4
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/JavaIntrospectionHelperTestCase.java
@@ -0,0 +1,185 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.implementation.java.introspect.impl.JavaIntrospectionHelper;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaIntrospectionHelperTestCase extends TestCase {
+
+ private List testNoGenericsList;
+ private List<String> testList;
+ private Map<String, Bean1> testMap;
+ private Entry[] testArray;
+ private String[] testStringArray;
+
+ public JavaIntrospectionHelperTestCase() {
+ super();
+ }
+
+ public JavaIntrospectionHelperTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testBean1AllPublicProtectedFields() throws Exception {
+ Set<Field> beanFields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(Bean1.class, true);
+ assertEquals(4, beanFields.size()); //Bean1.ALL_BEAN1_PUBLIC_PROTECTED_FIELDS
+ }
+
+ public void testGetSuperAllMethods() throws Exception {
+ Set<Method> superBeanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(SuperBean.class, true);
+ assertEquals(SuperBean.ALL_SUPER_METHODS, superBeanMethods.size());
+ }
+
+ public void testGetBean1AllMethods() throws Exception {
+ Set<Method> beanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class, true);
+ assertEquals(Bean1.ALL_BEAN1_METHODS, beanMethods.size());
+ }
+
+ public void testOverrideMethod() throws Exception {
+ Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class, true);
+ boolean invoked = false;
+ for (Method method : beanFields) {
+ if (method.getName().equals("override")) {
+ method.invoke(new Bean1(), "foo");
+ invoked = true;
+ }
+ }
+ if (!invoked) {
+ throw new Exception("Override never invoked");
+ }
+ }
+
+ public void testNoOverrideMethod() throws Exception {
+ Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class, true);
+ boolean found = false;
+ for (Method method : beanFields) {
+ if (method.getName().equals("noOverride") && method.getParameterTypes().length == 0) {
+ found = true;
+ }
+ }
+ if (!found) {
+ throw new Exception("No override not found");
+ }
+ }
+
+ public void testDefaultConstructor() throws Exception {
+ Constructor ctr = JavaIntrospectionHelper.getDefaultConstructor(Bean2.class);
+ assertEquals(ctr, Bean2.class.getConstructor());
+ assertTrue(Bean2.class == ctr.newInstance((Object[]) null).getClass());
+ }
+
+
+ public void testGetAllInterfaces() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Z.class);
+ assertEquals(2, interfaces.size());
+ assertTrue(interfaces.contains(W.class));
+ assertTrue(interfaces.contains(W2.class));
+ }
+
+
+ public void testGetAllInterfacesObject() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Object.class);
+ assertEquals(0, interfaces.size());
+ }
+
+ public void testGetAllInterfacesNoInterfaces() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(NoInterface.class);
+ assertEquals(0, interfaces.size());
+ }
+
+ /**
+ * Tests generics introspection capabilities
+ */
+ public void testGenerics() throws Exception {
+
+ List classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testList").getGenericType());
+ assertEquals(1, classes.size());
+ assertEquals(String.class, classes.get(0));
+
+ classes =
+ JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testNoGenericsList").getGenericType());
+ assertEquals(0, classes.size());
+
+ classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testMap").getGenericType());
+ assertEquals(2, classes.size());
+ assertEquals(String.class, classes.get(0));
+ assertEquals(Bean1.class, classes.get(1));
+
+ classes = JavaIntrospectionHelper
+ .getGenerics(getClass().getDeclaredMethod("fooMethod", Map.class).getGenericParameterTypes()[0]);
+ assertEquals(2, classes.size());
+ assertEquals(String.class, classes.get(0));
+ assertEquals(Bean1.class, classes.get(1));
+
+ classes = JavaIntrospectionHelper
+ .getGenerics(getClass().getDeclaredMethod("fooMethod", List.class).getGenericParameterTypes()[0]);
+ assertEquals(1, classes.size());
+ assertEquals(String.class, classes.get(0));
+
+ }
+
+ private void fooMethod(List<String> foo) {
+
+ }
+
+ private void fooMethod(Map<String, Bean1> foo) {
+
+ }
+
+ public void setTestArray(Entry[] array) {
+ }
+
+ private interface W {
+
+ }
+
+ private interface W2 {
+
+ }
+
+ private class X implements W {
+
+ }
+
+ private class Y extends X implements W, W2 {
+
+ }
+
+ private class Z extends Y {
+
+ }
+
+ private class NoInterface {
+
+ }
+
+}
diff --git a/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/SuperBean.java b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/SuperBean.java
new file mode 100644
index 0000000000..408cedb8be
--- /dev/null
+++ b/branches/sca-android/modules/implementation-java-runtime/src/test/java/org/apache/tuscany/sca/implementation/java/util/SuperBean.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.util;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SuperBean {
+
+ public static final int ALL_SUPER_FIELDS = 6;
+ public static final int ALL_SUPER_PUBLIC_PROTECTED_FIELDS = 5;
+ public static final int ALL_SUPER_METHODS = 4;
+ public String superField2;
+
+ protected String superField3;
+
+ private String superField1;
+
+ public void setSuperMethod1(String param) {
+ }
+
+ public void setSuperMethod1(int param) {
+ }
+
+ public void override(String param) throws Exception {
+ throw new Exception("Override not handled");
+ }
+
+ public void noOverride() throws Exception {
+ }
+
+}