Make ConversationManagers easier to subclass

Increased visibility of the following package scope classes:
- ContainedConversation
- ConversationContainer
- JdkConcurrentConversationLock
- NoOpConversationLock

Provided additional hook methods and accessors for subclasses.

Issue: SWF-756
This commit is contained in:
Phillip Webb
2012-11-12 19:26:45 -08:00
parent e44e65ca24
commit 6f6e06294a
5 changed files with 27 additions and 11 deletions

View File

@@ -33,7 +33,7 @@ import org.springframework.webflow.core.collection.SharedAttributeMap;
*
* @author Erwin Vervaet
*/
class ContainedConversation implements Conversation, Serializable {
public class ContainedConversation implements Conversation, Serializable {
private static final Log logger = LogFactory.getLog(SessionBindingConversationManager.class);
@@ -58,8 +58,16 @@ class ContainedConversation implements Conversation, Serializable {
this.attributes = new HashMap<Object, Object>();
}
protected void setContainer(ConversationContainer container) {
this.container = container;
}
public ConversationId getId() {
return id;
return this.id;
}
protected void setId(ConversationId id) {
this.id = id;
}
public void lock() {

View File

@@ -35,7 +35,7 @@ import org.springframework.webflow.conversation.NoSuchConversationException;
*
* @author Erwin Vervaet
*/
class ConversationContainer implements Serializable {
public class ConversationContainer implements Serializable {
private static final Log logger = LogFactory.getLog(ConversationContainer.class);
@@ -91,7 +91,7 @@ class ConversationContainer implements Serializable {
* @return the created conversation
*/
public synchronized Conversation createConversation(ConversationParameters parameters, ConversationLock lock) {
ContainedConversation conversation = new ContainedConversation(this, nextId(), lock);
ContainedConversation conversation = createContainedConversation(nextId(), lock);
conversation.putAttribute("name", parameters.getName());
conversation.putAttribute("caption", parameters.getCaption());
conversation.putAttribute("description", parameters.getDescription());
@@ -126,6 +126,10 @@ class ConversationContainer implements Serializable {
throw new NoSuchConversationException(id);
}
protected final List<ContainedConversation> getConversations() {
return conversations;
}
/**
* Remove identified conversation from this container.
*/
@@ -145,4 +149,10 @@ class ConversationContainer implements Serializable {
private boolean maxExceeded() {
return maxConversations > 0 && conversations.size() > maxConversations;
}
// Hook methods
protected ContainedConversation createContainedConversation(ConversationId id, ConversationLock lock) {
return new ContainedConversation(this, id, lock);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2004-2008 the original author or authors.
* Copyright 2004-2012 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.
@@ -27,7 +27,7 @@ import org.springframework.webflow.conversation.ConversationLockException;
*
* @author Keith Donald
*/
class JdkConcurrentConversationLock implements ConversationLock {
public class JdkConcurrentConversationLock implements ConversationLock {
private Lock lock = new ReentrantLock();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2004-2008 the original author or authors.
* Copyright 2004-2012 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.
@@ -23,7 +23,7 @@ import java.io.ObjectStreamException;
*
* @author Keith Donald
*/
class NoOpConversationLock implements ConversationLock {
public class NoOpConversationLock implements ConversationLock {
/**
* The singleton instance.

View File

@@ -131,13 +131,11 @@ public class SessionBindingConversationManager implements ConversationManager {
return new ConversationContainer(maxConversations, sessionKey);
}
// internal helpers
/**
* Obtain the conversation container from the session. Create a new empty container and add it to the session if no
* existing container can be found.
*/
private ConversationContainer getConversationContainer() {
protected final ConversationContainer getConversationContainer() {
SharedAttributeMap<Object> sessionMap = ExternalContextHolder.getExternalContext().getSessionMap();
synchronized (sessionMap.getMutex()) {
ConversationContainer container = (ConversationContainer) sessionMap.get(sessionKey);