summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope')
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java158
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java184
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java50
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java217
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java58
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java135
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java54
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java41
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java52
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java48
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java126
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java48
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java63
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java75
-rw-r--r--sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java54
15 files changed, 1363 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java
new file mode 100644
index 0000000000..7f1d507a1b
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.spi.AbstractLifecycle;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.PersistenceException;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.EventFilter;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.event.TrueFilter;
+
+/**
+ * Implements functionality common to scope contexts.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContainer extends AbstractLifecycle implements ScopeContainer {
+ private static final EventFilter TRUE_FILTER = new TrueFilter();
+
+ protected WorkContext workContext;
+ protected ScopeContainerMonitor monitor;
+ private Map<EventFilter, List<RuntimeEventListener>> listeners;
+
+ public AbstractScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ this.workContext = workContext;
+ this.monitor = monitor;
+ }
+
+ public void addListener(RuntimeEventListener listener) {
+ addListener(TRUE_FILTER, listener);
+ }
+
+ public void removeListener(RuntimeEventListener listener) {
+ assert listener != null;
+ synchronized (getListeners()) {
+ for (List<RuntimeEventListener> currentList : getListeners().values()) {
+ for (RuntimeEventListener current : currentList) {
+ if (current == listener) {
+ currentList.remove(current);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public void addListener(EventFilter filter, RuntimeEventListener listener) {
+ assert listener != null;
+ synchronized (getListeners()) {
+ List<RuntimeEventListener> list = getListeners().get(filter);
+ if (list == null) {
+ list = new CopyOnWriteArrayList<RuntimeEventListener>();
+ listeners.put(filter, list);
+ }
+ list.add(listener);
+ }
+ }
+
+ public void publish(Event event) {
+ assert event != null;
+ for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) {
+ if (entry.getKey().match(event)) {
+ for (RuntimeEventListener listener : entry.getValue()) {
+ listener.onEvent(event);
+ }
+ }
+ }
+ }
+
+ public Object getInstance(AtomicComponent component) throws TargetResolutionException {
+ InstanceWrapper ctx = getInstanceWrapper(component, true);
+ if (ctx != null) {
+ if (!ctx.isStarted()) {
+ ctx.start();
+ }
+ return ctx.getInstance();
+ }
+ return null;
+ }
+
+ public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException {
+ InstanceWrapper ctx = getInstanceWrapper(component, false);
+ if (ctx != null) {
+ if (!ctx.isStarted()) {
+ ctx.start();
+ }
+ return ctx.getInstance();
+ }
+ throw new TargetNotFoundException(component.getUri().toString());
+ }
+
+ public void persistNew(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+
+ }
+
+ public void persist(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+ }
+
+ public void remove(AtomicComponent component) throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+ }
+
+ protected Map<EventFilter, List<RuntimeEventListener>> getListeners() {
+ if (listeners == null) {
+ listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>();
+ }
+ return listeners;
+ }
+
+ protected void checkInit() {
+ if (getLifecycleState() != RUNNING) {
+ throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]");
+ }
+ }
+
+ protected WorkContext getWorkContext() {
+ return workContext;
+ }
+
+ public String toString() {
+ return "In state [" + super.toString() + ']';
+ }
+
+ protected abstract InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException;
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java
new file mode 100644
index 0000000000..623704fbee
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.ComponentStart;
+import org.apache.tuscany.core.component.event.ComponentStop;
+
+/**
+ * A scope context which manages atomic component instances keyed by composite
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeContainer extends AbstractScopeContainer {
+ private static final InstanceWrapper EMPTY = new EmptyWrapper();
+ private static final ComponentInitComparator COMPARATOR = new ComponentInitComparator();
+
+ private final Map<AtomicComponent, InstanceWrapper> instanceWrappers;
+ // the queue of instanceWrappers to destroy, in the order that their instances were created
+ private final List<InstanceWrapper> destroyQueue;
+
+ public CompositeScopeContainer(ScopeContainerMonitor monitor) {
+ super(null, monitor);
+ instanceWrappers = new ConcurrentHashMap<AtomicComponent, InstanceWrapper>();
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ }
+
+ public Scope getScope() {
+ return Scope.COMPOSITE;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof ComponentStart) {
+ try {
+ eagerInitComponents();
+ } catch (ObjectCreationException e) {
+ monitor.eagerInitializationError(e);
+ } catch (TargetResolutionException e) {
+ monitor.eagerInitializationError(e);
+ }
+ lifecycleState = RUNNING;
+ } else if (event instanceof ComponentStop) {
+ shutdownContexts();
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ checkInit();
+ instanceWrappers.clear();
+ synchronized (destroyQueue) {
+ destroyQueue.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ /**
+ * Notifies instanceWrappers of a shutdown in reverse order to which they were started
+ */
+ private void shutdownContexts() {
+ if (destroyQueue.size() == 0) {
+ return;
+ }
+ synchronized (destroyQueue) {
+ // shutdown destroyable instances in reverse instantiation order
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ destroyQueue.clear();
+ }
+ }
+
+ public void register(AtomicComponent component) {
+ checkInit();
+ instanceWrappers.put(component, EMPTY);
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ checkInit();
+ InstanceWrapper ctx = instanceWrappers.get(component);
+ assert ctx != null;
+ if (ctx == EMPTY && !create) {
+ return null;
+ }
+ if (ctx == EMPTY) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ instanceWrappers.put(component, ctx);
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+ }
+
+ private void eagerInitComponents() throws ObjectCreationException, TargetResolutionException {
+ List<AtomicComponent> componentList = new ArrayList<AtomicComponent>(instanceWrappers.keySet());
+ Collections.sort(componentList, COMPARATOR);
+ // start each group
+ for (AtomicComponent component : componentList) {
+ if (component.getInitLevel() <= 0) {
+ // Don't eagerly init
+ continue;
+ }
+ // the instance could have been created from a depth-first traversal
+ InstanceWrapper ctx = instanceWrappers.get(component);
+ if (ctx == EMPTY) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ instanceWrappers.put(component, ctx);
+ destroyQueue.add(ctx);
+ }
+ }
+ }
+
+ private static class ComponentInitComparator implements Comparator<AtomicComponent> {
+ public int compare(AtomicComponent o1, AtomicComponent o2) {
+ return o1.getInitLevel() - o2.getInitLevel();
+ }
+ }
+
+ private static class EmptyWrapper implements InstanceWrapper {
+ public Object getInstance() {
+ return null;
+ }
+
+ public boolean isStarted() {
+ return true;
+ }
+
+ public void start() throws TargetInitializationException {
+
+ }
+
+ public void stop() throws TargetDestructionException {
+
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java
new file mode 100644
index 0000000000..fc89bbc609
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new composite scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class CompositeScopeObjectFactory implements ObjectFactory<CompositeScopeContainer> {
+ private ScopeContainerMonitor monitor;
+
+ public CompositeScopeObjectFactory(@Reference ScopeRegistry registry,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.COMPOSITE, this);
+ this.monitor = monitor;
+ }
+
+ public CompositeScopeContainer getInstance() throws ObjectCreationException {
+ return new CompositeScopeContainer(monitor);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java
new file mode 100644
index 0000000000..eb4a06602f
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.PersistenceException;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreReadException;
+import org.apache.tuscany.spi.services.store.StoreWriteException;
+
+/**
+ * A scope context which manages atomic component instances keyed on a conversation session
+ *
+ * @version $Rev: 452655 $ $Date: 2006-10-03 18:09:02 -0400 (Tue, 03 Oct 2006) $
+ */
+public class ConversationalScopeContainer extends AbstractScopeContainer implements ScopeContainer {
+ private Store nonDurableStore;
+ private Map<AtomicComponent, AtomicComponent> components;
+
+ public ConversationalScopeContainer(Store store, WorkContext workContext, final ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ this.nonDurableStore = store;
+ if (store != null) {
+ store.addListener(new ExpirationListener(monitor));
+ }
+ components = new ConcurrentHashMap<AtomicComponent, AtomicComponent>();
+ }
+
+ public Scope getScope() {
+ return Scope.CONVERSATION;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ components.put(component, component);
+ component.addListener(this);
+ }
+
+ @Override
+ public Object getInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ } else {
+ instance = component.createInstance();
+ long expire = calculateExpiration(component);
+ nonDurableStore.insertRecord(component, conversationId, instance, expire);
+ component.init(instance);
+ }
+ return instance;
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ return instance;
+ } else {
+ throw new TargetNotFoundException(component.getUri().toString());
+ }
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public void persistNew(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.insertRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void persist(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.updateRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void remove(AtomicComponent component) throws PersistenceException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ nonDurableStore.removeRecord(component, conversationId);
+ }
+ } catch (StoreReadException e) {
+ throw new PersistenceException(e);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the conversation id associated with the current invocation context
+ */
+ private String getConversationId() {
+ String conversationId = (String) workContext.getIdentifier(Scope.CONVERSATION);
+ assert conversationId != null;
+ return conversationId;
+ }
+
+ private long calculateExpiration(AtomicComponent component) {
+ if (component.getMaxAge() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxAge();
+ } else if (component.getMaxIdleTime() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxIdleTime();
+ } else {
+ return Store.DEFAULT_EXPIRATION_OFFSET;
+ }
+ }
+
+ /**
+ * Receives expiration events from the store and notifies the corresponding atomic component
+ */
+ private static class ExpirationListener implements RuntimeEventListener {
+ private final ScopeContainerMonitor monitor;
+
+ public ExpirationListener(ScopeContainerMonitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public void onEvent(Event event) {
+ if (event instanceof StoreExpirationEvent) {
+ StoreExpirationEvent expiration = (StoreExpirationEvent) event;
+ SCAObject object = expiration.getOwner();
+ assert object instanceof AtomicComponent;
+ AtomicComponent owner = (AtomicComponent) object;
+ try {
+ owner.destroy(expiration.getInstance());
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java
new file mode 100644
index 0000000000..30a4487215
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new Session Scope context
+ *
+ * @version $$Rev: 450456 $$ $$Date: 2006-09-27 10:28:36 -0400 (Wed, 27 Sep 2006) $$
+ */
+@EagerInit
+public class ConversationalScopeObjectFactory implements ObjectFactory<ConversationalScopeContainer> {
+ private WorkContext context;
+ private Store store;
+ private ScopeContainerMonitor monitor;
+
+ public ConversationalScopeObjectFactory(@Reference ScopeRegistry registry,
+ @Reference WorkContext context,
+ @Reference Store store,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.CONVERSATION, this);
+ this.context = context;
+ this.store = store;
+ this.monitor = monitor;
+ }
+
+ public ConversationalScopeContainer getInstance() throws ObjectCreationException {
+ return new ConversationalScopeContainer(store, context, monitor);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java
new file mode 100644
index 0000000000..83c79b2367
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+
+/**
+ * A scope context which manages atomic component instances keyed on HTTP session
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContainer extends AbstractScopeContainer {
+ private final Map<AtomicComponent, Map<Object, InstanceWrapper>> contexts;
+ private final Map<Object, List<InstanceWrapper>> destroyQueues;
+
+ public HttpSessionScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ contexts = new ConcurrentHashMap<AtomicComponent, Map<Object, InstanceWrapper>>();
+ destroyQueues = new ConcurrentHashMap<Object, List<InstanceWrapper>>();
+ }
+
+ public Scope getScope() {
+ return Scope.SESSION;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof HttpSessionEnd) {
+ Object key = ((HttpSessionEnd) event).getId();
+ shutdownInstances(key);
+ workContext.clearIdentifier(key);
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ contexts.clear();
+ synchronized (destroyQueues) {
+ destroyQueues.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ contexts.put(component, new ConcurrentHashMap<Object, InstanceWrapper>());
+ component.addListener(this);
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ Object key = workContext.getIdentifier(Scope.SESSION);
+ assert key != null : "HTTP session key not bound in work context";
+ return getInstance(component, key, create);
+ }
+
+ private InstanceWrapper getInstance(AtomicComponent component, Object key, boolean create)
+ throws TargetResolutionException {
+ Map<Object, InstanceWrapper> wrappers = contexts.get(component);
+ InstanceWrapper ctx = wrappers.get(key);
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ wrappers.put(key, ctx);
+ List<InstanceWrapper> destroyQueue = destroyQueues.get(key);
+ if (destroyQueue == null) {
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ destroyQueues.put(key, destroyQueue);
+ }
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+
+ }
+
+ private void shutdownInstances(Object key) {
+ List<InstanceWrapper> destroyQueue = destroyQueues.remove(key);
+ if (destroyQueue != null) {
+ for (Map<Object, InstanceWrapper> map : contexts.values()) {
+ map.remove(key);
+ }
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ synchronized (destroyQueue) {
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java
new file mode 100644
index 0000000000..5fae335e6b
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new HTTP session scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class HttpSessionScopeObjectFactory implements ObjectFactory<HttpSessionScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+ public HttpSessionScopeObjectFactory(@Reference ScopeRegistry registry,
+ @Reference WorkContext context,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.SESSION, this);
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public HttpSessionScopeContainer getInstance() throws ObjectCreationException {
+ return new HttpSessionScopeContainer(context, monitor);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java
new file mode 100644
index 0000000000..121a6d3b70
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+
+/**
+ * Provides lifecycle management for an implementation instance associated with an {@link
+ * org.apache.tuscany.spi.component.AtomicComponent} for use by the atomic component's associated {@link
+ * org.apache.tuscany.spi.component.ScopeContainer}
+ *
+ * @version $Rev$ $Date$
+ */
+public interface InstanceWrapper<T> {
+
+ T getInstance();
+
+ boolean isStarted();
+
+ void start() throws TargetInitializationException;
+
+ void stop() throws TargetDestructionException;
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java
new file mode 100644
index 0000000000..e52b20fe84
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InstanceWrapperBase<T> implements InstanceWrapper<T> {
+ protected final T instance;
+ private boolean started;
+
+ public InstanceWrapperBase(T instance) {
+ assert instance != null;
+ this.instance = instance;
+ }
+
+ public T getInstance() {
+ assert started;
+ return instance;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void start() throws TargetInitializationException {
+ started = true;
+ }
+
+ public void stop() throws TargetDestructionException {
+ started = false;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java
new file mode 100644
index 0000000000..200f9a6e6d
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+
+/**
+ * Default implementation of an <code>InstanceWrapper</code>
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class InstanceWrapperImpl extends InstanceWrapperBase<Object> {
+ private AtomicComponent component;
+
+ public InstanceWrapperImpl(AtomicComponent component, Object instance) {
+ super(instance);
+ assert component != null;
+ this.component = component;
+ }
+
+ public void start() throws TargetInitializationException {
+ component.init(instance);
+ super.start();
+ }
+
+ public void stop() throws TargetDestructionException {
+ super.stop();
+ component.destroy(instance);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java
new file mode 100644
index 0000000000..22beaae740
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.RequestEnd;
+
+/**
+ * A scope context which manages atomic component instances keyed on the current request context
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContainer extends AbstractScopeContainer {
+ private final Map<AtomicComponent, Map<Thread, InstanceWrapper>> contexts;
+ private final Map<Thread, List<InstanceWrapper>> destroyQueues;
+
+ public RequestScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ contexts = new ConcurrentHashMap<AtomicComponent, Map<Thread, InstanceWrapper>>();
+ destroyQueues = new ConcurrentHashMap<Thread, List<InstanceWrapper>>();
+ }
+
+ public Scope getScope() {
+ return Scope.REQUEST;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof RequestEnd) {
+ shutdownInstances(Thread.currentThread());
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ contexts.clear();
+ synchronized (destroyQueues) {
+ destroyQueues.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ contexts.put(component, new ConcurrentHashMap<Thread, InstanceWrapper>());
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ Map<Thread, InstanceWrapper> instanceContextMap = contexts.get(component);
+ assert instanceContextMap != null : "Atomic component not registered";
+ InstanceWrapper ctx = instanceContextMap.get(Thread.currentThread());
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ instanceContextMap.put(Thread.currentThread(), ctx);
+ List<InstanceWrapper> destroyQueue = destroyQueues.get(Thread.currentThread());
+ if (destroyQueue == null) {
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ destroyQueues.put(Thread.currentThread(), destroyQueue);
+ }
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+ }
+
+ private void shutdownInstances(Thread key) {
+ List<InstanceWrapper> destroyQueue = destroyQueues.remove(key);
+ if (destroyQueue != null && destroyQueue.size() > 0) {
+ Thread thread = Thread.currentThread();
+ for (Map<Thread, InstanceWrapper> map : contexts.values()) {
+ map.remove(thread);
+ }
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ synchronized (destroyQueue) {
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java
new file mode 100644
index 0000000000..7ad2603eeb
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new request scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestScopeObjectFactory implements ObjectFactory<RequestScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+
+ public RequestScopeObjectFactory(@Reference WorkContext context, @Monitor ScopeContainerMonitor monitor) {
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public RequestScopeContainer getInstance() throws ObjectCreationException {
+ return new RequestScopeContainer(context, monitor);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java
new file mode 100644
index 0000000000..da338dd0ef
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * The default implementation of a scope registry
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeRegistryImpl implements ScopeRegistry {
+ private final Map<Scope, ScopeContainer> scopeCache =
+ new ConcurrentHashMap<Scope, ScopeContainer>();
+ private final Map<Scope, ObjectFactory<? extends ScopeContainer>> factoryCache =
+ new ConcurrentHashMap<Scope, ObjectFactory<? extends ScopeContainer>>();
+
+ public ScopeContainer getScopeContainer(Scope scope) {
+ assert Scope.COMPOSITE != scope;
+ ScopeContainer container = scopeCache.get(scope);
+ if (container == null) {
+ ObjectFactory<? extends ScopeContainer> factory = factoryCache.get(scope);
+ if (factory != null) {
+ container = factory.getInstance();
+ container.start();
+ scopeCache.put(scope, container);
+ }
+ }
+ return container;
+ }
+
+ public <T extends ScopeContainer> void registerFactory(Scope scope, ObjectFactory<T> factory) {
+ factoryCache.put(scope, factory);
+ }
+
+ public void deregisterFactory(Scope scope) {
+ factoryCache.remove(scope);
+ }
+
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java
new file mode 100644
index 0000000000..cbd47b6cdd
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * A scope context which manages stateless atomic component instances in a non-pooled fashion
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContainer extends AbstractScopeContainer {
+
+ public StatelessScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ }
+
+ public Scope getScope() {
+ return Scope.STATELESS;
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void onEvent(Event event) {
+ }
+
+ public void register(AtomicComponent component) {
+ checkInit();
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ // there never is a previously associated instance, return null
+ if (!create) {
+ return null;
+ }
+ InstanceWrapper ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ return ctx;
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java
new file mode 100644
index 0000000000..1522f6c528
--- /dev/null
+++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new stateless scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class StatelessScopeObjectFactory implements ObjectFactory<StatelessScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+ public StatelessScopeObjectFactory(@Reference ScopeRegistry registry,
+ @Reference WorkContext context,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.STATELESS, this);
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public StatelessScopeContainer getInstance() throws ObjectCreationException {
+ return new StatelessScopeContainer(context, monitor);
+ }
+}