From cdc40905ce50878dc894a27f6d30661517e59ad4 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Tue, 9 Sep 2008 02:37:58 +0000 Subject: Creating a branch for the android work. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@693346 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/core/scope/AbstractScopeContainer.java | 201 ++++++++++++++ .../sca/core/scope/CompositeScopeContainer.java | 77 ++++++ .../core/scope/CompositeScopeContainerFactory.java | 37 +++ .../core/scope/ConversationalScopeContainer.java | 290 +++++++++++++++++++++ .../scope/ConversationalScopeContainerFactory.java | 44 ++++ .../sca/core/scope/HttpSessionScopeContainer.java | 83 ++++++ .../scope/HttpSessionScopeContainerFactory.java | 41 +++ .../sca/core/scope/RequestScopeContainer.java | 86 ++++++ .../core/scope/RequestScopeContainerFactory.java | 37 +++ .../org/apache/tuscany/sca/core/scope/Scope.java | 66 +++++ .../tuscany/sca/core/scope/ScopeContainer.java | 159 +++++++++++ .../sca/core/scope/ScopeContainerFactory.java | 32 +++ .../tuscany/sca/core/scope/ScopeRegistry.java | 43 +++ .../tuscany/sca/core/scope/ScopeRegistryImpl.java | 62 +++++ .../core/scope/ScopedImplementationProvider.java | 65 +++++ .../sca/core/scope/ScopedRuntimeComponent.java | 40 +++ .../sca/core/scope/StatelessScopeContainer.java | 55 ++++ .../core/scope/StatelessScopeContainerFactory.java | 37 +++ .../sca/core/scope/TargetDestructionException.java | 44 ++++ .../core/scope/TargetInitializationException.java | 44 ++++ .../sca/core/scope/TargetNotFoundException.java | 44 ++++ .../sca/core/scope/TargetResolutionException.java | 44 ++++ 22 files changed, 1631 insertions(+) create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java create mode 100644 branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java (limited to 'branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope') diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java new file mode 100644 index 0000000000..3e981556dc --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/AbstractScopeContainer.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.event.Event; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * Implements functionality common to scope contexts. + * + * @version $Rev: 639271 $ $Date: 2008-03-20 05:54:38 -0700 (Thu, 20 Mar 2008) $ + */ +public abstract class AbstractScopeContainer implements ScopeContainer { + protected Map> wrappers = new ConcurrentHashMap>(); + protected final Scope scope; + + protected RuntimeComponent component; + protected volatile int lifecycleState = UNINITIALIZED; + + + public AbstractScopeContainer(Scope scope, RuntimeComponent component) { + this.scope = scope; + this.component = component; + } + + protected void checkInit() { + if (getLifecycleState() != RUNNING) { + throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]"); + } + } + + /** + * Creates a new physical instance of a component, wrapped in an + * InstanceWrapper. + * + * @param component the component whose instance should be created + * @return a wrapped instance that has been injected but not yet started + * @throws TargetResolutionException if there was a problem creating the + * instance + */ + protected InstanceWrapper createInstanceWrapper() throws TargetResolutionException { + ImplementationProvider implementationProvider = component.getImplementationProvider(); + if (implementationProvider instanceof ScopedImplementationProvider) { + return ((ScopedImplementationProvider)implementationProvider).createInstanceWrapper(); + } + return null; + } + + public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException { + return getWrapper(contextId); // TODO: what is this method supposed to do diff than getWrapper? + } + + public Scope getScope() { + return scope; + } + + public InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException { + return wrappers.get(contextId); + } + + public void addWrapperReference(KEY existingContextId, KEY newContextId) + throws TargetResolutionException + { + // do nothing here. the conversational scope container implements this + } + + public void registerWrapper(InstanceWrapper wrapper, KEY contextId) throws TargetResolutionException { + // do nothing here. the conversational scope container implements this + } + + public void onEvent(Event event) { + } + + protected boolean isEagerInit() { + ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider(); + if (implementationProvider instanceof ScopedImplementationProvider) { + return ((ScopedImplementationProvider)implementationProvider).isEagerInit(); + } + return false; + } + + public void returnWrapper(InstanceWrapper wrapper, KEY contextId) throws TargetDestructionException { + } + + /** + * Default implementation of remove which does nothing + * + * @param contextId the identifier of the context to remove. + */ + public void remove(KEY contextId) + throws TargetDestructionException { + } + + public synchronized void start() { + int lifecycleState = getLifecycleState(); + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + setLifecycleState(RUNNING); + } + + public void startContext(KEY contextId) { + if(isEagerInit()) { + try { + getWrapper(contextId); + } catch (TargetResolutionException e) { + // + } + } + } + + public synchronized void stop() { + int lifecycleState = getLifecycleState(); + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]"); + } + setLifecycleState(STOPPED); + } + + public void stopContext(KEY contextId) { + wrappers.remove(contextId); + } + + @Override + public String toString() { + String s; + switch (lifecycleState) { + case ScopeContainer.CONFIG_ERROR: + s = "CONFIG_ERROR"; + break; + case ScopeContainer.ERROR: + s = "ERROR"; + break; + case ScopeContainer.INITIALIZING: + s = "INITIALIZING"; + break; + case ScopeContainer.INITIALIZED: + s = "INITIALIZED"; + break; + case ScopeContainer.RUNNING: + s = "RUNNING"; + break; + case ScopeContainer.STOPPING: + s = "STOPPING"; + break; + case ScopeContainer.STOPPED: + s = "STOPPED"; + break; + case ScopeContainer.UNINITIALIZED: + s = "UNINITIALIZED"; + break; + default: + s = "UNKNOWN"; + break; + } + return "In state [" + s + ']'; + } + + public RuntimeComponent getComponent() { + return component; + } + + public void setComponent(RuntimeComponent component) { + this.component = component; + } + + public int getLifecycleState() { + return lifecycleState; + } + + /** + * Set the current state of the Lifecycle. + * + * @param lifecycleState the new state + */ + protected void setLifecycleState(int lifecycleState) { + this.lifecycleState = lifecycleState; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java new file mode 100644 index 0000000000..cad9279e5c --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainer.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * A scope context which manages atomic component instances keyed by composite + * + * @version $Rev: 571516 $ $Date: 2007-08-31 09:41:22 -0700 (Fri, 31 Aug 2007) $ + */ +public class CompositeScopeContainer extends AbstractScopeContainer { + private InstanceWrapper wrapper; + + public CompositeScopeContainer(RuntimeComponent component) { + super(Scope.COMPOSITE, component); + } + + @Override + public synchronized void stop() { + super.stop(); + if (wrapper != null) { + try { + wrapper.stop(); + } catch (TargetDestructionException e) { + throw new IllegalStateException(e); + } + } + wrapper = null; + } + + @Override + public synchronized InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException { + if (wrapper == null) { + wrapper = createInstanceWrapper(); + wrapper.start(); + } + return wrapper; + } + + @Override + public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException { + if (wrapper == null) { + throw new TargetNotFoundException(component.getURI()); + } + return wrapper; + } + + @Override + public synchronized void start() { + super.start(); + if (isEagerInit()) { + try { + getWrapper(null); + } catch (TargetResolutionException e) { + throw new IllegalStateException(e); + } + } + } +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java new file mode 100644 index 0000000000..c9693761e8 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/CompositeScopeContainerFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class CompositeScopeContainerFactory implements ScopeContainerFactory { + + public ScopeContainer createScopeContainer(RuntimeComponent component) { + return new CompositeScopeContainer(component); + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java new file mode 100644 index 0000000000..55244932c5 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainer.java @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.core.conversation.ConversationListener; +import org.apache.tuscany.sca.core.conversation.ConversationManager; +import org.apache.tuscany.sca.core.conversation.ExtendedConversation; +import org.apache.tuscany.sca.core.invocation.ThreadMessageContext; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.store.Store; + +/** + * A scope context which manages atomic component instances keyed on ConversationID + * + */ +public class ConversationalScopeContainer extends AbstractScopeContainer implements ConversationListener { + private ConversationManager conversationManager; + private Map instanceLifecycleCollection = + new ConcurrentHashMap(); + + public ConversationalScopeContainer(Store aStore, RuntimeComponent component) { + super(Scope.CONVERSATION, component); + + // Note: aStore is here to preserve the original factory interface. It is not currently used in this + // implementation since we do not support instance persistence. + + // Check System properties to see if timeout values have been specified. All timeout values + // will be specified in seconds. + // + + } + + + protected InstanceWrapper getInstanceWrapper(boolean create, Object contextId) throws TargetResolutionException { + + // we might get a null context if the target service has + // conversational scope but only its callback interface + // is conversational. In this case we need to invent a + // conversation Id here to store the service against + // and populate the thread context + if (contextId == null) { + contextId = UUID.randomUUID().toString(); + Message msgContext = ThreadMessageContext.getMessageContext(); + + if (msgContext != null) { + msgContext.getFrom().getReferenceParameters().setConversationID(contextId); + } + } + + InstanceLifeCycleWrapper anInstanceWrapper = this.instanceLifecycleCollection.get(contextId); + + if (anInstanceWrapper == null && !create) + return null; + + if (anInstanceWrapper == null) { + anInstanceWrapper = new InstanceLifeCycleWrapper(contextId); + this.instanceLifecycleCollection.put(contextId, anInstanceWrapper); + } + + return anInstanceWrapper.getInstanceWrapper(contextId); + + } + + @Override + public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException { + return getInstanceWrapper(true, contextId); + } + + /** + * This method allows a new context id to be registered alongside an existing one. This happens in + * one case, when a conversation includes a stateful callback. The client component instance + * must be registered against all outgoing conversation ids so that the component instance + * can be found when the callback arrives + * + * @param existingContextId the context id against which the component is already registered + * @param context this should be a conversation object so that the conversation can b stored + * and reset when the component instance is removed + */ + public void addWrapperReference(Object existingContextId, Object contextId) throws TargetResolutionException { + + + // get the instance wrapper via the existing id + InstanceLifeCycleWrapper existingInstanceWrapper = this.instanceLifecycleCollection.get(existingContextId); + InstanceLifeCycleWrapper newInstanceWrapper = this.instanceLifecycleCollection.get(contextId); + + // only add the extra reference once + if (newInstanceWrapper == null) { + // add the id to the list of ids that the wrapper holds. Used for reference + // counting and conversation resetting on destruction. + existingInstanceWrapper.addCallbackConversation(contextId); + + // add the reference to the collection + this.instanceLifecycleCollection.put(contextId, existingInstanceWrapper); + } + } + + public void registerWrapper(InstanceWrapper wrapper, Object contextId) throws TargetResolutionException { + // if a wrapper for a different instance is already registered for this contextId, remove it + InstanceLifeCycleWrapper anInstanceWrapper = this.instanceLifecycleCollection.get(contextId); + if (anInstanceWrapper != null) { + if (anInstanceWrapper.getInstanceWrapper(contextId).getInstance() != wrapper.getInstance()) { + remove(contextId); + } else { + return; + } + } + + anInstanceWrapper = new InstanceLifeCycleWrapper(wrapper, contextId); + this.instanceLifecycleCollection.put(contextId, anInstanceWrapper); + } + + // The remove is invoked when a conversation is explicitly ended. This can occur by using the @EndsConversation or API. + // In this case the instance is immediately removed. A new conversation will be started on the next operation + // associated with this conversationId's service reference. + // + @Override + public void remove(Object contextId) throws TargetDestructionException { + if (contextId != null) { + if (this.instanceLifecycleCollection.containsKey(contextId)) { + InstanceLifeCycleWrapper anInstanceLifeCycleWrapper = this.instanceLifecycleCollection.get(contextId); + this.instanceLifecycleCollection.remove(contextId); + anInstanceLifeCycleWrapper.removeInstanceWrapper(contextId); + } + } + } + + /* + * This is an inner class that keeps track of the lifecycle of a conversation scoped + * implementation instance. + * + */ + + private class InstanceLifeCycleWrapper { + private Object clientConversationId; + private List callbackConversations = new ArrayList(); + + private InstanceLifeCycleWrapper(Object contextId) throws TargetResolutionException { + this.clientConversationId = contextId; + this.createInstance(contextId); + } + + private InstanceLifeCycleWrapper(InstanceWrapper wrapper, Object contextId) throws TargetResolutionException { + this.clientConversationId = contextId; + wrappers.put(contextId, wrapper); + } + + + // Associates a callback conversation with this instance. Each time the scope container + // is asked to remove an object given a ontextId an associated conversation object will + // have its conversationId reset to null. When the list of ids is empty the component instance + // will be removed from the scope container + private void addCallbackConversation(Object conversationID) { + InstanceWrapper ctx = getInstanceWrapper(clientConversationId); + callbackConversations.add(conversationID); + wrappers.put(conversationID, ctx); + } + + // + // Return the backing implementation instance + // + private InstanceWrapper getInstanceWrapper(Object contextId) { + InstanceWrapper ctx = wrappers.get(contextId); + return ctx; + } + + private void removeInstanceWrapper(Object contextId) throws TargetDestructionException { + InstanceWrapper ctx = getInstanceWrapper(contextId); + wrappers.remove(contextId); + + // find out if we are dealing with the original client conversation id + // and reset accordingly + if ( ( clientConversationId != null ) && ( clientConversationId.equals(contextId)) ) { + clientConversationId = null; + } else { + // reset the conversationId in the conversation object if present + // so that and ending callback causes the conversation in the originating + // service reference in the client to be reset + callbackConversations.remove(contextId); + } + + // stop the component if this removes the last reference + if (clientConversationId == null && callbackConversations.isEmpty()) { + ctx.stop(); + } + } + + private void createInstance(Object contextId) throws TargetResolutionException { + InstanceWrapper instanceWrapper = createInstanceWrapper(); + instanceWrapper.start(); + wrappers.put(contextId, instanceWrapper); + } + + } + + /** + * @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationEnded(org.apache.tuscany.sca.core.conversation.ExtendedConversation) + */ + public void conversationEnded(ExtendedConversation conversation) { + try { + remove(conversation.getConversationID()); + } catch (Exception ex) { + + } + } + + /** + * @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationExpired(org.apache.tuscany.sca.core.conversation.ExtendedConversation) + */ + public void conversationExpired(ExtendedConversation conversation) { + + Object conversationId = conversation.getConversationID(); + InstanceLifeCycleWrapper ilcw = instanceLifecycleCollection.get(conversationId); + if (ilcw != null) + { + // cycle through all the references to this instance and + // remove them from the underlying wrappers collection and + // from the lifecycle wrappers collection + + for (Object conversationID : ilcw.callbackConversations) { + try{ + ilcw.removeInstanceWrapper(conversationID); + remove(conversationID); + } + catch(TargetDestructionException tde){ + System.out.println("Could not remove conversation id " + conversationID); + } + } + + + if (ilcw.clientConversationId != null) { + try{ + ilcw.removeInstanceWrapper(ilcw.clientConversationId); + remove(ilcw.clientConversationId); + } + catch(TargetDestructionException tde){ + System.out.println("Could not remove conversation id " + ilcw.clientConversationId); + } + } + + } + + } + + /** + * @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationStarted(org.apache.tuscany.sca.core.conversation.ExtendedConversation) + */ + public void conversationStarted(ExtendedConversation conversation) { + startContext(conversation.getConversationID()); + } + + /** + * @return the conversationManager + */ + public ConversationManager getConversationManager() { + return conversationManager; + } + + /** + * @param conversationManager the conversationManager to set + */ + public void setConversationManager(ConversationManager conversationManager) { + this.conversationManager = conversationManager; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java new file mode 100644 index 0000000000..487d2874b0 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ConversationalScopeContainerFactory.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.store.Store; + +/** + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class ConversationalScopeContainerFactory implements ScopeContainerFactory { + private Store store; + + public ConversationalScopeContainerFactory(Store store) { + super(); + this.store = store; + } + + public ScopeContainer createScopeContainer(RuntimeComponent component) { + return new ConversationalScopeContainer(store, component); + } + + public Scope getScope() { + return Scope.CONVERSATION; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java new file mode 100644 index 0000000000..62f1e3fb79 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainer.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.core.event.HttpSessionEnd; +import org.apache.tuscany.sca.event.Event; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * A scope context which manages atomic component instances keyed on HTTP + * session + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class HttpSessionScopeContainer extends AbstractScopeContainer { + + public HttpSessionScopeContainer(RuntimeComponent component) { + super(Scope.SESSION, component); + } + + @Override + public void onEvent(Event event) { + checkInit(); + if (event instanceof HttpSessionEnd) { + //FIXME key is not used + //Object key = ((HttpSessionEnd)event).getSessionID(); + // FIXME: Remove the session id + } + } + + @Override + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + @Override + public synchronized void stop() { + lifecycleState = STOPPED; + } + + protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException { +// Object key = workContext.getIdentifier(Scope.SESSION); + // FIXME: Need to fix this + Object key ="http-session-id"; + assert key != null : "HTTP session key not bound in work context"; + InstanceWrapper ctx = wrappers.get(key); + if (ctx == null && !create) { + return null; + } + if (ctx == null) { + ctx = super.createInstanceWrapper(); + ctx.start(); + wrappers.put(key, ctx); + } + return ctx; + } + + @Override + public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException { + return getInstanceWrapper(true); + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java new file mode 100644 index 0000000000..c42700c9a6 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/HttpSessionScopeContainerFactory.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class HttpSessionScopeContainerFactory implements ScopeContainerFactory { + + public HttpSessionScopeContainerFactory() { + super(); + } + + public ScopeContainer createScopeContainer(RuntimeComponent component) { + return new HttpSessionScopeContainer(component); + } + + public Scope getScope() { + return Scope.SESSION; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java new file mode 100644 index 0000000000..761430597c --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainer.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.core.event.RequestEnd; +import org.apache.tuscany.sca.event.Event; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * A scope context which manages atomic component instances keyed on the current + * request context + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class RequestScopeContainer extends AbstractScopeContainer { + private final Map contexts; + + public RequestScopeContainer(RuntimeComponent component) { + super(Scope.REQUEST, component); + contexts = new ConcurrentHashMap(); + } + + @Override + public void onEvent(Event event) { + checkInit(); + if (event instanceof RequestEnd) { + // shutdownInstances(Thread.currentThread()); + } + } + + @Override + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + @Override + public synchronized void stop() { + contexts.clear(); + // synchronized (destroyQueues) { + // destroyQueues.clear(); + // } + lifecycleState = STOPPED; + } + + protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException { + InstanceWrapper ctx = wrappers.get(Thread.currentThread()); + if (ctx == null && !create) { + return null; + } + if (ctx == null) { + ctx = super.createInstanceWrapper(); + ctx.start(); + wrappers.put(Thread.currentThread(), ctx); + } + return ctx; + } + + @Override + public InstanceWrapper getWrapper(Thread contextId) throws TargetResolutionException { + return getInstanceWrapper(true); + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java new file mode 100644 index 0000000000..c2a3172fe2 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/RequestScopeContainerFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class RequestScopeContainerFactory implements ScopeContainerFactory { + + public ScopeContainer createScopeContainer(RuntimeComponent component) { + return new RequestScopeContainer(component); + } + + public Scope getScope() { + return Scope.REQUEST; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java new file mode 100644 index 0000000000..1c72359e58 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/Scope.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +/** + * The default implementation scopes supported by assemblies. + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class Scope { + public static final Scope STATELESS = new Scope("STATELESS"); + public static final Scope REQUEST = new Scope("REQUEST"); + public static final Scope SESSION = new Scope("SESSION"); + public static final Scope CONVERSATION = new Scope("CONVERSATION"); + public static final Scope COMPOSITE = new Scope("COMPOSITE"); + public static final Scope SYSTEM = new Scope("SYSTEM"); + public static final Scope UNDEFINED = new Scope("UNDEFINED"); + + private String scope; + + public Scope(String scope) { + this.scope = scope.toUpperCase().intern(); + } + + public String getScope() { + return scope; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Scope scope1 = (Scope) o; + return !(scope != null ? scope != scope1.scope.intern() : scope1.scope != null); + } + + @Override + public int hashCode() { + return scope != null ? scope.hashCode() : 0; + } + + @Override + public String toString() { + return scope; + } +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java new file mode 100644 index 0000000000..ea91c5973c --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainer.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.event.RuntimeEventListener; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + + +/** + * Manages the lifecycle and visibility of instances associated with a an {@link RuntimeComponent}. + * + * @version $Rev: 572525 $ $Date: 2007-09-03 22:00:52 -0700 (Mon, 03 Sep 2007) $ + * @param the type of IDs that this container uses to identify its contexts. + * For example, for COMPOSITE scope this could be the URI of the composite component, + * or for HTTP Session scope it might be the HTTP session ID. + */ +public interface ScopeContainer extends RuntimeEventListener { + + /** + * Returns the Scope that this container supports. + * + * @return the Scope that this container supports + */ + Scope getScope(); + + /** + * Start a new context with the supplied ID. + * + * @param contextId an ID that uniquely identifies the context. + */ + void startContext(KEY contextId); + + /** + * Stop the context with the supplied ID. + * + * @param contextId an ID that uniquely identifies the context. + */ + void stopContext(KEY contextId); + + /** + * Returns an instance wrapper associated with the current scope context, creating one if necessary + * @param contextId the id for the scope context + * + * @return the wrapper for the target instance + * @throws TargetResolutionException if there was a problem instantiating the target instance + */ + InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException; + + /** + * Allows a component to be registered against more than one context id. This is required in the + * case of stateful callbacks where we want to identify the originating client component instance + * as the callback target but we don't want to reuse the clients original conversation id + * + * @param existingContextId an id that identifies an existing component instance + * @param newContextId a new id against which this component will also be registered + * @throws TargetResolutionException + */ + void addWrapperReference(KEY existingContextId, KEY newContextId) + throws TargetResolutionException; + + /** + * Register an existing instance against a context id. This is needed + * for a stateful callback where the service reference for the forward call + * contains a callback object that is not a service reference. + * + * @param wrapper the instance wrapper for the instance to be registered + * @param contextId the id for the scope context + * @throws TargetResolutionException + */ + void registerWrapper(InstanceWrapper wrapper, KEY contextId) + throws TargetResolutionException; + + /** + * Returns an implementation instance associated with the current scope context. + * If no instance is found, a {@link TargetNotFoundException} is thrown. + * @param contextId the id for the scope context + * + * @return the wrapper for the target instance + * @throws TargetResolutionException if there was a problem instantiating the target instance + */ + InstanceWrapper getAssociatedWrapper(KEY contextId) + throws TargetResolutionException; + + /** + * Return a wrapper after use (for example, after invoking the instance). + * @param wrapper the wrapper for the target instance being returned + * @param contextId the id for the scope context + * + * @throws TargetDestructionException if there was a problem returning the target instance + */ + void returnWrapper(InstanceWrapper wrapper, KEY contextId) + throws TargetDestructionException; + + /** + * Removes an identified component implementation instance associated with the current + * context from persistent storage + * + * @param contextId the identifier of the context to remove. + */ + void remove(KEY contextId) + throws TargetDestructionException; + + /* A configuration error state */ + int CONFIG_ERROR = -1; + /* Has not been initialized */ + int UNINITIALIZED = 0; + /* In the process of being configured and initialized */ + int INITIALIZING = 1; + /* Instantiated and configured */ + int INITIALIZED = 2; + /* Configured and initialized */ + int RUNNING = 4; + /* In the process of being shutdown */ + int STOPPING = 5; + /* Has been shutdown and removed from the composite */ + int STOPPED = 6; + /* In an error state */ + int ERROR = 7; + + /** + * Returns the lifecycle state + * + * @see #UNINITIALIZED + * @see #INITIALIZING + * @see #INITIALIZED + * @see #RUNNING + * @see #STOPPING + * @see #STOPPED + */ + int getLifecycleState(); + + /** + * Starts the Lifecycle. + */ + void start(); + + /** + * Stops the Lifecycle. + */ + void stop(); + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java new file mode 100644 index 0000000000..e5f23f9a0a --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeContainerFactory.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * Factory to create ScopeContainer for components + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public interface ScopeContainerFactory { + ScopeContainer createScopeContainer(RuntimeComponent component); + Scope getScope(); +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java new file mode 100644 index 0000000000..6ec5667cb1 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistry.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + + +/** + * Manages {@link ScopeContainer}s in the runtime + * + * @version $$Rev: 568826 $$ $$Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $$ + */ +public interface ScopeRegistry { + + /** + * Returns the scope container for the given scope or null if one not found + * + * @param scope the scope + * @return the scope container for the given scope or null if one not found + */ + ScopeContainer getScopeContainer(RuntimeComponent component); + + /** + * @param factory + */ + void register(ScopeContainerFactory factory); +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java new file mode 100644 index 0000000000..6c25dbd2d4 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopeRegistryImpl.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * The default implementation of a scope registry + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class ScopeRegistryImpl implements ScopeRegistry { + private final Map scopeCache = new ConcurrentHashMap(); + + public void register(ScopeContainerFactory factory) { + scopeCache.put(factory.getScope(), factory); + } + + public ScopeContainer getScopeContainer(RuntimeComponent runtimeComponent) { + if (!(runtimeComponent instanceof ScopedRuntimeComponent)) { + return null; + } + ScopedRuntimeComponent component = (ScopedRuntimeComponent)runtimeComponent; + if (component.getScopeContainer() != null) { + return component.getScopeContainer(); + } + ImplementationProvider implementationProvider = component.getImplementationProvider(); + if (implementationProvider instanceof ScopedImplementationProvider) { + ScopedImplementationProvider provider = (ScopedImplementationProvider)implementationProvider; + Scope scope = provider.getScope(); + if (scope == null) { + scope = Scope.STATELESS; + } + ScopeContainerFactory factory = scopeCache.get(scope); + ScopeContainer container = factory.createScopeContainer(component); + component.setScopeContainer(container); + return container; + } + return null; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java new file mode 100644 index 0000000000..8708c6e11e --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedImplementationProvider.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.provider.ImplementationProvider; + +/** + * A component implementation can implement this interface to provide scope + * management for the components + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public interface ScopedImplementationProvider extends ImplementationProvider { + /** + * Get the scope for the component implementation + * + * @return The scope for the component implementation, if null is returned, + * STATELESS will be used + */ + Scope getScope(); + + /** + * Indicate if the component needs to be eagerly initialized + * + * @return true if the component is marked to be eagerly initialized, false + * otherwise + */ + boolean isEagerInit(); + + /** + * @return the maxAge + */ + long getMaxAge(); + + /** + * @return the maxIdleTime + */ + long getMaxIdleTime(); + + /** + * Create a wrapper for the component instance for the scope management + * + * @return A wrapper for the component instance + */ + InstanceWrapper createInstanceWrapper(); + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java new file mode 100644 index 0000000000..c533822952 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/ScopedRuntimeComponent.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * Scoped runtime component + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public interface ScopedRuntimeComponent extends RuntimeComponent { + /** + * Set the associated scope container + * @param scopeContainer + */ + void setScopeContainer(ScopeContainer scopeContainer); + /** + * Get the assoicated scope container + * @return + */ + ScopeContainer getScopeContainer(); +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java new file mode 100644 index 0000000000..f785647683 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainer.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * A scope context which manages stateless atomic component instances in a non-pooled fashion. + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class StatelessScopeContainer extends AbstractScopeContainer { + + public StatelessScopeContainer(RuntimeComponent component) { + super(Scope.STATELESS, component); + } + + @Override + public InstanceWrapper getWrapper(KEY contextId) + throws TargetResolutionException { + InstanceWrapper ctx = createInstanceWrapper(); + ctx.start(); + return ctx; + } + + @Override + public InstanceWrapper getAssociatedWrapper(KEY contextId) + throws TargetResolutionException { + return getWrapper(contextId); + } + + @Override + public void returnWrapper(InstanceWrapper wrapper, KEY contextId) + throws TargetDestructionException { + wrapper.stop(); + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java new file mode 100644 index 0000000000..7507248b32 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/StatelessScopeContainerFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.core.scope; + +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class StatelessScopeContainerFactory implements ScopeContainerFactory { + + public ScopeContainer createScopeContainer(RuntimeComponent component) { + return new StatelessScopeContainer(component); + } + + public Scope getScope() { + return Scope.STATELESS; + } + +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java new file mode 100644 index 0000000000..a3c4e7ee1a --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetDestructionException.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +/** + * Denotes an error destroying a target + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class TargetDestructionException extends TargetResolutionException { + private static final long serialVersionUID = -6126684147851674709L; + + public TargetDestructionException() { + super(); + } + + public TargetDestructionException(String message, Throwable cause) { + super(message, cause); + } + + public TargetDestructionException(String message) { + super(message); + } + + public TargetDestructionException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java new file mode 100644 index 0000000000..29f43ed861 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetInitializationException.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +/** + * Denotes an error initializing a target + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class TargetInitializationException extends TargetResolutionException { + private static final long serialVersionUID = -6228778208649752698L; + + public TargetInitializationException() { + super(); + } + + public TargetInitializationException(String message, Throwable cause) { + super(message, cause); + } + + public TargetInitializationException(String message) { + super(message); + } + + public TargetInitializationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java new file mode 100644 index 0000000000..b8b1d6bbe3 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetNotFoundException.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +/** + * Thrown when a target of an operation cannot be found + * + * @version $$Rev: 568826 $$ $$Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $$ + */ +public class TargetNotFoundException extends TargetResolutionException { + private static final long serialVersionUID = 5541830480658471186L; + + public TargetNotFoundException() { + super(); + } + + public TargetNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public TargetNotFoundException(String message) { + super(message); + } + + public TargetNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java new file mode 100644 index 0000000000..d669711c40 --- /dev/null +++ b/branches/sca-android/core-android/src/main/java/org/apache/tuscany/sca/core/scope/TargetResolutionException.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.core.scope; + +/** + * Denotes an error retrieving a target instance + * + * @version $Rev: 568826 $ $Date: 2007-08-22 22:27:34 -0700 (Wed, 22 Aug 2007) $ + */ +public class TargetResolutionException extends Exception { + private static final long serialVersionUID = 2912513650522019405L; + + public TargetResolutionException() { + super(); + } + + public TargetResolutionException(String message, Throwable cause) { + super(message, cause); + } + + public TargetResolutionException(String message) { + super(message); + } + + public TargetResolutionException(Throwable cause) { + super(cause); + } +} -- cgit v1.2.3