/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.conversation.scope;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.conversation.Conversation;
import org.springframework.conversation.JoinMode;
import org.springframework.conversation.manager.ConversationManager;
import org.springframework.conversation.manager.ConversationResolver;
import org.springframework.conversation.manager.ConversationStore;
import org.springframework.util.Assert;
/**
* The default implementation of the {@link ConversationScope} exposed as
* "conversation"
scope. It needs the {@link ConversationStore} and
* the {@link ConversationResolver} to resolve and request the current
* conversation where attributes are resolved with and registered in.
*
* @author Micha Kiener
* @since 3.1
*/
public class ConversationScope implements Scope {
/** The name of the scope being exposed within the application context. */
public static final String CONVERSATION_SCOPE_NAME = "conversation";
/**
* The name of the contextual object for the conversation manager (see
* {@link org.springframework.beans.factory.config.Scope#resolveContextualObject(String)}).
*/
public static final String REFERENCE_CONVERSATION_MANAGER = "conversationManager";
/**
* The name of the contextual object for the conversation store (see
* {@link org.springframework.beans.factory.config.Scope#resolveContextualObject(String)}).
*/
public static final String REFERENCE_CONVERSATION_STORE = "conversationStore";
/**
* The name of the contextual object for the conversation resolver (see
* {@link org.springframework.beans.factory.config.Scope#resolveContextualObject(String)}).
*/
public static final String REFERENCE_CONVERSATION_RESOLVER = "conversationResolver";
/** Holds the conversation manager reference, if statically injected. */
private ConversationManager conversationManager;
/** Holds the conversation store reference, if statically injected. */
private ConversationStore conversationStore;
/** Holds the conversation resolver reference, if statically injected. */
private ConversationResolver conversationResolver;
/**
* This method is invoked to resolve the current conversation used where
* attributes having conversation scope are being resolved with or stored
* in.
*
* @return the currently used conversation, or null
, if no one
* currently available and createIfNotExisting
is
* false
*/
protected Conversation getCurrentConversation(boolean createNewIfNotExisting) {
ConversationResolver resolver = getConversationResolver();
Assert.notNull(resolver, "No conversation resolver available within the conversation scope");
String conversationId = resolver.getCurrentConversationId();
Conversation conversation;
if (conversationId == null) {
if (createNewIfNotExisting) {
// start a new, temporary conversation using the default join
// mode
ConversationManager manager = getConversationManager();
conversation = manager.beginConversation(true, JoinMode.getDefaultJoinMode());
} else {
return null;
}
} else {
ConversationStore store = getConversationStore();
Assert.notNull(store, "No conversation store available within the conversation scope");
conversation = store.getConversation(conversationId);
Assert.notNull(conversation, "The conversation with id <" + conversationId
+ "> is not available within the store");
}
return conversation;
}
/**
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
* org.springframework.beans.factory.ObjectFactory)
*/
public Object get(String name, ObjectFactory> objectFactory) {
Conversation conversation = getCurrentConversation(true);
Object attribute = conversation.getAttribute(name);
if (attribute == null) {
attribute = objectFactory.getObject();
conversation.setAttribute(name, attribute);
}
return attribute;
}
/**
* @see org.springframework.beans.factory.config.Scope#getConversationId()
*/
public String getConversationId() {
Conversation conversation = getCurrentConversation(false);
if (conversation != null) {
return conversation.getId();
}
return null;
}
/**
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
* java.lang.Runnable)
*/
public void registerDestructionCallback(String name, Runnable callback) {
Conversation conversation = getCurrentConversation(false);
if (conversation != null) {
conversation.registerDestructionCallback(name, callback);
}
}
/**
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
*/
public Object remove(String name) {
Conversation conversation = getCurrentConversation(false);
if (conversation != null) {
return conversation.removeAttribute(name);
}
return null;
}
/**
* Supports the following objects:
*
"conversationManager"
, returns the {@link ConversationManager}"conversationStore"
, returns the {@link ConversationStore}"conversationResolver"
, returns the {@link ConversationResolver}