diff options
Diffstat (limited to 'sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope')
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); + } +} |