summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-0.99/modules/core/src
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-0.99/modules/core/src
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-0.99/modules/core/src')
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ActivationException.java37
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivator.java144
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivatorImpl.java737
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/EndpointReferenceImpl.java146
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeAssemblyFactory.java61
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentImpl.java85
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java114
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java127
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java224
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java325
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java290
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java343
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/DefaultComponentContextFactory.java70
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/InstanceWrapper.java48
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java89
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java104
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/BaseEventPublisher.java89
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStart.java54
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStop.java53
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationEnd.java53
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationStart.java52
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionEnd.java53
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionStart.java52
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestEnd.java45
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestStart.java45
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectCreationException.java47
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectFactory.java35
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java55
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java57
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java160
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java138
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/DefaultProxyFactoryExtensionPoint.java144
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleWireProcessor.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/InvocationChainImpl.java130
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java105
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java304
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKProxyFactory.java89
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageFactoryImpl.java36
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java126
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NoMethodForOperationException.java43
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java183
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyCreationException.java48
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java78
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactoryExtensionPoint.java58
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvocationException.java45
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvokerCreationException.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java69
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/WireObjectFactory.java43
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java191
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java70
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java37
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java289
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java83
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java41
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java86
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java37
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java66
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java139
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java32
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java43
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java62
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java65
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java40
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java55
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java37
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java44
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/store/MemoryStore.java195
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237Work.java63
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237WorkScheduler.java165
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java219
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEventImpl.java74
-rw-r--r--branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItemImpl.java168
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java52
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/BaseEventPublisherTestCase.java98
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/EventTestCase.java69
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainerTestCase.java69
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/store/MemoryStoreTestCase.java165
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java55
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java66
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java72
-rw-r--r--branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/scope/ScopeTestCase.java61
86 files changed, 8749 insertions, 0 deletions
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ActivationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ActivationException.java
new file mode 100644
index 0000000000..c86c876075
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ActivationException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.assembly;
+
+
+/**
+ * Denotes an error starting the runtime
+ *
+ * @version $Rev$ $Date$
+ */
+public class ActivationException extends Exception {
+ private static final long serialVersionUID = 8612661660934426123L;
+
+ public ActivationException(String message) {
+ super(message);
+ }
+
+ public ActivationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivator.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivator.java
new file mode 100644
index 0000000000..e8d5474b83
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivator.java
@@ -0,0 +1,144 @@
+/*
+ * 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.core.assembly;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.core.context.ComponentContextHelper;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Start/stop a composite
+ *
+ * @version $Rev$ $Date$
+ */
+public interface CompositeActivator {
+ /**
+ * Activate a composite
+ * @param composite
+ */
+ void activate(Composite composite) throws ActivationException;
+
+ /**
+ * Activate a component reference
+ * @param component
+ * @param ref
+ */
+ void activate(RuntimeComponent component, RuntimeComponentReference ref);
+
+ /**
+ * Activate a component reference
+ * @param component
+ * @param ref
+ */
+ void activate(RuntimeComponent component, RuntimeComponentService service);
+
+ /**
+ * De-activate a component reference
+ * @param component
+ * @param ref
+ */
+ void deactivate(RuntimeComponent component, RuntimeComponentReference ref);
+
+ /**
+ * De-activate a component reference
+ * @param component
+ * @param ref
+ */
+ void deactivate(RuntimeComponent component, RuntimeComponentService service);
+
+ /**
+ * Stop a composite
+ * @param composite
+ */
+ void deactivate(Composite composite) throws ActivationException;
+
+ /**
+ * Start a component
+ * @param component
+ */
+ void start(Component component) throws ActivationException;
+
+ /**
+ * Stop a component
+ * @param component
+ */
+ void stop(Component component) throws ActivationException;
+
+ /**
+ * Start components in a composite
+ * @param composite
+ */
+ void start(Composite composite) throws ActivationException;
+
+ /**
+ * Stop components in a composite
+ * @param composite
+ */
+ void stop(Composite composite) throws ActivationException;
+
+ /**
+ * Get the component context helper
+ * @return
+ */
+ ComponentContextHelper getComponentContextHelper();
+
+ /**
+ * Get the proxy factory
+ * @return
+ */
+ ProxyFactory getProxyFactory();
+
+ /**
+ * Get the java interface factory
+ * @return
+ */
+ JavaInterfaceFactory getJavaInterfaceFactory();
+
+ /**
+ * Configure the runtime component with component context
+ * @param component
+ */
+ void configureComponentContext(RuntimeComponent component);
+
+ /**
+ * Resolve a component by URI in the domain
+ * @param componentURI
+ * @return
+ */
+ Component resolve(String componentURI);
+
+ /**
+ * Set the domain composite
+ * @param domainComposite
+ */
+ void setDomainComposite(Composite domainComposite);
+
+ /**
+ * Get the domain composite
+ * @return
+ */
+ Composite getDomainComposite();
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivatorImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivatorImpl.java
new file mode 100644
index 0000000000..80d2f7fb9a
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/CompositeActivatorImpl.java
@@ -0,0 +1,737 @@
+/*
+ * 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.core.assembly;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.SCABinding;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.WireableBinding;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.context.ComponentContextHelper;
+import org.apache.tuscany.sca.core.context.ComponentContextImpl;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.provider.BindingProviderFactory;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeActivatorImpl implements CompositeActivator {
+
+ private final static String CALLBACK_PREFIX = "$callback$.";
+
+ private final AssemblyFactory assemblyFactory;
+ private final InterfaceContractMapper interfaceContractMapper;
+ private final ScopeRegistry scopeRegistry;
+ private final WorkScheduler workScheduler;
+ private final RuntimeWireProcessor wireProcessor;
+ private final ProviderFactoryExtensionPoint providerFactories;
+
+ private final RequestContextFactory requestContextFactory;
+ private final ProxyFactory proxyFactory;
+ private final JavaInterfaceFactory javaInterfaceFactory;
+
+ private final ComponentContextHelper componentContextHelper;
+
+ private Composite domainComposite;
+
+ /**
+ * @param assemblyFactory
+ * @param interfaceContractMapper
+ * @param workContext
+ * @param workScheduler
+ * @param wirePostProcessorRegistry
+ */
+ public CompositeActivatorImpl(AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaInterfaceFactory,
+ SCABindingFactory scaBindingFactory,
+ InterfaceContractMapper interfaceContractMapper,
+ ScopeRegistry scopeRegistry,
+ WorkScheduler workScheduler,
+ RuntimeWireProcessor wireProcessor,
+ RequestContextFactory requestContextFactory,
+ ProxyFactory proxyFactory,
+ ProviderFactoryExtensionPoint providerFactories,
+ StAXArtifactProcessorExtensionPoint processors) {
+ this.assemblyFactory = assemblyFactory;
+ this.interfaceContractMapper = interfaceContractMapper;
+ this.scopeRegistry = scopeRegistry;
+ this.workScheduler = workScheduler;
+ this.wireProcessor = wireProcessor;
+ this.providerFactories = providerFactories;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ this.requestContextFactory = requestContextFactory;
+ this.proxyFactory = proxyFactory;
+ this.componentContextHelper = new ComponentContextHelper(assemblyFactory, javaInterfaceFactory, processors);
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.assembly.CompositeActivator#activate(org.apache.tuscany.sca.runtime.RuntimeComponent, org.apache.tuscany.sca.runtime.RuntimeComponentReference)
+ */
+ public void activate(RuntimeComponent component, RuntimeComponentReference ref) {
+ resolveTargets(ref);
+ for (Binding binding : ref.getBindings()) {
+ addReferenceBindingProvider(component, ref, binding);
+ addReferenceWire(component, ref, binding);
+ ReferenceBindingProvider provider = ref.getBindingProvider(binding);
+ if (provider != null) {
+ provider.start();
+ }
+ }
+ }
+
+ public void deactivate(RuntimeComponent component, RuntimeComponentReference ref) {
+ removeReferenceWires(ref);
+ for (Binding binding : ref.getBindings()) {
+ removeReferenceBindingProvider(component, ref, binding);
+ }
+
+ }
+
+ /**
+ * @param component
+ * @param reference
+ * @param binding
+ */
+ private void addReferenceBindingProvider(RuntimeComponent component,
+ RuntimeComponentReference reference,
+ Binding binding) {
+ BindingProviderFactory providerFactory =
+ (BindingProviderFactory)providerFactories.getProviderFactory(binding.getClass());
+ if (providerFactory != null) {
+ @SuppressWarnings("unchecked")
+ ReferenceBindingProvider bindingProvider =
+ providerFactory.createReferenceBindingProvider((RuntimeComponent)component,
+ (RuntimeComponentReference)reference,
+ binding);
+ if (bindingProvider != null) {
+ ((RuntimeComponentReference)reference).setBindingProvider(binding, bindingProvider);
+ }
+ } else {
+ throw new IllegalStateException("Provider factory not found for class: " + binding.getClass().getName());
+ }
+ }
+
+ /**
+ * @param reference
+ */
+ private void resolveTargets(RuntimeComponentReference reference) {
+ // Support for distributed domain follows
+
+ // go over any targets that have not been resolved yet (as they are running on other nodes)
+ // and try an resolve them remotely
+ // TODO - this should work for any kind of wired binding but the only wireable binding
+ // is currently the SCA binding so we assume that
+ for (ComponentService service : reference.getTargets()) {
+ if (service.isUnresolved()) {
+ for (Binding binding : service.getBindings()) {
+ // TODO - we should look at all the bindings now associated with the
+ // unresolved target but we assume the SCA binding here as
+ // its currently the only wireable one
+ if (binding instanceof WireableBinding) {
+ WireableBinding scaBinding = (WireableBinding)binding;
+
+ // clone the SCA binding and fill in service details
+ // its cloned as each target
+ SCABinding clonedSCABinding = null;
+ try {
+ clonedSCABinding = (SCABinding)((WireableBinding)scaBinding).clone();
+ clonedSCABinding.setURI(service.getName());
+ // wireable binding stuff needs to go. SCA binding uses it
+ // currently to get to the service to work out if the service
+ // is resolved.
+ WireableBinding endpoint = ((WireableBinding)clonedSCABinding);
+ endpoint.setTargetComponentService(service);
+ //endpoint.setTargetComponent(component); - not known for unresolved target
+ //endpoint.setTargetBinding(serviceBinding); - not known for unresolved target
+
+ // add the cloned SCA binding to the reference as it will be used to look up the
+ // provider later
+ reference.getBindings().remove(binding);
+ reference.getBindings().add(clonedSCABinding);
+ } catch (Exception e) {
+ // warning("The binding doesn't support clone: " + binding.getClass().getSimpleName(), binding);
+ }
+ } else {
+ throw new IllegalStateException(
+ "Unable to create a distributed SCA binding provider for reference: " + reference
+ .getName()
+ + " and target: "
+ + service.getName());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Create the runtime wires for a reference binding
+ *
+ * @param component
+ * @param reference
+ * @param binding
+ */
+ private void addReferenceWire(Component component, ComponentReference reference, Binding binding) {
+ if (!(reference instanceof RuntimeComponentReference)) {
+ return;
+ }
+
+ // create wire if binding has an endpoint
+ Component targetComponent = null;
+ ComponentService targetComponentService = null;
+ Binding targetBinding = null;
+ if (binding instanceof WireableBinding) {
+ WireableBinding endpoint = (WireableBinding)binding;
+ targetComponent = endpoint.getTargetComponent();
+ targetComponentService = endpoint.getTargetComponentService();
+ targetBinding = endpoint.getTargetBinding();
+ }
+
+ // create a forward wire, either static or dynamic
+ addReferenceWire(component, reference, binding, targetComponent, targetComponentService, targetBinding);
+
+ /*
+ // if static forward wire (not from self-reference), try to create a static callback wire
+ if (targetComponentService != null && !reference.getName().startsWith("$self$.")) {
+ ComponentReference callbackReference = targetComponentService.getCallbackReference();
+ if (callbackReference != null) {
+ Binding callbackBinding = null;
+ Binding callbackServiceBinding = null;
+ // select a service callback binding that can be wired back to this component
+ for (Binding refBinding : callbackReference.getBindings()) {
+ // first look for a callback binding whose name matches the target binding name
+ if (refBinding.getName().equals(targetBinding.getName())) {
+ callbackBinding = refBinding;
+ break;
+ }
+ }
+ // see if there is a matching reference callback binding
+ if (callbackBinding != null) {
+ callbackServiceBinding = reference.getCallbackService().getBinding(callbackBinding.getClass());
+ }
+ // if there isn't an end-to-end match, try again based on target binding type
+ if (callbackBinding == null || callbackServiceBinding == null) {
+ callbackBinding = callbackReference.getBinding(targetBinding.getClass());
+ if (callbackBinding != null) {
+ callbackServiceBinding = reference.getCallbackService().getBinding(callbackBinding.getClass());
+ }
+ }
+ if (callbackBinding != null && callbackServiceBinding != null) {
+ // end-to-end match, so create a static callback wire as well as the static forward wire
+
+ addReferenceWire(targetComponent, callbackReference, callbackBinding, component, reference
+ .getCallbackService(), callbackServiceBinding);
+ } else {
+ // no end-to-end match, so do not create a static callback wire
+ }
+ }
+ }
+ */
+ }
+
+ /**
+ * Create a reference wire for a forward call or a callback
+ * @param reference
+ * @param service
+ * @param serviceBinding
+ * @param component
+ * @param referenceBinding
+ */
+ private RuntimeWire addReferenceWire(Component refComponent,
+ ComponentReference reference,
+ Binding refBinding,
+ Component serviceComponent,
+ ComponentService service,
+ Binding serviceBinding) {
+ RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference;
+ InterfaceContract bindingContract = getInterfaceContract(reference, refBinding);
+
+ // Use the interface contract of the reference on the component type
+ Reference componentTypeRef = reference.getReference();
+ InterfaceContract sourceContract =
+ componentTypeRef == null ? reference.getInterfaceContract() : componentTypeRef.getInterfaceContract();
+ sourceContract = sourceContract.makeUnidirectional(false);
+
+ EndpointReference wireSource =
+ new EndpointReferenceImpl((RuntimeComponent)refComponent, reference, refBinding, sourceContract);
+ ComponentService callbackService = reference.getCallbackService();
+ if (callbackService != null) {
+ // select a reference callback binding to pass with invocations on this wire
+ Binding callbackBinding = null;
+ for (Binding binding : callbackService.getBindings()) {
+ // first look for a callback binding whose name matches the reference binding name
+ if (binding.getName().equals(refBinding.getName()) || binding.getName()
+ .equals(CALLBACK_PREFIX + refBinding.getName())) {
+ callbackBinding = binding;
+ break;
+ }
+ }
+ // if no callback binding found, try again based on reference binding type
+ if (callbackBinding == null) {
+ callbackBinding = callbackService.getBinding(refBinding.getClass());
+ }
+ InterfaceContract callbackContract = callbackService.getInterfaceContract();
+ EndpointReference callbackEndpoint =
+ new EndpointReferenceImpl((RuntimeComponent)refComponent, callbackService, callbackBinding,
+ callbackContract);
+ wireSource.setCallbackEndpoint(callbackEndpoint);
+ }
+
+ EndpointReference wireTarget =
+ new EndpointReferenceImpl((RuntimeComponent)serviceComponent, service, serviceBinding, bindingContract);
+
+ RuntimeWire wire =
+ new RuntimeWireImpl(wireSource, wireTarget, interfaceContractMapper, workScheduler, wireProcessor);
+ runtimeRef.getRuntimeWires().add(wire);
+
+ return wire;
+ }
+
+ private void addImplementationProvider(RuntimeComponent component, Implementation implementation) {
+ ImplementationProviderFactory providerFactory =
+ (ImplementationProviderFactory)providerFactories.getProviderFactory(implementation.getClass());
+ if (providerFactory != null) {
+ @SuppressWarnings("unchecked")
+ ImplementationProvider implementationProvider =
+ providerFactory.createImplementationProvider(component, implementation);
+ if (implementationProvider != null) {
+ component.setImplementationProvider(implementationProvider);
+ }
+ } else {
+ throw new IllegalStateException("Provider factory not found for class: " + implementation.getClass()
+ .getName());
+ }
+ }
+
+ private void removeImplementationProvider(RuntimeComponent component) {
+ component.setImplementationProvider(null);
+ }
+
+ /**
+ * @param component
+ * @param service
+ * @param binding
+ */
+ private void addServiceBindingProvider(RuntimeComponent component, RuntimeComponentService service, Binding binding) {
+ // REVIEW: Is this the right way to mark the binding as remote?
+ if ((binding instanceof WireableBinding) && (service.getInterfaceContract().getInterface().isRemotable())) {
+ WireableBinding wireableBinding = (WireableBinding)binding;
+ wireableBinding.setRemote(true);
+ }
+ BindingProviderFactory providerFactory =
+ (BindingProviderFactory)providerFactories.getProviderFactory(binding.getClass());
+ if (providerFactory != null) {
+ @SuppressWarnings("unchecked")
+ ServiceBindingProvider bindingProvider =
+ providerFactory.createServiceBindingProvider((RuntimeComponent)component,
+ (RuntimeComponentService)service,
+ binding);
+ if (bindingProvider != null) {
+ ((RuntimeComponentService)service).setBindingProvider(binding, bindingProvider);
+ }
+ } else {
+ throw new IllegalStateException("Provider factory not found for class: " + binding.getClass().getName());
+ }
+ }
+
+ private void removeServiceBindingProvider(RuntimeComponent component,
+ RuntimeComponentService service,
+ Binding binding) {
+ service.setBindingProvider(binding, null);
+ }
+
+ private void removeReferenceBindingProvider(RuntimeComponent component,
+ RuntimeComponentReference reference,
+ Binding binding) {
+ reference.setBindingProvider(binding, null);
+ }
+
+ public void start(Composite composite) {
+ for (Component component : composite.getComponents()) {
+ start(component);
+ }
+ }
+
+ public void stop(Composite composite) {
+ for (Component component : composite.getComponents()) {
+ stop(component);
+
+ }
+
+ }
+
+ public void start(Component component) {
+ RuntimeComponent runtimeComponent = ((RuntimeComponent)component);
+ configureComponentContext(runtimeComponent);
+
+ for (ComponentService service : component.getServices()) {
+ for (Binding binding : service.getBindings()) {
+ ServiceBindingProvider bindingProvider = ((RuntimeComponentService)service).getBindingProvider(binding);
+ if (bindingProvider != null) {
+ bindingProvider.start();
+ }
+ }
+ // for (RuntimeWire wire : ((RuntimeComponentService)service).getRuntimeWires()) {
+ // wireProcessor.process(wire);
+ // }
+ }
+
+ for (ComponentReference reference : component.getReferences()) {
+ ((RuntimeComponentReference)reference).setComponent(runtimeComponent);
+ }
+
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ start((Composite)implementation);
+ } else {
+ ImplementationProvider implementationProvider = runtimeComponent.getImplementationProvider();
+ if (implementationProvider != null) {
+ implementationProvider.start();
+ }
+ }
+
+ if (component instanceof ScopedRuntimeComponent) {
+ ScopedRuntimeComponent scopedRuntimeComponent = (ScopedRuntimeComponent)component;
+ if (scopedRuntimeComponent.getScopeContainer() != null) {
+ scopedRuntimeComponent.getScopeContainer().start();
+ }
+ }
+
+ runtimeComponent.setStarted(true);
+ }
+
+ /**
+ * @param runtimeComponent
+ */
+ public void configureComponentContext(RuntimeComponent runtimeComponent) {
+ RuntimeComponentContext componentContext =
+ new ComponentContextImpl(this, assemblyFactory, proxyFactory, interfaceContractMapper,
+ requestContextFactory, javaInterfaceFactory, runtimeComponent);
+ runtimeComponent.setComponentContext(componentContext);
+ }
+
+ /**
+ * Stop a component
+ */
+ public void stop(Component component) {
+ for (ComponentService service : component.getServices()) {
+ for (Binding binding : service.getBindings()) {
+ ServiceBindingProvider bindingProvider = ((RuntimeComponentService)service).getBindingProvider(binding);
+ if (bindingProvider != null) {
+ bindingProvider.stop();
+ }
+ }
+ }
+ for (ComponentReference reference : component.getReferences()) {
+ for (Binding binding : reference.getBindings()) {
+ ReferenceBindingProvider bindingProvider =
+ ((RuntimeComponentReference)reference).getBindingProvider(binding);
+ if (bindingProvider != null) {
+ bindingProvider.stop();
+ }
+ }
+ }
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ stop((Composite)implementation);
+ } else {
+ ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider();
+ if (implementationProvider != null) {
+ implementationProvider.stop();
+ }
+ }
+
+ if (component instanceof ScopedRuntimeComponent) {
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ if (runtimeComponent.getScopeContainer() != null) {
+ runtimeComponent.getScopeContainer().stop();
+ }
+ }
+
+ ((RuntimeComponent)component).setStarted(false);
+ }
+
+ /**
+ * Get the effective interface contract for a reference binding
+ *
+ * @param reference
+ * @param binding
+ * @return
+ */
+ private InterfaceContract getInterfaceContract(ComponentReference reference, Binding binding) {
+ InterfaceContract interfaceContract = reference.getInterfaceContract();
+ ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
+ if (provider != null) {
+ InterfaceContract bindingContract = provider.getBindingInterfaceContract();
+ if (bindingContract != null) {
+ interfaceContract = bindingContract;
+ }
+ }
+ return interfaceContract.makeUnidirectional(false);
+ }
+
+ /**
+ * Remove the runtime wires for a reference binding
+ * @param reference
+ */
+ private void removeReferenceWires(ComponentReference reference) {
+ if (!(reference instanceof RuntimeComponentReference)) {
+ return;
+ }
+ // [rfeng] Comment out the following statements to avoid the on-demand activation
+ // RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference;
+ // runtimeRef.getRuntimeWires().clear();
+ }
+
+ /**
+ * Get the effective interface contract for the service binding
+ *
+ * @param service
+ * @param binding
+ * @return
+ */
+ private InterfaceContract getInterfaceContract(ComponentService service, Binding binding) {
+ InterfaceContract interfaceContract = service.getInterfaceContract();
+
+ ServiceBindingProvider provider = ((RuntimeComponentService)service).getBindingProvider(binding);
+ if (provider != null) {
+ InterfaceContract bindingContract = provider.getBindingInterfaceContract();
+ if (bindingContract != null) {
+ interfaceContract = bindingContract;
+ }
+ }
+ return interfaceContract.makeUnidirectional(false);
+ }
+
+ /**
+ * Remove runtime wires for a service binding
+ *
+ * @param component
+ * @param service
+ */
+ private void removeServiceWires(ComponentService service) {
+ if (!(service instanceof RuntimeComponentService)) {
+ return;
+ }
+ RuntimeComponentService runtimeService = (RuntimeComponentService)service;
+ runtimeService.getRuntimeWires().clear();
+ }
+
+ /**
+ * Create a service wire for a forward call or a callback
+ * @param service
+ * @param serviceBinding
+ * @param reference
+ * @param component
+ * @param referenceBinding
+ */
+ private RuntimeWire addServiceWire(Component serviceComponent, ComponentService service, Binding serviceBinding) {
+ if (!(service instanceof RuntimeComponentService)) {
+ return null;
+ }
+ RuntimeComponentService runtimeService = (RuntimeComponentService)service;
+
+ // FIXME: [rfeng] We might need a better way to get the impl interface contract
+ Service targetService = service.getService();
+ if (targetService == null) {
+ targetService = service;
+ }
+ InterfaceContract targetContract = targetService.getInterfaceContract().makeUnidirectional(false);
+
+ InterfaceContract sourceContract = getInterfaceContract(service, serviceBinding);
+
+ EndpointReference wireSource = new EndpointReferenceImpl(null, null, serviceBinding, sourceContract);
+
+ EndpointReference wireTarget =
+ new EndpointReferenceImpl((RuntimeComponent)serviceComponent, (RuntimeComponentService)service,
+ serviceBinding, targetContract);
+
+ RuntimeWire wire =
+ new RuntimeWireImpl(wireSource, wireTarget, interfaceContractMapper, workScheduler, wireProcessor);
+ runtimeService.getRuntimeWires().add(wire);
+
+ return wire;
+ }
+
+ public void activate(RuntimeComponent component, RuntimeComponentService service) {
+ for (Binding binding : service.getBindings()) {
+ addServiceBindingProvider(component, service, binding);
+ addServiceWire(component, service, binding);
+ }
+ }
+
+ public void deactivate(RuntimeComponent component, RuntimeComponentService service) {
+ removeServiceWires(service);
+ for (Binding binding : service.getBindings()) {
+ removeServiceBindingProvider(component, service, binding);
+ }
+ }
+
+ private void addScopeContainer(Component component) {
+ if (!(component instanceof ScopedRuntimeComponent)) {
+ return;
+ }
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ runtimeComponent.setScopeContainer(scopeRegistry.getScopeContainer(runtimeComponent));
+ }
+
+ private void removeScopeContainer(Component component) {
+ if (!(component instanceof ScopedRuntimeComponent)) {
+ return;
+ }
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ runtimeComponent.setScopeContainer(null);
+ }
+
+ public void activate(Composite composite) throws ActivationException {
+ try {
+ for (Component component : composite.getComponents()) {
+
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ activate((Composite)implementation);
+ } else if (implementation != null) {
+ addImplementationProvider((RuntimeComponent)component, implementation);
+ addScopeContainer(component);
+ }
+
+ for (ComponentService service : component.getServices()) {
+ activate((RuntimeComponent)component, (RuntimeComponentService)service);
+ }
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ public void deactivate(Composite composite) throws ActivationException {
+ try {
+ for (Component component : composite.getComponents()) {
+ for (ComponentService service : component.getServices()) {
+ deactivate((RuntimeComponent)component, (RuntimeComponentService)service);
+ }
+
+ for (ComponentReference reference : component.getReferences()) {
+ deactivate((RuntimeComponent)component, (RuntimeComponentReference)reference);
+ }
+
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ deactivate((Composite)implementation);
+ } else if (implementation != null) {
+ removeImplementationProvider((RuntimeComponent)component);
+ removeScopeContainer(component);
+ }
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ /**
+ * @return the referenceHelper
+ */
+ public ComponentContextHelper getComponentContextHelper() {
+ return componentContextHelper;
+ }
+
+ /**
+ * @return the proxyFactory
+ */
+ public ProxyFactory getProxyFactory() {
+ return proxyFactory;
+ }
+
+ /**
+ * @return the domainComposite
+ */
+ public Composite getDomainComposite() {
+ return domainComposite;
+ }
+
+ /**
+ * @param domainComposite the domainComposite to set
+ */
+ public void setDomainComposite(Composite domainComposite) {
+ this.domainComposite = domainComposite;
+ }
+
+ public Component resolve(String componentURI) {
+ for (Composite composite : domainComposite.getIncludes()) {
+ Component component = resolve(composite, componentURI);
+ if (component != null) {
+ return component;
+ }
+ }
+ return null;
+ }
+
+ public Component resolve(Composite composite, String componentURI) {
+ String prefix = componentURI + "/";
+ for (Component component : composite.getComponents()) {
+ String uri = component.getURI();
+ if (uri.equals(componentURI)) {
+ return component;
+ }
+ if (componentURI.startsWith(prefix)) {
+ Implementation implementation = component.getImplementation();
+ if (!(implementation instanceof Composite)) {
+ return null;
+ }
+ return resolve((Composite)implementation, componentURI);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the javaInterfaceFactory
+ */
+ public JavaInterfaceFactory getJavaInterfaceFactory() {
+ return javaInterfaceFactory;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/EndpointReferenceImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/EndpointReferenceImpl.java
new file mode 100644
index 0000000000..da825dc37a
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/EndpointReferenceImpl.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.assembly;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EndpointReferenceImpl implements EndpointReference {
+ private RuntimeComponent component;
+ private Contract contract;
+ private Binding binding;
+ private InterfaceContract interfaceContract;
+ private String uri;
+ private EndpointReference callbackEndpoint;
+
+ /**
+ * @param component
+ * @param contract
+ * @param binding
+ * @param interfaceContract
+ */
+ public EndpointReferenceImpl(RuntimeComponent component,
+ Contract contract,
+ Binding binding,
+ InterfaceContract interfaceContract) {
+ super();
+ this.component = component;
+ this.contract = contract;
+ this.binding = binding;
+ this.interfaceContract = interfaceContract;
+ this.uri = (component != null ? component.getName() : "") + '/' +
+ (contract != null ? contract.getName() : "");
+ }
+
+ /**
+ * @param uri
+ */
+ public EndpointReferenceImpl(String uri) {
+ super();
+ this.uri = uri;
+ }
+
+ public Binding getBinding() {
+ return binding;
+ }
+
+ public void setBinding(Binding binding) {
+ this.binding = binding;
+ }
+
+ public RuntimeComponent getComponent() {
+ return component;
+ }
+
+ public void setComponent(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ public Contract getContract() {
+ return contract;
+ }
+
+ public void setContract(Contract contract) {
+ this.contract = contract;
+ }
+
+ public InterfaceContract getInterfaceContract() {
+ return interfaceContract;
+ }
+
+ public void setInterfaceContract(InterfaceContract interfaceContract) {
+ this.interfaceContract = interfaceContract;
+ }
+
+ public String getURI() {
+ return uri;
+ }
+
+ public void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ public EndpointReference getCallbackEndpoint() {
+ return callbackEndpoint;
+ }
+
+ public void setCallbackEndpoint(EndpointReference callbackEndpoint) {
+ this.callbackEndpoint = callbackEndpoint;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((uri == null) ? 0 : uri.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final EndpointReferenceImpl other = (EndpointReferenceImpl)obj;
+ if (uri == null) {
+ if (other.uri != null)
+ return false;
+ } else if (!uri.equals(other.uri))
+ return false;
+ return true;
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeAssemblyFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeAssemblyFactory.java
new file mode 100644
index 0000000000..ee52c27d14
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeAssemblyFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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.core.assembly;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.DefaultAssemblyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RuntimeAssemblyFactory extends DefaultAssemblyFactory implements AssemblyFactory {
+ private final ProxyFactory proxyFactory;
+ private final InterfaceContractMapper interfaceContractMapper;
+
+ /**
+ * @param proxyFactory
+ */
+ public RuntimeAssemblyFactory(InterfaceContractMapper interfaceContractMapper, ProxyFactory proxyFactory) {
+ super();
+ this.proxyFactory = proxyFactory;
+ this.interfaceContractMapper = interfaceContractMapper;
+ }
+
+ @Override
+ public Component createComponent() {
+ return new RuntimeComponentImpl(proxyFactory);
+ }
+
+ @Override
+ public ComponentReference createComponentReference() {
+ return new RuntimeComponentReferenceImpl(interfaceContractMapper);
+ }
+
+ @Override
+ public ComponentService createComponentService() {
+ return new RuntimeComponentServiceImpl(interfaceContractMapper);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentImpl.java
new file mode 100644
index 0000000000..cde9cbb18c
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentImpl.java
@@ -0,0 +1,85 @@
+/*
+ * 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.core.assembly;
+
+import org.apache.tuscany.sca.assembly.impl.ComponentImpl;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.ScopeContainer;
+import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RuntimeComponentImpl extends ComponentImpl implements RuntimeComponent, ScopedRuntimeComponent {
+ protected RuntimeComponentContext componentContext;
+ protected ImplementationProvider implementationProvider;
+ protected ProxyFactory proxyService;
+ protected ScopeContainer scopeContainer;
+ protected boolean started;
+
+ /**
+ * @param proxyService
+ */
+ public RuntimeComponentImpl(ProxyFactory proxyService) {
+ super();
+ this.proxyService = proxyService;
+ }
+
+ public ImplementationProvider getImplementationProvider() {
+ return implementationProvider;
+ }
+
+ public void setImplementationProvider(ImplementationProvider provider) {
+ this.implementationProvider = provider;
+ }
+
+ public ScopeContainer getScopeContainer() {
+ return scopeContainer;
+ }
+
+ public void setScopeContainer(ScopeContainer scopeContainer) {
+ this.scopeContainer = scopeContainer;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+ /**
+ * @return the componentContext
+ */
+ public RuntimeComponentContext getComponentContext() {
+ return componentContext;
+ }
+
+ /**
+ * @param componentContext the componentContext to set
+ */
+ public void setComponentContext(RuntimeComponentContext componentContext) {
+ this.componentContext = componentContext;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java
new file mode 100644
index 0000000000..5ad339b76d
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.assembly;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+
+public class RuntimeComponentReferenceImpl extends ComponentReferenceImpl implements RuntimeComponentReference {
+ private List<RuntimeWire> wires;
+ private Map<Binding, ReferenceBindingProvider> bindingProviders = new HashMap<Binding, ReferenceBindingProvider>();
+ private InterfaceContractMapper mapper;
+
+ private RuntimeComponent component;
+
+ public RuntimeComponentReferenceImpl(InterfaceContractMapper mapper) {
+ super();
+ this.mapper = mapper;
+ }
+
+ public synchronized List<RuntimeWire> getRuntimeWires() {
+ if (wires == null) {
+ wires = new ArrayList<RuntimeWire>();
+ component.getComponentContext().activate(this);
+ }
+ return wires;
+ }
+
+ public RuntimeWire getRuntimeWire(Binding binding) {
+ for (RuntimeWire wire : getRuntimeWires()) {
+ if (wire.getSource().getBinding() == binding) {
+ return wire;
+ }
+ }
+ return null;
+ }
+
+ public ReferenceBindingProvider getBindingProvider(Binding binding) {
+ return bindingProviders.get(binding);
+ }
+
+ public void setBindingProvider(Binding binding, ReferenceBindingProvider bindingProvider) {
+ bindingProviders.put(binding, bindingProvider);
+ }
+
+ public Invoker getInvoker(Binding binding, Operation operation) {
+ RuntimeWire wire = getRuntimeWire(binding);
+ if (wire == null) {
+ return null;
+ }
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ Operation op = chain.getSourceOperation();
+ if (mapper.isCompatible(operation, op, op.getInterface().isRemotable())) {
+ return chain.getHeadInvoker();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the component
+ */
+ public RuntimeComponent getComponent() {
+ return component;
+ }
+
+ /**
+ * @param component the component to set
+ */
+ public void setComponent(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeComponentReferenceImpl ref = (RuntimeComponentReferenceImpl) super.clone();
+ ref.wires = null;
+ ref.bindingProviders = new HashMap<Binding, ReferenceBindingProvider>();
+ return ref;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java
new file mode 100644
index 0000000000..d86e810096
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java
@@ -0,0 +1,127 @@
+/*
+ * 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.core.assembly;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.impl.ComponentServiceImpl;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.ServiceRuntimeException;
+
+public class RuntimeComponentServiceImpl extends ComponentServiceImpl implements RuntimeComponentService {
+ private InterfaceContractMapper mapper;
+ private List<RuntimeWire> wires = new ArrayList<RuntimeWire>();
+ private List<RuntimeWire> callbackWires = new ArrayList<RuntimeWire>();
+ private Map<Binding, ServiceBindingProvider> bindingProviders = new HashMap<Binding, ServiceBindingProvider>();
+
+ public RuntimeComponentServiceImpl(InterfaceContractMapper mapper) {
+ super();
+ this.mapper = mapper;
+ }
+
+ public List<RuntimeWire> getRuntimeWires() {
+ return wires;
+ }
+
+ public RuntimeWire getRuntimeWire(Binding binding) {
+ for (RuntimeWire wire : wires) {
+ if (wire.getTarget().getBinding() == binding) {
+ return wire;
+ }
+ }
+ return null;
+ }
+
+ public List<RuntimeWire> getCallbackWires() {
+ return callbackWires;
+ }
+
+ public ServiceBindingProvider getBindingProvider(Binding binding) {
+ return bindingProviders.get(binding);
+ }
+
+ public void setBindingProvider(Binding binding, ServiceBindingProvider bindingProvider) {
+ bindingProviders.put(binding, bindingProvider);
+ }
+
+ public Invoker getInvoker(Binding binding, Operation operation) {
+ return getInvoker(binding, null, operation);
+ }
+
+ public Invoker getInvoker(Binding binding, InterfaceContract interfaceContract, Operation operation) {
+ InvocationChain chain = getInvocationChain(binding, interfaceContract, operation);
+ if (chain != null) {
+ return chain.getHeadInvoker();
+ } else {
+ return null;
+ }
+ }
+
+ public InvocationChain getInvocationChain(Binding binding, InterfaceContract interfaceContract, Operation operation) {
+ RuntimeWire wire = getRuntimeWire(binding);
+ if (wire == null) {
+ return null;
+ }
+ if (interfaceContract != null && interfaceContract != wire.getSource().getInterfaceContract()) {
+ try {
+ wire = (RuntimeWire)wire.clone();
+ wire.getSource().setInterfaceContract(interfaceContract);
+ } catch (CloneNotSupportedException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ Operation op = chain.getTargetOperation();
+ if (mapper.isCompatible(operation, op, op.getInterface().isRemotable())) {
+ return chain;
+ }
+ }
+ return null;
+ }
+
+ public InvocationChain getInvocationChain(Binding binding, Operation operation) {
+ return getInvocationChain(binding, null, operation);
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.assembly.impl.ComponentServiceImpl#clone()
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeComponentServiceImpl clone = (RuntimeComponentServiceImpl)super.clone();
+ clone.bindingProviders =
+ (Map<Binding, ServiceBindingProvider>)((HashMap<Binding, ServiceBindingProvider>)bindingProviders).clone();
+ clone.wires = (List<RuntimeWire>)((ArrayList<RuntimeWire>)wires).clone();
+ clone.callbackWires = (List<RuntimeWire>)((ArrayList<RuntimeWire>)callbackWires).clone();
+ return clone;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
new file mode 100644
index 0000000000..9a8635ddb0
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.assembly;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.core.invocation.InvocationChainImpl;
+import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider2;
+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.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RuntimeWireImpl implements RuntimeWire {
+ private EndpointReference wireSource;
+ private EndpointReference wireTarget;
+
+ private transient RuntimeWireProcessor wireProcessor;
+ private transient InterfaceContractMapper interfaceContractMapper;
+ private transient WorkScheduler workScheduler;
+
+ private List<InvocationChain> chains;
+
+ /**
+ * @param source
+ * @param target
+ * @param interfaceContractMapper
+ * @param workScheduler
+ * @param wireProcessor
+ */
+ public RuntimeWireImpl(EndpointReference source,
+ EndpointReference target,
+ InterfaceContractMapper interfaceContractMapper,
+ WorkScheduler workScheduler,
+ RuntimeWireProcessor wireProcessor) {
+ super();
+ this.wireSource = source;
+ this.wireTarget = target;
+ this.interfaceContractMapper = interfaceContractMapper;
+ this.workScheduler = workScheduler;
+ this.wireProcessor = wireProcessor;
+ }
+
+ public synchronized List<InvocationChain> getInvocationChains() {
+ if (chains == null) {
+ initInvocationChains();
+ }
+ return chains;
+ }
+
+ /**
+ * Initialize the invocation chains
+ */
+ private void initInvocationChains() {
+ chains = new ArrayList<InvocationChain>();
+ InterfaceContract sourceContract = wireSource.getInterfaceContract();
+ InterfaceContract targetContract = wireTarget.getInterfaceContract();
+
+ Contract source = wireSource.getContract();
+ if (source instanceof RuntimeComponentReference) {
+ // It's the reference wire
+ RuntimeComponentReference reference = (RuntimeComponentReference)wireSource.getContract();
+ Binding refBinding = wireSource.getBinding();
+ for (Operation operation : sourceContract.getInterface().getOperations()) {
+ Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
+ InvocationChain chain = new InvocationChainImpl(operation, targetOperation);
+ if (operation.isNonBlocking()) {
+ addNonBlockingInterceptor(reference, refBinding, chain);
+ }
+ addBindingInterceptor(reference, refBinding, chain, operation);
+ chains.add(chain);
+ }
+ } else {
+ // It's the service wire
+ RuntimeComponentService service = (RuntimeComponentService)wireTarget.getContract();
+ RuntimeComponent serviceComponent = wireTarget.getComponent();
+ for (Operation operation : sourceContract.getInterface().getOperations()) {
+ Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
+ InvocationChain chain = new InvocationChainImpl(operation, targetOperation);
+ addImplementationInterceptor(serviceComponent, service, chain, targetOperation);
+ chains.add(chain);
+ }
+ }
+ wireProcessor.process(this);
+ }
+
+ public EndpointReference getSource() {
+ return wireSource;
+ }
+
+ public EndpointReference getTarget() {
+ return wireTarget;
+ }
+
+ public void setTarget(EndpointReference target) {
+ this.wireTarget = target;
+ this.chains = null;
+ }
+
+ /**
+ * Add the interceptor for a binding
+ *
+ * @param reference
+ * @param binding
+ * @param chain
+ * @param operation
+ */
+ private void addBindingInterceptor(ComponentReference reference,
+ Binding binding,
+ InvocationChain chain,
+ Operation operation) {
+ try {
+ ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
+ if (provider != null) {
+ Invoker invoker = null;
+ if (provider instanceof ReferenceBindingProvider2) {
+ invoker = ((ReferenceBindingProvider2)provider).createInvoker(operation);
+ } else {
+ // must be an old provider that only has the deprecated signature
+ invoker = provider.createInvoker(operation, false);
+ }
+ if (invoker != null) {
+ chain.addInvoker(invoker);
+ }
+ }
+ } catch (RuntimeException e) {
+ // TODO: [rfeng] Ignore the self reference if a runtime exception happens
+ if (!reference.getName().startsWith("$self$.")) {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Add a non-blocking interceptor if the reference binding needs it
+ *
+ * @param reference
+ * @param binding
+ * @param chain
+ */
+ private void addNonBlockingInterceptor(ComponentReference reference, Binding binding, InvocationChain chain) {
+ ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
+ if (provider != null) {
+ boolean supportsAsyncOneWayInvocation = false;
+ if (provider instanceof ReferenceBindingProvider2) {
+ supportsAsyncOneWayInvocation = ((ReferenceBindingProvider2)provider).supportsAsyncOneWayInvocation();
+ } else {
+ // must be an old provider that doesn't have this method
+ }
+ if (!supportsAsyncOneWayInvocation) {
+ chain.addInterceptor(new NonBlockingInterceptor(workScheduler));
+ }
+ }
+ }
+
+ /**
+ * Add the interceptor for a component implementation
+ *
+ * @param component
+ * @param service
+ * @param chain
+ * @param operation
+ */
+ private void addImplementationInterceptor(Component component,
+ ComponentService service,
+ InvocationChain chain,
+ Operation operation) {
+ ImplementationProvider provider = ((RuntimeComponent)component).getImplementationProvider();
+ if (provider != null) {
+ Invoker invoker = null;
+ invoker = provider.createInvoker((RuntimeComponentService)service, operation);
+ chain.addInvoker(invoker);
+ }
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeWireImpl copy =(RuntimeWireImpl) super.clone();
+ copy.wireSource = (EndpointReference) wireSource.clone();
+ copy.wireTarget = (EndpointReference) wireTarget.clone();
+ copy.chains = null;
+ return copy;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java
new file mode 100644
index 0000000000..95691c22d0
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.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.core.context;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.net.URI;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.SCABinding;
+import org.apache.tuscany.sca.assembly.WireableBinding;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl;
+import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
+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.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+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.osoa.sca.CallableReference;
+import org.osoa.sca.Conversation;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Base class for implementations of service and callback references.
+ *
+ * @version $Rev$ $Date$
+ * @param <B> the type of the business interface
+ */
+public class CallableReferenceImpl<B> implements CallableReference<B>, Externalizable, ObjectFactory<B> {
+ protected transient CompositeActivator compositeActivator;
+ protected transient ProxyFactory proxyFactory;
+
+ protected transient Class<B> businessInterface;
+
+ // if the wire targets a conversational service this holds the conversation state
+ protected transient ConversationImpl conversation;
+
+ protected transient RuntimeComponent component;
+ protected transient RuntimeComponentReference reference;
+ protected transient Binding binding;
+
+ protected String componentURI; //The URI of the owning component
+ protected Object conversationID; // The conversationID should be serializable
+ protected Object callbackID; // The callbackID should be serializable
+
+ protected String scdl;
+
+ protected CallableReferenceImpl() {
+ super();
+ }
+
+ protected CallableReferenceImpl(Class<B> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentReference reference,
+ Binding binding,
+ ProxyFactory proxyFactory,
+ CompositeActivator compositeActivator) {
+ this.proxyFactory = proxyFactory;
+ this.businessInterface = businessInterface;
+ this.component = component;
+ this.reference = reference;
+ this.binding = binding;
+ // FIXME: The SCA spec is not clear how we should handle multiplicty for CallableReference
+ if (this.binding == null) {
+ this.binding = this.reference.getBinding(SCABinding.class);
+ if (this.binding == null) {
+ this.binding = this.reference.getBindings().get(0);
+ }
+ }
+
+ // FIXME: Should we normalize the componentName/serviceName URI into an absolute SCA URI in the SCA binding?
+ // sca:component1/component11/component112/service1?
+ String componentURI = component.getURI(); // The target will be relative to this base URI
+ this.componentURI = componentURI;
+ this.compositeActivator = compositeActivator;
+ RuntimeWire wire = this.reference.getRuntimeWire(this.binding);
+ init(wire);
+ }
+
+ public CallableReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
+ this.proxyFactory = proxyFactory;
+ this.businessInterface = businessInterface;
+ bind(wire);
+ }
+
+ public RuntimeWire getRuntimeWire() {
+ return reference.getRuntimeWire(binding);
+ }
+
+ protected void bind(RuntimeWire wire) {
+ if (wire != null) {
+ this.component = wire.getSource().getComponent();
+ this.reference = (RuntimeComponentReference)wire.getSource().getContract();
+ this.binding = wire.getSource().getBinding();
+ this.componentURI = component.getURI();
+ this.compositeActivator = ((ComponentContextImpl)component.getComponentContext()).getCompositeActivator();
+ init(wire);
+ }
+ }
+
+ protected void init(RuntimeWire wire) {
+ EndpointReference target = wire.getTarget();
+
+ // look to see if the target is conversational and if so create a conversation
+ InterfaceContract contract = target.getInterfaceContract();
+ if (contract == null) {
+ contract = reference.getInterfaceContract();
+ }
+ Interface contractInterface = contract.getInterface();
+
+ if (contractInterface != null && contractInterface.isConversational()) {
+ conversation = new ConversationImpl();
+ }
+
+ if (contract.getCallbackInterface() != null) {
+ this.callbackID = createCallbackID();
+ }
+ }
+
+ public B getInstance() throws ObjectCreationException {
+ try {
+ resolve();
+ return businessInterface.cast(proxyFactory.createProxy(this));
+ } catch (Exception e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+
+ public B getService() {
+ try {
+ return getInstance();
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public Class<B> getBusinessInterface() {
+ return businessInterface;
+ }
+
+ public boolean isConversational() {
+ return getConversation() != null;
+ }
+
+ public Conversation getConversation() {
+ return conversation;
+ }
+
+ public Object getCallbackID() {
+ return callbackID;
+ }
+
+ public EndpointReference getEndpointReference() {
+ return new EndpointReferenceImpl(component, reference, binding, reference.getInterfaceContract());
+ }
+
+ /**
+ * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+ */
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ this.scdl = in.readUTF();
+ // resolve();
+
+ String uri = in.readUTF();
+ int index = uri.indexOf('?');
+ if (index == -1) {
+ componentURI = uri;
+ } else {
+ componentURI = uri.substring(0, index);
+ String query = uri.substring(index);
+ StringTokenizer tokenizer = new StringTokenizer(query, "&");
+ while (tokenizer.hasMoreTokens()) {
+ String attr = tokenizer.nextToken();
+ String pair[] = attr.split("=");
+ if (pair[0].equals("sca.conversationID")) {
+ this.conversationID = pair[1];
+ } else if (pair[0].equals("sca.callbackID")) {
+ this.callbackID = pair[1];
+ }
+ }
+ }
+ }
+
+ /**
+ * @throws IOException
+ */
+ private synchronized void resolve() throws Exception {
+ if (scdl != null && component == null && reference == null) {
+ ComponentContextHelper componentContextHelper = ComponentContextHelper.getCurrentComponentContextHelper();
+ if (componentContextHelper != null) {
+ CompositeActivator currentActivator = ComponentContextHelper.getCurrentCompositeActivator();
+ this.compositeActivator = currentActivator;
+ Component c = componentContextHelper.fromXML(scdl);
+ this.component = (RuntimeComponent)c;
+ currentActivator.configureComponentContext(this.component);
+ this.reference = (RuntimeComponentReference)c.getReferences().get(0);
+ this.reference.setComponent(this.component);
+ URI uri = URI.create("/" + componentURI);
+ for (Binding binding : reference.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ String targetURI = uri.resolve(binding.getURI()).toString();
+ int index = targetURI.lastIndexOf('/');
+ String serviceName = targetURI.substring(index + 1);
+ targetURI = targetURI.substring(1, index);
+ Component targetComponet = compositeActivator.resolve(targetURI);
+ ComponentService targetService = null;
+ if (targetComponet != null) {
+ if ("".equals(serviceName)) {
+ targetService = ComponentContextHelper.getSingleService(targetComponet);
+ } else {
+ for (ComponentService service : targetComponet.getServices()) {
+ if (service.getName().equals(serviceName)) {
+ targetService = service;
+ break;
+ }
+ }
+ }
+ }
+ WireableBinding wireableBinding = (WireableBinding)binding;
+ wireableBinding.setTargetComponent(targetComponet);
+ wireableBinding.setTargetComponentService(targetService);
+ if (targetService != null) {
+ for (Binding serviceBinding : targetService.getBindings()) {
+ if (serviceBinding.getClass() == binding.getClass()) {
+ wireableBinding.setTargetBinding(serviceBinding);
+ break;
+ }
+ }
+ }
+ }
+ }
+ // FIXME: The SCA spec is not clear how we should handle multiplicty for CallableReference
+ if (binding == null) {
+ binding = reference.getBinding(SCABinding.class);
+ if (binding == null) {
+ binding = reference.getBindings().get(0);
+ }
+ }
+ Interface i = reference.getInterfaceContract().getInterface();
+ if (i instanceof JavaInterface) {
+ JavaInterface javaInterface = (JavaInterface)i;
+ if (javaInterface.isUnresolved()) {
+ javaInterface.setJavaClass(Thread.currentThread().getContextClassLoader()
+ .loadClass(javaInterface.getName()));
+ currentActivator.getJavaInterfaceFactory().createJavaInterface(javaInterface,
+ javaInterface.getJavaClass());
+ }
+ this.businessInterface = (Class<B>)javaInterface.getJavaClass();
+ }
+ this.proxyFactory = currentActivator.getProxyFactory();
+ }
+ }
+ }
+
+ /**
+ * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
+ */
+ public void writeExternal(ObjectOutput out) throws IOException {
+ try {
+ String scdl =
+ ((CompositeActivatorImpl)compositeActivator).getComponentContextHelper().toXML(component, reference);
+ out.writeUTF(scdl);
+ StringBuffer uri = new StringBuffer(componentURI);
+ boolean first = true;
+ if (conversationID != null) {
+ uri.append("?sca.conversationID=").append(conversationID);
+ first = false;
+ }
+ if (callbackID != null) {
+ if (!first) {
+ uri.append("&");
+ } else {
+ uri.append("?");
+ }
+ uri.append("sca.callbackID=").append(callbackID);
+ }
+ out.writeUTF(uri.toString());
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ /**
+ * Create a callback id
+ *
+ * @return the callback id
+ */
+ private String createCallbackID() {
+ return UUID.randomUUID().toString();
+ }
+
+ public void attachCallbackID(Object callbackID) {
+ this.callbackID = callbackID;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java
new file mode 100644
index 0000000000..e6679b7ce4
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java
@@ -0,0 +1,290 @@
+/*
+ * 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.core.context;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.WireableBinding;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+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.Message;
+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.RuntimeComponentService;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentContextHelper {
+
+ private final AssemblyFactory assemblyFactory;
+ private final JavaInterfaceFactory javaInterfaceFactory;
+ private final StAXArtifactProcessorExtensionPoint staxProcessors;
+
+ /**
+ * @param assemblyFactory The factory to create assembly models
+ * @param processors The extension point for stax artifact processors
+ */
+ public ComponentContextHelper(AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaInterfaceFactory,
+ StAXArtifactProcessorExtensionPoint processors) {
+ this.assemblyFactory = assemblyFactory;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ this.staxProcessors = processors;
+ }
+
+ /**
+ * Create a self-reference for a component service
+ * @param component
+ * @param service
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ public ComponentReference createSelfReference(Component component,
+ ComponentService service,
+ Class<?> businessInterface) throws CloneNotSupportedException,
+ InvalidInterfaceException {
+ ComponentReference componentReference = assemblyFactory.createComponentReference();
+ componentReference.setName("$self$." + service.getName());
+ for (Binding binding : service.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ WireableBinding wireableBinding = (WireableBinding)((WireableBinding)binding).clone();
+ wireableBinding.setTargetBinding(binding);
+ wireableBinding.setTargetComponent(component);
+ wireableBinding.setTargetComponentService(service);
+ wireableBinding.setRemote(false);
+ componentReference.getBindings().add(wireableBinding);
+ } else {
+ componentReference.getBindings().add(binding);
+ }
+ }
+
+ componentReference.setCallback(service.getCallback());
+ componentReference.getTargets().add(service);
+ componentReference.getPolicySets().addAll(service.getPolicySets());
+ componentReference.getRequiredIntents().addAll(service.getRequiredIntents());
+
+ InterfaceContract interfaceContract = service.getInterfaceContract();
+ Service componentTypeService = service.getService();
+ if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
+ interfaceContract = componentTypeService.getInterfaceContract();
+ }
+ interfaceContract = getInterfaceContract(interfaceContract, businessInterface);
+ componentReference.setInterfaceContract(interfaceContract);
+ componentReference.setMultiplicity(Multiplicity.ONE_ONE);
+ // component.getReferences().add(componentReference);
+ return componentReference;
+ }
+
+ /**
+ * @param interfaceContract
+ * @param businessInterface
+ * @return
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ private InterfaceContract getInterfaceContract(InterfaceContract interfaceContract, Class<?> businessInterface)
+ throws CloneNotSupportedException, InvalidInterfaceException {
+ Interface interfaze = interfaceContract.getInterface();
+ if (interfaze instanceof JavaInterface) {
+ Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
+ if (!businessInterface.isAssignableFrom(cls)) {
+ // The interface is not assignable from the interface contract
+ interfaceContract = (InterfaceContract)interfaceContract.clone();
+ interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface));
+ }
+ }
+ return interfaceContract;
+ }
+
+ /**
+ * Bind a component reference to a component service
+ * @param <B>
+ * @param businessInterface
+ * @param reference
+ * @param service
+ * @return
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ public RuntimeComponentReference bindComponentReference(Class<?> businessInterface,
+ RuntimeComponentReference reference,
+ RuntimeComponent component,
+ RuntimeComponentService service)
+ throws CloneNotSupportedException, InvalidInterfaceException {
+ RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
+ InterfaceContract interfaceContract = reference.getInterfaceContract();
+ Reference componentTypeReference = reference.getReference();
+ if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
+ interfaceContract = componentTypeReference.getInterfaceContract();
+ }
+ InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
+ if (refInterfaceContract != interfaceContract) {
+ ref = (RuntimeComponentReference)reference.clone();
+ ref.setInterfaceContract(interfaceContract);
+ }
+ ref.setComponent(component);
+ ref.getTargets().add(service);
+ ref.getBindings().clear();
+ for (Binding binding : service.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ WireableBinding wireableBinding = (WireableBinding)((WireableBinding)binding).clone();
+ wireableBinding.setTargetBinding(binding);
+ wireableBinding.setTargetComponent(component);
+ wireableBinding.setTargetComponentService(service);
+ wireableBinding.setRemote(false);
+ ref.getBindings().add(wireableBinding);
+ } else {
+ ref.getBindings().add(binding);
+ }
+ }
+ return ref;
+ }
+
+ public void write(Component component, ComponentReference reference, Writer writer) throws IOException {
+ try {
+ StAXArtifactProcessor<Composite> processor = staxProcessors.getProcessor(Composite.class);
+ Composite composite = assemblyFactory.createComposite();
+ composite.setName(new QName("http://tuscany.apache.org/xmlns/sca/1.0", "default"));
+ Component comp = assemblyFactory.createComponent();
+ comp.setName("default");
+ comp.setURI(component.getURI());
+ composite.getComponents().add(comp);
+ comp.getReferences().add(reference);
+
+ XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+ XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(writer);
+ processor.write(composite, streamWriter);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public String toXML(Component component, ComponentReference reference) throws IOException {
+ StringWriter writer = new StringWriter();
+ write(component, reference, writer);
+ return writer.toString();
+ }
+
+ public RuntimeComponent read(Reader reader) throws IOException {
+ try {
+ StAXArtifactProcessor<Composite> processor = staxProcessors.getProcessor(Composite.class);
+ XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ XMLStreamReader streamReader = inputFactory.createXMLStreamReader(reader);
+ Composite composite = processor.read(streamReader);
+ RuntimeComponent component = (RuntimeComponent)composite.getComponents().get(0);
+ return component;
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public Component fromXML(String xml) throws IOException {
+ return read(new StringReader(xml));
+ }
+
+ public static RuntimeComponent getCurrentComponent() {
+ Message message = ThreadMessageContext.getMessageContext();
+ if (message != null) {
+ EndpointReference to = message.getTo();
+ if (to == null) {
+ return null;
+ }
+ RuntimeComponent component = message.getTo().getComponent();
+ return component;
+ }
+ return null;
+ }
+
+ public static CompositeActivator getCurrentCompositeActivator() {
+ RuntimeComponent component = getCurrentComponent();
+ if (component != null) {
+ ComponentContextImpl context = (ComponentContextImpl)component.getComponentContext();
+ return context.getCompositeActivator();
+ }
+ return null;
+ }
+
+ public static ComponentContextHelper getCurrentComponentContextHelper() {
+ CompositeActivator activator = getCurrentCompositeActivator();
+ if (activator != null) {
+ return activator.getComponentContextHelper();
+ }
+ return null;
+ }
+
+ /**
+ * @param component
+ */
+ public static ComponentService getSingleService(Component component) {
+ ComponentService targetService;
+ List<ComponentService> services = component.getServices();
+ List<ComponentService> regularServices = new ArrayList<ComponentService>();
+ for (ComponentService service : services) {
+ if (service.isCallback()) {
+ continue;
+ }
+ String name = service.getName();
+ if (!name.startsWith("$") || name.startsWith("$dynamic$")) {
+ regularServices.add(service);
+ }
+ }
+ if (regularServices.size() == 0) {
+ throw new ServiceRuntimeException("No service is declared on component " + component.getURI());
+ }
+ if (regularServices.size() != 1) {
+ throw new ServiceRuntimeException("More than one service is declared on component " + component.getURI()
+ + ". Service name is required to get the service.");
+ }
+ targetService = regularServices.get(0);
+ return targetService;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java
new file mode 100644
index 0000000000..f020ede4c9
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java
@@ -0,0 +1,343 @@
+/*
+ * 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.core.context;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.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.assembly.Service;
+import org.apache.tuscany.sca.assembly.WireableBinding;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Implementation of ComponentContext that delegates to a ComponentContextProvider.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentContextImpl implements RuntimeComponentContext {
+ private final RuntimeComponent component;
+
+ private final CompositeActivator compositeActivator;
+ private final RequestContextFactory requestContextFactory;
+ private final ProxyFactory proxyFactory;
+ private final AssemblyFactory assemblyFactory;
+ private final JavaInterfaceFactory javaInterfaceFactory;
+
+ public ComponentContextImpl(CompositeActivator compositeActivator,
+ AssemblyFactory assemblyFactory,
+ ProxyFactory proxyFactory,
+ InterfaceContractMapper interfaceContractMapper,
+ RequestContextFactory requestContextFactory,
+ JavaInterfaceFactory javaInterfaceFactory,
+ RuntimeComponent component) {
+ super();
+ this.compositeActivator = compositeActivator;
+ this.assemblyFactory = assemblyFactory;
+ this.proxyFactory = proxyFactory;
+ this.requestContextFactory = requestContextFactory;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ this.component = component;
+ }
+
+ public String getURI() {
+ return component.getURI();
+ }
+
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ return (R)proxyFactory.cast(target);
+ }
+
+ public <B> B getService(Class<B> businessInterface, String referenceName) {
+ ServiceReference<B> serviceRef = getServiceReference(businessInterface, referenceName);
+ return serviceRef.getService();
+ }
+
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
+ try {
+ for (ComponentReference ref : component.getReferences()) {
+ if (referenceName.equals(ref.getName())) {
+ return getServiceReference(businessInterface, (RuntimeComponentReference)ref);
+ }
+ }
+ throw new ServiceRuntimeException("Reference not found: " + referenceName);
+ } catch (ServiceRuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public <B> B getProperty(Class<B> type, String propertyName) {
+ for (ComponentProperty p : component.getProperties()) {
+ if (propertyName.equals(propertyName)) {
+ return type.cast(p.getValue());
+ }
+ }
+ throw new ServiceRuntimeException("Property not found: " + propertyName);
+ }
+
+ public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface) {
+ ComponentService service = ComponentContextHelper.getSingleService(component);
+ try {
+ RuntimeComponentReference ref =
+ (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
+ ref.setComponent(component);
+
+ return getServiceReference(businessInterface, ref);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, String serviceName) {
+ try {
+ for (ComponentService service : component.getServices()) {
+ if (serviceName.equals(service.getName())) {
+ RuntimeComponentReference ref =
+ (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
+ ref.setComponent(component);
+ return getServiceReference(businessInterface, ref);
+ }
+ }
+ throw new ServiceRuntimeException("Service not found: " + serviceName);
+ } catch (ServiceRuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public RequestContext getRequestContext() {
+ if (requestContextFactory != null) {
+ return requestContextFactory.createRequestContext();
+ } else {
+ return new RequestContextImpl(proxyFactory);
+ }
+ }
+
+ /**
+ * @param businessInterface
+ * @param reference
+ * @return
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, RuntimeComponentReference reference) {
+ try {
+ RuntimeComponentReference ref = (RuntimeComponentReference)reference;
+ InterfaceContract interfaceContract = reference.getInterfaceContract();
+ Reference componentTypeReference = reference.getReference();
+ if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
+ interfaceContract = componentTypeReference.getInterfaceContract();
+ }
+ InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
+ if (refInterfaceContract != interfaceContract) {
+ ref = (RuntimeComponentReference)reference.clone();
+ ref.setInterfaceContract(interfaceContract);
+ }
+ ref.setComponent(component);
+ return new ServiceReferenceImpl<B>(businessInterface, component, ref, proxyFactory, compositeActivator);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Bind a component reference to a component service
+ * @param <B>
+ * @param businessInterface
+ * @param reference
+ * @param service
+ * @return
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface,
+ RuntimeComponentReference reference,
+ RuntimeComponent component,
+ RuntimeComponentService service) {
+ try {
+ RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
+ InterfaceContract interfaceContract = reference.getInterfaceContract();
+ Reference componentTypeReference = reference.getReference();
+ if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
+ interfaceContract = componentTypeReference.getInterfaceContract();
+ }
+ InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
+ if (refInterfaceContract != interfaceContract) {
+ ref = (RuntimeComponentReference)reference.clone();
+ ref.setInterfaceContract(interfaceContract);
+ }
+ ref.getTargets().add(service);
+ ref.getBindings().clear();
+ for (Binding binding : service.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ WireableBinding wireableBinding = (WireableBinding)((WireableBinding)binding).clone();
+ wireableBinding.setTargetBinding(binding);
+ wireableBinding.setTargetComponent(component);
+ wireableBinding.setTargetComponentService(service);
+ wireableBinding.setRemote(false);
+ ref.getBindings().add(wireableBinding);
+ } else {
+ ref.getBindings().add(binding);
+ }
+ }
+ return new ServiceReferenceImpl<B>(businessInterface, component, ref, proxyFactory, compositeActivator);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public <B> CallableReference<B> getCallableReference(Class<B> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentService service) {
+ try {
+ if (businessInterface == null) {
+ InterfaceContract contract = service.getInterfaceContract();
+ businessInterface = (Class<B>)((JavaInterface)contract.getInterface()).getJavaClass();
+ }
+ RuntimeComponentReference ref =
+ (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
+ ref.setComponent(component);
+ return new CallableReferenceImpl<B>(businessInterface, component, ref, null, proxyFactory,
+ compositeActivator);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Create a self-reference for a component service
+ * @param component
+ * @param service
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ private ComponentReference createSelfReference(Component component,
+ ComponentService service,
+ Class<?> businessInterface) throws CloneNotSupportedException,
+ InvalidInterfaceException {
+ ComponentReference componentReference = assemblyFactory.createComponentReference();
+ componentReference.setName("$self$." + service.getName());
+ for (Binding binding : service.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ WireableBinding wireableBinding = (WireableBinding)((WireableBinding)binding).clone();
+ wireableBinding.setTargetBinding(binding);
+ wireableBinding.setTargetComponent(component);
+ wireableBinding.setTargetComponentService(service);
+ wireableBinding.setRemote(false);
+ componentReference.getBindings().add(wireableBinding);
+ } else {
+ componentReference.getBindings().add(binding);
+ }
+ }
+
+ componentReference.setCallback(service.getCallback());
+ componentReference.getTargets().add(service);
+ componentReference.getPolicySets().addAll(service.getPolicySets());
+ componentReference.getRequiredIntents().addAll(service.getRequiredIntents());
+
+ InterfaceContract interfaceContract = service.getInterfaceContract();
+ Service componentTypeService = service.getService();
+ if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
+ interfaceContract = componentTypeService.getInterfaceContract();
+ }
+ interfaceContract = getInterfaceContract(interfaceContract, businessInterface);
+ componentReference.setInterfaceContract(interfaceContract);
+ componentReference.setMultiplicity(Multiplicity.ONE_ONE);
+ // component.getReferences().add(componentReference);
+ return componentReference;
+ }
+
+ /**
+ * @param interfaceContract
+ * @param businessInterface
+ * @return
+ * @throws CloneNotSupportedException
+ * @throws InvalidInterfaceException
+ */
+ private InterfaceContract getInterfaceContract(InterfaceContract interfaceContract, Class<?> businessInterface)
+ throws CloneNotSupportedException, InvalidInterfaceException {
+ Interface interfaze = interfaceContract.getInterface();
+ if (interfaze instanceof JavaInterface) {
+ Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
+ if (!businessInterface.isAssignableFrom(cls)) {
+ // The interface is not assignable from the interface contract
+ interfaceContract = (InterfaceContract)interfaceContract.clone();
+ interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface));
+ }
+ }
+ return interfaceContract;
+ }
+
+ /**
+ * @return the compositeActivator
+ */
+ public CompositeActivator getCompositeActivator() {
+ return compositeActivator;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#activate(org.apache.tuscany.sca.runtime.RuntimeComponentReference)
+ */
+ public void activate(RuntimeComponentReference reference) {
+ compositeActivator.activate(component, reference);
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#read(java.io.Reader)
+ */
+ public RuntimeComponent read(Reader reader) throws IOException {
+ RuntimeComponent component = compositeActivator.getComponentContextHelper().read(reader);
+ compositeActivator.configureComponentContext(component);
+ return component;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#write(org.apache.tuscany.sca.runtime.RuntimeComponentReference, java.io.Writer)
+ */
+ public void write(RuntimeComponentReference reference, Writer writer) throws IOException {
+ compositeActivator.getComponentContextHelper().write(component, reference, writer);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java
new file mode 100644
index 0000000000..8e7d979daf
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.context;
+
+import org.osoa.sca.Conversation;
+
+
+/**
+ * Default implementation of a Conversation.
+ *
+ * @version $Rev: 557524 $ $Date: 2007-07-19 09:46:56 +0100 (Thu, 19 Jul 2007) $
+ */
+public class ConversationImpl implements Conversation {
+
+ private Object conversationId;
+
+ public Object getConversationID() {
+ return conversationId;
+ }
+
+ public void setConversationID(Object conversationId) {
+ this.conversationId = conversationId;
+ }
+
+ public void end() {
+ conversationId = null;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/DefaultComponentContextFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/DefaultComponentContextFactory.java
new file mode 100644
index 0000000000..c5b68389b2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/DefaultComponentContextFactory.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.context;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.context.ComponentContextFactory;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.osoa.sca.ComponentContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DefaultComponentContextFactory implements ComponentContextFactory {
+ private final CompositeActivator compositeActivator;
+ private final RequestContextFactory requestContextFactory;
+ private final ProxyFactory proxyFactory;
+ private final AssemblyFactory assemblyFactory;
+ private final JavaInterfaceFactory javaInterfaceFactory;
+ private final InterfaceContractMapper interfaceContractMapper;
+
+ public DefaultComponentContextFactory(CompositeActivator compositeActivator,
+ AssemblyFactory assemblyFactory,
+ ProxyFactory proxyFactory,
+ InterfaceContractMapper interfaceContractMapper,
+ RequestContextFactory requestContextFactory,
+ JavaInterfaceFactory javaInterfaceFactory) {
+ super();
+ this.compositeActivator = compositeActivator;
+ this.assemblyFactory = assemblyFactory;
+ this.proxyFactory = proxyFactory;
+ this.requestContextFactory = requestContextFactory;
+ this.javaInterfaceFactory = javaInterfaceFactory;
+ this.interfaceContractMapper = interfaceContractMapper;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.context.ComponentContextFactory#createComponentContext(org.apache.tuscany.sca.runtime.RuntimeComponent, org.apache.tuscany.sca.context.RequestContextFactory)
+ */
+ public ComponentContext createComponentContext(RuntimeComponent component,
+ RequestContextFactory requestContextFactory) {
+ if (requestContextFactory == null) {
+ requestContextFactory = this.requestContextFactory;
+ }
+ return new ComponentContextImpl(compositeActivator, assemblyFactory, proxyFactory, interfaceContractMapper,
+ requestContextFactory, javaInterfaceFactory, component);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/InstanceWrapper.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/InstanceWrapper.java
new file mode 100644
index 0000000000..b577180291
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/InstanceWrapper.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.core.context;
+
+import org.apache.tuscany.sca.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetInitializationException;
+
+
+/**
+ * Provides lifecycle management for an implementation instance associated with
+ * a component for use by the component's associated {@link org.apache.tuscany.sca.core.scope.ScopeContainer}
+ *
+ * @version $Rev$ $Date$
+ */
+public interface InstanceWrapper<T> {
+
+ /**
+ * @return
+ */
+ T getInstance();
+
+ /**
+ * @throws TargetInitializationException
+ */
+ void start() throws TargetInitializationException;
+
+ /**
+ * @throws TargetDestructionException
+ */
+ void stop() throws TargetDestructionException;
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java
new file mode 100644
index 0000000000..6810f44d08
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.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.core.context;
+
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.apache.tuscany.sca.core.invocation.CallbackWireObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+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.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.RequestContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RequestContextImpl implements RequestContext {
+
+ private ProxyFactory proxyFactory;
+
+ public RequestContextImpl(ProxyFactory proxyFactory) {
+ this.proxyFactory = proxyFactory;
+ }
+
+ public Subject getSecuritySubject() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getServiceName() {
+ return ThreadMessageContext.getMessageContext().getTo().getContract().getName();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <B> CallableReference<B> getServiceReference() {
+ // FIXME: [rfeng] Is this the service reference matching the caller side?
+ EndpointReference to = ThreadMessageContext.getMessageContext().getTo();
+ RuntimeComponentService service = (RuntimeComponentService) to.getContract();
+ RuntimeComponent component = (RuntimeComponent) to.getComponent();
+
+ CallableReference<B> callableReference = component.getComponentContext().getCallableReference(null, component, service);
+ ((CallableReferenceImpl<B>) callableReference).attachCallbackID(ThreadMessageContext.getMessageContext().getCorrelationID());
+ return callableReference;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <CB> CB getCallback() {
+ return (CB) getCallbackReference().getService();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <CB> CallableReference<CB> getCallbackReference() {
+ EndpointReference to = ThreadMessageContext.getMessageContext().getTo();
+ RuntimeComponentService service = (RuntimeComponentService) to.getContract();
+ RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference();
+ if (callbackReference == null) {
+ return null;
+ }
+ JavaInterface javaInterface = (JavaInterface) callbackReference.getInterfaceContract().getInterface();
+ Class<CB> javaClass = (Class<CB>)javaInterface.getJavaClass();
+ List<RuntimeWire> wires = callbackReference.getRuntimeWires();
+ CallbackWireObjectFactory factory = new CallbackWireObjectFactory(javaClass, proxyFactory, wires);
+ factory.resolveTarget();
+ factory.attachCallbackID(ThreadMessageContext.getMessageContext().getCorrelationID());
+ return factory;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java
new file mode 100644
index 0000000000..86d9e09642
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java
@@ -0,0 +1,104 @@
+/*
+ * 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.core.context;
+
+import java.util.UUID;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+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.Conversation;
+import org.osoa.sca.ServiceReference;
+
+/**
+ * Default implementation of a ServiceReference.
+ *
+ * @version $Rev$ $Date$
+ * @param <B> the type of the business interface
+ */
+public class ServiceReferenceImpl<B> extends CallableReferenceImpl<B> implements ServiceReference<B> {
+ private static final long serialVersionUID = 6763709434194361540L;
+
+ protected transient Object callback;
+
+ public ServiceReferenceImpl() {
+ super();
+ }
+
+ /**
+ * @param businessInterface
+ * @param wire
+ * @param proxyFactory
+ */
+ public ServiceReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
+ super(businessInterface, wire, proxyFactory);
+ }
+
+ public ServiceReferenceImpl(Class<B> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentReference reference,
+ ProxyFactory proxyFactory,
+ CompositeActivator compositeActivator) {
+ super(businessInterface, component, reference, null, proxyFactory, compositeActivator);
+ }
+
+ public ServiceReferenceImpl(Class<B> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentReference reference,
+ Binding binding,
+ ProxyFactory proxyFactory,
+ CompositeActivator compositeActivator) {
+ super(businessInterface, component, reference, binding, proxyFactory, compositeActivator);
+ }
+
+ public Object getConversationID() {
+ return conversationID;
+ }
+
+ public void setConversationID(Object conversationID) throws IllegalStateException {
+ Conversation conversation = getConversation();
+ if (conversation == null) {
+ if (conversationID == null) {
+ this.conversationID = UUID.randomUUID().toString();
+ } else {
+ this.conversationID = conversationID;
+ }
+ } else {
+ // FIXME: [refng] Commented it out for now so that test cases are not broken
+ // throw new IllegalStateException("A conversation is currently associated with this reference");
+ this.conversationID = conversationID;
+ ((ConversationImpl) conversation).setConversationID(conversationID);
+ }
+ }
+
+ public void setCallbackID(Object callbackID) {
+ this.callbackID = callbackID;
+ }
+
+ public Object getCallback() {
+ return callback;
+ }
+
+ public void setCallback(Object callback) {
+ this.callback = callback;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/BaseEventPublisher.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/BaseEventPublisher.java
new file mode 100644
index 0000000000..517e5579a4
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/BaseEventPublisher.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.core.event;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.sca.event.Event;
+import org.apache.tuscany.sca.event.EventFilter;
+import org.apache.tuscany.sca.event.EventPublisher;
+import org.apache.tuscany.sca.event.RuntimeEventListener;
+import org.apache.tuscany.sca.event.TrueFilter;
+
+/**
+ * Base implementation of an <code>EventPublisher</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class BaseEventPublisher implements EventPublisher {
+ protected static final EventFilter TRUE_FILTER = new TrueFilter();
+ protected Map<EventFilter, List<RuntimeEventListener>> listeners;
+
+ public void addListener(RuntimeEventListener listener) {
+ addListener(TRUE_FILTER, listener);
+ }
+
+ public void removeListener(RuntimeEventListener listener) {
+ assert listener != null : "Listener cannot be null";
+ synchronized (getListeners()) {
+ for (List<RuntimeEventListener> currentList : getListeners().values()) {
+ for (RuntimeEventListener current : currentList) {
+ if (current == listener) {
+ currentList.remove(current);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public void addListener(EventFilter filter, RuntimeEventListener listener) {
+ assert listener != null : "Listener cannot be null";
+ synchronized (getListeners()) {
+ List<RuntimeEventListener> list = getListeners().get(filter);
+ if (list == null) {
+ list = new CopyOnWriteArrayList<RuntimeEventListener>();
+ listeners.put(filter, list);
+ }
+ list.add(listener);
+ }
+ }
+
+ public void publish(Event event) {
+ assert event != null : "Event object was null";
+ for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) {
+ if (entry.getKey().match(event)) {
+ for (RuntimeEventListener listener : entry.getValue()) {
+ listener.onEvent(event);
+ }
+ }
+ }
+ }
+
+ protected Map<EventFilter, List<RuntimeEventListener>> getListeners() {
+ if (listeners == null) {
+ listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>();
+ }
+ return listeners;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStart.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStart.java
new file mode 100644
index 0000000000..8e90c953e5
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStart.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.core.event;
+
+import java.net.URI;
+
+import org.apache.tuscany.sca.event.Event;
+
+/**
+ * Propagated when a component starts
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ComponentStart implements Event {
+
+ private Object source;
+ private URI uri;
+
+ /**
+ * Creates a component start event
+ *
+ * @param source the source of the event
+ * @param componentURI the uri of the component being started
+ */
+ public ComponentStart(Object source, URI componentURI) {
+ this.source = source;
+ this.uri = componentURI;
+ }
+
+ public URI getComponentURI() {
+ return uri;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStop.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStop.java
new file mode 100644
index 0000000000..d879182e14
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ComponentStop.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.event;
+
+import java.net.URI;
+
+import org.apache.tuscany.sca.event.Event;
+
+/**
+ * Propagated when a component stops
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ComponentStop implements Event {
+
+ private Object source;
+ private URI uri;
+
+ /**
+ * Creates a component stop event
+ *
+ * @param source the source of the event
+ * @param componentUri the composite component associated the component being stopped
+ */
+ public ComponentStop(Object source, URI componentUri) {
+ this.source = source;
+ this.uri = componentUri;
+ }
+
+ public URI getComponentURI() {
+ return uri;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationEnd.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationEnd.java
new file mode 100644
index 0000000000..cd14710880
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationEnd.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+
+
+/**
+ * Propagated when a conversation is expired
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ConversationEnd implements Event {
+
+ private Object source;
+ private Object id;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the conversation being ended
+ */
+ public ConversationEnd(Object source, Object id) {
+ this.source = source;
+ this.id = id;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public Object getConversationID() {
+ return id;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationStart.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationStart.java
new file mode 100644
index 0000000000..a4cc49204e
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/ConversationStart.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+
+/**
+ * Propagated when a conversation has started
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ConversationStart implements Event {
+
+ private Object source;
+ private Object id;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the conversation being started
+ */
+ public ConversationStart(Object source, Object id) {
+ this.source = source;
+ this.id = id;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public Object getConversationID() {
+ return id;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionEnd.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionEnd.java
new file mode 100644
index 0000000000..4c3fd8b397
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionEnd.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+
+
+/**
+ * Propagated when an HTTP-based session is expired
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class HttpSessionEnd implements Event {
+
+ private Object source;
+ private Object id;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpSessionEnd(Object source, Object id) {
+ this.source = source;
+ this.id = id;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public Object getSessionID() {
+ return id;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionStart.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionStart.java
new file mode 100644
index 0000000000..67b922b99c
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/HttpSessionStart.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+
+/**
+ * Propagated when an HTTP-based session has started
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class HttpSessionStart implements Event {
+
+ private Object source;
+ private Object id;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being started
+ */
+ public HttpSessionStart(Object source, Object id) {
+ this.source = source;
+ this.id = id;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public Object getSessionID() {
+ return id;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestEnd.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestEnd.java
new file mode 100644
index 0000000000..8b5c512cf2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestEnd.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.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+/**
+ * Propagated when a request completes or is ended
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestEnd implements Event {
+
+ private Object source;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ */
+ public RequestEnd(Object source) {
+ this.source = source;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestStart.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestStart.java
new file mode 100644
index 0000000000..974563b57c
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/event/RequestStart.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.core.event;
+
+import org.apache.tuscany.sca.event.Event;
+
+/**
+ * Propagated when a request is started in the runtime
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestStart implements Event {
+
+ private Object source;
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ */
+ public RequestStart(Object source) {
+ this.source = source;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectCreationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectCreationException.java
new file mode 100644
index 0000000000..d35b27fd24
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectCreationException.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.core.factory;
+
+
+/**
+ * Denotes an error creating a new object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class ObjectCreationException extends RuntimeException {
+ private static final long serialVersionUID = -6423113430265944499L;
+
+ public ObjectCreationException() {
+ super();
+ }
+
+ public ObjectCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ObjectCreationException(String message) {
+ super(message);
+ }
+
+ public ObjectCreationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectFactory.java
new file mode 100644
index 0000000000..3f64d2405b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/factory/ObjectFactory.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.core.factory;
+
+/**
+ * Implementations create new instances of a particular type
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ObjectFactory<T> {
+
+ /**
+ * Return a instance of the type that this factory creates.
+ *
+ * @return a instance from this factory
+ */
+ T getInstance() throws ObjectCreationException;
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java
new file mode 100644
index 0000000000..f53551962b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.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.core.invocation;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.osoa.sca.CallableReference;
+
+/**
+ * Uses a wire to return a callable reference
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallableReferenceObjectFactory implements ObjectFactory<CallableReference<?>> {
+ private CallableReference<?> callableReference;
+
+ /**
+ * Constructor.
+ *
+ * To support the @Reference protected CallableReference<MyService> ref;
+ *
+ * @param interfaze the interface to inject on the client
+ * @param wire the backing wire
+ * @param proxyService the wire service to create the proxy
+ * @throws NoMethodForOperationException
+ */
+ public CallableReferenceObjectFactory(Class<?> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentReference reference) {
+ this.callableReference = component.getComponentContext().getServiceReference(businessInterface, reference);
+ }
+
+ public CallableReference<?> getInstance() throws ObjectCreationException {
+ return callableReference;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java
new file mode 100644
index 0000000000..219dc55536
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.osoa.sca.NoRegisteredCallbackException;
+
+/**
+ * An interceptor applied to the forward direction of a wire that ensures the callback target implements the required
+ * service contract. This is required as callback targets may be set dynamically by service implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallbackInterfaceInterceptor implements Interceptor {
+ private boolean invokingServiceImplements;
+ private Invoker next;
+
+ public CallbackInterfaceInterceptor(boolean invokingServiceImplements) {
+ this.invokingServiceImplements = invokingServiceImplements;
+ }
+
+ public Message invoke(Message msg) {
+ // TODO check in the context if a callback object is set, if so invoke next since the setCallback will
+ // perform the check
+ if (!invokingServiceImplements) {
+ throw new NoRegisteredCallbackException("Callback target does not implement the callback interface");
+ }
+ return next.invoke(msg);
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java
new file mode 100644
index 0000000000..b6cd2dcc9f
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java
@@ -0,0 +1,160 @@
+/*
+ * 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.core.invocation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.WireableBinding;
+import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.invocation.Message;
+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.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+
+/**
+ * Returns proxy instance for a wire callback
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallbackWireObjectFactory<B> extends CallableReferenceImpl<B> {
+ private RuntimeWire wire;
+ private List<RuntimeWire> wires;
+ private EndpointReference resolvedEndpoint;
+
+ public CallbackWireObjectFactory(Class<B> interfaze, ProxyFactory proxyFactory, List<RuntimeWire> wires) {
+ super(interfaze, null, proxyFactory);
+ this.wires = wires;
+ }
+
+ public void resolveTarget() {
+ Message msgContext = ThreadMessageContext.getMessageContext();
+ wire = selectCallbackWire(msgContext, wires);
+ if (wire == null) {
+ //FIXME: need better exception
+ throw new RuntimeException("No callback wire found for " + msgContext.getFrom().getURI());
+ }
+ resolvedEndpoint = msgContext.getFrom();
+ bind(wire);
+ }
+
+ @Override
+ public B getInstance() throws ObjectCreationException {
+ if (wire != null) {
+ // wire and endpoint already resolved, so return a pre-wired proxy
+ wire.setTarget(resolvedEndpoint);
+ return super.getInstance();
+ } else {
+ // wire not yet selected, so return a proxy that resolves the target dynamically
+ return proxyFactory.createCallbackProxy(businessInterface, wires);
+ }
+ }
+
+ public static RuntimeWire selectCallbackWire(Message msgContext, List<RuntimeWire> wires) {
+ EndpointReference from = msgContext.getFrom();
+ if (from == null) {
+ return null;
+ }
+
+ //FIXME: need a cache for better performance. This requires making this
+ // method non-static, which means changing the signature of createCallbackProxy().
+
+ // first choice is wire with matching destination endpoint
+ for (RuntimeWire wire : wires) {
+ if (from.getURI().equals(wire.getTarget().getURI())) {
+ return wire;
+ }
+ }
+
+ // no exact match, so find callback binding with same name as service binding
+ EndpointReference to = msgContext.getTo();
+ if (to == null) {
+ //FIXME: need better exception
+ throw new RuntimeException("Destination for forward call is not available");
+ }
+ for (RuntimeWire wire : wires) {
+ if (wire.getSource().getBinding().getName().equals(to.getBinding().getName())) {
+ //FIXME: need better way to represent dynamic wire
+ if (wire.getTarget().getURI().equals("/")) { // dynamic wire
+ //FIXME: avoid doing this for genuine dynamic wires
+ return cloneAndBind(msgContext, wire);
+ }
+ //FIXME: no dynamic wire, so should attempt to create a static wire
+ }
+ }
+
+ // no match so far, so find callback binding with same type as service binding
+ for (RuntimeWire wire : wires) {
+ if (wire.getSource().getBinding().getClass() == to.getBinding().getClass()) {
+ //FIXME: need better way to represent dynamic wire
+ if (wire.getTarget().getURI().equals("/")) { // dynamic wire
+ //FIXME: avoid doing this for genuine dynamic wires
+ return cloneAndBind(msgContext, wire);
+ }
+ //FIXME: no dynamic wire, so should attempt to create a static wire
+ }
+ }
+
+ // no suitable callback wire was found
+ return null;
+ }
+
+ private static RuntimeWire cloneAndBind(Message msgContext, RuntimeWire wire) {
+ EndpointReference callback = msgContext.getFrom();
+ if (callback != null && callback.getContract() != null) {
+ try {
+ RuntimeComponentReference ref =
+ bind((RuntimeComponentReference)wire.getSource().getContract(),
+ callback.getComponent(),
+ (RuntimeComponentService)callback.getContract());
+ return ref.getRuntimeWires().get(0);
+ } catch (CloneNotSupportedException e) {
+ // will not happen
+ return null;
+ }
+ } else {
+ return wire;
+ }
+ }
+
+ private static RuntimeComponentReference bind(RuntimeComponentReference reference,
+ RuntimeComponent component,
+ RuntimeComponentService service) throws CloneNotSupportedException {
+ RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
+ ref.getTargets().add(service);
+ ref.getBindings().clear();
+ for (Binding binding : service.getBindings()) {
+ if (binding instanceof WireableBinding) {
+ WireableBinding wireableBinding = (WireableBinding)((WireableBinding)binding).clone();
+ wireableBinding.setTargetBinding(binding);
+ wireableBinding.setTargetComponent(component);
+ wireableBinding.setTargetComponentService(service);
+ wireableBinding.setRemote(false);
+ ref.getBindings().add(wireableBinding);
+ } else {
+ ref.getBindings().add(binding);
+ }
+ }
+ return ref;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java
new file mode 100644
index 0000000000..4fad747b3f
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java
@@ -0,0 +1,138 @@
+/*
+ * 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.core.invocation;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ServiceReference;
+
+/**
+ * The implementation of a wire service that uses cglib dynamic proxies
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("unused")
+public class CglibProxyFactory implements ProxyFactory {
+ private MessageFactory messageFactory;
+
+ public CglibProxyFactory() {
+ this(new MessageFactoryImpl(), new InterfaceContractMapperImpl());
+ }
+
+ public CglibProxyFactory(MessageFactory messageFactory, InterfaceContractMapper mapper) {
+ this.messageFactory = messageFactory;
+
+ }
+
+ public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(interfaze);
+ enhancer.setCallback(new CglibMethodInterceptor<T>(interfaze, wire));
+ Object proxy = enhancer.create();
+ return interfaze.cast(proxy);
+ }
+
+ /**
+ * create the proxy with cglib. use the same JDKInvocationHandler as
+ * JDKProxyService.
+ */
+ public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
+ Enhancer enhancer = new Enhancer();
+ Class<T> interfaze = callableReference.getBusinessInterface();
+ enhancer.setSuperclass(interfaze);
+ enhancer.setCallback(new CglibMethodInterceptor<T>(callableReference));
+ Object proxy = enhancer.create();
+ return interfaze.cast(proxy);
+ }
+
+ /**
+ * create the callback proxy with cglib. use the same
+ * JDKCallbackInvocationHandler as JDKProxyService.
+ */
+ public <T> T createCallbackProxy(Class<T> interfaze, final List<RuntimeWire> wires) throws ProxyCreationException {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(interfaze);
+ enhancer.setCallback(new CglibMethodInterceptor<T>(wires));
+ Object proxy = enhancer.create();
+ return interfaze.cast(proxy);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ if (isProxyClass(target.getClass())) {
+ Factory factory = (Factory)target;
+ Callback[] callbacks = factory.getCallbacks();
+ if (callbacks.length != 1 || !(callbacks[0] instanceof CglibMethodInterceptor)) {
+ throw new IllegalArgumentException("The object is not a known proxy.");
+ }
+ CglibMethodInterceptor interceptor = (CglibMethodInterceptor)callbacks[0];
+ return (R)interceptor.invocationHandler.getCallableReference();
+ } else {
+ throw new IllegalArgumentException("The object is not a known proxy.");
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
+ */
+ public boolean isProxyClass(Class<?> clazz) {
+ return Factory.class.isAssignableFrom(clazz);
+ }
+
+ private class CglibMethodInterceptor<T> implements MethodInterceptor {
+ private JDKInvocationHandler invocationHandler;
+
+ public CglibMethodInterceptor(CallableReference<T> callableReference) {
+ invocationHandler = new JDKInvocationHandler(messageFactory, callableReference);
+ }
+
+ public CglibMethodInterceptor(Class<T> interfaze, RuntimeWire wire) {
+ ServiceReference<T> serviceRef = new ServiceReferenceImpl<T>(interfaze, wire, CglibProxyFactory.this);
+ invocationHandler = new JDKInvocationHandler(messageFactory, serviceRef);
+ }
+
+ public CglibMethodInterceptor(List<RuntimeWire> wires) {
+ invocationHandler = new JDKCallbackInvocationHandler(messageFactory, wires);
+ }
+
+ /**
+ * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
+ */
+ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
+ Object result = invocationHandler.invoke(proxy, method, args);
+ return result;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/DefaultProxyFactoryExtensionPoint.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/DefaultProxyFactoryExtensionPoint.java
new file mode 100644
index 0000000000..b40574394b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/DefaultProxyFactoryExtensionPoint.java
@@ -0,0 +1,144 @@
+/*
+ * 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.core.invocation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+
+public class DefaultProxyFactoryExtensionPoint implements ProxyFactoryExtensionPoint {
+ private InterfaceContractMapper interfaceContractMapper;
+ private MessageFactory messageFactory;
+
+ private ProxyFactory interfaceFactory;
+ private ProxyFactory classFactory;
+
+ public DefaultProxyFactoryExtensionPoint() {
+ this(new MessageFactoryImpl(), new InterfaceContractMapperImpl());
+ }
+
+ public DefaultProxyFactoryExtensionPoint(MessageFactory messageFactory, InterfaceContractMapper mapper) {
+ this.interfaceContractMapper = mapper;
+ this.messageFactory = messageFactory;
+ interfaceFactory = new JDKProxyFactory(messageFactory, mapper);
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint#getClassProxyFactory()
+ */
+ public ProxyFactory getClassProxyFactory() {
+ return classFactory;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint#getInterfaceProxyFactory()
+ */
+ public ProxyFactory getInterfaceProxyFactory() {
+ return interfaceFactory;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint#setClassProxyFactory(org.apache.tuscany.sca.core.invocation.ProxyFactory)
+ */
+ public void setClassProxyFactory(ProxyFactory factory) {
+ this.classFactory = factory;
+
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint#setInterfaceProxyFactory(org.apache.tuscany.sca.core.invocation.ProxyFactory)
+ */
+ public void setInterfaceProxyFactory(ProxyFactory factory) {
+ this.interfaceFactory = factory;
+
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#cast(java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ if (interfaceFactory.isProxyClass(target.getClass())) {
+ return (R)interfaceFactory.cast(target);
+ } else if (classFactory != null && classFactory.isProxyClass(target.getClass())) {
+ return (R)classFactory.cast(target);
+ } else {
+ throw new IllegalArgumentException("The target is not a callable proxy");
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#createCallbackProxy(java.lang.Class,
+ * java.util.List)
+ */
+ public <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException {
+ if (interfaze.isInterface()) {
+ return interfaceFactory.createCallbackProxy(interfaze, wires);
+ } else {
+ return classFactory.createCallbackProxy(interfaze, wires);
+ }
+ }
+
+ public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
+ if (callableReference.getBusinessInterface().isInterface()) {
+ return interfaceFactory.createProxy(callableReference);
+ } else {
+ return classFactory.createProxy(callableReference);
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#createProxy(java.lang.Class,
+ * org.apache.tuscany.sca.runtime.RuntimeWire)
+ */
+ public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
+ if (interfaze.isInterface()) {
+ return interfaceFactory.createProxy(interfaze, wire);
+ } else {
+ return classFactory.createProxy(interfaze, wire);
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
+ */
+ public boolean isProxyClass(Class<?> clazz) {
+ return interfaceFactory.isProxyClass(clazz) || (classFactory != null && classFactory.isProxyClass(clazz));
+ }
+
+ /**
+ * @return the interfaceContractMapper
+ */
+ public InterfaceContractMapper getInterfaceContractMapper() {
+ return interfaceContractMapper;
+ }
+
+ /**
+ * @return the messageFactory
+ */
+ public MessageFactory getMessageFactory() {
+ return messageFactory;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleWireProcessor.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleWireProcessor.java
new file mode 100644
index 0000000000..934f2f7aa0
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleWireProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+
+/**
+ * The default implementation of an extensible <code>WireProcessor</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExtensibleWireProcessor implements RuntimeWireProcessor {
+
+ private RuntimeWireProcessorExtensionPoint processors;
+
+ public ExtensibleWireProcessor(RuntimeWireProcessorExtensionPoint processors) {
+ this.processors = processors;
+ }
+
+ public void process(RuntimeWire wire) {
+ for (RuntimeWireProcessor processor : processors.getWireProcessors()) {
+ processor.process(wire);
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/InvocationChainImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/InvocationChainImpl.java
new file mode 100644
index 0000000000..72ce0f87fb
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/InvocationChainImpl.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+
+/**
+ * Default implementation of an invocation chain
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvocationChainImpl implements InvocationChain {
+ private Operation sourceOperation;
+ private Operation targetOperation;
+ private Invoker invokerChainHead;
+ private Invoker invokerChainTail;
+
+ public InvocationChainImpl(Operation operation) {
+ assert operation != null;
+ this.targetOperation = operation;
+ this.sourceOperation = operation;
+ }
+
+ public InvocationChainImpl(Operation sourceOperation, Operation targetOperation) {
+ assert sourceOperation != null;
+ assert targetOperation != null;
+ this.targetOperation = targetOperation;
+ this.sourceOperation = sourceOperation;
+ }
+
+ public Operation getTargetOperation() {
+ return targetOperation;
+ }
+
+ public void setTargetOperation(Operation operation) {
+ this.targetOperation = operation;
+ }
+
+ public void addInterceptor(Interceptor interceptor) {
+ if (invokerChainHead == null) {
+ invokerChainHead = interceptor;
+ } else {
+ if (invokerChainHead instanceof Interceptor) {
+ ((Interceptor)invokerChainTail).setNext(interceptor);
+ }
+ }
+ invokerChainTail = interceptor;
+ }
+
+ public void addInvoker(Invoker invoker) {
+ if (invokerChainHead == null) {
+ invokerChainHead = invoker;
+ } else {
+ if (invokerChainTail instanceof Interceptor) {
+ ((Interceptor)invokerChainTail).setNext(invoker);
+ }
+ }
+ invokerChainTail = invoker;
+ }
+
+ public Invoker getHeadInvoker() {
+ return invokerChainHead;
+ }
+
+ public Invoker getTailInvoker() {
+ return invokerChainTail;
+ }
+
+ /**
+ * @return the sourceOperation
+ */
+ public Operation getSourceOperation() {
+ return sourceOperation;
+ }
+
+ /**
+ * @param sourceOperation the sourceOperation to set
+ */
+ public void setSourceOperation(Operation sourceOperation) {
+ this.sourceOperation = sourceOperation;
+ }
+
+ public void addInterceptor(int index, Interceptor interceptor) {
+ int i = 0;
+ Invoker next = invokerChainHead;
+ Invoker prev = null;
+ while (next != null && i < index) {
+ prev = next;
+ if (next instanceof Interceptor) {
+ next = ((Interceptor)next).getNext();
+ i++;
+ } else {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ }
+ if (i == index) {
+ if (prev != null) {
+ ((Interceptor)prev).setNext(interceptor);
+ } else {
+ invokerChainHead = interceptor;
+ }
+ interceptor.setNext(next);
+ if (next == null) {
+ invokerChainTail = interceptor;
+ }
+ } else {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
new file mode 100644
index 0000000000..9c6432682e
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
@@ -0,0 +1,105 @@
+/*
+ * 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.core.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.NoRegisteredCallbackException;
+
+/**
+ * Responsible for dispatching to a callback through a wire. <p/> TODO cache
+ * target invoker
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDKCallbackInvocationHandler extends JDKInvocationHandler {
+ private static final long serialVersionUID = -3350283555825935609L;
+ private transient List<RuntimeWire> wires;
+
+ public JDKCallbackInvocationHandler(MessageFactory messageFactory, List<RuntimeWire> wires) {
+ super(messageFactory, (CallableReference<?>) null);
+ this.wires = wires;
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
+ return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
+ } else if (method.getDeclaringClass().equals(Object.class) && "equals".equals(method.getName())) {
+ // TODO implement
+ throw new UnsupportedOperationException();
+ } else if (Object.class.equals(method.getDeclaringClass()) && "hashCode".equals(method.getName())) {
+ return hashCode();
+ // TODO beter hash algorithm
+ }
+
+ // wire not pre-selected, so select a wire now to be used for the callback
+ Message msgContext = ThreadMessageContext.getMessageContext();
+ RuntimeWire wire = CallbackWireObjectFactory.selectCallbackWire(msgContext, wires);
+ if (wire == null) {
+ //FIXME: need better exception
+ throw new RuntimeException("No callback wire found for " + msgContext.getFrom().getURI());
+ }
+ setConversational(wire);
+ callbackID = msgContext.getCorrelationID();
+ setEndpoint(msgContext.getFrom());
+
+
+ // need to set the endpoint on the binding also so that when the chains are created next
+ // the sca binding can decide whether to provide local or remote invokers.
+ // TODO - there is a problem here though in that I'm setting a target on a
+ // binding that may possibly be trying to point at two things in the multi threaded
+ // case. Need to confirm the general model here and how the clone and bind part
+ // is intended to work
+ wire.getSource().getBinding().setURI(msgContext.getFrom().getURI());
+
+ // also need to set the target contract as it varies for the sca binding depending on
+ // whether it is local or remote
+ RuntimeComponentReference ref = (RuntimeComponentReference)wire.getSource().getContract();
+ Binding binding = wire.getSource().getBinding();
+ wire.getTarget().setInterfaceContract(ref.getBindingProvider(binding).getBindingInterfaceContract());
+
+ //FIXME: can we use the same code as JDKInvocationHandler to select the chain?
+ InvocationChain chain = getInvocationChain(method, wire);
+ if (chain == null) {
+ throw new IllegalArgumentException("No matching operation is found: " + method);
+ }
+
+ try {
+ return invoke(chain, args, wire);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof NoRegisteredCallbackException) {
+ throw t;
+ }
+ throw e;
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java
new file mode 100644
index 0000000000..99a769f256
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java
@@ -0,0 +1,304 @@
+/*
+ * 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.core.invocation;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
+import org.apache.tuscany.sca.core.context.ConversationImpl;
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.NoRegisteredCallbackException;
+import org.osoa.sca.ServiceReference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKInvocationHandler implements InvocationHandler, Serializable {
+ private static final long serialVersionUID = -3366410500152201371L;
+
+ protected boolean conversational;
+ protected ConversationImpl conversation;
+ protected boolean conversationStarted;
+ protected MessageFactory messageFactory;
+ protected EndpointReference endpoint;
+ protected Object callbackID;
+ protected Object callbackObject;
+ protected RuntimeWire wire;
+ protected CallableReference<?> callableReference;
+
+ public JDKInvocationHandler(MessageFactory messageFactory, RuntimeWire wire) {
+ this.messageFactory = messageFactory;
+ this.wire = wire;
+ setConversational(wire);
+ }
+
+ public JDKInvocationHandler(MessageFactory messageFactory, CallableReference<?> callableReference) {
+ this.messageFactory = messageFactory;
+ this.callableReference = callableReference;
+ if (callableReference != null) {
+ this.callbackID = callableReference.getCallbackID();
+ this.conversation = (ConversationImpl)callableReference.getConversation();
+ this.wire = ((CallableReferenceImpl<?>)callableReference).getRuntimeWire();
+ if (callableReference instanceof ServiceReference) {
+ this.callbackObject = ((ServiceReference)callableReference).getCallback();
+ }
+ if (wire != null) {
+ setConversational(wire);
+ }
+ }
+ }
+
+ protected void setConversational(RuntimeWire wire) {
+ InterfaceContract contract = wire.getSource().getInterfaceContract();
+ this.conversational = contract.getInterface().isConversational();
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
+ return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
+ } else if (method.getDeclaringClass().equals(Object.class) && "equals".equals(method.getName())) {
+ Object obj = args[0];
+ if (obj == null) {
+ return false;
+ }
+ if (!Proxy.isProxyClass(obj.getClass())) {
+ return false;
+ }
+ return equals(Proxy.getInvocationHandler(obj));
+ } else if (Object.class.equals(method.getDeclaringClass()) && "hashCode".equals(method.getName())) {
+ return hashCode();
+ }
+ if (wire == null) {
+ //FIXME: need better exception
+ throw new RuntimeException("Destination for call is not known");
+ }
+ InvocationChain chain = getInvocationChain(method, wire);
+ if (chain == null) {
+ throw new IllegalArgumentException("No matching operation is found: " + method);
+ }
+
+ // send the invocation down the wire
+ Object result = invoke(chain, args, wire);
+
+ return result;
+ }
+
+ /**
+ * Determines if the given operation matches the given method
+ *
+ * @return true if the operation matches, false if does not
+ */
+ @SuppressWarnings("unchecked")
+ private static boolean match(Operation operation, Method method) {
+ Class<?>[] params = method.getParameterTypes();
+ DataType<List<DataType>> inputType = operation.getInputType();
+ List<DataType> types = inputType.getLogical();
+ boolean matched = true;
+ if (types.size() == params.length && method.getName().equals(operation.getName())) {
+ for (int i = 0; i < params.length; i++) {
+ Class<?> clazz = params[i];
+ if (!operation.getInputType().getLogical().get(i).getPhysical().isAssignableFrom(clazz)) {
+ matched = false;
+ }
+ }
+ } else {
+ matched = false;
+ }
+ return matched;
+
+ }
+
+ protected InvocationChain getInvocationChain(Method method, RuntimeWire wire) {
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ Operation operation = chain.getSourceOperation();
+ if (operation.isDynamic()) {
+ operation.setName(method.getName());
+ return chain;
+ } else if (match(operation, method)) {
+ return chain;
+ }
+ }
+ return null;
+ }
+
+ public void setEndpoint(EndpointReference endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public void setCallbackID(Object callbackID) {
+ this.callbackID = callbackID;
+ }
+
+ protected Object invoke(InvocationChain chain, Object[] args, RuntimeWire wire) throws Throwable {
+
+ Message msgContext = ThreadMessageContext.getMessageContext();
+ Object msgContextConversationId = msgContext.getConversationID();
+
+ Message msg = messageFactory.createMessage();
+
+ // make sure that the conversation id is set so it can be put in the
+ // outgoing messages. The id can come from one of three places
+ // 1 - Generated here (if the source is stateless)
+ // 2 - Specified by the application (through a service reference)
+ // 3 - from the message context (if the source is stateful)
+ //
+ // TODO - number 3 seems a little shaky as we end up propagating
+ // a conversationId through the source component. If we don't
+ // do this though we can't correlate the callback call with the
+ // current target instance. Currently specifying an application
+ // conversationId in this case also means that the callback
+ // can't be correlated with the source component instance
+ if (conversational) {
+ if (conversation == null) {
+ // this is a callback so create a conversation to
+ // hold onto the conversation state for the lifetime of the
+ // stateful callback
+ conversation = new ConversationImpl();
+ }
+ Object conversationId = conversation.getConversationID();
+
+ // create a conversation id if one doesn't exist
+ // already, i.e. the conversation is just starting
+ if ((conversationStarted == false) && (conversationId == null)) {
+
+ // It the current component is already in a conversation
+ // the use this just in case this message has a stateful
+ // callback. In which case the callback will come back
+ // to the correct instance.
+ // TODO - we should always create a unique id here or
+ // take the application defined conversation id.
+ // This implies we have to re-register the component
+ // instance against this
+ if (msgContextConversationId == null) {
+ conversationId = createConversationID();
+ } else {
+ conversationId = msgContextConversationId;
+ }
+
+ conversation.setConversationID(conversationId);
+ }
+ //TODO - assuming that the conversation ID is a string here when
+ // it can be any object that is serializable to XML
+ msg.setConversationID((String)conversationId);
+ }
+
+ Invoker headInvoker = chain.getHeadInvoker();
+ msg.setCorrelationID(callbackID);
+ Operation operation = chain.getTargetOperation();
+ msg.setOperation(operation);
+ Interface contract = operation.getInterface();
+ if (contract != null && contract.isConversational()) {
+ ConversationSequence sequence = operation.getConversationSequence();
+ if (sequence == ConversationSequence.CONVERSATION_END) {
+ msg.setConversationSequence(ConversationSequence.CONVERSATION_END);
+ conversationStarted = false;
+ if (conversation != null) {
+ conversation.setConversationID(null);
+ }
+ } else if (sequence == ConversationSequence.CONVERSATION_CONTINUE) {
+ if (conversationStarted) {
+ msg.setConversationSequence(ConversationSequence.CONVERSATION_CONTINUE);
+ } else {
+ conversationStarted = true;
+ msg.setConversationSequence(ConversationSequence.CONVERSATION_START);
+ }
+ }
+ }
+ msg.setBody(args);
+ if (wire.getSource() != null && wire.getSource().getCallbackEndpoint() != null) {
+ if (callbackObject != null) {
+ if (callbackObject instanceof ServiceReference) {
+ msg.setFrom(((CallableReferenceImpl)callbackObject).getRuntimeWire().getTarget());
+ } else {
+ if (contract != null) {
+ if (!contract.isConversational()) {
+ throw new NoRegisteredCallbackException(
+ "Callback object for stateless callback is not a ServiceReference");
+ } else {
+ //FIXME: add callback object to scope container
+ msg.setFrom(wire.getSource().getCallbackEndpoint());
+ }
+ }
+ }
+ } else {
+ //FIXME: check that the source component implements the callback interface
+ msg.setFrom(wire.getSource().getCallbackEndpoint());
+ }
+ }
+ if (endpoint != null) {
+ msg.setTo(endpoint);
+ } else {
+ msg.setTo(wire.getTarget());
+ }
+
+ ThreadMessageContext.setMessageContext(msg);
+ try {
+ // dispatch the wire down the chain and get the response
+ Message resp = headInvoker.invoke(msg);
+ Object body = resp.getBody();
+ if (resp.isFault()) {
+ throw (Throwable)body;
+ }
+ return body;
+ } finally {
+ ThreadMessageContext.setMessageContext(msgContext);
+ }
+ }
+
+ /**
+ * Creates a new conversational id
+ *
+ * @return the conversational id
+ */
+ private String createConversationID() {
+ return UUID.randomUUID().toString();
+ }
+
+ /**
+ * @return the callableReference
+ */
+ public CallableReference<?> getCallableReference() {
+ return callableReference;
+ }
+
+ /**
+ * @param callableReference the callableReference to set
+ */
+ public void setCallableReference(CallableReference<?> callableReference) {
+ this.callableReference = callableReference;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKProxyFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKProxyFactory.java
new file mode 100644
index 0000000000..9766286b56
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKProxyFactory.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.core.invocation;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+
+/**
+ * the default implementation of a wire service that uses JDK dynamic proxies
+ *
+ * @version $$Rev$$ $$Date: 2007-04-11 18:59:43 -0700 (Wed, 11 Apr
+ * 2007) $$
+ */
+public class JDKProxyFactory implements ProxyFactory {
+ protected InterfaceContractMapper contractMapper;
+ private MessageFactory messageFactory;
+
+ public JDKProxyFactory() {
+ this(new MessageFactoryImpl(), new InterfaceContractMapperImpl());
+ }
+
+ public JDKProxyFactory(MessageFactory messageFactory, InterfaceContractMapper mapper) {
+ this.contractMapper = mapper;
+ this.messageFactory = messageFactory;
+ }
+
+ /**
+ * The original createProxy method assumes that the proxy doesn't want to
+ * share conversation state so sets the conversaton object to null
+ */
+ public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
+ JDKInvocationHandler handler = new JDKInvocationHandler(messageFactory, wire);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[] {interfaze}, handler));
+ }
+
+ public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
+ assert callableReference != null;
+ Class<T> interfaze = callableReference.getBusinessInterface();
+ JDKInvocationHandler handler = new JDKInvocationHandler(messageFactory, callableReference);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[] {interfaze}, handler));
+ }
+
+ public <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException {
+ ClassLoader cl = interfaze.getClassLoader();
+ JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(messageFactory, wires);
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[] {interfaze}, handler));
+ }
+
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ InvocationHandler handler = Proxy.getInvocationHandler(target);
+ if (handler instanceof JDKInvocationHandler) {
+ return (R)((JDKInvocationHandler)handler).getCallableReference();
+ } else {
+ throw new IllegalArgumentException("The object is not a known proxy.");
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
+ */
+ public boolean isProxyClass(Class<?> clazz) {
+ return Proxy.isProxyClass(clazz);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageFactoryImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageFactoryImpl.java
new file mode 100644
index 0000000000..6e182a6a14
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageFactoryImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.core.invocation;
+
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+
+/**
+ * Implementation of MessageFactory.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MessageFactoryImpl implements MessageFactory {
+
+ public Message createMessage() {
+ return new MessageImpl();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java
new file mode 100644
index 0000000000..379973af0d
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.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.core.invocation;
+
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+
+/**
+ * The default implementation of a message flowed through a wire during an invocation
+ *
+ * @version $Rev $Date
+ */
+public class MessageImpl implements Message {
+ private Object body;
+ private Object messageID;
+ private Object correlationID;
+ private boolean isFault;
+ private ConversationSequence conversationSequence;
+ private String conversationId;
+ private Operation op;
+
+ private EndpointReference from;
+ private EndpointReference to;
+
+ public MessageImpl(String conversationId, ConversationSequence conversationSequence, Object body) {
+ this.conversationId = conversationId;
+ this.conversationSequence = conversationSequence;
+ this.body = body;
+ }
+
+ public MessageImpl() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getBody() {
+ return (T) body;
+ }
+
+ public <T> void setBody(T body) {
+ this.isFault = false;
+ this.body = body;
+ }
+
+ public String getConversationID() {
+ return conversationId;
+ }
+
+ public void setConversationID(String conversationId) {
+ this.conversationId = conversationId;
+ }
+
+ public ConversationSequence getConversationSequence() {
+ return conversationSequence;
+ }
+
+ public void setConversationSequence(ConversationSequence conversationSequence) {
+ this.conversationSequence = conversationSequence;
+ }
+
+ public Object getMessageID() {
+ return messageID;
+ }
+
+ public void setMessageID(Object messageId) {
+ this.messageID = messageId;
+ }
+
+ public Object getCorrelationID() {
+ return correlationID;
+ }
+
+ public void setCorrelationID(Object correlationId) {
+ this.correlationID = correlationId;
+ }
+
+ public boolean isFault() {
+ return isFault;
+ }
+
+ public void setFaultBody(Object fault) {
+ this.isFault = true;
+ this.body = fault;
+ }
+
+ public EndpointReference getFrom() {
+ return from;
+ }
+
+ public void setFrom(EndpointReference from) {
+ this.from = from;
+ }
+
+ public EndpointReference getTo() {
+ return to;
+ }
+
+ public void setTo(EndpointReference to) {
+ this.to = to;
+ }
+
+ public Operation getOperation() {
+ return op;
+ }
+
+ public void setOperation(Operation op) {
+ this.op = op;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NoMethodForOperationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NoMethodForOperationException.java
new file mode 100644
index 0000000000..733544d387
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NoMethodForOperationException.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.core.invocation;
+
+
+/**
+ * Thrown when an {@link org.apache.tuscany.sca.core.factory.model.Operation} cannot be mapped to a method on an interface
+ * @version $Rev$ $Date$
+ */
+public class NoMethodForOperationException extends ProxyCreationException {
+ private static final long serialVersionUID = 5116536602309483679L;
+
+ public NoMethodForOperationException() {
+ }
+
+ public NoMethodForOperationException(String message) {
+ super(message);
+ }
+
+ public NoMethodForOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoMethodForOperationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java
new file mode 100644
index 0000000000..fcf708c00a
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.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.core.invocation;
+
+import java.util.LinkedList;
+
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+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.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Adds non-blocking behavior to an invocation chain
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class NonBlockingInterceptor implements Interceptor {
+
+ private static final Message RESPONSE = new ImmutableMessage();
+
+ private WorkScheduler workScheduler;
+ private Invoker next;
+
+ public NonBlockingInterceptor(WorkScheduler workScheduler) {
+ this.workScheduler = workScheduler;
+ }
+
+ public NonBlockingInterceptor(WorkScheduler workScheduler, Interceptor next) {
+ this.workScheduler = workScheduler;
+ this.next = next;
+ }
+
+ public Message invoke(final Message msg) {
+ // Retrieve conversation id to transfer to new thread
+ // Notice that we cannot clear the conversation id from the current thread
+ final String conversationID = ThreadMessageContext.getMessageContext().getConversationID();
+ // Schedule the invocation of the next interceptor in a new Work instance
+ try {
+ workScheduler.scheduleWork(new Runnable() {
+ public void run() {
+ msg.setCorrelationID(null);
+ // if we got a conversation id, transfer it to new thread
+ if (conversationID != null) {
+ msg.setConversationID(conversationID);
+ }
+ Message context = ThreadMessageContext.setMessageContext(msg);
+ try {
+ next.invoke(msg);
+ } finally {
+ ThreadMessageContext.setMessageContext(context);
+ }
+ }
+ });
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ return RESPONSE;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ /**
+ * A dummy message passed back on an invocation
+ */
+ private static class ImmutableMessage implements Message {
+
+ public String getConversationID() {
+ return null;
+ }
+
+ public RuntimeWire getWire() {
+ return null;
+ }
+
+ public void setConversationID(String conversationId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setWire(RuntimeWire wire) {
+ throw new UnsupportedOperationException();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getBody() {
+ return null;
+ }
+
+ public void setBody(Object body) {
+ if (body != null) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void setCallbackWires(LinkedList<RuntimeWire> wires) {
+
+ }
+
+ public Object getMessageID() {
+ return null;
+ }
+
+ public void setMessageID(Object messageId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getCorrelationID() {
+ return null;
+ }
+
+ public void setCorrelationID(Object correlationId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isFault() {
+ return false;
+ }
+
+ public void setFaultBody(Object fault) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setConversationSequence(ConversationSequence sequence) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ConversationSequence getConversationSequence() {
+ return null;
+ }
+
+ public EndpointReference getFrom() {
+ return null;
+ }
+
+ public EndpointReference getTo() {
+ return null;
+ }
+
+ public void setFrom(EndpointReference from) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setTo(EndpointReference to) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Operation getOperation() {
+ return null;
+ }
+
+ public void setOperation(Operation op) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyCreationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyCreationException.java
new file mode 100644
index 0000000000..c0646f577a
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyCreationException.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.core.invocation;
+
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+
+
+/**
+ * Denotes an error creating a proxy
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ProxyCreationException extends ObjectCreationException {
+ private static final long serialVersionUID = 8002454344828513781L;
+
+ public ProxyCreationException() {
+ super();
+ }
+
+ public ProxyCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyCreationException(String message) {
+ super(message);
+ }
+
+ public ProxyCreationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java
new file mode 100644
index 0000000000..b72730397e
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.CallableReference;
+
+/**
+ * Creates proxies that implement Java interfaces and invocation handlers for fronting wires
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+
+public interface ProxyFactory {
+
+ /**
+ * Creates a Java proxy for the given wire
+ *
+ * @param interfaze the interface the proxy implements
+ * @param wire the wire to proxy
+ * @return the proxy
+ * @throws ProxyCreationException
+ */
+ <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException;
+
+ /**
+ * Creates a Java proxy for the given callable reference
+ *
+ * @param callableReference The callable reference
+ * @return the proxy
+ * @throws ProxyCreationException
+ */
+ <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException;
+
+ /**
+ * Creates a Java proxy for the service contract callback
+ *
+ * @param interfaze the interface the proxy should implement
+ * @return the proxy
+ * @throws ProxyCreationException
+ */
+ <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException;
+
+ /**
+ * Cast a proxy to a CallableReference.
+ *
+ * @param target a proxy generated by this implementation
+ * @return a CallableReference (or subclass) equivalent to this prozy
+ * @throws IllegalArgumentException if the object supplied is not a proxy
+ */
+ <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException;
+
+ /**
+ * Test if a given class is a generated proxy class by this factory
+ * @param clazz A java class or interface
+ * @return true if the class is a generated proxy class by this factory
+ */
+ boolean isProxyClass(Class<?> clazz);
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactoryExtensionPoint.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactoryExtensionPoint.java
new file mode 100644
index 0000000000..fdd710c465
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactoryExtensionPoint.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.invocation;
+
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+
+/**
+ * The extension point to plug in proxy factories
+ * @version $Rev$ $Date$
+ */
+public interface ProxyFactoryExtensionPoint extends ProxyFactory {
+ /**
+ * Get the proxy factory for java interfaces
+ * @return
+ */
+ ProxyFactory getInterfaceProxyFactory();
+
+ /**
+ * Get the proxy factory for java classes
+ * @return
+ */
+ ProxyFactory getClassProxyFactory();
+
+ /**
+ * Set the proxy factory for java interfaces
+ * @param factory
+ */
+ void setInterfaceProxyFactory(ProxyFactory factory);
+
+ /**
+ * Set the proxy factory for java classes
+ * @param factory
+ */
+ void setClassProxyFactory(ProxyFactory factory);
+
+ /**
+ * @return the interfaceContractMapper
+ */
+ InterfaceContractMapper getInterfaceContractMapper();
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvocationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvocationException.java
new file mode 100644
index 0000000000..2c4d657882
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvocationException.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.core.invocation;
+
+/**
+ * Raised when an error is encountered during a target invocation
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetInvocationException extends Exception {
+
+ private static final long serialVersionUID = -6553427708442761743L;
+
+ public TargetInvocationException() {
+ super();
+ }
+
+ public TargetInvocationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetInvocationException(String message) {
+ super(message);
+ }
+
+ public TargetInvocationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvokerCreationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvokerCreationException.java
new file mode 100644
index 0000000000..354c3c34d9
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/TargetInvokerCreationException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.invocation;
+
+/**
+ * Denotes an error creating a target invoker
+ *
+ * @version $Rev$ $Date$
+ * @Deprecated
+ */
+public abstract class TargetInvokerCreationException extends Exception {
+
+ public TargetInvokerCreationException() {
+ super();
+ }
+
+ public TargetInvokerCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetInvokerCreationException(String message) {
+ super(message);
+ }
+
+ public TargetInvokerCreationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java
new file mode 100644
index 0000000000..f37e8182fa
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java
@@ -0,0 +1,69 @@
+/*
+ * 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.core.invocation;
+
+import org.apache.tuscany.sca.invocation.Message;
+
+/**
+ * Class for tunneling a WorkContext through the invocation of a user class.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class ThreadMessageContext {
+
+ private static final ThreadLocal<Message> CONTEXT = new ThreadLocal<Message>() {
+ @Override
+ protected synchronized Message initialValue() {
+ return new MessageImpl();
+ }
+ };
+
+ private ThreadMessageContext() {
+ }
+
+ /**
+ * Set the WorkContext for the current thread.
+ * The current work context is returned and must be restored after the invocation is complete.
+ * Typical usage would be:
+ * <pre>
+ * WorkContext old = PojoWorkContextTunnel.setThreadWorkContext(newContext);
+ * try {
+ * ... invoke user code ...
+ * } finally {
+ * PojoWorkContextTunnel.setThreadWorkContext(old);
+ * }
+ * </pre>
+ * @param context
+ * @return the current work context for the thread; this must be restored after the invocation is made
+ */
+ public static Message setMessageContext(Message context) {
+ Message old = CONTEXT.get();
+ CONTEXT.set(context);
+ return old;
+ }
+
+ /**
+ * Returns the WorkContext for the current thread.
+ *
+ * @return the WorkContext for the current thread
+ */
+ public static Message getMessageContext() {
+ return CONTEXT.get();
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/WireObjectFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/WireObjectFactory.java
new file mode 100644
index 0000000000..0a40d49b36
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/WireObjectFactory.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.core.invocation;
+
+import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+
+/**
+ * Uses a wire to return an object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class WireObjectFactory<T> extends ServiceReferenceImpl<T> implements ObjectFactory<T> {
+ /**
+ * Constructor.
+ *
+ * @param interfaze the interface to inject on the client
+ * @param wire the backing wire
+ * @param proxyService the wire service to create the proxy
+ * @throws NoMethodForOperationException
+ */
+ public WireObjectFactory(Class<T> interfaze, RuntimeWire wire, ProxyFactory proxyService) {
+ super(interfaze, wire, proxyService);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java
new file mode 100644
index 0000000000..c39b39d491
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java
@@ -0,0 +1,191 @@
+/*
+ * 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.core.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.event.Event;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Implements functionality common to scope contexts.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContainer<KEY> implements ScopeContainer<KEY> {
+ protected Map<KEY, InstanceWrapper<?>> wrappers = new ConcurrentHashMap<KEY, InstanceWrapper<?>>();
+ protected final Scope scope;
+
+ protected RuntimeComponent component;
+ protected volatile int lifecycleState = UNINITIALIZED;
+
+
+ public AbstractScopeContainer(Scope scope, RuntimeComponent component) {
+ this.scope = scope;
+ this.component = component;
+ }
+
+ protected void checkInit() {
+ if (getLifecycleState() != RUNNING) {
+ throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]");
+ }
+ }
+
+ /**
+ * Creates a new physical instance of a component, wrapped in an
+ * InstanceWrapper.
+ *
+ * @param component the component whose instance should be created
+ * @return a wrapped instance that has been injected but not yet started
+ * @throws TargetResolutionException if there was a problem creating the
+ * instance
+ */
+ protected InstanceWrapper createInstanceWrapper() throws TargetResolutionException {
+ ImplementationProvider implementationProvider = component.getImplementationProvider();
+ if (implementationProvider instanceof ScopedImplementationProvider) {
+ return ((ScopedImplementationProvider)implementationProvider).createInstanceWrapper();
+ }
+ return null;
+ }
+
+ public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException {
+ return getWrapper(contextId); // TODO: what is this method spossed to do diff than getWrapper?
+ }
+
+ public Scope getScope() {
+ return scope;
+ }
+
+ public InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException {
+ return wrappers.get(contextId);
+ }
+
+ public void onEvent(Event event) {
+ }
+
+ protected boolean isEagerInit() {
+ ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider();
+ if (implementationProvider instanceof ScopedImplementationProvider) {
+ return ((ScopedImplementationProvider)implementationProvider).isEagerInit();
+ }
+ return false;
+ }
+
+ public void returnWrapper(InstanceWrapper wrapper, KEY contextId) throws TargetDestructionException {
+ }
+
+ /**
+ * Default implmentation of remove which does nothing
+ *
+ * @param contextId the identifier of the context to remove.
+ */
+ public void remove(KEY contextId)
+ throws TargetDestructionException {
+ }
+
+ public synchronized void start() {
+ int lifecycleState = getLifecycleState();
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ setLifecycleState(RUNNING);
+ }
+
+ public void startContext(KEY contextId) {
+ if(isEagerInit()) {
+ try {
+ getWrapper(contextId);
+ } catch (TargetResolutionException e) {
+ //
+ }
+ }
+ }
+
+ public synchronized void stop() {
+ int lifecycleState = getLifecycleState();
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ setLifecycleState(STOPPED);
+ }
+
+ public void stopContext(KEY contextId) {
+ wrappers.remove(contextId);
+ }
+
+ @Override
+ public String toString() {
+ String s;
+ switch (lifecycleState) {
+ case ScopeContainer.CONFIG_ERROR:
+ s = "CONFIG_ERROR";
+ break;
+ case ScopeContainer.ERROR:
+ s = "ERROR";
+ break;
+ case ScopeContainer.INITIALIZING:
+ s = "INITIALIZING";
+ break;
+ case ScopeContainer.INITIALIZED:
+ s = "INITIALIZED";
+ break;
+ case ScopeContainer.RUNNING:
+ s = "RUNNING";
+ break;
+ case ScopeContainer.STOPPING:
+ s = "STOPPING";
+ break;
+ case ScopeContainer.STOPPED:
+ s = "STOPPED";
+ break;
+ case ScopeContainer.UNINITIALIZED:
+ s = "UNINITIALIZED";
+ break;
+ default:
+ s = "UNKNOWN";
+ break;
+ }
+ return "In state [" + s + ']';
+ }
+
+ public RuntimeComponent getComponent() {
+ return component;
+ }
+
+ public void setComponent(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ public int getLifecycleState() {
+ return lifecycleState;
+ }
+
+ /**
+ * Set the current state of the Lifecycle.
+ *
+ * @param lifecycleState the new state
+ */
+ protected void setLifecycleState(int lifecycleState) {
+ this.lifecycleState = lifecycleState;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java
new file mode 100644
index 0000000000..80c27aca1b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * A scope context which manages atomic component instances keyed by composite
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeContainer<KEY> extends AbstractScopeContainer<KEY> {
+ private InstanceWrapper<?> wrapper;
+
+ public CompositeScopeContainer(RuntimeComponent component) {
+ super(Scope.COMPOSITE, component);
+ }
+
+ @Override
+ public synchronized void stop() {
+ super.stop();
+ wrapper = null;
+ }
+
+ @Override
+ public synchronized InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException {
+ if (wrapper == null) {
+ wrapper = createInstanceWrapper();
+ wrapper.start();
+ }
+ return wrapper;
+ }
+
+ @Override
+ public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException {
+ if (wrapper == null) {
+ throw new TargetNotFoundException(component.getURI());
+ }
+ return wrapper;
+ }
+
+ @Override
+ public synchronized void start() {
+ super.start();
+ if(isEagerInit()) {
+ try {
+ getWrapper(null);
+ } catch (TargetResolutionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java
new file mode 100644
index 0000000000..786988613b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeContainerFactory implements ScopeContainerFactory {
+
+ public ScopeContainer createScopeContainer(RuntimeComponent component) {
+ return new CompositeScopeContainer(component);
+ }
+
+ public Scope getScope() {
+ return Scope.COMPOSITE;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java
new file mode 100644
index 0000000000..26f4544d14
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java
@@ -0,0 +1,289 @@
+/*
+ * 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.core.scope;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.store.Store;
+import org.osoa.sca.ConversationEndedException;
+
+/**
+ * A scope context which manages atomic component instances keyed on ConversationID
+ *
+ */
+public class ConversationalScopeContainer extends AbstractScopeContainer<Object> {
+
+ private Map<Object, InstanceLifeCycleWrapper> instanceLifecycleCollection = new ConcurrentHashMap<Object, InstanceLifeCycleWrapper>();
+
+ //TODO: This needs to observe the value set by ConversationalAttributes for now we will hard code it.
+ private long max_age = 60 * 60 * 1000; // 1 hour;
+ private long max_idle_time = 60 * 60 * 1000; // 1 hour;
+ private long reaper_interval = 60; // every minute;
+ private ScheduledExecutorService scheduler;
+
+ public ConversationalScopeContainer(Store aStore, RuntimeComponent component) {
+ super(Scope.CONVERSATION, component);
+
+ // Note: aStore is here to preserve the original factory interface. It is not currently used in this
+ // implemenation since we do not support instance persistence.
+
+ // Check System properties to see if timeout values have been specified. All timeout values
+ // will be specifed in seconds.
+ //
+ String aProperty;
+ aProperty = System.getProperty("org.apache.tuscany.sca.core.scope.ConversationalScopeContainer.MaxIdleTime");
+ if (aProperty != null)
+ try
+ {
+ max_idle_time = (new Long(aProperty) * 1000);
+ }
+ catch (NumberFormatException nfe) {};
+
+ aProperty = System.getProperty("org.apache.tuscany.sca.core.scope.ConversationalScopeContainer.MaxAge");
+ if (aProperty != null)
+ try
+ {
+ max_age = (new Long(aProperty) * 1000);
+ }
+ catch (NumberFormatException nfe) {};
+
+ aProperty = System.getProperty("org.apache.tuscany.sca.core.scope.ConversationalScopeContainer.ReaperInterval");
+ if (aProperty != null)
+ try
+ {
+ reaper_interval = new Long(aProperty);
+ }
+ catch (NumberFormatException nfe) {};
+
+
+ // Check to see if the maxAge and/or maxIdleTime have been specified using @ConversationAttributes.
+ // Implementation annoated attributes are honored first.
+ if (this.getComponent().getImplementationProvider() instanceof ScopedImplementationProvider)
+ {
+ ScopedImplementationProvider aScopedImpl = (ScopedImplementationProvider) this.getComponent().getImplementationProvider();
+
+ long maxAge = aScopedImpl.getMaxAge();
+ if (maxAge > 0) {
+ max_age = maxAge;
+ }
+ long maxIdleTime = aScopedImpl.getMaxIdleTime();
+ if (maxIdleTime > 0 ) {
+ max_idle_time = maxIdleTime;
+ }
+ }
+
+ }
+
+
+ @Override
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+
+ // Get a scheduler and scheduled a task to be run in the future indefinitely until its explicitly shutdown.
+ this.scheduler = Executors.newSingleThreadScheduledExecutor();
+ scheduler.scheduleAtFixedRate(new ConversationalInstanceReaper(this.instanceLifecycleCollection), 3, reaper_interval, TimeUnit.SECONDS);
+
+ lifecycleState = RUNNING;
+ }
+
+ @Override
+ public synchronized void stop() {
+
+ // Prevent the scheduler from submitting any additional reapers, initiate an orderly shutdown if a reaper task is in progress.
+ if (this.scheduler != null)
+ this.scheduler.shutdown();
+
+ lifecycleState = STOPPED;
+ }
+
+ protected InstanceWrapper getInstanceWrapper(boolean create,Object contextId) throws TargetResolutionException {
+
+ // we might get a null context if the target service has
+ // conversational scope but only its callback interface
+ // is conversational. In this case we need to invent a
+ // conversation Id here to store the service against
+ // and populate the thread context
+ if (contextId == null){
+ contextId = UUID.randomUUID().toString();
+ Message msgContext = ThreadMessageContext.getMessageContext();
+
+ if (msgContext != null){
+ msgContext.setConversationID(contextId.toString());
+ }
+
+ }
+
+ InstanceLifeCycleWrapper anInstanceWrapper = this.instanceLifecycleCollection.get(contextId);
+
+ if (anInstanceWrapper == null && !create)
+ return null;
+
+ if (anInstanceWrapper == null)
+ {
+ anInstanceWrapper = new InstanceLifeCycleWrapper(contextId);
+ this.instanceLifecycleCollection.put(contextId, anInstanceWrapper);
+ }
+ // If an existing intsance is found return it only if its not expired and update its
+ // last referenced time.
+ else
+ {
+ if (anInstanceWrapper.isExpired())
+ throw new ConversationEndedException();
+ anInstanceWrapper.updateLastReferencedTime();
+ }
+
+ return anInstanceWrapper.getInstanceWrapper();
+
+ }
+
+ @Override
+ public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException {
+ return getInstanceWrapper(true,contextId);
+ }
+
+
+ // The remove is invoked when a conversation is explicitly ended. This can occur by using the @EndsConversation or API.
+ // In this case the instance is immediately removed. A new conversation will be started on the next operation
+ // associated with this conversationId's service reference.
+ //
+ @Override
+ public void remove(Object contextId) throws TargetDestructionException {
+ if (this.instanceLifecycleCollection.containsKey(contextId))
+ {
+ InstanceLifeCycleWrapper anInstanceLifeCycleWrapper = this.instanceLifecycleCollection.get(contextId);
+ this.instanceLifecycleCollection.remove(contextId);
+ anInstanceLifeCycleWrapper.removeInstanceWrapper();
+ }
+ }
+
+
+ /*
+ * This is an inner class that keeps track of the lifecycle of a conversation scoped
+ * implementation instance.
+ *
+ */
+
+ private class InstanceLifeCycleWrapper
+ {
+ private Object instanceId;
+ private long creationTime;
+ private long lastReferencedTime;
+ private long expirationInterval;
+ private long maxIdleTime;
+
+ private InstanceLifeCycleWrapper(Object contextId) throws TargetResolutionException
+ {
+ this.instanceId = contextId;
+ this.creationTime = System.currentTimeMillis();
+ this.lastReferencedTime = this.creationTime;
+ this.expirationInterval = max_age;
+ this.maxIdleTime = max_idle_time;
+ this.createInstance();
+ }
+
+ private boolean isExpired()
+ {
+ long currentTime = System.currentTimeMillis();
+ if ((this.lastReferencedTime + this.maxIdleTime) < currentTime) // max idle time exceeded
+ return true;
+ if ((this.creationTime + this.expirationInterval) < currentTime) // max time to live exceeded
+ return true;
+
+ return false;
+ }
+
+ private void updateLastReferencedTime()
+ {
+ this.lastReferencedTime = System.currentTimeMillis();
+ }
+
+ //
+ // Return the backing implementation instance
+ //
+ private InstanceWrapper getInstanceWrapper()
+ {
+ InstanceWrapper ctx = wrappers.get(this.instanceId);
+ return ctx;
+ }
+
+ private void removeInstanceWrapper() throws TargetDestructionException
+ {
+ InstanceWrapper ctx = getInstanceWrapper();
+ ctx.stop();
+ wrappers.remove(this.instanceId);
+ }
+
+ private void createInstance() throws TargetResolutionException
+ {
+ InstanceWrapper instanceWrapper = createInstanceWrapper();
+ instanceWrapper.start();
+ wrappers.put(this.instanceId, instanceWrapper);
+ }
+
+ }
+
+ //
+ // This inner class is an instance reaper. It periodically iterates over the InstanceLifeCycleCollection
+ // and for any instances that have expired removes the backing instance and the entry in the InstanceLifeCycle
+ // Collection.
+ //
+ class ConversationalInstanceReaper implements Runnable
+ {
+ private Map<Object, InstanceLifeCycleWrapper> instanceLifecycleCollection;
+
+ public ConversationalInstanceReaper(Map<Object, InstanceLifeCycleWrapper> aMap)
+ {
+ this.instanceLifecycleCollection = aMap;
+ }
+
+ public void run()
+ {
+ Iterator<Map.Entry<Object,InstanceLifeCycleWrapper>> anIterator = this.instanceLifecycleCollection.entrySet().iterator();
+
+ while (anIterator.hasNext())
+ {
+ Map.Entry<Object,InstanceLifeCycleWrapper> anEntry = anIterator.next();
+ InstanceLifeCycleWrapper anInstanceLifeCycleWrapper = anEntry.getValue();
+ if (anInstanceLifeCycleWrapper.isExpired())
+ {
+ try {
+ anInstanceLifeCycleWrapper.removeInstanceWrapper();
+ this.instanceLifecycleCollection.remove(anInstanceLifeCycleWrapper.instanceId);
+ } catch (Exception ex) {
+ // TODO - what to do with any asynchronous exceptions?
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java
new file mode 100644
index 0000000000..a6663aba09
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.store.Store;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalScopeContainerFactory implements ScopeContainerFactory {
+ private Store store;
+
+ public ConversationalScopeContainerFactory(Store store) {
+ super();
+ this.store = store;
+ }
+
+ public ScopeContainer createScopeContainer(RuntimeComponent component) {
+ return new ConversationalScopeContainer(store, component);
+ }
+
+ public Scope getScope() {
+ return Scope.CONVERSATION;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java
new file mode 100644
index 0000000000..5ae8b94647
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.core.event.HttpSessionEnd;
+import org.apache.tuscany.sca.event.Event;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * A scope context which manages atomic component instances keyed on HTTP
+ * session
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContainer extends AbstractScopeContainer<Object> {
+
+ public HttpSessionScopeContainer(RuntimeComponent component) {
+ super(Scope.SESSION, component);
+ }
+
+ @Override
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof HttpSessionEnd) {
+ //FIXME key is not used
+ //Object key = ((HttpSessionEnd)event).getSessionID();
+ // FIXME: Remove the session id
+ }
+ }
+
+ @Override
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ @Override
+ public synchronized void stop() {
+ lifecycleState = STOPPED;
+ }
+
+ protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException {
+// Object key = workContext.getIdentifier(Scope.SESSION);
+ // FIXME: Need to fix this
+ Object key ="http-session-id";
+ assert key != null : "HTTP session key not bound in work context";
+ InstanceWrapper ctx = wrappers.get(key);
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = super.createInstanceWrapper();
+ ctx.start();
+ wrappers.put(key, ctx);
+ }
+ return ctx;
+ }
+
+ @Override
+ public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException {
+ return getInstanceWrapper(true);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java
new file mode 100644
index 0000000000..49f89661b1
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContainerFactory implements ScopeContainerFactory {
+
+ public HttpSessionScopeContainerFactory() {
+ super();
+ }
+
+ public ScopeContainer createScopeContainer(RuntimeComponent component) {
+ return new HttpSessionScopeContainer(component);
+ }
+
+ public Scope getScope() {
+ return Scope.SESSION;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java
new file mode 100644
index 0000000000..f11a61e662
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.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.core.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.core.event.RequestEnd;
+import org.apache.tuscany.sca.event.Event;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * A scope context which manages atomic component instances keyed on the current
+ * request context
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContainer extends AbstractScopeContainer<Thread> {
+ private final Map<Thread, InstanceWrapper> contexts;
+
+ public RequestScopeContainer(RuntimeComponent component) {
+ super(Scope.REQUEST, component);
+ contexts = new ConcurrentHashMap<Thread, InstanceWrapper>();
+ }
+
+ @Override
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof RequestEnd) {
+ // shutdownInstances(Thread.currentThread());
+ }
+ }
+
+ @Override
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ @Override
+ public synchronized void stop() {
+ contexts.clear();
+ // synchronized (destroyQueues) {
+ // destroyQueues.clear();
+ // }
+ lifecycleState = STOPPED;
+ }
+
+ protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException {
+ InstanceWrapper ctx = wrappers.get(Thread.currentThread());
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = super.createInstanceWrapper();
+ ctx.start();
+ wrappers.put(Thread.currentThread(), ctx);
+ }
+ return ctx;
+ }
+
+ @Override
+ public InstanceWrapper getWrapper(Thread contextId) throws TargetResolutionException {
+ return getInstanceWrapper(true);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java
new file mode 100644
index 0000000000..1cfb6b06a4
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContainerFactory implements ScopeContainerFactory {
+
+ public ScopeContainer createScopeContainer(RuntimeComponent component) {
+ return new RequestScopeContainer(component);
+ }
+
+ public Scope getScope() {
+ return Scope.REQUEST;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java
new file mode 100644
index 0000000000..0a20d793f7
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.scope;
+
+/**
+ * The default implementation scopes supported by assemblies.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Scope {
+ public static final Scope STATELESS = new Scope("STATELESS");
+ public static final Scope REQUEST = new Scope("REQUEST");
+ public static final Scope SESSION = new Scope("SESSION");
+ public static final Scope CONVERSATION = new Scope("CONVERSATION");
+ public static final Scope COMPOSITE = new Scope("COMPOSITE");
+ public static final Scope SYSTEM = new Scope("SYSTEM");
+ public static final Scope UNDEFINED = new Scope("UNDEFINED");
+
+ private String scope;
+
+ public Scope(String scope) {
+ this.scope = scope.toUpperCase().intern();
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final Scope scope1 = (Scope) o;
+ return !(scope != null ? scope != scope1.scope.intern() : scope1.scope != null);
+ }
+
+ @Override
+ public int hashCode() {
+ return scope != null ? scope.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return scope;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java
new file mode 100644
index 0000000000..cd0deb4900
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java
@@ -0,0 +1,139 @@
+/*
+ * 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.core.scope;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.event.RuntimeEventListener;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+
+/**
+ * Manages the lifecycle and visibility of instances associated with a an {@link RuntimeComponent}.
+ *
+ * @version $Rev$ $Date$
+ * @param <KEY> the type of IDs that this container uses to identify its contexts.
+ * For example, for COMPOSITE scope this could be the URI of the composite component,
+ * or for HTTP Session scope it might be the HTTP session ID.
+ */
+public interface ScopeContainer<KEY> extends RuntimeEventListener {
+
+ /**
+ * Returns the Scope that this container supports.
+ *
+ * @return the Scope that this container supports
+ */
+ Scope getScope();
+
+ /**
+ * Start a new context with the supplied ID.
+ *
+ * @param contextId an ID that uniquely identifies the context.
+ */
+ void startContext(KEY contextId);
+
+ /**
+ * Stop the context with the supplied ID.
+ *
+ * @param contextId an ID that uniquely identifies the context.
+ */
+ void stopContext(KEY contextId);
+
+ /**
+ * Returns an instance wrapper associated with the current scope context, creating one if necessary
+ * @param contextId the id for the scope context
+ *
+ * @return the wrapper for the target instance
+ * @throws TargetResolutionException if there was a problem instantiating the target instance
+ */
+ InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException;
+
+ /**
+ * Returns an implementation instance associated with the current scope context.
+ * If no instance is found, a {@link TargetNotFoundException} is thrown.
+ * @param contextId the id for the scope context
+ *
+ * @return the wrapper for the target instance
+ * @throws TargetResolutionException if there was a problem instantiating the target instance
+ */
+ InstanceWrapper getAssociatedWrapper(KEY contextId)
+ throws TargetResolutionException;
+
+ /**
+ * Return a wrapper after use (for example, after invoking the instance).
+ * @param wrapper the wrapper for the target instance being returned
+ * @param contextId the id for the scope context
+ *
+ * @throws TargetDestructionException if there was a problem returning the target instance
+ */
+ void returnWrapper(InstanceWrapper wrapper, KEY contextId)
+ throws TargetDestructionException;
+
+ /**
+ * Removes an identified component implementation instance associated with the current
+ * context from persistent storage
+ *
+ * @param contextId the identifier of the context to remove.
+ */
+ void remove(KEY contextId)
+ throws TargetDestructionException;
+
+ /* A configuration error state */
+ int CONFIG_ERROR = -1;
+ /* Has not been initialized */
+ int UNINITIALIZED = 0;
+ /* In the process of being configured and initialized */
+ int INITIALIZING = 1;
+ /* Instantiated and configured */
+ int INITIALIZED = 2;
+ /* Configured and initialized */
+ int RUNNING = 4;
+ /* In the process of being shutdown */
+ int STOPPING = 5;
+ /* Has been shutdown and removed from the composite */
+ int STOPPED = 6;
+ /* In an error state */
+ int ERROR = 7;
+
+ /**
+ * Returns the lifecycle state
+ *
+ * @see #UNINITIALIZED
+ * @see #INITIALIZING
+ * @see #INITIALIZED
+ * @see #RUNNING
+ * @see #STOPPING
+ * @see #STOPPED
+ */
+ int getLifecycleState();
+
+ /**
+ * Starts the Lifecycle.
+ *
+ * @throws CoreRuntimeException
+ */
+ void start();
+
+ /**
+ * Stops the Lifecycle.
+ *
+ * @throws CoreRuntimeException
+ */
+ void stop();
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java
new file mode 100644
index 0000000000..b19c14b3e0
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.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.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Factory to create ScopeContainer for components
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeContainerFactory {
+ ScopeContainer createScopeContainer(RuntimeComponent component);
+ Scope getScope();
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java
new file mode 100644
index 0000000000..43a3288ff2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.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.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+
+/**
+ * Manages {@link ScopeContainer}s in the runtime
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public interface ScopeRegistry {
+
+ /**
+ * Returns the scope container for the given scope or null if one not found
+ *
+ * @param scope the scope
+ * @return the scope container for the given scope or null if one not found
+ */
+ ScopeContainer getScopeContainer(RuntimeComponent component);
+
+ /**
+ * @param factory
+ */
+ void register(ScopeContainerFactory factory);
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java
new file mode 100644
index 0000000000..75261e11a8
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * The default implementation of a scope registry
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeRegistryImpl implements ScopeRegistry {
+ private final Map<Scope, ScopeContainerFactory> scopeCache = new ConcurrentHashMap<Scope, ScopeContainerFactory>();
+
+ public void register(ScopeContainerFactory factory) {
+ scopeCache.put(factory.getScope(), factory);
+ }
+
+ public ScopeContainer getScopeContainer(RuntimeComponent runtimeComponent) {
+ if (!(runtimeComponent instanceof ScopedRuntimeComponent)) {
+ return null;
+ }
+ ScopedRuntimeComponent component = (ScopedRuntimeComponent)runtimeComponent;
+ if (component.getScopeContainer() != null) {
+ return component.getScopeContainer();
+ }
+ ImplementationProvider implementationProvider = component.getImplementationProvider();
+ if (implementationProvider instanceof ScopedImplementationProvider) {
+ ScopedImplementationProvider provider = (ScopedImplementationProvider)implementationProvider;
+ Scope scope = provider.getScope();
+ if (scope == null) {
+ scope = Scope.STATELESS;
+ }
+ ScopeContainerFactory factory = scopeCache.get(scope);
+ ScopeContainer container = factory.createScopeContainer(component);
+ component.setScopeContainer(container);
+ return container;
+ }
+ return null;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java
new file mode 100644
index 0000000000..85a6626cdd
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+
+/**
+ * A component implementation can implement this interface to provide scope
+ * management for the components
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopedImplementationProvider extends ImplementationProvider {
+ /**
+ * Get the scope for the component implementation
+ *
+ * @return The scope for the component implementation, if null is returned,
+ * STATELESS will be used
+ */
+ Scope getScope();
+
+ /**
+ * Indicate if the component needs to be eagerly initialized
+ *
+ * @return true if the component is marked to be eagerly initialized, false
+ * otherwise
+ */
+ boolean isEagerInit();
+
+ /**
+ * @return the maxAge
+ */
+ long getMaxAge();
+
+ /**
+ * @return the maxIdleTime
+ */
+ long getMaxIdleTime();
+
+ /**
+ * Create a wrapper for the component instance for the scope management
+ *
+ * @return A wrapper for the component instance
+ */
+ InstanceWrapper createInstanceWrapper();
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java
new file mode 100644
index 0000000000..c27b112f8a
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.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.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Scoped runtime component
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopedRuntimeComponent extends RuntimeComponent {
+ /**
+ * Set the associated scope container
+ * @param scopeContainer
+ */
+ void setScopeContainer(ScopeContainer scopeContainer);
+ /**
+ * Get the assoicated scope container
+ * @return
+ */
+ ScopeContainer getScopeContainer();
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java
new file mode 100644
index 0000000000..a2c0edb9b4
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.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.core.scope;
+
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * A scope context which manages stateless atomic component instances in a non-pooled fashion.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContainer<KEY> extends AbstractScopeContainer<KEY> {
+
+ public StatelessScopeContainer(RuntimeComponent component) {
+ super(Scope.STATELESS, component);
+ }
+
+ @Override
+ public InstanceWrapper getWrapper(KEY contextId)
+ throws TargetResolutionException {
+ InstanceWrapper ctx = createInstanceWrapper();
+ ctx.start();
+ return ctx;
+ }
+
+ @Override
+ public InstanceWrapper getAssociatedWrapper(KEY contextId)
+ throws TargetResolutionException {
+ return getWrapper(contextId);
+ }
+
+ @Override
+ public void returnWrapper(InstanceWrapper wrapper, KEY contextId)
+ throws TargetDestructionException {
+ wrapper.stop();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java
new file mode 100644
index 0000000000..0471b2c52e
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.scope;
+
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContainerFactory implements ScopeContainerFactory {
+
+ public ScopeContainer createScopeContainer(RuntimeComponent component) {
+ return new StatelessScopeContainer(component);
+ }
+
+ public Scope getScope() {
+ return Scope.STATELESS;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java
new file mode 100644
index 0000000000..0f83dad97d
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+/**
+ * Denotes an error destroying a target
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetDestructionException extends TargetResolutionException {
+ private static final long serialVersionUID = -6126684147851674709L;
+
+ public TargetDestructionException() {
+ super();
+ }
+
+ public TargetDestructionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetDestructionException(String message) {
+ super(message);
+ }
+
+ public TargetDestructionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java
new file mode 100644
index 0000000000..15959c0608
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+/**
+ * Denotes an error initializing a target
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetInitializationException extends TargetResolutionException {
+ private static final long serialVersionUID = -6228778208649752698L;
+
+ public TargetInitializationException() {
+ super();
+ }
+
+ public TargetInitializationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetInitializationException(String message) {
+ super(message);
+ }
+
+ public TargetInitializationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java
new file mode 100644
index 0000000000..6e51a8c9ec
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+/**
+ * Thrown when a target of an operation cannot be found
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class TargetNotFoundException extends TargetResolutionException {
+ private static final long serialVersionUID = 5541830480658471186L;
+
+ public TargetNotFoundException() {
+ super();
+ }
+
+ public TargetNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetNotFoundException(String message) {
+ super(message);
+ }
+
+ public TargetNotFoundException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java
new file mode 100644
index 0000000000..ea8d0e876c
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.scope;
+
+/**
+ * Denotes an error retrieving a target instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetResolutionException extends Exception {
+ private static final long serialVersionUID = 2912513650522019405L;
+
+ public TargetResolutionException() {
+ super();
+ }
+
+ public TargetResolutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetResolutionException(String message) {
+ super(message);
+ }
+
+ public TargetResolutionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/store/MemoryStore.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/store/MemoryStore.java
new file mode 100644
index 0000000000..5b838116c5
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/store/MemoryStore.java
@@ -0,0 +1,195 @@
+/*
+ * 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.core.store;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tuscany.sca.core.event.BaseEventPublisher;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.store.DuplicateRecordException;
+import org.apache.tuscany.sca.store.RecoveryListener;
+import org.apache.tuscany.sca.store.Store;
+import org.apache.tuscany.sca.store.StoreExpirationEvent;
+import org.apache.tuscany.sca.store.StoreMonitor;
+import org.apache.tuscany.sca.store.StoreWriteException;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Implements a non-durable, non-transactional store using a simple in-memory map
+ *
+ * @version $Rev$ $Date$
+ */
+@Service(Store.class)
+@EagerInit
+public class MemoryStore extends BaseEventPublisher implements Store {
+ private Map<RuntimeComponent, Map<String, Record>> store;
+ // TODO integrate with a core threading scheme
+ private ScheduledExecutorService scheduler;
+ private long reaperInterval = 300000;
+ private StoreMonitor monitor;
+ private long defaultExpirationOffset = 600000; // 10 minutes
+
+ public MemoryStore(StoreMonitor monitor) {
+ this.monitor = monitor;
+ this.store = new ConcurrentHashMap<RuntimeComponent, Map<String, Record>>();
+ this.scheduler = Executors.newSingleThreadScheduledExecutor();
+ }
+
+ /**
+ * Returns the maximum default expiration offset for records in the store
+ *
+ * @return the maximum default expiration offset for records in the store
+ */
+ public long getDefaultExpirationOffset() {
+ return defaultExpirationOffset;
+ }
+
+ /**
+ * Sets the maximum default expiration offset for records in the store
+ */
+ @Property
+ public void setDefaultExpirationOffset(long defaultExpirationOffset) {
+ this.defaultExpirationOffset = defaultExpirationOffset;
+ }
+
+ /**
+ * Sets the interval for expired entry scanning to be performed
+ */
+ @Property
+ public void setReaperInterval(long reaperInterval) {
+ this.reaperInterval = reaperInterval;
+ }
+
+ public long getReaperInterval() {
+ return reaperInterval;
+ }
+
+ @Init
+ public void init() {
+ scheduler.scheduleWithFixedDelay(new Reaper(), reaperInterval, reaperInterval, TimeUnit.MILLISECONDS);
+ monitor.start("In-memory store started");
+ }
+
+ @Destroy
+ public void destroy() {
+ scheduler.shutdown();
+ monitor.stop("In-memory store stopped");
+ }
+
+ public void insertRecord(RuntimeComponent owner, String id, Object object, long expiration) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Record>();
+ store.put(owner, map);
+ }
+ if (map.containsKey(id)) {
+ throw new DuplicateRecordException("Duplicate record: " + owner.getURI() +" : " + id);
+ }
+ map.put(id, new Record(object, expiration));
+ }
+
+ public void updateRecord(RuntimeComponent owner, String id, Object object, long expiration) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ throw new StoreWriteException("Record not found: " + owner.getURI() +" : " + id);
+ }
+ Record record = map.get(id);
+ if (record == null) {
+ throw new StoreWriteException("Record not found: " + owner.getURI() +" : " + id);
+ }
+ record.data = object;
+ }
+
+ public Object readRecord(RuntimeComponent owner, String id) {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ return null;
+ }
+ Record record = map.get(id);
+ if (record != null) {
+ return record.data;
+ }
+ return null;
+ }
+
+ public void removeRecords() {
+ store.clear();
+ }
+
+ public void removeRecord(RuntimeComponent owner, String id) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ throw new StoreWriteException("Owner not found: " + owner.getURI() +" : " + id);
+ }
+ if (map.remove(id) == null) {
+ throw new StoreWriteException("Owner not found: " + owner.getURI() +" : " + id);
+ }
+ }
+
+ public void recover(RecoveryListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ private class Record {
+ private Object data;
+ private long expiration = NEVER;
+
+ public Record(Object data, long expiration) {
+ this.data = data;
+ this.expiration = expiration;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public long getExpiration() {
+ return expiration;
+ }
+ }
+
+ private class Reaper implements Runnable {
+
+ public void run() {
+ long now = System.currentTimeMillis();
+ for (Map.Entry<RuntimeComponent, Map<String, Record>> entries : store.entrySet()) {
+ for (Map.Entry<String, Record> entry : entries.getValue().entrySet()) {
+ final long expiration = entry.getValue().expiration;
+ if (expiration != NEVER && now >= expiration) {
+ RuntimeComponent owner = entries.getKey();
+ Object instance = entry.getValue().getData();
+ // notify listeners of the expiration
+ StoreExpirationEvent event = new StoreExpirationEvent(this, owner, instance);
+ publish(event);
+ entries.getValue().remove(entry.getKey());
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237Work.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237Work.java
new file mode 100644
index 0000000000..6fe883157f
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237Work.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.work;
+
+/*
+ * JCA work wrapper.
+ */
+public class Jsr237Work<T extends Runnable> implements commonj.work.Work {
+
+ // Work that is being executed.
+ private T work;
+
+ /*
+ * Initializes the work instance.
+ */
+ public Jsr237Work(T work) {
+ this.work = work;
+ }
+
+ /*
+ * Returns the completed work.
+ */
+ public T getWork() {
+ return work;
+ }
+
+ /*
+ * Release the work.
+ */
+ public void release() {
+ }
+
+ /*
+ * Work attributes are not daemon.
+ */
+ public boolean isDaemon() {
+ return false;
+ }
+
+ /*
+ * Runs the work.
+ */
+ public void run() {
+ work.run();
+ }
+} \ No newline at end of file
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237WorkScheduler.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237WorkScheduler.java
new file mode 100644
index 0000000000..1abe040c14
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Jsr237WorkScheduler.java
@@ -0,0 +1,165 @@
+/*
+ * 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.core.work;
+
+import org.apache.tuscany.sca.work.NotificationListener;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.apache.tuscany.sca.work.WorkSchedulerException;
+
+import commonj.work.WorkEvent;
+import commonj.work.WorkListener;
+
+/**
+ * A work scheduler implementation based on a JSR 237 work manager.
+ * <p/>
+ * <p/>
+ * This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a
+ * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work
+ * manager implementaion available. For example, if the managed environment supports work manager the runtime can use
+ * the appropriate lookup mechanism to inject the work manager implementation. </p>
+ */
+public class Jsr237WorkScheduler implements WorkScheduler {
+
+ /**
+ * Underlying JSR-237 work manager
+ */
+ private ThreadPoolWorkManager jsr237WorkManager;
+
+ /**
+ * Initializes the JSR 237 work manager.
+ *
+ * @param jsr237WorkManager JSR 237 work manager.
+ */
+ public Jsr237WorkScheduler() {
+ jsr237WorkManager = new ThreadPoolWorkManager(10);
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ */
+ public <T extends Runnable> void scheduleWork(T work) {
+ scheduleWork(work, null);
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ * @param listener Notification listener for callbacks.
+ */
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+
+ if (work == null) {
+ throw new IllegalArgumentException("Work cannot be null");
+ }
+
+ Jsr237Work<T> jsr237Work = new Jsr237Work<T>(work);
+ try {
+ if (listener == null) {
+ jsr237WorkManager.schedule(jsr237Work);
+ } else {
+ Jsr237WorkListener<T> jsr237WorkListener = new Jsr237WorkListener<T>(listener, work);
+ jsr237WorkManager.schedule(jsr237Work, jsr237WorkListener);
+ }
+ } catch (IllegalArgumentException ex) {
+ if (listener != null) {
+ listener.workRejected(work);
+ } else {
+ throw new WorkSchedulerException(ex);
+ }
+ } catch (Exception ex) {
+ throw new WorkSchedulerException(ex);
+ }
+
+ }
+
+ public void destroy() {
+ jsr237WorkManager.destroy();
+ }
+
+ /*
+ * Worklistener for keeping track of work status callbacks.
+ *
+ */
+ private class Jsr237WorkListener<T extends Runnable> implements WorkListener {
+
+ // Notification listener
+ private NotificationListener<T> listener;
+
+ // Work
+ private T work;
+
+ /*
+ * Initializes the notification listener.
+ */
+ public Jsr237WorkListener(NotificationListener<T> listener, T work) {
+ this.listener = listener;
+ this.work = work;
+ }
+
+ /*
+ * Callback when the work is accepted.
+ */
+ public void workAccepted(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workAccepted(work);
+ }
+
+ /*
+ * Callback when the work is rejected.
+ */
+ public void workRejected(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workRejected(work);
+ }
+
+ /*
+ * Callback when the work is started.
+ */
+ public void workStarted(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workStarted(work);
+ }
+
+ /*
+ * Callback when the work is completed.
+ */
+ public void workCompleted(WorkEvent workEvent) {
+ T work = getWork();
+ Exception exception = workEvent.getException();
+ if (exception != null) {
+ listener.workFailed(work, exception);
+ } else {
+ listener.workCompleted(work);
+ }
+ }
+
+ /*
+ * Gets the underlying work from the work event.
+ */
+ private T getWork() {
+ return work;
+ }
+
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java
new file mode 100644
index 0000000000..60696692e1
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java
@@ -0,0 +1,219 @@
+/*
+ * 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.core.work;
+
+import java.rmi.server.UID;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Property;
+
+import commonj.work.Work;
+import commonj.work.WorkEvent;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+import commonj.work.WorkListener;
+import commonj.work.WorkManager;
+
+/**
+ * A thread-pool based implementation for the JSR-237 work manager.
+ * <p/>
+ * <p/>
+ * This implementation supports only local work.
+ * <p/>
+ * TODO Elaborate the implementation. </p>
+ */
+public class ThreadPoolWorkManager implements WorkManager {
+
+ // Map of work items currently handled by the work manager
+ private Map<WorkItemImpl, WorkListener> workItems = new ConcurrentHashMap<WorkItemImpl, WorkListener>();
+
+ // Thread-pool
+ private ExecutorService executor;
+
+ /**
+ * Initializes the thread-pool.
+ *
+ * @param threadPoolSize Thread-pool size.
+ */
+ public ThreadPoolWorkManager(@Property(name = "poolSize") int threadPoolSize) {
+ executor = Executors.newFixedThreadPool(threadPoolSize);
+ }
+
+ /**
+ * Schedules a unit of work asynchronously.
+ *
+ * @param work Work that needs to be scheduled.
+ * @return Work Work item representing the asynchronous work
+ */
+ public WorkItem schedule(Work work) throws IllegalArgumentException {
+ return schedule(work, null);
+ }
+
+ /**
+ * Schedules a unit of work asynchronously.
+ *
+ * @param work Work that needs to be scheduled.
+ * @param workListener Work listener for callbacks.
+ * @return Work Work item representing the asynchronous work
+ */
+ public WorkItem schedule(Work work, WorkListener workListener) throws IllegalArgumentException {
+
+ WorkItemImpl workItem = new WorkItemImpl(new UID().toString(), work);
+ if (workListener != null) {
+ workItems.put(workItem, workListener);
+ }
+ workAccepted(workItem, work);
+ if (scheduleWork(work, workItem)) {
+ return workItem;
+ } else {
+ workItem.setStatus(WorkEvent.WORK_REJECTED);
+ if (workListener != null) {
+ workListener.workRejected(new WorkEventImpl(workItem));
+ }
+ throw new IllegalArgumentException("Unable to schedule work");
+ }
+ }
+
+ /**
+ * Wait for all the specified units of work to finish.
+ *
+ * @param works Units of the work that need to finish.
+ * @param timeout Timeout for waiting for the units of work to finish.
+ */
+ public boolean waitForAll(Collection works, long timeout) {
+ throw new UnsupportedOperationException("waitForAll not supported");
+ }
+
+ /**
+ * Wait for any of the specified units of work to finish.
+ *
+ * @param works Units of the work that need to finish.
+ * @param timeout Timeout for waiting for the units of work to finish.
+ */
+ public Collection waitForAny(Collection works, long timeout) {
+ throw new UnsupportedOperationException("waitForAny not supported");
+ }
+
+ /**
+ * Method provided for subclasses to indicate a work accptance.
+ *
+ * @param workItem Work item representing the work that was accepted.
+ * @param work Work that was accepted.
+ */
+ private void workAccepted(final WorkItemImpl workItem, final Work work) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_ACCEPTED);
+ WorkEvent event = new WorkEventImpl(workItem);
+ listener.workAccepted(event);
+ }
+ }
+
+ /*
+ * Method to indicate a work start.
+ */
+ private void workStarted(final WorkItemImpl workItem, final Work work) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_STARTED);
+ WorkEvent event = new WorkEventImpl(workItem);
+ listener.workStarted(event);
+ }
+ }
+
+ /*
+ * Method to indicate a work completion.
+ */
+ private void workCompleted(final WorkItemImpl workItem, final Work work) {
+ workCompleted(workItem, work, null);
+ }
+
+ /*
+ * Method to indicate a work completion.
+ */
+ private void workCompleted(final WorkItemImpl workItem, final Work work, final WorkException exception) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_COMPLETED);
+ workItem.setResult(work);
+ workItem.setException(exception);
+ WorkEvent event = new WorkEventImpl(workItem);
+ listener.workCompleted(event);
+ workItems.remove(workItem);
+ }
+ }
+
+ /*
+ * Schedules the work using the threadpool.
+ */
+ private boolean scheduleWork(final Work work, final WorkItemImpl workItem) {
+ try {
+ executor.execute(new DecoratingWork(workItem, work));
+ return true;
+ } catch (RejectedExecutionException ex) {
+ return false;
+ }
+ }
+
+ /*
+ * Class that decorates the original worker so that it can get callbacks when work is done.
+ */
+ private final class DecoratingWork implements Runnable {
+
+ // Work item for this work.
+ private WorkItemImpl workItem;
+
+ // The original work.
+ private Work decoratedWork;
+
+ /*
+ * Initializes the work item and underlying work.
+ */
+ private DecoratingWork(final WorkItemImpl workItem, final Work decoratedWork) {
+ this.workItem = workItem;
+ this.decoratedWork = decoratedWork;
+ }
+
+ /*
+ * Overrides the run method.
+ */
+ public void run() {
+ workStarted(workItem, decoratedWork);
+ try {
+ decoratedWork.run();
+ workCompleted(workItem, decoratedWork);
+ } catch (Throwable th) {
+ workCompleted(workItem, decoratedWork, new WorkException(th.getMessage(), th));
+ }
+ }
+
+ }
+
+ @Destroy
+ public void destroy() {
+ executor.shutdown();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEventImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEventImpl.java
new file mode 100644
index 0000000000..62ebeea1fb
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEventImpl.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.core.work;
+
+
+import commonj.work.WorkEvent;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+
+/**
+ * Default immutable implementation of the <code>WorkEvent</code> class.
+ */
+class WorkEventImpl implements WorkEvent {
+
+ // Work item for this event
+ private WorkItem workItem;
+
+ // Exception if something has gone wrong
+ private WorkException exception;
+
+ /**
+ * Instantiates the event.
+ *
+ * @param workItem Work item for this event.
+ */
+ public WorkEventImpl(final WorkItemImpl workItem) {
+ this.workItem = workItem;
+ this.exception = workItem.getException();
+ }
+
+ /**
+ * Returns the work type based on whether the work was accepted, started,
+ * rejected or completed.
+ *
+ * @return Work type.
+ */
+ public int getType() {
+ return workItem.getStatus();
+ }
+
+ /**
+ * Returns the work item associated with this work type.
+ *
+ * @return Work item.
+ */
+ public WorkItem getWorkItem() {
+ return workItem;
+ }
+
+ /**
+ * Returns the exception if the work completed with an exception.
+ *
+ * @return Work exception.
+ */
+ public WorkException getException() {
+ return exception;
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItemImpl.java b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItemImpl.java
new file mode 100644
index 0000000000..39a7c647f7
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItemImpl.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.work;
+
+import commonj.work.Work;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+
+/**
+ * An identity based immutable implementation of the <code>WorkItem</code>
+ * interface.
+ *
+ */
+class WorkItemImpl implements WorkItem {
+
+ // Id scoped for the VM
+ private String id;
+
+ // Status
+ private int status = -1;
+
+ // Result
+ private Work result;
+
+ // Original work
+ private Work originalWork;
+
+ // Exception
+ private WorkException exception;
+
+ /**
+ * Instantiates an id for this item.
+ *
+ * @param id of this work event.
+ */
+ protected WorkItemImpl(final String id, final Work orginalWork) {
+ this.id = id;
+ this.originalWork = orginalWork;
+ }
+
+ /**
+ * Returns the id.
+ *
+ * @return Id of this item.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the original work.
+ *
+ * @return Original work.
+ */
+ public Work getOriginalWork() {
+ return originalWork;
+ }
+
+ /**
+ * Returns the work result if the work completed.
+ *
+ * @return Work.
+ * @throws WorkException If the work completed with an exception.
+ */
+ public Work getResult() {
+ return result;
+ }
+
+ /**
+ * Sets the result.
+ *
+ * @param result Result.
+ */
+ protected void setResult(final Work result) {
+ this.result = result;
+ }
+
+ /**
+ * Returns the exception if work completed with an exception.
+ *
+ * @return Work exception.
+ */
+ protected WorkException getException() {
+ return exception;
+ }
+
+ /**
+ * Sets the exception.
+ *
+ * @param exception Exception.
+ */
+ protected void setException(final WorkException exception) {
+ this.exception = exception;
+ }
+
+ /**
+ * Returns the work type based on whether the work was accepted, started,
+ * rejected or completed.
+ *
+ * @return Work status.
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets the status.
+ *
+ * @param status Status.
+ */
+ protected void setStatus(final int status) {
+ this.status = status;
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param obj Object to be compared.
+ * @return true if this object is the same as the obj argument; false
+ * otherwise..
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ return (obj != null) && (obj.getClass() == WorkItemImpl.class) && ((WorkItemImpl) obj).id.equals(id);
+ }
+
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+ *
+ * @param o Object to be compared.
+ * @return A negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @throws ClassCastException needs better documentation.
+ */
+ public int compareTo(final Object o) {
+ if (o.getClass() != WorkItemImpl.class) {
+ throw new ClassCastException(o.getClass().getName());
+ } else {
+ return ((WorkItemImpl) o).getId().compareTo(getId());
+ }
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java
new file mode 100644
index 0000000000..7b44736d4b
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core;
+
+import junit.framework.TestCase;
+
+public class DefaultExtensionPointRegistryTestCase extends TestCase {
+ private ExtensionPointRegistry registry;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new DefaultExtensionPointRegistry();
+ }
+
+ public void testRegistry() {
+ MyRegistry service = new MyREgistryImpl();
+ registry.addExtensionPoint(service);
+ assertSame(service, registry.getExtensionPoint(MyRegistry.class));
+ registry.removeExtensionPoint(service);
+ assertNull(registry.getExtensionPoint(MyRegistry.class));
+ }
+
+ public static interface MyRegistry {
+ void doSomething();
+ }
+
+ private static class MyREgistryImpl implements MyRegistry {
+
+ public void doSomething() {
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/BaseEventPublisherTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/BaseEventPublisherTestCase.java
new file mode 100644
index 0000000000..2bc78c3d35
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/BaseEventPublisherTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * 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.core.event;
+
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.event.Event;
+import org.apache.tuscany.sca.event.EventFilter;
+import org.apache.tuscany.sca.event.EventPublisher;
+import org.apache.tuscany.sca.event.RuntimeEventListener;
+import org.apache.tuscany.sca.event.TrueFilter;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BaseEventPublisherTestCase extends TestCase {
+ EventPublisher publisher;
+
+ public void testFireListener() {
+ Event event = new TestEvent();
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ listener.onEvent(EasyMock.same(event));
+ EasyMock.expectLastCall();
+ EasyMock.replay(listener);
+ publisher.addListener(listener);
+ publisher.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testRemoveListener() {
+ Event event = new TestEvent();
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ EasyMock.replay(listener);
+ publisher.addListener(listener);
+ publisher.removeListener(listener);
+ publisher.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testFalseFilterListener() {
+ Event event = new TestEvent();
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ EasyMock.replay(listener);
+ publisher.addListener(new FalseFilter(), listener);
+ publisher.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testTrueFilterListener() {
+ Event event = new TestEvent();
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ listener.onEvent(EasyMock.same(event));
+ EasyMock.expectLastCall();
+ EasyMock.replay(listener);
+ publisher.addListener(new TrueFilter(), listener);
+ publisher.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ publisher = new BaseEventPublisher() {
+ };
+ }
+
+ private class TestEvent implements Event {
+ public Object getSource() {
+ return null;
+ }
+ }
+
+ private class FalseFilter implements EventFilter {
+
+ public boolean match(Event event) {
+ return false;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/EventTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/EventTestCase.java
new file mode 100644
index 0000000000..48dcf8df07
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/event/EventTestCase.java
@@ -0,0 +1,69 @@
+/*
+ * 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.core.event;
+
+import java.net.URI;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EventTestCase extends TestCase {
+ private URI uri = URI.create("foo");
+
+ public void testCompositeStart() {
+ ComponentStart event = new ComponentStart(this, uri);
+ assertEquals(uri, event.getComponentURI());
+ }
+
+ public void testCompositeStop() {
+ ComponentStop event = new ComponentStop(this, uri);
+ assertEquals(uri, event.getComponentURI());
+ }
+
+ public void testHttpSessionStart() {
+ Object id = new Object();
+ HttpSessionStart event = new HttpSessionStart(this, id);
+ assertEquals(this, event.getSource());
+ assertEquals(id, event.getSessionID());
+ }
+
+ public void testHttpSessionEnd() {
+ Object id = new Object();
+ HttpSessionEnd event = new HttpSessionEnd(this, id);
+ assertEquals(this, event.getSource());
+ assertEquals(id, event.getSessionID());
+ }
+
+ public void testRequestStart() {
+ RequestStart event = new RequestStart(this);
+ assertEquals(this, event.getSource());
+ }
+
+ public void testReequestEnd() {
+ RequestEnd event = new RequestEnd(this);
+ assertEquals(this, event.getSource());
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ }
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainerTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainerTestCase.java
new file mode 100644
index 0000000000..64114f7fb2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainerTestCase.java
@@ -0,0 +1,69 @@
+/*
+ * 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.core.scope;
+
+import java.net.URI;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.core.context.InstanceWrapper;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContainerTestCase<T, KEY> extends TestCase {
+ protected IMocksControl control;
+ protected ScopeContainer<KEY> scopeContainer;
+ protected URI groupId;
+ protected KEY contextId;
+ protected RuntimeComponent component;
+ protected ScopedImplementation implementation;
+ protected InstanceWrapper<T> wrapper;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ control = EasyMock.createStrictControl();
+ component = control.createMock(RuntimeComponent.class);
+ wrapper = control.createMock(InstanceWrapper.class);
+ implementation = control.createMock(ScopedImplementation.class);
+ EasyMock.expect(component.getImplementation()).andReturn(implementation).anyTimes();
+ }
+
+ protected void preRegisterComponent() throws Exception {
+ scopeContainer.start();
+ EasyMock.expect(implementation.isEagerInit()).andStubReturn(false);
+ }
+
+ protected void expectCreateWrapper() throws Exception {
+ EasyMock.expect(implementation.createInstanceWrapper()).andReturn(wrapper);
+ wrapper.start();
+ }
+
+ protected static interface ScopedImplementation extends ScopedImplementationProvider, Implementation {
+
+ }
+
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/store/MemoryStoreTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/store/MemoryStoreTestCase.java
new file mode 100644
index 0000000000..d46d77b4b8
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/store/MemoryStoreTestCase.java
@@ -0,0 +1,165 @@
+/*
+ * 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.core.store;
+
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.event.RuntimeEventListener;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.store.DuplicateRecordException;
+import org.apache.tuscany.sca.store.Store;
+import org.apache.tuscany.sca.store.StoreExpirationEvent;
+import org.apache.tuscany.sca.store.StoreMonitor;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MemoryStoreTestCase extends TestCase {
+ private StoreMonitor monitor;
+
+ public void testEviction() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, 1);
+ Thread.sleep(200);
+ assertNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testNotifyOnEviction() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ listener.onEvent(EasyMock.isA(StoreExpirationEvent.class));
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.countDown();
+ return null;
+ }
+ });
+ EasyMock.replay(listener);
+ MemoryStore store = new MemoryStore(monitor);
+ store.addListener(listener);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, 1);
+ if (!latch.await(1000, TimeUnit.MILLISECONDS)) {
+ // failed to notify listener
+ fail();
+ }
+ EasyMock.verify(listener);
+ }
+
+ public void testNoEviction() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ Thread.sleep(100);
+ assertNotNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testInsertRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.destroy();
+ }
+
+ public void testInsertAlreadyExists() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createMock(RuntimeComponent.class);
+ EasyMock.expect(component.getURI()).andReturn("component");
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ try {
+ store.insertRecord(component, id, value, Store.NEVER);
+ fail();
+ } catch (DuplicateRecordException e) {
+ //expected
+ }
+ store.destroy();
+ }
+
+ public void testUpdateRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ Object newValue = new Object();
+
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.updateRecord(component, id, newValue, 1L);
+ assertEquals(newValue, store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testDeleteRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ RuntimeComponent component = EasyMock.createNiceMock(RuntimeComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.removeRecord(component, id);
+ assertNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ monitor = EasyMock.createNiceMock(StoreMonitor.class);
+ EasyMock.replay(monitor);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java
new file mode 100644
index 0000000000..58503fd852
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.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.core.wire;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.invocation.CallbackInterfaceInterceptor;
+import org.apache.tuscany.sca.core.invocation.MessageFactoryImpl;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Message;
+import org.easymock.EasyMock;
+import org.osoa.sca.NoRegisteredCallbackException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CallbackInterfaceInterceptorTestCase extends TestCase {
+
+ public void testImplements() {
+ CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(true);
+ Interceptor next = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(next.invoke(EasyMock.isA(Message.class))).andReturn(null);
+ EasyMock.replay(next);
+ interceptor.setNext(next);
+ interceptor.invoke(new MessageFactoryImpl().createMessage());
+ EasyMock.verify(next);
+ }
+
+ public void testDoesNotImplement() {
+ CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(false);
+ try {
+ interceptor.invoke(new MessageFactoryImpl().createMessage());
+ fail();
+ } catch (NoRegisteredCallbackException e) {
+ // expected
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java
new file mode 100644
index 0000000000..83f7bdd887
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.wire;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.invocation.InvocationChainImpl;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InvocationChainImplTestCase extends TestCase {
+
+ public void testInsertAtEnd() throws Exception {
+ InvocationChain chain = new InvocationChainImpl(new OperationImpl("foo"));
+ Interceptor inter2 = new MockInterceptor();
+ Interceptor inter1 = new MockInterceptor();
+ chain.addInterceptor(inter1);
+ chain.addInterceptor(inter2);
+ Interceptor head = (Interceptor)chain.getHeadInvoker();
+ assertEquals(inter1, head);
+ assertEquals(inter2, head.getNext());
+ assertEquals(inter2, chain.getTailInvoker());
+
+ }
+
+ private class MockInterceptor implements Interceptor {
+
+ private Invoker next;
+
+ public Message invoke(Message msg) {
+ return null;
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java
new file mode 100644
index 0000000000..c5f93edeb6
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.wire;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
+import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NonBlockingInterceptorTestCase extends TestCase {
+
+ public void testInvoke() throws Exception {
+ WorkScheduler scheduler = createMock(WorkScheduler.class);
+ scheduler.scheduleWork(isA(Runnable.class));
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ Runnable runnable = (Runnable) getCurrentArguments()[0];
+ runnable.run();
+ return null;
+ }
+ });
+ replay(scheduler);
+ Message context = createMock(Message.class);
+ String convID = "convID";
+ EasyMock.expect(context.getConversationID()).andReturn(convID);
+ EasyMock.replay(context);
+ ThreadMessageContext.setMessageContext(context);
+ Message msg = createMock(Message.class);
+ msg.setCorrelationID(null);
+ msg.setConversationID(convID);
+ Interceptor next = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(next);
+ EasyMock.replay(msg);
+ Interceptor interceptor = new NonBlockingInterceptor(scheduler, next);
+ interceptor.invoke(msg);
+ verify(context);
+ verify(next);
+ verify(msg);
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/scope/ScopeTestCase.java b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/scope/ScopeTestCase.java
new file mode 100644
index 0000000000..341d889b7d
--- /dev/null
+++ b/branches/sca-java-0.99/modules/core/src/test/java/org/apache/tuscany/sca/scope/ScopeTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * 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.scope;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.core.scope.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ScopeTestCase extends TestCase {
+
+ public void testEquals() throws Exception {
+ Scope scope = new Scope("COMPOSITE");
+ assertTrue(scope.equals(Scope.COMPOSITE));
+ }
+
+ public void testEqualsNew() throws Exception {
+ Scope foo = new Scope("foo");
+ Scope foo2 = new Scope("FOO");
+ assertTrue(foo.equals(foo2));
+ }
+
+ public void testNotEquals() throws Exception {
+ Scope foo = new Scope("BAR");
+ Scope foo2 = new Scope("FOO");
+ assertFalse(foo.equals(foo2));
+ }
+
+ public void testNotEqualsDifferent() throws Exception {
+ Scope foo = new Scope("FOO");
+ assertFalse(foo.equals(new Bar("FOO")));
+ }
+
+ public class Bar {
+ String scope;
+
+ public Bar(String scope) {
+ this.scope = scope;
+ }
+ }
+
+
+}