Source Code Cross Referenced for FlowNavigationHandler.java in  » Workflow-Engines » spring-webflow-1.0.4 » org » springframework » webflow » executor » jsf » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » spring webflow 1.0.4 » org.springframework.webflow.executor.jsf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.springframework.webflow.executor.jsf;
017:
018:        import javax.faces.application.NavigationHandler;
019:        import javax.faces.context.FacesContext;
020:
021:        import org.apache.commons.logging.Log;
022:        import org.apache.commons.logging.LogFactory;
023:        import org.springframework.binding.mapping.AttributeMapper;
024:        import org.springframework.web.jsf.DecoratingNavigationHandler;
025:        import org.springframework.webflow.context.ExternalContext;
026:        import org.springframework.webflow.context.ExternalContextHolder;
027:        import org.springframework.webflow.core.collection.LocalAttributeMap;
028:        import org.springframework.webflow.core.collection.MutableAttributeMap;
029:        import org.springframework.webflow.definition.FlowDefinition;
030:        import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
031:        import org.springframework.webflow.engine.NoMatchingTransitionException;
032:        import org.springframework.webflow.execution.FlowExecution;
033:        import org.springframework.webflow.execution.FlowExecutionFactory;
034:        import org.springframework.webflow.execution.ViewSelection;
035:        import org.springframework.webflow.executor.RequestParameterInputMapper;
036:        import org.springframework.webflow.executor.support.FlowExecutorArgumentExtractor;
037:
038:        /**
039:         * An implementation of a JSF <code>NavigationHandler</code> that provides integration with Spring Web Flow.
040:         * Responsible for delegating to Spring Web Flow to launch and resume flow executions, treating JSF action outcomes
041:         * (like a command button click) as web flow events.
042:         * 
043:         * This class delegates to the standard NavigationHandler implementation when a navigation request does not pertain to a
044:         * flow execution.
045:         * <p>
046:         * The following navigation handler algorithm is implemented by default:
047:         * </p>
048:         * <p>
049:         * If a flow execution has been restored in the current request:
050:         * <ul>
051:         * <li>Resume the flow execution by signaling the JSF action outcome as an event against the current state.
052:         * <li>Once event processing completes expose the selected view as the "current" {@link ViewSelection}.
053:         * </ul>
054:         * </p>
055:         * <p>
056:         * If a flow execution has not been restored in the current request:
057:         * <ul>
058:         * <li>If the specified logical outcome is of the form <em>flowId:xxx</em> look up the corresponding
059:         * {@link FlowDefinition} with that id and launch a new flow execution in the starting state. Expose the new execution
060:         * as the "current" flow execution for this request. Expose the first selected view as the "current" view selection.
061:         * <li>If the specified logical outcome is not of the form <em>flowId:xxx</em>, simply delegate to the standard
062:         * <code>NavigationHandler</code> implementation and return.
063:         * </ul>
064:         * </p>
065:         * How the flowId and eventId arguments are extracted can be customized by setting a custom
066:         * {@link #setArgumentExtractor(FlowExecutorArgumentExtractor) argument extractor}.
067:         * 
068:         * Note about customization: since NavigationHandlers managed directly by the JSF provider cannot be benefit from
069:         * DependencyInjection, See Spring's {@link org.springframework.web.jsf.DelegatingNavigationHandlerProxy} when you need
070:         * to customize a FlowNavigationHandler instance.
071:         * 
072:         * @author Craig McClanahan
073:         * @author Colin Sampaleanu
074:         * @author Keith Donald
075:         */
076:        public class FlowNavigationHandler extends DecoratingNavigationHandler {
077:
078:            /**
079:             * Logger, usable by subclasses.
080:             */
081:            protected final Log logger = LogFactory.getLog(getClass());
082:
083:            /**
084:             * A helper for extracting parameters needed by this flow navigation handler.
085:             */
086:            private FlowExecutorArgumentExtractor argumentExtractor = new FlowNavigationHandlerArgumentExtractor();
087:
088:            /**
089:             * The service responsible for mapping attributes of an {@link ExternalContext} to a new {@link FlowExecution}
090:             * during the {@link #launch(String, ExternalContext) launch flow} operation.
091:             * <p>
092:             * This allows developers to control what attributes are made available in the <code>inputMap</code> to new
093:             * top-level flow executions. The starting execution may then choose to map that available input into its own local
094:             * scope.
095:             * <p>
096:             * The default implementation simply exposes all request parameters as flow execution input attributes. May be null.
097:             */
098:            private AttributeMapper inputMapper = new RequestParameterInputMapper();
099:
100:            /**
101:             * Create a new {@link FlowNavigationHandler} using the default constructor.
102:             */
103:            public FlowNavigationHandler() {
104:                super ();
105:            }
106:
107:            /**
108:             * Create a new {@link FlowNavigationHandler}, wrapping the specified standard navigation handler implementation.
109:             * @param originalNavigationHandler Standard <code>NavigationHandler</code> we are wrapping
110:             */
111:            public FlowNavigationHandler(
112:                    NavigationHandler originalNavigationHandler) {
113:                super (originalNavigationHandler);
114:            }
115:
116:            /**
117:             * Returns the argument extractor used by this navigation handler.
118:             */
119:            public FlowExecutorArgumentExtractor getArgumentExtractor() {
120:                return argumentExtractor;
121:            }
122:
123:            /**
124:             * Sets the argument extractor to use by this navigation handler. Call to customize how flow id and event id
125:             * arguments are extracted.
126:             */
127:            public void setArgumentExtractor(
128:                    FlowExecutorArgumentExtractor argumentExtractor) {
129:                this .argumentExtractor = argumentExtractor;
130:            }
131:
132:            /**
133:             * Returns the configured flow execution input mapper.
134:             */
135:            public AttributeMapper getInputMapper() {
136:                return inputMapper;
137:            }
138:
139:            /**
140:             * Sets the service responsible for mapping attributes of an {@link ExternalContext} to a new {@link FlowExecution}
141:             * during a launch flow operation.
142:             * <p>
143:             * The default implementation simply exposes all request parameters as flow execution input attributes. May be null.
144:             * @see RequestParameterInputMapper
145:             */
146:            public void setInputMapper(AttributeMapper inputMapper) {
147:                this .inputMapper = inputMapper;
148:            }
149:
150:            public void handleNavigation(FacesContext facesContext,
151:                    String fromAction, String outcome,
152:                    NavigationHandler originalNavigationHandler) {
153:                try {
154:                    JsfExternalContext context = getCurrentContext();
155:                    // record the navigation handler context
156:                    context.handleNavigationCalled(fromAction, outcome);
157:                    // first see if we need to launch a new flow execution if the flow id is present
158:                    if (argumentExtractor.isFlowIdPresent(context)) {
159:                        // a flow execution launch has been requested - create the new execution
160:                        String flowId = argumentExtractor
161:                                .extractFlowId(context);
162:                        FlowDefinition flowDefinition = getLocator(context)
163:                                .getFlowDefinition(flowId);
164:                        FlowExecution flowExecution = getFactory(context)
165:                                .createFlowExecution(flowDefinition);
166:                        // check to see if this execution was created while another was running
167:                        if (FlowExecutionHolderUtils
168:                                .isFlowExecutionRestored(facesContext)) {
169:                            // replace the current flow execution with the new one
170:                            FlowExecutionHolderUtils.getFlowExecutionHolder(
171:                                    facesContext).replaceWith(flowExecution);
172:                        } else {
173:                            // bind the new execution as the 'current execution'
174:                            FlowExecutionHolderUtils.setFlowExecutionHolder(
175:                                    new FlowExecutionHolder(flowExecution),
176:                                    facesContext);
177:                        }
178:                        // start the new execution
179:                        ViewSelection selectedView = flowExecution.start(
180:                                createInput(context), context);
181:                        // set the starting view to render
182:                        FlowExecutionHolderUtils.getFlowExecutionHolder(
183:                                facesContext).setViewSelection(selectedView);
184:                    } else {
185:                        // not a launch request - see if this is a resume request to continue an existing execution
186:                        if (FlowExecutionHolderUtils
187:                                .isFlowExecutionRestored(facesContext)) {
188:                            // a flow execution has been restored - see if we need to signal an event against it
189:                            if (argumentExtractor.isEventIdPresent(context)) {
190:                                // signal the event against the current flow execution
191:                                String eventId = argumentExtractor
192:                                        .extractEventId(context);
193:                                try {
194:                                    FlowExecutionHolder holder = FlowExecutionHolderUtils
195:                                            .getFlowExecutionHolder(facesContext);
196:                                    ViewSelection selectedView = holder
197:                                            .getFlowExecution().signalEvent(
198:                                                    eventId, context);
199:                                    // set the next view to render
200:                                    holder.setViewSelection(selectedView);
201:                                } catch (NoMatchingTransitionException e) {
202:                                    if (logger.isDebugEnabled()) {
203:                                        logger
204:                                                .debug("No flow state transition found for event '"
205:                                                        + eventId
206:                                                        + "'; falling back to standard navigation handler.");
207:                                    }
208:                                    // not a valid event in the current state: proceed with standard navigation
209:                                    originalNavigationHandler.handleNavigation(
210:                                            facesContext, fromAction, outcome);
211:                                }
212:                            }
213:                        } else {
214:                            // neither a flow launch or resume request: proceed with standard navigation
215:                            originalNavigationHandler.handleNavigation(
216:                                    facesContext, fromAction, outcome);
217:                        }
218:                    }
219:                } catch (RuntimeException e) {
220:                    cleanupResources(facesContext);
221:                    throw e;
222:                } catch (Error e) {
223:                    cleanupResources(facesContext);
224:                    throw e;
225:                }
226:            }
227:
228:            /**
229:             * Factory method that creates the input attribute map for a newly created {@link FlowExecution}. This
230:             * implementation uses the registered input mapper, if any.
231:             * @param context the external context
232:             * @return the input map, or null if no input
233:             */
234:            protected MutableAttributeMap createInput(ExternalContext context) {
235:                if (inputMapper != null) {
236:                    MutableAttributeMap inputMap = new LocalAttributeMap();
237:                    inputMapper.map(context, inputMap, null);
238:                    return inputMap;
239:                } else {
240:                    return null;
241:                }
242:            }
243:
244:            // helpers
245:
246:            private JsfExternalContext getCurrentContext() {
247:                return (JsfExternalContext) ExternalContextHolder
248:                        .getExternalContext();
249:            }
250:
251:            private FlowDefinitionLocator getLocator(JsfExternalContext context) {
252:                return FlowFacesUtils.getDefinitionLocator(context
253:                        .getFacesContext());
254:            }
255:
256:            private FlowExecutionFactory getFactory(JsfExternalContext context) {
257:                return FlowFacesUtils.getExecutionFactory(context
258:                        .getFacesContext());
259:            }
260:
261:            private void cleanupResources(FacesContext context) {
262:                if (logger.isDebugEnabled()) {
263:                    logger.debug("Cleaning up allocated flow system resources");
264:                }
265:                FlowExecutionHolderUtils.cleanupCurrentFlowExecution(context);
266:                ExternalContextHolder.setExternalContext(null);
267:            }
268:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.