View Javadoc

1   /*
2    * Copyright (c) 2005-2007 Creative Sphere Limited.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *
10   *   Creative Sphere - initial API and implementation
11   *
12   */
13  package org.abstracthorizon.danube.webflow;
14  
15  import java.util.HashMap;
16  import java.util.Map;
17  
18  import org.abstracthorizon.danube.connection.Connection;
19  import org.abstracthorizon.danube.connection.ConnectionException;
20  import org.abstracthorizon.danube.http.HTTPConnection;
21  import org.abstracthorizon.danube.http.session.HTTPSessionManager;
22  import org.abstracthorizon.danube.http.session.SimpleSessionManager;
23  import org.abstracthorizon.danube.mvc.Controller;
24  import org.abstracthorizon.danube.mvc.ModelAndView;
25  import org.springframework.webflow.context.ExternalContext;
26  import org.springframework.webflow.execution.support.ApplicationView;
27  import org.springframework.webflow.executor.FlowExecutor;
28  import org.springframework.webflow.executor.ResponseInstruction;
29  import org.springframework.webflow.executor.mvc.FlowController;
30  import org.springframework.webflow.executor.support.FlowExecutorArgumentExtractor;
31  import org.springframework.webflow.executor.support.FlowRequestHandler;
32  
33  /**
34   * <p>
35   *   Flow execution manager for Danube MVC. This is a glue between Spring Webflow and Danube.
36   * </p>
37   * <p>
38   *   Note: Code is based on the code from {@link FlowController} by Erwin Vervaet and Keith Donald
39   * </p>
40   *
41   * @author Daniel Sendula
42   */
43  public class DanubeFlowController implements Controller {
44  
45      /** Flow executor */
46      private FlowExecutor flowExecutor;
47  
48      /** Argument extractor */
49      private FlowExecutorArgumentExtractor argumentExtractor = null; // TODO !!! new FlowExecutorArgumentExtractor();
50  
51      /** Session manager */
52      private HTTPSessionManager sessionManager;
53  
54      /** Context attributes */
55      private Map<String, Object> attributes;
56  
57      /**
58       * Constructor.
59       */
60      public DanubeFlowController() {
61      }
62  
63      /**
64       * Sets the flow locator. It automatically creates and sets {@link FlowExecutionImpl}.
65  
66       * @param flowLocator flow locator
67       */
68  //  TODO !!!
69  //    public void setFlowLocator(FlowLocator flowLocator) {
70  //        this.flowExecutor = new FlowExecutorImpl(flowLocator);
71  //    }
72  
73      /**
74       * Returns flow executor.
75       *
76       * @return flow executor
77       */
78      public FlowExecutor getFlowExecutor() {
79          return flowExecutor;
80      }
81  
82      /**
83       * Sets flow executor.
84       *
85       * @param flowExecutor flow executor
86       */
87      public void setFlowExecutor(FlowExecutor flowExecutor) {
88          this.flowExecutor = flowExecutor;
89      }
90  
91      /**
92       * Returns argument extractor used by this controller.
93       * @return argument extractor
94       */
95      public FlowExecutorArgumentExtractor getArgumentExtractor() {
96          if (argumentExtractor == null) {
97  //          TODO !!! argumentExtractor = new FlowExecutorArgumentExtractor();
98          }
99          return argumentExtractor;
100     }
101 
102     /**
103      * Sets argument extractor to be used.
104      *
105      * @param parameterExtractor argument extractor
106      */
107     public void setArgumentExtractor(FlowExecutorArgumentExtractor parameterExtractor) {
108         this.argumentExtractor = parameterExtractor;
109     }
110 
111     /**
112      * Sets default flow id if none is specified with the parameters.
113      *
114      * @param defaultFlowId default flow id
115      */
116     public void setDefaultFlowId(String defaultFlowId) {
117         // TODO !!! this.argumentExtractor.setDefaultFlowId(defaultFlowId);
118     }
119 
120     /**
121      * Handles request
122      * @param connection connection
123      * @return model and view combination
124      * @throws ConnectionException connection exception
125      */
126     public ModelAndView handleRequest(Connection connection) throws ConnectionException {
127         try {
128             HTTPConnection httpConnection = (HTTPConnection) connection;
129 
130             DanubeExternalContext context = new DanubeExternalContext(this, httpConnection);
131 
132             FlowRequestHandler flowRequestHandler = new FlowRequestHandler(getFlowExecutor(), getArgumentExtractor());
133             ResponseInstruction responseInstruction = flowRequestHandler.handleFlowRequest(context);
134 
135             return toModelAndView(responseInstruction, context);
136         } catch (ConnectionException e) {
137             throw e;
138         } catch (Exception e) {
139             throw new ConnectionException(e);
140         }
141     }
142 
143     /**
144      * Returns model and a view combination
145      * @param response response instruction
146      * @param context external context
147      * @return model and view
148      */
149     @SuppressWarnings("unchecked")
150     protected ModelAndView toModelAndView(ResponseInstruction response, ExternalContext context) {
151         if (response.isApplicationView()) {
152             ApplicationView view = (ApplicationView)response.getViewSelection();
153             Map<String, Object> model = new HashMap<String, Object>(view.getModel());
154 //          TODO
155 //            argumentExtractor.put(response.getFlowExecutionKey(), model);
156 //            argumentExtractor.put(response.getFlowExecutionContext(), model);
157             return new ModelAndView(view.getViewName(), model);
158 // TODO
159 //        } else if (response.isConversationRedirect()) {
160 //            // redirect to active conversation URL
161 //            Serializable conversationId = response.getFlowExecutionKey().getConversationId();
162 //            String conversationUrl = argumentExtractor.createConversationUrl(conversationId, context);
163 //            return new org.springframework.web.servlet.ModelAndView(new RedirectView(conversationUrl, true));
164 //        } else if (response.isExternalRedirect()) {
165 //            // redirect to external URL
166 //            ExternalRedirect redirect = (ExternalRedirect)response.getViewSelection();
167 //            String externalUrl = argumentExtractor.createExternalUrl(redirect, response.getFlowExecutionKey(), context);
168 //            return new org.springframework.web.servlet.ModelAndView(new RedirectView(externalUrl, redirect.isContextRelative()));
169 //        } else if (response.isFlowRedirect()) {
170 //            // restart the flow by redirecting to flow launch URL
171 //            String flowUrl = argumentExtractor.createFlowUrl((FlowRedirect)response.getViewSelection(), context);
172 //            return new org.springframework.web.servlet.ModelAndView(new RedirectView(flowUrl, true));
173         } else if (response.isNull()) {
174             return null;
175         } else {
176             throw new IllegalArgumentException("Don't know how to handle response instruction " + response);
177         }
178     }
179 
180     /**
181      * Returns session manaager
182      * @return http session manager
183      */
184     public HTTPSessionManager getSessionManager() {
185         if (sessionManager == null) {
186             sessionManager = new SimpleSessionManager();
187         }
188         return sessionManager;
189     }
190 
191     /**
192      * Sets session manager
193      * @param sessionManager http session manager
194      */
195     public void setSessionManager(HTTPSessionManager sessionManager) {
196         this.sessionManager = sessionManager;
197     }
198 
199     /**
200      * Returns attributes as a map
201      * @return attributes
202      */
203     public Map<String, Object> getAttributes() {
204         if (attributes == null) {
205             attributes = new HashMap<String, Object>();
206         }
207         return attributes;
208     }
209 
210     /**
211      * Sets attributes map
212      * @param attributes attributes
213      */
214     public void setAttributes(Map<String, Object> attributes) {
215         if (attributes == null) {
216             getAttributes();
217         }
218         this.attributes = attributes;
219     }
220 }