1 16 package org.springframework.webflow.execution.repository.continuation; 17 18 import java.io.Serializable ; 19 20 import org.apache.commons.codec.binary.Base64; 21 import org.springframework.util.Assert; 22 import org.springframework.webflow.conversation.Conversation; 23 import org.springframework.webflow.conversation.ConversationException; 24 import org.springframework.webflow.conversation.ConversationId; 25 import org.springframework.webflow.conversation.ConversationManager; 26 import org.springframework.webflow.conversation.ConversationParameters; 27 import org.springframework.webflow.conversation.NoSuchConversationException; 28 import org.springframework.webflow.core.collection.CollectionUtils; 29 import org.springframework.webflow.execution.FlowExecution; 30 import org.springframework.webflow.execution.repository.FlowExecutionKey; 31 import org.springframework.webflow.execution.repository.FlowExecutionRestorationFailureException; 32 import org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository; 33 import org.springframework.webflow.execution.repository.support.FlowExecutionStateRestorer; 34 35 76 public class ClientContinuationFlowExecutionRepository extends AbstractConversationFlowExecutionRepository { 77 78 82 private FlowExecutionContinuationFactory continuationFactory = new SerializedFlowExecutionContinuationFactory(); 83 84 88 public ClientContinuationFlowExecutionRepository(FlowExecutionStateRestorer executionStateRestorer) { 89 super(executionStateRestorer, new NoOpConversationManager()); 90 } 91 92 99 public ClientContinuationFlowExecutionRepository(FlowExecutionStateRestorer executionStateRestorer, 100 ConversationManager conversationManager) { 101 super(executionStateRestorer, conversationManager); 102 } 103 104 107 protected FlowExecutionContinuationFactory getContinuationFactory() { 108 return continuationFactory; 109 } 110 111 114 public void setContinuationFactory(FlowExecutionContinuationFactory continuationFactory) { 115 Assert.notNull(continuationFactory, "The continuation factory is required"); 116 this.continuationFactory = continuationFactory; 117 } 118 119 public FlowExecution getFlowExecution(FlowExecutionKey key) { 120 124 FlowExecutionContinuation continuation = decode((String )getContinuationId(key)); 125 try { 126 FlowExecution execution = continuation.unmarshal(); 127 return getExecutionStateRestorer().restoreState(execution, getConversationScope(key)); 130 } 131 catch (ContinuationUnmarshalException e) { 132 throw new FlowExecutionRestorationFailureException(key, e); 133 } 134 } 135 136 public void putFlowExecution(FlowExecutionKey key, FlowExecution flowExecution) { 137 141 putConversationScope(key, flowExecution.getConversationScope()); 144 } 145 146 protected final Serializable generateContinuationId(FlowExecution flowExecution) { 147 return encode(flowExecution); 148 } 149 150 protected final Serializable parseContinuationId(String encodedId) { 151 return encodedId; 153 } 154 155 164 protected Serializable encode(FlowExecution flowExecution) { 165 FlowExecutionContinuation continuation = continuationFactory.createContinuation(flowExecution); 166 return new String (Base64.encodeBase64(continuation.toByteArray())); 167 } 168 169 179 protected FlowExecutionContinuation decode(String encodedContinuation) { 180 byte[] bytes = Base64.decodeBase64(encodedContinuation.getBytes()); 181 return continuationFactory.createContinuation(bytes); 182 } 183 184 190 private static class NoOpConversationManager implements ConversationManager { 191 192 195 private static final NoOpConversation INSTANCE = new NoOpConversation(); 196 197 public Conversation beginConversation(ConversationParameters conversationParameters) 198 throws ConversationException { 199 return INSTANCE; 200 } 201 202 public Conversation getConversation(ConversationId id) throws NoSuchConversationException { 203 return INSTANCE; 204 } 205 206 public ConversationId parseConversationId(String encodedId) throws ConversationException { 207 return NoOpConversation.ID; 208 } 209 210 private static class NoOpConversation implements Conversation { 211 212 private static final ConversationId ID = new ConversationId() { 213 public String toString() { 214 return "NoOpConversation id"; 215 } 216 }; 217 218 public ConversationId getId() { 219 return ID; 220 } 221 222 public void lock() { 223 } 224 225 public Object getAttribute(Object name) { 226 return CollectionUtils.EMPTY_ATTRIBUTE_MAP; 227 } 228 229 public void putAttribute(Object name, Object value) { 230 } 231 232 public void removeAttribute(Object name) { 233 } 234 235 public void end() { 236 } 237 238 public void unlock() { 239 } 240 } 241 } 242 } | Popular Tags |