summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context')
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java89
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java85
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java35
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java40
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java66
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java106
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java27
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java57
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java66
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java24
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java75
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java32
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java83
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java31
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java72
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java652
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java222
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java112
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java77
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java92
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java158
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java67
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java184
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java52
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java254
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java182
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java224
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java145
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java62
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java56
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java107
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java59
46 files changed, 4153 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java
new file mode 100644
index 0000000000..c1abcb3c03
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java
@@ -0,0 +1,89 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Functionality common to all <code>Context<code> implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractContext implements Context {
+
+ public AbstractContext() {
+ }
+
+ public AbstractContext(String name) {
+ this.name = name;
+ }
+
+ protected String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ protected int lifecycleState = UNINITIALIZED;
+
+ public int getLifecycleState() {
+ return lifecycleState;
+ }
+
+ public void setLifecycleState(int state) {
+ lifecycleState = state;
+ }
+
+ protected List<LifecycleEventListener> contextListener = new CopyOnWriteArrayList();
+
+ public void addContextListener(LifecycleEventListener listener) {
+ contextListener.add(listener);
+ }
+
+ public void removeContextListener(LifecycleEventListener listener) {
+ contextListener.remove(listener);
+ }
+
+ public String toString() {
+ switch (lifecycleState) {
+ case (CONFIG_ERROR):
+ return "Context [" + name + "] in state [CONFIG_ERROR]";
+ case (ERROR):
+ return "Context [" + name + "] in state [ERROR]";
+ case (INITIALIZING):
+ return "Context [" + name + "] in state [INITIALIZING]";
+ case (INITIALIZED):
+ return "Context [" + name + "] in state [INITIALIZED]";
+ case (RUNNING):
+ return "Context [" + name + "] in state [RUNNING]";
+ case (STOPPING):
+ return "Context [" + name + "] in state [STOPPING]";
+ case (STOPPED):
+ return "Context [" + name + "] in state [STOPPED]";
+ case (UNINITIALIZED):
+ return "Context [" + name + "] in state [UNINITIALIZED]";
+ default:
+ return "Context [" + name + "] in state [UNKNOWN]";
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java
new file mode 100644
index 0000000000..0fab87358f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java
@@ -0,0 +1,85 @@
+package org.apache.tuscany.core.context;
+
+import java.util.List;
+
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.assembly.AggregatePart;
+
+/**
+ * A context which contains child component contexts.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface AggregateContext extends InstanceContext {
+
+ /**
+ * Propagates an event to registered listeners. All lifecycle events will be propagated to children in the order
+ * that they were registered. Listeners are expected to be well-behaved and if an exception is thrown the
+ * notification process will be aborted.
+ *
+ * @param pEventType the type of event. Basic types are defined in {@link EventContext}
+ * @param pMessage the message associated with the event or null
+ * @throws EventException if an error occurs while sending the event
+ */
+ public void fireEvent(int pEventType, Object pMessage) throws EventException;
+
+ /**
+ * Registers a listener to receive notifications for the context
+ *
+ * @throws ContextRuntimeException if an error occurs during registration
+ */
+ public void registerListener(RuntimeEventListener listener) throws ContextRuntimeException;
+
+ /**
+ * Adds runtime artifacts represented by the set of model objects to the aggregate context by merging them with
+ * existing artifacts. Implementing classes may support only a subset of {@link AggregatePart} types.
+ *
+ * @see org.apache.tuscany.model.assembly.Component
+ * @see org.apache.tuscany.model.assembly.ModuleComponent
+ * @see org.apache.tuscany.model.assembly.SimpleComponent
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ * @see org.apache.tuscany.model.assembly.ExternalService
+ */
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException;
+
+ /**
+ * Adds a runtime artifact represented by the model object to the aggregate context by merging it with existing
+ * artifacts. Implementing classes may support only a subset of {@link AggregatePart} types.
+ *
+ * @see org.apache.tuscany.model.assembly.Component
+ * @see org.apache.tuscany.model.assembly.ModuleComponent
+ * @see org.apache.tuscany.model.assembly.SimpleComponent
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ * @see org.apache.tuscany.model.assembly.ExternalService
+ */
+ public void registerModelObject(Extensible model) throws ConfigurationException;
+
+ /**
+ * Returns the child context associated with a given name
+ */
+ public InstanceContext getContext(String name);
+
+ /**
+ * Returns the parent context, or null if the context does not have one
+ */
+ public AggregateContext getParent();
+
+ /**
+ * Intended for internal use by the runtime, returns an implementation instance for the given context name, which
+ * may be a compound component/service form. Unlike {@link InstanceContext#getInstance(QualifiedName)}, which for aggregate contexts only returns
+ * entry point proxies, this method will return any type of contained implementation instance.
+ *
+ * @throws TargetException if there was an error returning the instance
+ */
+ public Object locateInstance(String name) throws TargetException;
+
+ /**
+ * Returns the aggregate managed by this aggregate context
+ * @return
+ */
+ @Deprecated
+ public Aggregate getAggregate();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java
new file mode 100644
index 0000000000..5f3973f358
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * A specialization of an AggregateContext that is able to automatically resolve references
+ * for its children using EntryPoint or Service interfaces exposed by it or, recursively, any
+ * of it parents.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface AutowireContext extends AggregateContext {
+
+ /**
+ * Returns an reference to the requested service.
+ *
+ * @param instanceInterface the type of service being requested
+ * @return a reference to the requested service or null if none can be found
+ * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire
+ */
+ <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException;
+
+ // todo add additional methods that allow other qualifications to be supplied
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java
new file mode 100644
index 0000000000..4da4206a94
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an exception while resolving an automatic wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutowireResolutionException extends TargetException {
+
+ public AutowireResolutionException() {
+ super();
+ }
+
+ public AutowireResolutionException(String message) {
+ super(message);
+ }
+
+ public AutowireResolutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AutowireResolutionException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java
new file mode 100644
index 0000000000..a57ed03ffd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java
@@ -0,0 +1,66 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.model.assembly.Extensible;
+
+/**
+ * Offers configuration services in the runtime. A ConfigurationContext is able to configure a model and then build the
+ * runtime representation corresponding to that model in the live system. <p/> Configuration contexts will typically be
+ * hierarchical, delegating to their parent <b>after</b> performing an operation. The parent ConfigurationContext will
+ * typically be injected into an implementation of this interface during registration.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ConfigurationContext {
+
+ /**
+ * Adds additional configuration information to a model object.
+ *
+ * @param model the model object to be configured
+ * @throws ConfigurationException
+ */
+ public void configure(Extensible model) throws ConfigurationException;
+
+ /**
+ * Decorates the supplied model object with a {@link org.apache.tuscany.core.builder.RuntimeConfiguration} that can
+ * be used to create the runtime context corresponding to the model.
+ *
+ * @param parent an AggregrateContext that will ultimately become the parent of the runtime context
+ * @param model the model object that defines the configuration to be built
+ * @throws BuilderConfigException
+ * @see org.apache.tuscany.core.builder.RuntimeConfiguration
+ */
+ public void build(AggregateContext parent, Extensible model) throws BuilderConfigException;
+
+ /**
+ * Constructs a wire from a source proxy factory to a corresponding target, potentially performing optimizations
+ *
+ * @param sourceFactory the proxy factory that will be used to create the injected proxy for a reference
+ * @param targetFactory the proxy factory that contains the invocation chains for the target side of the wire
+ * @param targetType the {@link org.apache.tuscany.core.builder.RuntimeConfiguration} implementation type for the
+ * wire target
+ * @param downScope whether the source is a shorter lived scope than the target. Used in optimization.
+ * @param targetScopeContext the scope context of the target service
+ * @throws BuilderConfigException
+ */
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException;
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java
new file mode 100644
index 0000000000..2eb70e8711
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java
@@ -0,0 +1,106 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * An entity that provides an execution context for a runtime artifact
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Context {
+
+ /* A configuration error state */
+ public static final int CONFIG_ERROR = -1;
+
+ /* Has not been initialized */
+ public static final int UNINITIALIZED = 0;
+
+ /* In the process of being configured and initialized */
+ public static final int INITIALIZING = 1;
+
+ /* Instantiated and configured */
+ public static final int INITIALIZED = 2;
+
+ /* Configured and initialized */
+ public static final int RUNNING = 4;
+
+ /* In the process of being shutdown */
+ public static final int STOPPING = 5;
+
+ /* Has been shutdown and removed from the module */
+ public static final int STOPPED = 6;
+
+ /* In an error state */
+ public static final int ERROR = 7;
+
+ /**
+ * Returns the name of the context
+ */
+ public String getName();
+
+ /**
+ * Sets the name of the context
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the lifecycle state
+ *
+ * @see #UNINITIALIZED
+ * @see #INITIALIZING
+ * @see #INITIALIZED
+ * @see #RUNNING
+ * @see #STOPPING
+ * @see #STOPPED
+ */
+ public int getLifecycleState();
+
+ /**
+ * Sets the lifecycle state
+ *
+ * @see #UNINITIALIZED
+ * @see #INITIALIZING
+ * @see #INITIALIZED
+ * @see #RUNNING
+ * @see #STOPPING
+ * @see #STOPPED
+ */
+ public void setLifecycleState(int state);
+
+ /**
+ * Starts the container
+ *
+ * @throws CoreRuntimeException
+ */
+ public void start() throws CoreRuntimeException;
+
+ /**
+ * Stops the container
+ *
+ * @throws CoreRuntimeException
+ */
+ public void stop() throws CoreRuntimeException;
+
+ /**
+ * Registers a listener for context events
+ */
+ public void addContextListener(LifecycleEventListener listener);
+
+ /**
+ * Deregisters a context event listener
+ */
+ public void removeContextListener(LifecycleEventListener listener);
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java
new file mode 100644
index 0000000000..e024a98b0e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an error encountered while initializing an instance context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextInitException extends ContextRuntimeException {
+
+ public ContextInitException() {
+ super();
+ }
+
+ public ContextInitException(String message) {
+ super(message);
+ }
+
+ public ContextInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContextInitException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java
new file mode 100644
index 0000000000..0d35f145dc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * An unchecked exception encountered by an {@link org.apache.tuscany.core.context.Context}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextRuntimeException extends CoreRuntimeException {
+
+ public ContextRuntimeException() {
+ super();
+ }
+
+ public ContextRuntimeException(String message) {
+ super(message);
+ }
+
+ public ContextRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContextRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java
new file mode 100644
index 0000000000..a46d35c22c
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java
@@ -0,0 +1,27 @@
+package org.apache.tuscany.core.context;
+
+import org.apache.tuscany.common.TuscanyRuntimeException;
+
+/**
+ * The root exception for the runtime package. Exceptions occurring in the runtime are generally non-recoverable
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class CoreRuntimeException extends TuscanyRuntimeException {
+
+ public CoreRuntimeException() {
+ super();
+ }
+
+ public CoreRuntimeException(String message) {
+ super(message);
+ }
+
+ public CoreRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CoreRuntimeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java
new file mode 100644
index 0000000000..81a334d3c8
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an attempt to add a context with a name equal to an existing context
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateNameException extends ContextRuntimeException {
+
+ public DuplicateNameException() {
+ super();
+ }
+
+ public DuplicateNameException(String message) {
+ super(message);
+ }
+
+ public DuplicateNameException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DuplicateNameException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java
new file mode 100644
index 0000000000..aef2840f9a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java
@@ -0,0 +1,57 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * The runtime artifact representing an entry point, <code>EntryPointContext</code> manages invocation handler
+ * instances that expose service operations offered by a component in the parent aggregate. The invocation handler
+ * instance is responsible for dispatching the request down an invocation chain to the target instance. The invocation
+ * chain may contain {@link org.apache.tuscany.core.invocation.Interceptor}s and
+ * {@link org.apache.tuscany.core.invocation.MessageHandler}s that implement policies or perform mediations on the
+ * invocation.
+ * <p>
+ * Entry point contexts are used by transport binding artifacts to invoke an operation on a service. The transport
+ * binding uses an {@link java.lang.reflect.InvocationHandler} instance obtained from the <code>EntryPointContext</code>
+ * to perform the invocation as in:
+ *
+ * <pre>
+ * AggregateContext aggregateContext = ...
+ * EntryPointContext ctx = (EntryPointContext) aggregateContext.getContext(&quot;source&quot;);
+ * Assert.assertNotNull(ctx);
+ * InvocationHandler handler = (InvocationHandler) ctx.getImplementationInstance();
+ * Object response = handler.invoke(null, operation, new Object[] { param });
+ * </pre>
+ *
+ * The <code>Proxy</code> instance passed to <code>InvocationHandler</code> may be null as the client is invoking
+ * directly on the handler.
+ * <p>
+ * Alternatively, the following will return a proxy implementing the service interface exposed by the entry point:
+ *
+ * <pre>
+ * AggregateContext aggregateContext = ...
+ * EntryPointContext ctx = (EntryPointContext) aggregateContext.getContext(&quot;source&quot;);
+ * Assert.assertNotNull(ctx);
+ * HelloWorld proxy = (Helloworld) ctx.getInstance(null); // service name not necessary
+ * </pre>
+ *
+ * The proxy returned will be backed by the entry point invocation chain.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EntryPointContext extends InstanceContext {
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java
new file mode 100644
index 0000000000..9f7c98200a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java
@@ -0,0 +1,66 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Implementations are responsible for tracking scope keys associated with the current request.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EventContext {
+
+ /* An event type fired when a request is first serviced in the runtime */
+ public static final int REQUEST_START = 1;
+
+ /* An event type fired when the runtime finishes servicing a request */
+ public static final int REQUEST_END = 2;
+
+ /* An event type fired when a session is set for the current context */
+ public static final int SESSION_NOTIFY = 3;
+
+ /* An event type fired when a session is invalidated in the runtime */
+ public static final int SESSION_END = 4;
+
+ /* An event type fired when the current deployment unit is initialized */
+ public static final int MODULE_START = 5;
+
+ /* An event type fired when the current deployment unit is quiesced */
+ public static final int MODULE_STOP = 6;
+
+ public static final int SYSTEM_START = 7;
+
+ public static final int SYSTEM_STOP = 8;
+
+ /* An identifier type associated with an HTTP session */
+ public static final Object HTTP_SESSION = new Object();
+
+ /**
+ * Returns the unique key for the given identifier, e.g a session
+ */
+ public Object getIdentifier(Object type);
+
+ /**
+ * Sets the unique key for the given identifier, e.g a session
+ */
+ public void setIdentifier(Object type, Object identifier);
+
+ /**
+ * Clears the unique key for the given identifier, e.g a session
+ */
+ public void clearIdentifier(Object type);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java
new file mode 100644
index 0000000000..aaf26aee69
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an error encountered while firing a module event
+ *
+ * @version $Rev$ $Date$
+ */
+public class EventException extends CoreRuntimeException {
+
+ public EventException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EventException(String message) {
+ super(message);
+ }
+
+ public EventException(Throwable cause) {
+ super(cause);
+ }
+
+ public EventException() {
+ super();
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java
new file mode 100644
index 0000000000..298246dc81
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java
@@ -0,0 +1,24 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Manages an external service
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ExternalServiceContext extends InstanceContext {
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java
new file mode 100644
index 0000000000..473762b6b0
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java
@@ -0,0 +1,75 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Manages instances of a runtime artifact. An <code>InstanceContext</code> may contain child contexts which
+ * themselves manage implementation instances or it may be a leaf context.
+ *
+ * @see org.apache.tuscany.core.context.SimpleComponentContext
+ * @see org.apache.tuscany.core.context.AggregateContext
+ * @see org.apache.tuscany.core.context.EntryPointContext
+ * @see org.apache.tuscany.core.context.ExternalServiceContext
+ *
+ * @version $Rev$ $Date$
+ */
+public interface InstanceContext extends Context {
+
+ /**
+ * Returns the instance associated with the requested name, which may be in a simple or compound form. Simple (i.e.
+ * leaf) contexts will return an instance associated with the service name part of the compound name, which may be
+ * null.
+ * <p>
+ * Aggregate contexts will return an instance (likely a proxy) of a contained entry point context. In this case, the
+ * port name on the qualified name will correspond to the aggregate context name and the part name will be used to
+ * retrieve the contained entry point context. The latter may be null. If the contained context is not an entry
+ * point context, an exception will be thrown.
+ *
+ * @param qName a qualified name of the requested instance
+ * @return the implementation instance or a proxy to it
+ * @throws TargetException if an error occurs retrieving the instance or the requested component is not an entry
+ * point.
+ *
+ * @see AggregateContext
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ */
+ public Object getInstance(QualifiedName qName) throws TargetException;
+
+ /**
+ * Returns an instance associated with the requested name without notifying <code>ContextEventListener</code>s
+ * that may be registered with this context on instance creation. Note that {@link #getInstance(QualifiedName)}
+ * should generally be called and this method is only provided as an optimization for particular circumstances.
+ *
+ * @param qName a qualified name of the requested instance
+ * @param notify whether to notify <code>ContextEventListener</code>s
+ * @return the instance or a proxy to it
+ * @throws TargetException if an error occurs retrieving the instance or proxy
+ * @see LifecycleEventListener
+ */
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException;
+
+ /**
+ * Returns the implementation instance associated witht he component. An implementation instance does not
+ * have a proxy invocation chainXXX
+ * @return
+ * @throws TargetException
+ */
+ public Object getImplementationInstance() throws TargetException;
+
+ public Object getImplementationInstance(boolean notify) throws TargetException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java
new file mode 100644
index 0000000000..65c709e569
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an invalid name
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidNameException extends ContextRuntimeException {
+
+ public InvalidNameException() {
+ super();
+ }
+
+ public InvalidNameException(String message) {
+ super(message);
+ }
+
+ public InvalidNameException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidNameException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java
new file mode 100644
index 0000000000..78962b53b4
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java
@@ -0,0 +1,32 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.EventListener;
+
+/**
+ * Callback interface for receiving instance context lifecycle events
+ *
+ * @version $Rev$ $Date$
+ */
+public interface LifecycleEventListener extends EventListener {
+
+ /**
+ * Notifies the listener that a new component context was created
+ */
+ public void onInstanceCreate(Context component);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java
new file mode 100644
index 0000000000..ad71721b75
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * An evaluated name consisting of a part/port pair. In the runtime, a part generally 'contains' or 'provides' ports
+ * such as a module component/entry point or a component/service pair.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QualifiedName {
+
+ private String qName;
+
+ private String partName;
+
+ private String portName;
+
+ public static final String NAME_SEPARATOR = "/";
+
+ /**
+ * Constructs a new qualified name
+ *
+ * @throws InvalidNameException if the name is in an invalid format
+ */
+ public QualifiedName(String qualifiedName) throws InvalidNameException {
+ assert (qualifiedName != null) : "Name was null";
+ int pos = qualifiedName.indexOf(QualifiedName.NAME_SEPARATOR);
+ switch (pos) {
+ case -1:
+ partName = qualifiedName;
+ break;
+ case 0:
+ throw new InvalidNameException(qualifiedName);
+ default:
+ partName = qualifiedName.substring(0, pos);
+ portName = qualifiedName.substring(pos + 1);
+ break;
+ }
+ qName = qualifiedName;
+ }
+
+ /**
+ * Returns the parsed part name
+ */
+ public String getPartName() {
+ return partName;
+ }
+
+ /**
+ * Returns the parsed port name if the original is of the compound for part/port
+ */
+ public String getPortName() {
+ return portName;
+ }
+
+ /**
+ * Returns the full part/port name pair
+ *
+ * @return
+ */
+ public String getQualifiedName() {
+ return qName;
+ }
+
+ public String toString() {
+ return qName;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java
new file mode 100644
index 0000000000..e90f30b9cc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.EventListener;
+
+/**
+ * Listeners observe events fired in the SCA runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface RuntimeEventListener extends EventListener {
+
+ /**
+ * A method called when an event for which the <tt>Listener</tt> class is registered to observe is fired in the runtime
+ *
+ * @param type the event type identifier
+ * @param message the event message
+ * @throws EventException if an error occurs processing the event
+ */
+ public void onEvent(int type, Object message) throws EventException;
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java
new file mode 100644
index 0000000000..565d7b49a6
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.Map;
+
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Denotes an aggregate context that supports scopes
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeAwareContext extends AggregateContext {
+
+ /**
+ * Returns an immutable collection of scopes keyed by type for the aggregate context
+ */
+ public Map<Scope, ScopeContext> getScopeContexts();
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
new file mode 100644
index 0000000000..abda942c88
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
@@ -0,0 +1,72 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.List;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+
+/**
+ * Manages the lifecycle and visibility of <code>InstanceContext</code>s.
+ *
+ * @see org.apache.tuscany.core.context.InstanceContext
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeContext extends InstanceContext, RuntimeEventListener {
+
+ /**
+ * Returns whether implementation instances may be held for the duration of an invocation
+ */
+ public boolean isCacheable();
+
+ /**
+ * Registers the runtime configurations used to construct instance contexts for the scope
+ */
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations);
+
+ /**
+ * Adds a runtime configuration to the scope
+ */
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration);
+
+ /**
+ * Returns a context bound to the given name or null if the component does not exist. The returned context is bound
+ * to a key determined from the thread context.
+ */
+ public InstanceContext getContext(String name);
+
+ /**
+ * Returns a context bound to the given name and scoped to the given key or null if the context does not exist
+ */
+ public InstanceContext getContextByKey(String name, Object key);
+
+ /**
+ * Removes a context with the given name, determining the scope key from the thread context
+ *
+ * @throws ScopeRuntimeException
+ */
+ public void removeContext(String name) throws ScopeRuntimeException;
+
+ /**
+ * Removes a context bound to the given name and scope key
+ *
+ * @throws ScopeRuntimeException
+ */
+ public void removeContextByKey(String name, Object key) throws ScopeRuntimeException;
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java
new file mode 100644
index 0000000000..38a847295c
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Implementations enable lazy retrieval of a scope id associated with a request, i.e. an id (and presumably a context) do not
+ * have to be generated if the scope is never accessed. Identifiers are associated with the current request thread and keyed on
+ * scope type.
+ *
+ * @version $Rev$ $Date$
+ * @see org.apache.tuscany.container.module.EventContext
+ */
+public interface ScopeIdentifier {
+
+ /**
+ * Returns the scope id for the request.
+ */
+ public Object getIdentifier();
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java
new file mode 100644
index 0000000000..6ef5bfe9dd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an initialization exception thrown by a scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeInitializationException extends ScopeRuntimeException {
+
+ public ScopeInitializationException() {
+ super();
+ }
+
+ public ScopeInitializationException(String message) {
+ super(message);
+ }
+
+ public ScopeInitializationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ScopeInitializationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java
new file mode 100644
index 0000000000..5022f7589d
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes a general runtime exception encountered by a scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeRuntimeException extends CoreRuntimeException {
+
+ public ScopeRuntimeException() {
+ super();
+ }
+
+ public ScopeRuntimeException(String message) {
+ super(message);
+ }
+
+ public ScopeRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ScopeRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java
new file mode 100644
index 0000000000..b648fc2dcc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import java.util.Map;
+
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implementations provide scope container creation facilities and scope semantics to the runtime
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeStrategy {
+
+ /* Denotes an undefined scope */
+ public static final int SCOPE_NOT_FOUND = -3;
+
+ /**
+ * Creates and returns new instances of configured scope containers
+ */
+ public Map<Scope, ScopeContext> createScopes(EventContext eventContext);
+
+ /**
+ * Determines whether a wire proceeds from a source of higher scope to a target of lesser scope
+ */
+ public boolean downScopeReference(Scope sourceScope, Scope targetScope);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java
new file mode 100644
index 0000000000..253909d7fa
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import org.osoa.sca.ServiceUnavailableException;
+
+/**
+ * Denotes the specific case where a service was not found at runtime
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceNotFoundException extends ServiceUnavailableException {
+
+ public ServiceNotFoundException() {
+ super();
+ }
+
+ public ServiceNotFoundException(String message) {
+ super(message);
+ }
+
+ public ServiceNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ public ServiceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java
new file mode 100644
index 0000000000..d35a3712a0
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * A runtime entity that manages a non-aggregate (i.e. leaf-type) instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SimpleComponentContext extends InstanceContext {
+
+ /**
+ * Returns whether a the context should be eagerly initialized
+ */
+ public boolean isEagerInit();
+
+ /**
+ * Returns whether a the context should be called back when its scope ends
+ */
+ public boolean isDestroyable();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java
new file mode 100644
index 0000000000..afb8499104
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+import org.apache.tuscany.core.config.ConfigurationException;
+
+/**
+ * Marker type for system aggregate contexts
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SystemAggregateContext extends AutowireContext, ScopeAwareContext, ConfigurationContext {
+
+ /**
+ * Register a simple Java Object as a system component.
+ * This is primarily intended for use by bootstrap code to create the initial
+ * configuration components.
+ *
+ * @param name the name of the resulting component
+ * @param instance the Object that will become the component's implementation
+ * @throws ConfigurationException
+ */
+ void registerJavaObject(String name, Object instance) throws ConfigurationException;
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java
new file mode 100644
index 0000000000..dd39d06aa1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context;
+
+/**
+ * Denotes an error while performing an operation on a target component implementation instance or proxy
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetException extends CoreRuntimeException {
+
+ public TargetException() {
+ super();
+ }
+
+ public TargetException(String message) {
+ super(message);
+ }
+
+ public TargetException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java
new file mode 100644
index 0000000000..9ee1878625
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java
@@ -0,0 +1,652 @@
+package org.apache.tuscany.core.context.impl;
+
+import static org.apache.tuscany.core.context.EventContext.HTTP_SESSION;
+import static org.apache.tuscany.core.context.EventContext.REQUEST_END;
+import static org.apache.tuscany.core.context.EventContext.SESSION_NOTIFY;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.wsdl.Part;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.DuplicateNameException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeAwareContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.scope.DefaultScopeStrategy;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyInitializationException;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.system.annotation.ParentContext;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Component;
+import org.apache.tuscany.model.assembly.EntryPoint;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.assembly.ExternalService;
+import org.apache.tuscany.model.assembly.Module;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+
+/**
+ * The base implementation of an aggregate context
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractAggregateContext extends AbstractContext implements AutowireContext, ScopeAwareContext {
+
+ public static final int DEFAULT_WAIT = 1000 * 60;
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // The parent context, if one exists
+ @ParentContext
+ protected AggregateContext parentContext;
+
+ // The parent configuration context, if one exists
+ @Autowire(required = false)
+ protected ConfigurationContext configurationContext;
+
+ // The system monitor factory
+ @Autowire(required = false)
+ protected MonitorFactory monitorFactory;
+
+ // The logical model representing the module assembly
+ // protected ModuleComponent moduleComponent;
+ protected Module module;
+
+ protected Map<String, RuntimeConfiguration<InstanceContext>> configurations = new HashMap();
+
+ // Factory for scope contexts
+ @Autowire(required = false)
+ protected ScopeStrategy scopeStrategy;
+
+ // The event context for associating context events to threads
+ protected EventContext eventContext;
+
+ // The scopes for this context
+ protected Map<Scope, ScopeContext> scopeContexts;
+
+ protected Map<Scope, ScopeContext> immutableScopeContexts;
+
+ // A component context name to scope context index
+ protected Map<String, ScopeContext> scopeIndex;
+
+ // Listeners for context events
+ protected List<RuntimeEventListener> listeners = new CopyOnWriteArrayList();
+
+ // Blocking latch to ensure the module is initialized exactly once prior to servicing requests
+ protected CountDownLatch initializeLatch = new CountDownLatch(1);
+
+ // Indicates whether the module context has been initialized
+ protected boolean initialized;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AbstractAggregateContext() {
+ scopeIndex = new ConcurrentHashMap();
+ // FIXME the factory should be injected
+ module = new AssemblyFactoryImpl().createModule();
+ }
+
+ public AbstractAggregateContext(String name, AggregateContext parent, ScopeStrategy strategy, EventContext ctx,
+ ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name);
+ this.scopeStrategy = strategy;
+ this.eventContext = ctx;
+ this.configurationContext = configCtx;
+ this.monitorFactory = factory;
+ scopeIndex = new ConcurrentHashMap();
+ parentContext = parent;
+ // FIXME the factory should be injected
+ module = new AssemblyFactoryImpl().createModule();
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() {
+ synchronized (initializeLatch) {
+ try {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Context not in UNINITIALIZED state");
+ }
+ lifecycleState = INITIALIZING;
+ initializeScopes();
+
+ Map<Scope, List<RuntimeConfiguration<SimpleComponentContext>>> configurationsByScope = new HashMap();
+ if (configurations != null) {
+ for (RuntimeConfiguration source : configurations.values()) {
+ // FIXME scopes are defined at the interface level
+ Scope sourceScope = source.getScope();
+ wireSource(source);
+ buildTarget(source);
+ scopeIndex.put(source.getName(), scopeContexts.get(sourceScope));
+ List<RuntimeConfiguration<SimpleComponentContext>> list = configurationsByScope.get(sourceScope);
+ if (list == null) {
+ list = new ArrayList();
+ configurationsByScope.put(sourceScope, list);
+ }
+ list.add(source);
+ }
+ }
+ for (EntryPoint ep : module.getEntryPoints()) {
+ registerAutowire(ep);
+ }
+ for (Component component : module.getComponents()) {
+ registerAutowire(component);
+ }
+ for (ExternalService es : module.getExternalServices()) {
+ registerAutowire(es);
+ }
+ for (Map.Entry entries : configurationsByScope.entrySet()) {
+ // register configurations with scope contexts
+ ScopeContext scope = scopeContexts.get(entries.getKey());
+ scope.registerConfigurations((List<RuntimeConfiguration<InstanceContext>>) entries.getValue());
+ }
+ initializeProxies();
+ for (ScopeContext scope : scopeContexts.values()) {
+ // register scope contexts as a listeners for events in the aggregate context
+ registerListener(scope);
+ scope.start();
+ }
+ lifecycleState = RUNNING;
+ } catch (ProxyInitializationException e) {
+ lifecycleState = ERROR;
+ ContextInitException cie = new ContextInitException(e);
+ cie.addContextName(getName());
+ throw cie;
+ } catch (ConfigurationException e) {
+ lifecycleState = ERROR;
+ throw new ContextInitException(e);
+ } catch (CoreRuntimeException e) {
+ lifecycleState = ERROR;
+ e.addContextName(getName());
+ throw e;
+ } finally {
+ initialized = true;
+ // release the latch and allow requests to be processed
+ initializeLatch.countDown();
+ }
+ }
+ }
+
+ public void stop() {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+ // need to block a start until reset is complete
+ initializeLatch = new CountDownLatch(2);
+ lifecycleState = STOPPING;
+ initialized = false;
+ if (scopeContexts != null) {
+ for (ScopeContext scope : scopeContexts.values()) {
+ try {
+ if (scope.getLifecycleState() == ScopeContext.RUNNING) {
+ scope.stop();
+ }
+ } catch (ScopeRuntimeException e) {
+ // log.error("Error stopping scope container [" + scopeContainers[i].getName() + "]", e);
+ }
+ }
+ }
+ scopeContexts = null;
+ scopeIndex.clear();
+ // allow initialized to be called
+ initializeLatch.countDown();
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void setModule(Module module) {
+ assert (module != null) : "Module cannot be null";
+ name = module.getName();
+ this.module = module;
+ }
+
+ public void setScopeStrategy(ScopeStrategy scopeStrategy) {
+ this.scopeStrategy = scopeStrategy;
+ }
+
+ public void setEventContext(EventContext eventContext) {
+ this.eventContext = eventContext;
+ }
+
+ public void setMonitorFactory(MonitorFactory factory) {
+ this.monitorFactory = factory;
+ }
+
+ public AggregateContext getParent() {
+ return parentContext;
+ }
+
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException {
+ assert (models != null) : "Model object collection was null";
+ for (Extensible model : models) {
+ registerModelObject(model);
+ }
+ }
+
+ public void registerModelObject(Extensible model) throws ConfigurationException {
+ assert (model != null) : "Model object was null";
+ initializeScopes();
+ if (configurationContext != null) {
+ try {
+ configurationContext.configure(model);
+ configurationContext.build(this, model);
+ } catch (ConfigurationException e) {
+ e.addContextName(getName());
+ throw e;
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ RuntimeConfiguration<InstanceContext> configuration = null;
+ if (model instanceof Module) {
+ // merge new module definition with the existing one
+ Module oldModule = module;
+ Module newModule = (Module) model;
+ module = newModule;
+ for (Component component : newModule.getComponents()) {
+ ComponentImplementation componentImplementation = component.getComponentImplementation();
+ if (componentImplementation == null) {
+ ConfigurationException e = new ConfigurationException("Component implementation not set");
+ e.addContextName(component.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ configuration = (RuntimeConfiguration<InstanceContext>) componentImplementation.getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.addContextName(component.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(component);
+ }
+ for (EntryPoint ep : newModule.getEntryPoints()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(ep.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(ep);
+ }
+ for (ExternalService service : newModule.getExternalServices()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(service.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(service);
+ }
+ if (lifecycleState == RUNNING) {
+ for (Component component : newModule.getComponents()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) component
+ .getComponentImplementation().getRuntimeConfiguration();
+ wireSource(config);
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+ for (EntryPoint ep : newModule.getEntryPoints()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) ep
+ .getConfiguredReference().getRuntimeConfiguration();
+ wireSource(config);
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+ for (ExternalService es : newModule.getExternalServices()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) es
+ .getConfiguredService().getRuntimeConfiguration();
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+
+ }
+ // merge existing module component assets
+ module.getComponents().addAll(oldModule.getComponents());
+ module.getEntryPoints().addAll(oldModule.getEntryPoints());
+ module.getExternalServices().addAll(oldModule.getExternalServices());
+ } else {
+ if (model instanceof Component) {
+ Component component = (Component) model;
+ module.getComponents().add(component);
+ configuration = (RuntimeConfiguration<InstanceContext>) component.getComponentImplementation()
+ .getRuntimeConfiguration();
+ } else if (model instanceof EntryPoint) {
+ EntryPoint ep = (EntryPoint) model;
+ module.getEntryPoints().add(ep);
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ } else if (model instanceof ExternalService) {
+ ExternalService service = (ExternalService) model;
+ module.getExternalServices().add(service);
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ } else {
+ BuilderConfigException e = new BuilderConfigException("Unknown model type");
+ e.setIdentifier(model.getClass().getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ if (model instanceof Part) {
+ e.setIdentifier(((Part) model).getName());
+ }
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(model);
+ }
+ }
+
+ protected void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) throws ConfigurationException {
+ if (lifecycleState == RUNNING) {
+ if (scopeIndex.get(configuration.getName()) != null) {
+ throw new DuplicateNameException(configuration.getName());
+ }
+ ScopeContext scope = scopeContexts.get(configuration.getScope());
+ if (scope == null) {
+ ConfigurationException e = new ConfigurationException("Component has an unknown scope");
+ e.addContextName(configuration.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ scope.registerConfiguration(configuration);
+ scopeIndex.put(configuration.getName(), scope);
+ configurations.put(configuration.getName(), configuration); // xcv
+ } else {
+ if (configurations.get(configuration.getName()) != null) {
+ throw new DuplicateNameException(configuration.getName());
+ }
+ configurations.put(configuration.getName(), configuration);
+ }
+
+ }
+
+ public void registerListener(RuntimeEventListener listener) {
+ assert (listener != null) : "Listener cannot be null";
+ listeners.add(listener);
+ }
+
+ public void fireEvent(int eventType, Object message) throws EventException {
+ checkInit();
+ if (eventType == SESSION_NOTIFY) {
+ // update context
+ eventContext.setIdentifier(HTTP_SESSION, message);
+ } else if (eventType == REQUEST_END) {
+ // be very careful with pooled threads, ensuring threadlocals are cleaned up
+ eventContext.clearIdentifier(HTTP_SESSION);
+ }
+ for (RuntimeEventListener listener : listeners) {
+ listener.onEvent(eventType, message);
+ }
+ }
+
+ public InstanceContext getContext(String componentName) {
+ checkInit();
+ assert (componentName != null) : "Name was null";
+ ScopeContext scope = scopeIndex.get(componentName);
+ if (scope == null) {
+ return null;
+ }
+ return scope.getContext(componentName);
+
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ assert (qName != null) : "Name was null ";
+ // use the port name to get the context since entry points ports
+ ScopeContext scope = scopeIndex.get(qName.getPortName());
+ if (scope == null) {
+ return null;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPortName());
+ if (!(ctx instanceof EntryPointContext)) {
+ TargetException e = new TargetException("Target not an entry point");
+ e.setIdentifier(qName.getQualifiedName());
+ e.addContextName(name);
+ throw e;
+ }
+ return ctx.getInstance(null, notify);
+ }
+
+ public Object locateInstance(String qualifiedName) throws TargetException {
+ checkInit();
+ QualifiedName qName = new QualifiedName(qualifiedName);
+ ScopeContext scope = scopeIndex.get(qName.getPartName());
+ if (scope == null) {
+ TargetException e = new TargetException("Component not found");
+ e.setIdentifier(qualifiedName);
+ e.addContextName(getName());
+ throw e;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPartName());
+ try {
+ return ctx.getInstance(qName, true);
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+
+ public Map<Scope, ScopeContext> getScopeContexts() {
+ initializeScopes();
+ return immutableScopeContexts;
+ }
+
+ // ----------------------------------
+ // Abstract methods
+ // ----------------------------------
+
+ /**
+ * Registers a model object as autowirable
+ *
+ * @throws ContextInitException
+ */
+ protected abstract void registerAutowire(Extensible model) throws ConfigurationException;
+
+ // ----------------------------------
+ // Protected methods
+ // ----------------------------------
+
+ /**
+ * Blocks until the module context has been initialized
+ */
+ protected void checkInit() {
+ if (!initialized) {
+ try {
+ /* block until the module has initialized */
+ boolean success = initializeLatch.await(DEFAULT_WAIT, TimeUnit.MILLISECONDS);
+ if (!success) {
+ throw new ContextInitException("Timeout waiting for module context to initialize");
+ }
+ } catch (InterruptedException e) { // should not happen
+ }
+ }
+
+ }
+
+ protected void initializeScopes() {
+ if (scopeContexts == null) {
+ if (scopeStrategy == null) {
+ scopeStrategy = new DefaultScopeStrategy();
+ }
+ scopeContexts = scopeStrategy.createScopes(eventContext);
+ immutableScopeContexts = Collections.unmodifiableMap(scopeContexts);
+ }
+ }
+
+ /**
+ * Iterates through references and delegates to the configuration context to wire them to their targets
+ */
+ protected void wireSource(RuntimeConfiguration source) {
+ Scope sourceScope = source.getScope();
+ if (source.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceFactory : ((Map<String, ProxyFactory>) source.getSourceProxyFactories()).values()) {
+ QualifiedName targetName = sourceFactory.getProxyConfiguration().getTargetName();
+ RuntimeConfiguration target = configurations.get(targetName.getPartName());
+ if (target == null) {
+ ContextInitException e = new ContextInitException("Target not found");
+ e.setIdentifier(targetName.getPartName());
+ e.addContextName(source.getName());
+ e.addContextName(name);
+ throw e;
+ }
+ // get the proxy chain for the target
+ ProxyFactory targetFactory = target.getTargetProxyFactory(sourceFactory.getProxyConfiguration().getTargetName()
+ .getPortName());
+ if (targetFactory == null) {
+ ContextInitException e = new ContextInitException("No proxy factory found for service");
+ e.setIdentifier(sourceFactory.getProxyConfiguration().getTargetName().getPortName());
+ e.addContextName(target.getName());
+ e.addContextName(source.getName());
+ e.addContextName(name);
+ throw e;
+ }
+ boolean downScope = scopeStrategy.downScopeReference(sourceScope, target.getScope());
+ configurationContext.wire(sourceFactory, targetFactory, target.getClass(), downScope, scopeContexts.get(target
+ .getScope()));
+ }
+ }
+ // wire invokers when the proxy only contains the target chain
+ if (source.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetFactory : ((Map<String, ProxyFactory>) source.getTargetProxyFactories()).values()) {
+ configurationContext.wire(targetFactory, source.getClass(), scopeContexts.get(sourceScope));
+ }
+ }
+ source.prepare();
+ }
+
+ /**
+ * Signals to target side of reference configurations to initialize
+ */
+ protected void buildTarget(RuntimeConfiguration target) {
+ if (target.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetFactory : ((Map<String, ProxyFactory>) target.getTargetProxyFactories()).values()) {
+ for (InvocationConfiguration iConfig : (Collection<InvocationConfiguration>) targetFactory
+ .getProxyConfiguration().getInvocationConfigurations().values()) {
+ iConfig.build();
+ }
+ }
+ }
+ }
+
+ protected void initializeProxies() throws ProxyInitializationException {
+ for (RuntimeConfiguration config : configurations.values()) {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories().values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories().values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.core.context.AggregateContext#getAggregate()
+ */
+ public Aggregate getAggregate() {
+ return module;
+ }
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java
new file mode 100644
index 0000000000..69e0b8edfc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java
@@ -0,0 +1,222 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.impl;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.AutowireResolutionException;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.core.context.ServiceNotFoundException;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceUnavailableException;
+
+/**
+ * The standard implementation of an aggregate context. Autowiring is performed by delegating to the parent context.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AggregateContextImpl extends AbstractAggregateContext implements ConfigurationContext, ModuleContext {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ @Autowire(required = false)
+ private AutowireContext autowireContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AggregateContextImpl() {
+ super();
+ eventContext = new EventContextImpl();
+ }
+
+ public AggregateContextImpl(String name, AggregateContext parent, ScopeStrategy strategy, EventContext ctx,
+ ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name, parent, strategy, ctx, configCtx, factory);
+ }
+
+ public AggregateContextImpl(String name, AggregateContext parent, AutowireContext autowireContext, ScopeStrategy strategy,
+ EventContext ctx, ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name, parent, strategy, ctx, configCtx, factory);
+ this.autowireContext = autowireContext;
+ }
+
+ // ----------------------------------
+ // ModuleContext methods
+ // ----------------------------------
+
+ private String uri;
+
+ public String getURI() {
+ return uri;
+ }
+
+ public void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ public Object locateService(String qualifiedName) throws ServiceUnavailableException {
+ checkInit();
+ QualifiedName qName = new QualifiedName(qualifiedName);
+ ScopeContext scope = scopeIndex.get(qName.getPartName());
+ if (scope == null) {
+ throw new ServiceNotFoundException(qualifiedName);
+ }
+ InstanceContext ctx = scope.getContext(qName.getPartName());
+ try {
+ Object o = ctx.getInstance(qName, true);
+ if (o == null) {
+ throw new ServiceUnavailableException(qualifiedName);
+ }
+ return o;
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw new ServiceUnavailableException(e);
+ }
+ }
+
+ public ServiceReference createServiceReference(String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public RequestContext getRequestContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object self) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object self, String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String serviceName, Object sessionId) {
+ throw new UnsupportedOperationException();
+ }
+
+ // ----------------------------------
+ // AutowireContext methods
+ // ----------------------------------
+
+ public <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException {
+ if (MonitorFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(monitorFactory);
+ } else if (ConfigurationContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (AutowireContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ }
+ if (autowireContext != null) {
+ try {
+ return autowireContext.resolveInstance(instanceInterface);
+ } catch (AutowireResolutionException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void registerAutowire(Extensible model) {
+ // this context only delegates autowiring
+ }
+
+ // ----------------------------------
+ // ConfigurationContext methods
+ // ----------------------------------
+
+ public void configure(Extensible model) throws ConfigurationException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.configure(model);
+ } catch (ConfigurationException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void build(AggregateContext parent, Extensible model) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.build(parent, model);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(sourceFactory, targetFactory, targetType, downScope, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(targetFactory, targetType, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return this;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java
new file mode 100644
index 0000000000..791ce6b8a5
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java
@@ -0,0 +1,112 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context.impl;
+
+import java.lang.reflect.InvocationHandler;
+
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.jdk.JDKInvocationHandler;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.message.MessageFactory;
+
+/**
+ * The default implementation of an entry point context
+ *
+ * @version $Rev$ $Date$
+ */
+public class EntryPointContextImpl extends AbstractContext implements EntryPointContext {
+
+ private MessageFactory messageFactory;
+
+ private ProxyFactory proxyFactory;
+
+ private Object target;
+
+ private InvocationHandler invocationHandler;
+
+ // a proxy implementing the service exposed by the entry point backed by the invocation handler
+ private Object proxy;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates a new entry point
+ *
+ * @param name the entry point name
+ * @param proxyFactory the proxy factory containing the invocation chains for the entry point
+ * @param parentContext the containing aggregate of the entry point
+ * @param messageFactory a factory for generating invocation messages
+ * @throws ContextInitException if an error occurs creating the entry point
+ */
+ public EntryPointContextImpl(String name, ProxyFactory proxyFactory, MessageFactory messageFactory)
+ throws ContextInitException {
+ super(name);
+ assert (proxyFactory != null) : "Proxy factory was null";
+ assert (messageFactory != null) : "Message factory was null";
+ this.proxyFactory = proxyFactory;
+ this.messageFactory = messageFactory;
+ invocationHandler = new JDKInvocationHandler(messageFactory, proxyFactory.getProxyConfiguration()
+ .getInvocationConfigurations());
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ if (proxy == null) {
+ try {
+ proxy = proxyFactory.createProxy();
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException(e);
+ te.addContextName(getName());
+ throw te;
+ }
+ }
+ return proxy;
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public void start() throws ContextInitException {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return invocationHandler;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return getImplementationInstance();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java
new file mode 100644
index 0000000000..accf6b3030
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java
@@ -0,0 +1,77 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeIdentifier;
+
+/**
+ * An implementation of an {@link org.apache.tuscany.core.context.EventContext} that handles event-to-thread associations using an
+ * <code>InheritableThreadLocal</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class EventContextImpl implements EventContext {
+
+ // @TODO design a proper propagation strategy for creating new threads
+ /*
+ * a map ( associated with the current thread) of scope identifiers keyed on the event context id type. the scope identifier
+ * may be a {@link ScopeIdentifier} or an opaque id
+ */
+ private ThreadLocal<Map> eventContext = new InheritableThreadLocal();
+
+ public Object getIdentifier(Object type) {
+ Map map = eventContext.get();
+ if (map == null) {
+ return null;
+ }
+ Object currentId = map.get(type);
+ if (currentId instanceof ScopeIdentifier) {
+ currentId = ((ScopeIdentifier) currentId).getIdentifier();
+ // once we have accessed the id, replace the lazy wrapper
+ map.put(type, currentId);
+ }
+ return currentId;
+ }
+
+ public void setIdentifier(Object type, Object identifier) {
+ Map map = eventContext.get();
+ if (map == null) {
+ map = new HashMap();
+ eventContext.set(map);
+ }
+ map.put(type, identifier);
+ }
+
+ public void clearIdentifier(Object type) {
+ if (type == null) {
+ return;
+ }
+ Map map = eventContext.get();
+ if (map != null) {
+ map.remove(type);
+ }
+ }
+
+ public EventContextImpl() {
+ super();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java
new file mode 100644
index 0000000000..a73081ef66
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context.impl;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.ExternalServiceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+/**
+ * The default implementation of an external service context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExternalServiceContextImpl extends AbstractContext implements ExternalServiceContext {
+
+ private ProxyFactory targetProxyFactory;
+
+ private ObjectFactory targetInstanceFactory;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates an external service context
+ *
+ * @param name the name of the external service
+ * @param targetProxyFactory the factory which creates proxies implementing the configured service interface for the
+ * external service. There is always only one proxy factory as an external service is configured with one
+ * service
+ * @param targetInstanceFactory the object factory that creates an artifact capabile of communicating over the
+ * binding transport configured on the external service. The object factory may implement a caching strategy.
+ */
+ public ExternalServiceContextImpl(String name, ProxyFactory targetProxyFactory, ObjectFactory targetInstanceFactory) {
+ super(name);
+ assert (targetProxyFactory != null) : "Target proxy factory was null";
+ assert (targetInstanceFactory != null) : "Target instance factory was null";
+ this.targetProxyFactory = targetProxyFactory;
+ this.targetInstanceFactory = targetInstanceFactory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ try {
+ return targetProxyFactory.createProxy();
+ // TODO do we cache the proxy, (assumes stateful capabilities will be provided in an interceptor)
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException(e);
+ te.addContextName(getName());
+ throw te;
+ }
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public void start() throws CoreRuntimeException {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ lifecycleState = STOPPED;
+ }
+
+ public Object getImplementationInstance() throws TargetException {
+ return targetInstanceFactory.getInstance();
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return getImplementationInstance();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
new file mode 100644
index 0000000000..449af4bdf8
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
@@ -0,0 +1,158 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * Implements functionality common to scope contexts.
+ * <p>
+ * <b>NB: </b>Minimal synchronization is performed, particularly for initializing and destroying scopes, and it is
+ * assumed the scope container will block requests until these operations have completed.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContext extends AbstractContext implements ScopeContext{
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // The collection of runtime configurations for the scope
+ protected Map<String, RuntimeConfiguration<InstanceContext>> runtimeConfigurations = new ConcurrentHashMap();
+
+ // The event context the scope container is associated with
+ protected EventContext eventContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AbstractScopeContext(EventContext eventContext) {
+ assert (eventContext != null) : "Event context was null";
+ this.eventContext = eventContext;
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // --------------------------_--------
+
+ public synchronized void start() {
+ }
+
+ public synchronized void stop() {
+ }
+
+
+ // ----------------------------------
+ // Scope methods
+ // ----------------------------------
+
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations) {
+ for (RuntimeConfiguration<InstanceContext> configuration : configurations) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ Object instance = null;
+ InstanceContext context = getContext(qName.getPartName());
+ if (context == null) {
+ TargetException e = new TargetException("Target not found");
+ e.setIdentifier(qName.getQualifiedName());
+ throw e;
+ }
+ return context.getInstance(qName);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ //----------------------------------
+ // InstanceContext methods
+ //----------------------------------
+
+ public Object getImplementationInstance() throws TargetException{
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException{
+ return this;
+ }
+
+ // ----------------------------------
+ // Protected methods
+ // ----------------------------------
+
+ protected EventContext getEventContext() {
+ return eventContext;
+ }
+
+ /**
+ * Notfies instances that are associated with a context and configured to receive callbacks that the context is
+ * being destroyed in reverse order
+ *
+ * @param key the context key
+ */
+ protected void notifyInstanceShutdown(Object key) {
+ InstanceContext[] contexts = getShutdownContexts(key);
+ if ((contexts == null) || (contexts.length < 1)) {
+ return;
+ }
+ // shutdown destroyable instances in reverse instantiation order
+ for (int i = contexts.length - 1; i >= 0; i--) {
+ InstanceContext context = contexts[i];
+
+ if (context.getLifecycleState() == Context.RUNNING) {
+ synchronized (context) {
+ context.setLifecycleState(Context.STOPPING);
+ removeContextByKey(context.getName(), key);
+ try {
+ context.stop();
+ } catch (TargetException e) {
+ // TODO send a monitoring event
+ // log.error("Error releasing instance [" + context.getName() + "]",e);
+ }
+ }
+ }
+ }
+ }
+
+ protected void checkInit() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not running [" + lifecycleState + "]");
+ }
+ }
+
+ /**
+ * Returns an array of contexts that need to be notified of scope shutdown. The array must be in the order in which
+ * component contexts were created
+ */
+ protected abstract InstanceContext[] getShutdownContexts(Object key);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java
new file mode 100644
index 0000000000..f89d09196d
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java
@@ -0,0 +1,67 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements basic scope strategy functionality
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeStrategy implements ScopeStrategy {
+
+ public AbstractScopeStrategy() {
+ }
+
+ /**
+ * Determines legal scope references according to standard SCA scope rules
+ *
+ * @param pReferrer the scope of the component making the reference
+ * @param pReferee the scope of the component being referred to
+ */
+ public boolean downScopeReference(Scope pReferrer, Scope pReferee) {
+ if (pReferrer == Scope.UNDEFINED || pReferee == Scope.UNDEFINED) {
+ return false;
+ }
+ if (pReferee == pReferrer){
+ return false;
+ }else if(pReferrer == Scope.INSTANCE){
+ return false;
+ }else if(pReferee == Scope.INSTANCE){
+ return true;
+ }else if (pReferrer == Scope.REQUEST && pReferee == Scope.SESSION){
+ return false;
+ }else if (pReferrer == Scope.REQUEST && pReferee == Scope.MODULE){
+ return false;
+// }else if (pReferrer == Scope.SESSION && pReferee == Scope.REQUEST){
+// return true;
+ }else if (pReferrer == Scope.SESSION && pReferee == Scope.MODULE){
+ return false;
+// }else if (pReferrer == Scope.MODULE){
+// return true;
+ }else{
+ return true;
+ }
+ //FIXME Jim this does not work with enumerations, what does it mean to have a scope <0?
+// } else if ((pReferrer < 0) || (pReferee < 0)) {
+// return false;
+// }
+//
+// return (pReferrer > pReferee);
+// return pReferrer != pReferee;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java
new file mode 100644
index 0000000000..19f554a625
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java
@@ -0,0 +1,184 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeInitializationException;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * Manages the lifecycle of aggregate component contexts, i.e. contexts which contain child contexts
+ *
+ * @see org.apache.tuscany.core.context.AggregateContext
+ * @version $Rev$ $Date$
+ */
+public class AggregateScopeContext extends AbstractContext implements ScopeContext {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ private EventContext eventContext;
+
+ private List<RuntimeConfiguration<InstanceContext>> configs = new ArrayList();
+
+ // Aggregate component contexts in this scope keyed by name
+ private Map<String, AggregateContext> contexts = new ConcurrentHashMap();
+
+ // indicates if a module start event has been previously propagated so child contexts added after can be notified
+ private boolean moduleScopeStarted;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AggregateScopeContext(EventContext eventContext) {
+ assert (eventContext != null) : "Event context was null";
+ this.eventContext = eventContext;
+ name = "Aggregate Scope";
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() throws ScopeInitializationException {
+ for (RuntimeConfiguration<InstanceContext> configuration : configs) {
+ InstanceContext context = configuration.createInstanceContext();
+ if (!(context instanceof AggregateContext)) {
+ ScopeInitializationException e = new ScopeInitializationException("Context not an aggregate type");
+ e.addContextName(context.getName());
+ throw e;
+ }
+ AggregateContext aggregateCtx = (AggregateContext) context;
+ aggregateCtx.start();
+ contexts.put(aggregateCtx.getName(), aggregateCtx);
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws ScopeRuntimeException {
+ for (AggregateContext context : contexts.values()) {
+ context.stop();
+ }
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations) {
+ this.configs = configurations;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ assert (configuration != null) : "Configuration was null";
+ configs.add(configuration);
+ if (lifecycleState == RUNNING) {
+ InstanceContext context = configuration.createInstanceContext();
+ if (!(context instanceof AggregateContext)) {
+ ScopeInitializationException e = new ScopeInitializationException("Context not an aggregate type");
+ e.setIdentifier(context.getName());
+ throw e;
+ }
+ AggregateContext aggregateCtx = (AggregateContext) context;
+ aggregateCtx.start();
+ if (moduleScopeStarted) {
+ aggregateCtx.fireEvent(EventContext.MODULE_START, null);
+ }
+ contexts.put(aggregateCtx.getName(), aggregateCtx);
+ }
+ }
+
+ public boolean isCacheable() {
+ return false;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ Object instance = null;
+ InstanceContext context = getContext(qName.getPartName());
+ if (context == null) {
+ TargetException e = new TargetException("Component not found");
+ e.setIdentifier(qName.getQualifiedName());
+ throw e;
+ }
+ return context.getInstance(qName);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ return contexts.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ return getContext(ctxName);
+ }
+
+ public void removeContext(String ctxName) throws ScopeRuntimeException {
+ InstanceContext context = contexts.remove(ctxName);
+ if (context != null) {
+ context.stop();
+ }
+ }
+
+ public void removeContextByKey(String ctxName, Object key) throws ScopeRuntimeException {
+ }
+
+ public void onEvent(int type, Object message) throws EventException {
+ if (type == EventContext.MODULE_START) {
+ // track module starting so that aggregate contexts registered after the event are notified properly
+ moduleScopeStarted = true;
+ } else if (type == EventContext.MODULE_STOP) {
+ moduleScopeStarted = false;
+ }
+ // propagate events to child contexts
+ for (AggregateContext context : contexts.values()) {
+ context.fireEvent(type, message);
+ }
+ }
+
+ public Object getImplementationInstance() throws TargetException{
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException{
+ return this;
+ }
+
+ private void checkInit() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not running [" + lifecycleState + "]");
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java
new file mode 100644
index 0000000000..509eb7941f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements a {@link org.apache.tuscany.core.context.ScopeStrategy} for the default module scopes: stateless, request, session,
+ * and module.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultScopeStrategy extends AbstractScopeStrategy {
+
+ public DefaultScopeStrategy() {
+ }
+
+ public Map<Scope,ScopeContext> createScopes(EventContext eventContext) {
+ ScopeContext moduleScope = new ModuleScopeContext(eventContext);
+ ScopeContext sessionScope = new HttpSessionScopeContext(eventContext);
+ ScopeContext requestScope = new RequestScopeContext(eventContext);
+ ScopeContext statelessScope = new StatelessScopeContext(eventContext);
+ ScopeContext aggregrateScope = new AggregateScopeContext(eventContext);
+ Map<Scope,ScopeContext> scopes = new HashMap();
+ scopes.put(Scope.MODULE,moduleScope);
+ scopes.put(Scope.SESSION,sessionScope);
+ scopes.put(Scope.REQUEST,requestScope);
+ scopes.put(Scope.INSTANCE,statelessScope);
+ scopes.put(Scope.AGGREGATE,aggregrateScope);
+ return scopes;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java
new file mode 100644
index 0000000000..e1fcc4ab70
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java
@@ -0,0 +1,254 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * An implementation of an HTTP session-scoped component container where each HTTP session is mapped to a context in the scope
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // The collection of service component contexts keyed by session
+ private Map<Object, Map<String, InstanceContext>> contexts;
+
+ // Stores ordered lists of contexts to shutdown keyed by session
+ private Map<Object, Queue<InstanceContext>> destroyableContexts;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public HttpSessionScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Http Session Scope");
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope container must be in UNINITIALIZED state");
+ }
+ super.start();
+ contexts = new ConcurrentHashMap();
+ destroyableContexts = new ConcurrentHashMap();
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope container in wrong state");
+ }
+ super.stop();
+ contexts = null;
+ contexts = null;
+ destroyableContexts = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ checkInit();
+ if (key == null) {
+ return;
+ }
+ if (type == EventContext.SESSION_END) {
+ notifyInstanceShutdown(key);
+ destroyComponentContext(key);
+ }
+ }
+
+ // ----------------------------------
+ // Scope methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ if (ctxName == null) {
+ return null;
+ }
+ // try{
+ Map<String, InstanceContext> ctxs = getSessionContext();
+ if (ctxs == null) {
+ return null;
+ }
+ InstanceContext ctx = ctxs.get(ctxName);
+ if (ctx == null) {
+ // the configuration was added after the session had started, so create a context now and start it
+ RuntimeConfiguration<InstanceContext> configuration = runtimeConfigurations.get(ctxName);
+ if (configuration != null) {
+ ctx = configuration.createInstanceContext();
+ ctx.addContextListener(this);
+ ctx.start();
+ ctxs.put(ctx.getName(), ctx);
+ }
+ }
+ return ctx;
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null && ctxName == null) {
+ return null;
+ }
+ Map components = (Map) contexts.get(key);
+ if (components == null) {
+ return null;
+ }
+ return (InstanceContext) components.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ removeContextByKey(ctxName, key);
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null || ctxName == null) {
+ return;
+ }
+ Map components = (Map) contexts.get(key);
+ if (components == null) {
+ return;
+ }
+ components.remove(ctxName);
+ Map definitions = contexts.get(key);
+ InstanceContext meta = (InstanceContext) definitions.get(ctxName);
+ destroyableContexts.get(key).remove(meta);
+ definitions.remove(ctxName);
+ }
+
+ public void onInstanceCreate(Context context) throws ScopeRuntimeException {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ // if destroyable, queue the context to have its component implementation instance released
+ if (((SimpleComponentContext) context).isDestroyable()) {
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ Queue comps = destroyableContexts.get(key);
+ if (comps == null) {
+ ScopeRuntimeException e = new ScopeRuntimeException("Shutdown queue not found for key");
+ e.setIdentifier(key.toString());
+ throw e;
+ }
+ comps.add(context);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown or
+ * null if none found.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ /*
+ * This method will be called from the Listener which is associated with a different thread than the request. So, just
+ * grab the key directly
+ */
+ Queue queue = destroyableContexts.get(key);
+ if (queue != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) queue.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ /**
+ * Returns and, if necessary, creates a context for the current sesion
+ */
+ private Map<String, InstanceContext> getSessionContext() throws CoreRuntimeException {
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ if (key == null) {
+ throw new ScopeRuntimeException("Session key not set in request context");
+ }
+ Map m = contexts.get(key);
+ if (m != null) {
+ return m; // already created, return
+ }
+ Map<String, InstanceContext> sessionContext = new ConcurrentHashMap(runtimeConfigurations.size());
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ sessionContext.put(context.getName(), context);
+ }
+
+ Queue shutdownQueue = new ConcurrentLinkedQueue();
+ contexts.put(key, sessionContext);
+ destroyableContexts.put(key, shutdownQueue);
+ // initialize eager components. Note this cannot be done when we initially create each context since a component may
+ // contain a forward reference to a component which has not been instantiated
+ for (InstanceContext context : sessionContext.values()) {
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext simpleCtx = (SimpleComponentContext) context;
+ if (simpleCtx.isEagerInit()) {
+ // Get the instance and perform manual shutdown registration to avoid a map lookup
+ context.getInstance(null, false);
+ if (simpleCtx.isDestroyable()) {
+ shutdownQueue.add(context);
+ }
+ }
+ }
+ }
+ return sessionContext;
+ }
+
+ /**
+ * Removes the components associated with an expiring context
+ */
+ private void destroyComponentContext(Object key) {
+ contexts.remove(key);
+ destroyableContexts.remove(key);
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
new file mode 100644
index 0000000000..00f2747fae
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
@@ -0,0 +1,182 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * Manages component contexts whose implementations are module scoped
+ *
+ * @version $Rev$ $Date$
+ */
+public class ModuleScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // Component contexts in this scope keyed by name
+ private Map<String, InstanceContext> componentContexts;
+
+ private Queue<SimpleComponentContext> destroyableContexts;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public ModuleScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Module Scope");
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ if (type == EventContext.MODULE_START) {
+ lifecycleState = RUNNING;
+ initComponentContexts();
+ } else if (type == EventContext.MODULE_STOP) {
+ notifyInstanceShutdown(key);
+ }
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ componentContexts = null;
+ destroyableContexts = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ if (lifecycleState == RUNNING) {
+ componentContexts.put(configuration.getName(), configuration.createInstanceContext());
+ }
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ return componentContexts.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ return componentContexts.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ Object component = componentContexts.remove(ctxName);
+ if (component != null) {
+ destroyableContexts.remove(component);
+ }
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ removeContext(ctxName);
+ }
+
+ public void onInstanceCreate(Context context) {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext serviceContext = (SimpleComponentContext) context;
+ // Queue the context to have its implementation instance released if destroyable
+ if (serviceContext.isDestroyable()) {
+ destroyableContexts.add(serviceContext);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ if (destroyableContexts != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) destroyableContexts.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ private synchronized void initComponentContexts() throws CoreRuntimeException {
+ if (componentContexts == null) {
+ componentContexts = new ConcurrentHashMap();
+ destroyableContexts = new ConcurrentLinkedQueue();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ componentContexts.put(context.getName(), context);
+ }
+ // Initialize eager contexts. Note this cannot be done when we initially create each context since a component may
+ // contain a forward reference to a component which has not been instantiated
+ for (InstanceContext context : componentContexts.values()) {
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext simpleCtx = (SimpleComponentContext) context;
+ if (simpleCtx.isEagerInit()) {
+ // perform silent creation and manual shutdown registration
+ simpleCtx.getInstance(null, false);
+ if (simpleCtx.isDestroyable()) {
+ destroyableContexts.add(simpleCtx);
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
new file mode 100644
index 0000000000..deed3e2dee
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
@@ -0,0 +1,224 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * An implementation of a request-scoped component container.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // A collection of service component contexts keyed by thread. Note this could have been implemented with a ThreadLocal but
+ // using a Map allows finer-grained concurrency.
+ private Map<Object, Map<String, InstanceContext>> contextMap;
+
+ // stores ordered lists of contexts to shutdown for each thread.
+ private Map<Object, Queue> destroyComponents;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public RequestScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Request Scope");
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ checkInit();
+ /* clean up current context for pooled threads */
+ if (type == EventContext.REQUEST_END) {
+ getEventContext().clearIdentifier(EventContext.HTTP_SESSION);
+ notifyInstanceShutdown(Thread.currentThread());
+ destroyContext();
+ }
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ super.start();
+ contextMap = new ConcurrentHashMap();
+ destroyComponents = new ConcurrentHashMap();
+ lifecycleState = RUNNING;
+
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ contextMap = null;
+ destroyComponents = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ Map<String, InstanceContext> contexts = getComponentContexts();
+ InstanceContext ctx = contexts.get(ctxName);
+ if (ctx == null){
+ // check to see if the configuration was added after the request was started
+ RuntimeConfiguration<InstanceContext> configuration = runtimeConfigurations.get(ctxName);
+ if (configuration != null) {
+ ctx = configuration.createInstanceContext();
+ ctx.addContextListener(this);
+ ctx.start();
+ contexts.put(ctx.getName(), ctx);
+ }
+ }
+ return ctx;
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null) {
+ return null;
+ }
+ Map<String, InstanceContext> components = (Map) contextMap.get(key);
+ if (components == null) {
+ return null;
+ }
+ return components.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ removeContextByKey(ctxName, Thread.currentThread());
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null || ctxName == null) {
+ return;
+ }
+ Map components = (Map) contextMap.get(key);
+ if (components == null) {
+ return;
+ }
+ components.remove(ctxName);
+ Map<String, InstanceContext> contexts = (Map) contextMap.get(key);
+ // no synchronization for the following two operations since the request
+ // context will not be shutdown before the second call is processed
+ InstanceContext context = contexts.get(ctxName);
+ destroyComponents.get(key).remove(context);
+ }
+
+ public void onInstanceCreate(Context context) {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ // Queue the context to have its implementation instance released if destroyable
+ if (((SimpleComponentContext) context).isDestroyable()) {
+ Queue collection = destroyComponents.get(Thread.currentThread());
+ collection.add(context);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ checkInit();
+ Queue queue = destroyComponents.get(Thread.currentThread());
+ if (queue != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) queue.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ private void destroyContext() {
+ // TODO uninitialize all request-scoped components
+ contextMap.remove(Thread.currentThread());
+ destroyComponents.remove(Thread.currentThread());
+ }
+
+ /**
+ * Initializes ServiceComponentContexts for the current request.
+ * <p>
+ * TODO This eagerly creates all component contexts, even if the component is never accessed during the request. This method
+ * should be profiled to determine if lazy initialization is more performant
+ * <p>
+ * TODO Eager initialization is not performed for request-scoped components
+ */
+
+ private Map<String, InstanceContext> getComponentContexts() throws CoreRuntimeException {
+ Map contexts = (Map) contextMap.get(Thread.currentThread());
+ if (contexts == null) {
+ contexts = new ConcurrentHashMap();
+ Queue shutdownQueue = new ConcurrentLinkedQueue();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ contexts.put(context.getName(), context);
+ }
+ contextMap.put(Thread.currentThread(), contexts);
+ destroyComponents.put(Thread.currentThread(), shutdownQueue);
+ }
+ return contexts;
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
new file mode 100644
index 0000000000..8b12f8b183
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
@@ -0,0 +1,145 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+
+/**
+ * A container that manages stateless components.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // Component contexts keyed by name
+ private Map<String, InstanceContext> contextMap;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public StatelessScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Stateless Scope");
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ super.start();
+ lifecycleState = RUNNING;
+ prepare();
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ contextMap = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ if (lifecycleState == RUNNING) {
+ contextMap.put(configuration.getName(), configuration.createInstanceContext());
+ }
+
+ }
+
+ public void onEvent(int type, Object key) {
+ // do nothing
+ }
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ return contextMap.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ return getContext(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ removeContextByKey(ctxName, null);
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ contextMap.remove(ctxName);
+ }
+
+ /**
+ * Always returns null since stateless components cannot be shutdown
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ return null;
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ public void onInstanceCreate(Context component) {
+ // do nothing
+ }
+
+ private void prepare() throws CoreRuntimeException {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not in INITIALIZED state [" + lifecycleState + "]");
+ }
+ if (contextMap == null) {
+ contextMap = new ConcurrentHashMap();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ for (int i = 0; i < runtimeConfigurations.size(); i++) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ contextMap.put(context.getName(), context);
+ }
+
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java
new file mode 100644
index 0000000000..923b9fb941
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java
@@ -0,0 +1,62 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.webapp;
+
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+
+/**
+ * Cleans up resources used by expired sessions
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPSessionExpirationListener implements HttpSessionListener {
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public HTTPSessionExpirationListener() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void sessionCreated(HttpSessionEvent event) {
+ // do nothing since sessions are lazily created in {@link
+ // org.apache.tuscany.tomcat.webapp.listener.RequestFilter}
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ TuscanyWebAppRuntime tuscanyRuntime = null;
+ try {
+ tuscanyRuntime = (TuscanyWebAppRuntime) event.getSession().getServletContext().getAttribute(
+ TuscanyWebAppRuntime.class.getName());
+ tuscanyRuntime.start();
+
+ // End the session
+ AggregateContext context = tuscanyRuntime.getModuleComponentContext();
+ context.fireEvent(EventContext.SESSION_END, event.getSession());
+ } finally {
+ if (tuscanyRuntime != null)
+ tuscanyRuntime.stop();
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java
new file mode 100644
index 0000000000..186f35df14
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java
@@ -0,0 +1,56 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.webapp;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.core.context.ScopeIdentifier;
+
+/**
+ * Implements a <code>ScopeIdentifier</code> for a Servlet-based transport.
+ * Wraps an <code>HttpServletRequest</code> so that the session id associated
+ * with the current request may be lazily retrieved by the module context - i.e.
+ * if a session context or session-scoped component is not accessed, no session
+ * is created.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LazyHTTPSessionId implements ScopeIdentifier {
+
+ private HttpServletRequest request;
+
+ //----------------------------------
+ // Constructors
+ //----------------------------------
+
+ public LazyHTTPSessionId(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ //----------------------------------
+ // Methods
+ //----------------------------------
+
+ /**
+ * Returns the session identifier
+ *
+ * @see org.apache.tuscany.core.context.ScopeIdentifier#getIdentifier()
+ */
+ public Object getIdentifier() {
+ return request.getSession(true);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java
new file mode 100644
index 0000000000..8e92c9ebd4
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java
@@ -0,0 +1,107 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.webapp;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+
+/**
+ * Notifies the {@link org.apache.tuscany.core.context.AggregateContext} of web request start and end events as well as setting up the
+ * current session context. The latter is done using lazy Servlet-based session retrieval. The filter fires a session
+ * start event, passing a <tt>LazyServletSessionId</tt> as the session id. The <tt>LazyServletSessionId</tt> is a
+ * wrapper for the servlet request which may be called by the <tt>ModuleContext</tt> to retrieve the session id
+ * lazily.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyRequestFilter implements Filter {
+ private TuscanyWebAppRuntime tuscanyRuntime;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public TuscanyRequestFilter() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ // Get the Tuscany runtime from the servlet context
+ tuscanyRuntime = (TuscanyWebAppRuntime) filterConfig.getServletContext().getAttribute(
+ TuscanyWebAppRuntime.class.getName());
+ }
+
+ public void destroy() {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException,
+ IOException {
+ // Get the module component context from the tuscany runtime
+ AggregateContext context = tuscanyRuntime.getModuleComponentContext();
+ try {
+
+ // Start the SCA implementation
+ tuscanyRuntime.start();
+
+ // Handle a request
+ if (request instanceof HttpServletRequest) {
+ if (((HttpServletRequest) request).getSession(false) != null) {
+
+ // A session is already active
+ context.fireEvent(EventContext.SESSION_NOTIFY, ((HttpServletRequest) request).getSession(true));
+ } else {
+ // Create a lazy wrapper since a session is not yet active
+ context.fireEvent(EventContext.SESSION_NOTIFY, new LazyHTTPSessionId((HttpServletRequest) request));
+ }
+ } else {
+ context.fireEvent(EventContext.SESSION_NOTIFY, request);
+ }
+ // Start processing the request
+ context.fireEvent(EventContext.REQUEST_START, request);
+ // Dispatch to the next filter
+ filterChain.doFilter(request, response);
+ } catch (Exception e) {
+ throw new ServletException(e);
+
+ } finally {
+ try {
+ // End processing the request
+ context.fireEvent(EventContext.REQUEST_END, request);
+ // Stop the SCA implementation
+ tuscanyRuntime.stop();
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java
new file mode 100644
index 0000000000..3b9801a811
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java
@@ -0,0 +1,59 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.core.context.webapp;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.SCA;
+
+/**
+ * An implementation of the SCA runtime for use in a Web app
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyWebAppRuntime extends SCA {
+ private AggregateContext moduleComponentContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public TuscanyWebAppRuntime(AggregateContext moduleComponentContext) {
+ this.moduleComponentContext = moduleComponentContext;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Returns the module component context associated with this runtime
+ */
+ public AggregateContext getModuleComponentContext() {
+ return moduleComponentContext;
+ }
+
+ public void start() {
+ // Associate it with the current thread
+ setModuleContext((ModuleContext) moduleComponentContext);
+ }
+
+ public void stop() {
+ setModuleContext(null);
+ }
+
+}