SWFFlowExecutorImpl.java :  » Web-Framework » RSF » uk » org » ponder » rsf » swf » support » Java Open Source

Java Open Source » Web Framework » RSF 
RSF » uk » org » ponder » rsf » swf » support » SWFFlowExecutorImpl.java
/*
 * Created on 13 Sep 2007
 */
package uk.org.ponder.rsf.swf.support;

import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.execution.FlowExecution;
import org.springframework.webflow.execution.ViewSelection;
import org.springframework.webflow.execution.repository.FlowExecutionKey;
import org.springframework.webflow.execution.repository.FlowExecutionLock;
import org.springframework.webflow.execution.repository.FlowExecutionRepository;
import org.springframework.webflow.executor.FlowExecutorImpl;
import org.springframework.webflow.executor.ResponseInstruction;

/**
 * A mirror of the builtin SWF "FlowExecutorImpl" construct, modified marginally
 * to supply a "work payload" represented by a Runnable to be executed before
 * the flow is closed. The implementation "operate" is a composite of the
 * "resume" and "refresh" functions of the original Executor, since the event
 * identity or even whether there is an event will not be known until the
 * supplied "StringGetter" has executed within the context of the opened flow.
 * </p>
 * Within RSF, this Executor takes place as an "AlterationWrapper".
 * 
 * @author Antranig Basman (antranig@caret.cam.ac.uk)
 * 
 */

public class SWFFlowExecutorImpl {

  private FlowExecutionRepository executionRepository;

  public void setFlowExecutorImpl(FlowExecutorImpl flowExecutorImpl) {
    executionRepository = flowExecutorImpl.getExecutionRepository();
  }

  public void operate(String flowExecutionKey, SWFExecutionPayload payload,
      final ExternalContext context) throws FlowException {
    // expose external context as a thread-bound service
    ExternalContextHolder.setExternalContext(context);
    try {
      final FlowExecutionKey key = executionRepository
          .parseFlowExecutionKey(flowExecutionKey);
      FlowExecutionLock lock = executionRepository.getLock(key);
      // make sure we're the only one manipulating the flow execution
      lock.lock();
      try {
        final FlowExecution flowExecution = executionRepository
            .getFlowExecution(key);
        payload.executeInRequest(flowExecution,
            new ResponseInstructionGetter() {
              public ResponseInstruction getResponse(String eventId) {
                if (eventId != null) {
                  ViewSelection selectedView = flowExecution.signalEvent(
                      eventId, context);

                  if (flowExecution.isActive()) {
                    // execution still active => store it in the repository
                    FlowExecutionKey innerkey = executionRepository.getNextKey(
                        flowExecution, key);
                    executionRepository.putFlowExecution(innerkey,
                        flowExecution);
                    return new ResponseInstruction(innerkey.toString(),
                        flowExecution, selectedView);
                  }
                  else {
                    // execution ended => remove it from the repository
                    executionRepository.removeFlowExecution(key);
                    return new ResponseInstruction(flowExecution, selectedView);
                  }
                }
                else {
                  ViewSelection selectedView = flowExecution.refresh(context);
                  // don't generate a new key for a refresh, just update
                  // the flow execution with it's existing key
                  executionRepository.putFlowExecution(key, flowExecution);
                  return new ResponseInstruction(key.toString(), flowExecution,
                      selectedView);
                }
              }
            });

      }
      finally {
        lock.unlock();
      }
    }
    finally {
      ExternalContextHolder.setExternalContext(null);
    }
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.