Source Code Cross Referenced for FlowControllerFactory.java in  » Library » Apache-beehive-1.0.2-src » org » apache » beehive » netui » pageflow » 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 » Library » Apache beehive 1.0.2 src » org.apache.beehive.netui.pageflow 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         *
017:         * $Header:$
018:         */
019:        package org.apache.beehive.netui.pageflow;
020:
021:        import java.util.Map;
022:        import java.util.LinkedHashMap;
023:        import java.util.Iterator;
024:        import java.lang.reflect.Modifier;
025:        import javax.servlet.http.HttpServletRequest;
026:        import javax.servlet.http.HttpServletResponse;
027:        import javax.servlet.ServletContext;
028:
029:        import org.apache.beehive.netui.core.factory.Factory;
030:        import org.apache.beehive.netui.core.factory.FactoryUtils;
031:        import org.apache.beehive.netui.util.logging.Logger;
032:        import org.apache.beehive.netui.util.config.ConfigUtil;
033:        import org.apache.beehive.netui.util.config.bean.PageFlowFactoryConfig;
034:        import org.apache.beehive.netui.util.config.bean.PageFlowFactoriesConfig;
035:        import org.apache.beehive.netui.util.config.bean.PageFlowConfig;
036:        import org.apache.beehive.netui.util.config.bean.SharedFlowRefConfig;
037:        import org.apache.beehive.netui.pageflow.internal.InternalUtils;
038:        import org.apache.beehive.netui.pageflow.internal.InternalConstants;
039:        import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
040:        import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig;
041:        import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
042:        import org.apache.beehive.netui.pageflow.handler.Handlers;
043:        import org.apache.struts.config.ModuleConfig;
044:        import org.apache.struts.config.ControllerConfig;
045:
046:        /**
047:         * <p>
048:         * Factory for creating {@link FlowController}s - user {@link PageFlowController}s and {@link SharedFlowController}s.
049:         * </p>
050:         */
051:        public class FlowControllerFactory extends Factory {
052:            private static final Logger LOG = Logger
053:                    .getInstance(FlowControllerFactory.class);
054:
055:            private static final String CONTEXT_ATTR = InternalConstants.ATTR_PREFIX
056:                    + "fcFactory";
057:            private static final String NO_GLOBAL_APP_KEY = InternalConstants.ATTR_PREFIX
058:                    + "noglobalapp";
059:
060:            private transient ReloadableClassHandler _rch;
061:
062:            protected FlowControllerFactory() {
063:            }
064:
065:            /**
066:             * Initialize an instance of this class in the ServletContext.  This is a framework-invoked
067:             * method and should not normally be called directly.
068:             */
069:            public static void init(ServletContext servletContext) {
070:                PageFlowFactoriesConfig factoriesBean = ConfigUtil.getConfig()
071:                        .getPageFlowFactories();
072:                FlowControllerFactory factory = null;
073:
074:                if (factoriesBean != null) {
075:                    PageFlowFactoryConfig fcFactoryBean = factoriesBean
076:                            .getPageFlowFactory();
077:                    factory = (FlowControllerFactory) FactoryUtils.getFactory(
078:                            servletContext, fcFactoryBean,
079:                            FlowControllerFactory.class);
080:                }
081:
082:                if (factory == null)
083:                    factory = new FlowControllerFactory();
084:
085:                factory.reinit(servletContext);
086:
087:                servletContext.setAttribute(CONTEXT_ATTR, factory);
088:            }
089:
090:            /**
091:             * Called to reinitialize this instance, most importantly after it has been serialized/deserialized.
092:             *
093:             * @param servletContext the current ServletContext.
094:             */
095:            protected void reinit(ServletContext servletContext) {
096:                super .reinit(servletContext);
097:                if (_rch == null)
098:                    _rch = Handlers.get(servletContext)
099:                            .getReloadableClassHandler();
100:            }
101:
102:            /**
103:             * Get a {@link FlowControllerFactory}.  The instance returned may or may not have been cached.
104:             *
105:             * @param servletContext the current {@link ServletContext}.
106:             * @return a {@link FlowControllerFactory} for the given {@link ServletContext}.
107:             */
108:            public static FlowControllerFactory get(
109:                    ServletContext servletContext) {
110:                FlowControllerFactory factory = (FlowControllerFactory) servletContext
111:                        .getAttribute(CONTEXT_ATTR);
112:                assert factory != null : FlowControllerFactory.class.getName()
113:                        + " was not found in ServletContext attribute "
114:                        + CONTEXT_ATTR;
115:                factory.reinit(servletContext);
116:                return factory;
117:            }
118:
119:            /**
120:             * Get the page flow instance that should be associated with the given request.  If it doesn't exist, create it.
121:             * If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
122:             * stored as the current page flow.
123:             *
124:             * @param context a {@link RequestContext} object which contains the current request and response.
125:             * @return the {@link PageFlowController} for the request, or <code>null</code> if none was found.
126:             */
127:            public PageFlowController getPageFlowForRequest(
128:                    RequestContext context) throws InstantiationException,
129:                    IllegalAccessException {
130:                String servletPath = InternalUtils
131:                        .getDecodedServletPath(context.getHttpRequest());
132:                return getPageFlowForPath(context, servletPath);
133:            }
134:
135:            /**
136:             * Get the page flow instance that should be associated with the given path.  If it doesn't exist, create it.
137:             * If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
138:             * stored as the current page flow.
139:             *
140:             * @param context a {@link RequestContext} object which contains the current request and response.
141:             * @param path a <strong>webapp-relative</strong> path.  The path should not contain the webapp context path.
142:             * @return the {@link PageFlowController} for the given path, or <code>null</code> if none was found.
143:             */
144:            public PageFlowController getPageFlowForPath(
145:                    RequestContext context, String path)
146:                    throws InstantiationException, IllegalAccessException {
147:                HttpServletRequest request = context.getHttpRequest();
148:                HttpServletResponse response = context.getHttpResponse();
149:                PageFlowController cur = PageFlowUtils.getCurrentPageFlow(
150:                        request, getServletContext());
151:                String parentDir = PageFlowUtils
152:                        .getModulePathForRelativeURI(path);
153:
154:                //
155:                // Reinitialize transient data that may have been lost on session failover.
156:                //
157:                if (cur != null)
158:                    cur.reinitialize(request, response, getServletContext());
159:
160:                //
161:                // If there's no current PageFlow, or if the current PageFlowController has a module path that
162:                // is incompatible with the current request URI, then create the appropriate PageFlowController.
163:                //
164:                if (cur == null
165:                        || !PageFlowUtils.getModulePathForRelativeURI(
166:                                cur.getURI()).equals(parentDir)) {
167:                    String className = null;
168:                    try {
169:                        className = InternalUtils.getFlowControllerClassName(
170:                                parentDir, request, getServletContext());
171:                        return className != null ? createPageFlow(context,
172:                                className) : null;
173:                    } catch (ClassNotFoundException e) {
174:                        if (LOG.isInfoEnabled())
175:                            LOG.info("No page flow exists for path " + path
176:                                    + ".  Unable to load class \"" + className
177:                                    + "\".  Cause: " + e, e);
178:                        return null;
179:                    }
180:                }
181:
182:                return cur;
183:            }
184:
185:            /**
186:             * Create a {@link PageFlowController} of the given type.  The {@link PageFlowController} stack used
187:             * for nesting will be cleared or pushed, and the new instance will be stored as the current
188:             * {@link PageFlowController}.
189:             *
190:             * @param context a {@link RequestContext} object which contains the current request and response.
191:             * @param pageFlowClassName the type name of the desired page flow.
192:             * @return the newly-created PageFlowController, or <code>null</code> if none was found.
193:             */
194:            public PageFlowController createPageFlow(RequestContext context,
195:                    String pageFlowClassName) throws ClassNotFoundException,
196:                    InstantiationException, IllegalAccessException {
197:                Class pageFlowClass = getFlowControllerClass(pageFlowClassName);
198:                return createPageFlow(context, pageFlowClass);
199:            }
200:
201:            /**
202:             * Create a {@link PageFlowController} of the given type.  The PageFlowController stack (for
203:             * nesting) will be cleared or pushed, and the new instance will be stored as the current
204:             * PageFlowController.
205:             *
206:             * @param context a {@link RequestContext} object which contains the current request and response.
207:             * @param pageFlowClass the type of the desired {@link PageFlowController}.
208:             * @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
209:             */
210:            public PageFlowController createPageFlow(RequestContext context,
211:                    Class pageFlowClass) throws InstantiationException,
212:                    IllegalAccessException {
213:                assert PageFlowController.class.isAssignableFrom(pageFlowClass) : pageFlowClass
214:                        .getName();
215:
216:                // If this is an abstract controller class, don't use it.
217:                if (Modifier.isAbstract(pageFlowClass.getModifiers())) {
218:                    if (LOG.isInfoEnabled())
219:                        LOG.info("Unable to create Page Flow for class \""
220:                                + pageFlowClass.getName()
221:                                + "\" because the class is abstract");
222:                    return null;
223:                }
224:
225:                //
226:                // First check if this is a request for a "long lived" page flow.  If so, try
227:                // PageFlowUtils.getCurrentPageFlow again, with the longLived flag.
228:                //
229:                HttpServletRequest request = context.getHttpRequest();
230:                HttpServletResponse response = context.getHttpResponse();
231:                ServletContext servletContext = getServletContext();
232:                PageFlowController retVal = null;
233:                // Make sure our request wrapper is in place.
234:                request = PageFlowRequestWrapper.wrapRequest(request);
235:                String modulePath = InternalUtils
236:                        .inferModulePathFromClassName(pageFlowClass.getName());
237:                ModuleConfig mc = InternalUtils.ensureModuleConfig(modulePath,
238:                        servletContext);
239:
240:                if (mc == null) {
241:                    LOG.error("Struts module " + modulePath + " not found for "
242:                            + pageFlowClass.getName()
243:                            + "; cannot create page flow.");
244:                    return null;
245:                }
246:
247:                if (InternalUtils.isLongLived(mc)) {
248:                    retVal = PageFlowUtils.getLongLivedPageFlow(modulePath,
249:                            request, servletContext);
250:
251:                    if (LOG.isDebugEnabled()) {
252:                        if (retVal != null) {
253:                            LOG
254:                                    .debug("Using long lived PageFlowController of type "
255:                                            + pageFlowClass.getName());
256:                        }
257:                    }
258:                }
259:
260:                //
261:                // First, see if this is a nested page flow that's already on the stack.  Unless "renesting" is explicitly
262:                // enabled, we don't want to allow another instance of this page flow to be nested.  This is a common
263:                // browser back-button problem:
264:                //    1) request nested page flow A
265:                //    2) request nested page flow B
266:                //    3) press back button, and execute an action on A.
267:                //
268:                // This logic does not deal with immediate self-nesting (A->A), which is taken care of in
269:                // PageFlowController.forwardTo().  Nested page flows can only self-nest by forwarding to the .jpf URI, not
270:                // indirectly by executing actions on themselves (think about it -- that would be a disaster).
271:                //
272:                boolean createdNew = false;
273:                boolean isNestable = InternalUtils.isNestable(mc);
274:                PageFlowStack pfStack = PageFlowStack.get(request,
275:                        getServletContext(), false);
276:
277:                if (isNestable && pfStack != null) {
278:                    PageFlowConfig options = ConfigUtil.getConfig()
279:                            .getPageFlowConfig();
280:
281:                    if (options == null || !options.isEnableSelfNesting()) {
282:                        PageFlowController existing = pfStack.popUntil(request,
283:                                pageFlowClass, true);
284:
285:                        if (existing != null) {
286:                            existing.persistInSession(request, response);
287:                            return existing;
288:                        } else {
289:                            //
290:                            // If the feature is enabled, crawl back through the nesting history.
291:                            // This is implemented below.
292:                            //
293:                        }
294:                    }
295:                }
296:
297:                //
298:                // OK, if it's not an existing long lived page flow, and if this wasn't a nested page flow already on the
299:                // stack, then create a new instance.
300:                //
301:                if (retVal == null) {
302:                    if (LOG.isDebugEnabled())
303:                        LOG.debug("Creating PageFlowController of type "
304:                                + pageFlowClass.getName());
305:
306:                    retVal = (PageFlowController) getFlowControllerInstance(pageFlowClass);
307:                    createdNew = true;
308:                }
309:
310:                //
311:                // Store the previous PageFlowController on the nesting stack (if this one is nestable),
312:                // or destroy the nesting stack.
313:                //
314:                if (isNestable) {
315:                    //
316:                    // Call create() on the newly-created page flow.  Note, the PageFlowController is responsible for
317:                    // driving the appropriate Control lifecycle.
318:                    //
319:                    if (createdNew)
320:                        retVal.create(request, response, servletContext);
321:
322:                    PageFlowController current = PageFlowUtils
323:                            .getCurrentPageFlow(request, getServletContext());
324:
325:                    if (current != null) {
326:                        if (LOG.isDebugEnabled())
327:                            LOG.debug("Pushing PageFlowController " + current
328:                                    + " onto the nesting stack");
329:
330:                        if (pfStack == null)
331:                            pfStack = PageFlowStack.get(request,
332:                                    getServletContext(), true);
333:                        pfStack.push(current, request);
334:                    }
335:
336:                    retVal.reinitialize(request, response, servletContext);
337:                    retVal.persistInSession(request, response);
338:                }
339:                //
340:                // New page flow is not nestable; behave accordingly
341:                //
342:                else {
343:                    //
344:                    // A Page Flow nesting stack exists and needs to be destroyed.
345:                    //
346:                    if (pfStack != null) {
347:                        if (LOG.isDebugEnabled())
348:                            LOG
349:                                    .debug("Destroying the PageFlowController stack.");
350:
351:                        //
352:                        // Start popping page flows until:
353:                        // 1) there are none left on the stack
354:                        // 2) we find one of the type we're returning.
355:                        // If (2), we'll use that one (this means that executing an action on a nesting page flow
356:                        // while in a nested one will not destroy the nesting page flow only to create a new instance of it).
357:                        //
358:                        PageFlowController onStackAlready = pfStack.popUntil(
359:                                request, retVal.getClass(), false);
360:
361:                        if (onStackAlready != null) {
362:                            if (LOG.isDebugEnabled())
363:                                LOG
364:                                        .debug("Found a page flow of type "
365:                                                + retVal.getClass()
366:                                                + " in the stack; "
367:                                                + "using that instance and stopping destruction of the nesting stack.");
368:
369:                            retVal = onStackAlready;
370:                            retVal.persistInSession(request, response);
371:                        } else {
372:                            //
373:                            // We're actually using the newly-created page flow, so call create() on it.
374:                            // Note that we make the call to persistInSession *before* create, so the previous flow's
375:                            // onDestroy() gets called before the new one's onCreate().
376:                            //
377:                            retVal.reinitialize(request, response,
378:                                    servletContext);
379:                            retVal.persistInSession(request, response);
380:                            retVal.create(request, response, servletContext);
381:                        }
382:                    }
383:                    //
384:                    // There is no nesting stack, so just persist the new page flow
385:                    //
386:                    else {
387:                        //
388:                        // We're actually using the newly-created page flow, so take several steps that:
389:                        // 1. reinitialize the new page flow
390:                        // 2. persiste the new page flow in the session.  Note, this causes the "destroy" lifecycle
391:                        //    method to be invoked on the previous page flow which is still in the session.
392:                        // 3. if the page flow is newly created, invoke its "create" lifecycle method.
393:                        //
394:                        // Note, steps 2 and 3 must happen in this order in order to remove the previous page flow from
395:                        // the session before adding the new one.
396:                        //
397:                        // For example, this code will execute when forwarding from an existing Page Flow to a new Page Flow
398:                        //
399:                        retVal.reinitialize(request, response, servletContext);
400:                        retVal.persistInSession(request, response);
401:                        if (createdNew)
402:                            retVal.create(request, response, servletContext);
403:                    }
404:                }
405:
406:                return retVal;
407:            }
408:
409:            /**
410:             * Create a {@link SharedFlowController} of the given type.
411:             *
412:             * @param context a {@link RequestContext} object which contains the current request and response.
413:             * @param sharedFlowClassName the type name of the desired SharedFlowController.
414:             * @return the newly-created SharedFlowController, or <code>null</code> if none was found.
415:             */
416:            public SharedFlowController createSharedFlow(
417:                    RequestContext context, String sharedFlowClassName)
418:                    throws ClassNotFoundException, InstantiationException,
419:                    IllegalAccessException {
420:                Class sharedFlowClass = getFlowControllerClass(sharedFlowClassName);
421:                return createSharedFlow(context, sharedFlowClass);
422:            }
423:
424:            /**
425:             * Create a {@link SharedFlowController} of the given type.
426:             *
427:             * @param context a {@link RequestContext} object which contains the current request and response.
428:             * @param sharedFlowClass the type of the desired SharedFlowController.
429:             * @return the newly-created SharedFlowController, or <code>null</code> if none was found.
430:             */
431:            public SharedFlowController createSharedFlow(
432:                    RequestContext context, Class sharedFlowClass)
433:                    throws InstantiationException, IllegalAccessException {
434:                assert SharedFlowController.class
435:                        .isAssignableFrom(sharedFlowClass) : sharedFlowClass
436:                        .getName();
437:
438:                if (LOG.isDebugEnabled()) {
439:                    LOG.debug("Creating SharedFlowController of type "
440:                            + sharedFlowClass.getName());
441:                }
442:
443:                SharedFlowController retVal = (SharedFlowController) getFlowControllerInstance(sharedFlowClass);
444:                HttpServletRequest request = context.getHttpRequest();
445:                HttpServletResponse response = context.getHttpResponse();
446:                retVal.create(request, response, getServletContext());
447:
448:                if (LOG.isDebugEnabled()) {
449:                    LOG.debug("Storing new shared flow " + retVal
450:                            + " in the session");
451:                }
452:
453:                retVal.persistInSession(request, response);
454:                return retVal;
455:            }
456:
457:            /**
458:             * Get the map of shared flows for the given request.  The map is derived from the shared flows
459:             * that are declared (through the <code>sharedFlowRefs</code> attribute of
460:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller &#64;Jpf.Controller}) in the
461:             * page flow for the request.
462:             *
463:             * @param context a {@link RequestContext} object which contains the current request and response.
464:             * @return a Map of shared-flow-name (String) to {@link SharedFlowController}.
465:             * @throws ClassNotFoundException if a declared shared flow class could not be found.
466:             * @throws InstantiationException if a declared shared flow class could not be instantiated.
467:             * @throws IllegalAccessException if a declared shared flow class was not accessible.
468:             */
469:            public Map/*< String, SharedFlowController >*/getSharedFlowsForRequest(
470:                    RequestContext context) throws ClassNotFoundException,
471:                    InstantiationException, IllegalAccessException {
472:                String path = InternalUtils.getDecodedServletPath(context
473:                        .getHttpRequest());
474:                return getSharedFlowsForPath(context, path);
475:            }
476:
477:            /**
478:             * Get the map of shared flows for the given path.  The map is derived from the shared flows
479:             * that are declared (through the <code>sharedFlowRefs</code> attribute of
480:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller &#64;Jpf.Controller}) in the page flow
481:             * for the path.
482:             *
483:             * @param context a {@link RequestContext} object which contains the current request and response.
484:             * @param path a <strong>webapp-relative</strong> path.  The path should not contain the webapp context path.
485:             * @return a Map of shared-flow-name (String) to {@link SharedFlowController}.
486:             * @throws ClassNotFoundException if a declared shared flow class could not be found.
487:             * @throws InstantiationException if a declared shared flow class could not be instantiated.
488:             * @throws IllegalAccessException if a declared shared flow class was not accessible.
489:             */
490:            public Map/*< String, SharedFlowController >*/getSharedFlowsForPath(
491:                    RequestContext context, String path)
492:                    throws ClassNotFoundException, InstantiationException,
493:                    IllegalAccessException {
494:                String parentDir = PageFlowUtils
495:                        .getModulePathForRelativeURI(path);
496:                HttpServletRequest request = context.getHttpRequest();
497:                HttpServletResponse response = context.getHttpResponse();
498:                ModuleConfig mc = InternalUtils.ensureModuleConfig(parentDir,
499:                        getServletContext());
500:                LinkedHashMap/*< String, SharedFlowController >*/sharedFlows = getDefaultSharedFlows(context);
501:
502:                if (mc != null) {
503:                    ControllerConfig cc = mc.getControllerConfig();
504:
505:                    if (cc instanceof  PageFlowControllerConfig) {
506:                        Map/*< String, String >*/sharedFlowTypes = ((PageFlowControllerConfig) cc)
507:                                .getSharedFlowTypes();
508:
509:                        if (sharedFlowTypes != null
510:                                && sharedFlowTypes.size() > 0) {
511:                            if (sharedFlows == null)
512:                                sharedFlows = new LinkedHashMap/*< String, SharedFlowController >*/();
513:
514:                            for (Iterator/*<Map.Entry>*/i = sharedFlowTypes
515:                                    .entrySet().iterator(); i.hasNext();) {
516:                                Map.Entry entry = (Map.Entry) i.next();
517:                                String name = (String) entry.getKey();
518:                                String type = (String) entry.getValue();
519:                                addSharedFlow(context, name, type, sharedFlows);
520:                            }
521:
522:                            return sharedFlows;
523:                        }
524:                    }
525:                }
526:
527:                //
528:                // Legacy behavior: if there's no shared flow for the request, initialize a GlobalApp instance.
529:                //
530:                SharedFlowController ga = PageFlowUtils.getGlobalApp(request);
531:
532:                if (ga != null) {
533:                    ga.reinitialize(request, response, getServletContext());
534:                } else {
535:                    getGlobalApp(request, response, getServletContext());
536:                }
537:
538:                return sharedFlows;
539:            }
540:
541:            /**
542:             * Get a FlowController class.  By default, this loads the class using the thread context class loader.
543:             * 
544:             * @param className the name of the {@link FlowController} class to load.
545:             * @return the loaded {@link FlowController} class.
546:             * @throws ClassNotFoundException if the requested class could not be found.
547:             */
548:            public Class getFlowControllerClass(String className)
549:                    throws ClassNotFoundException {
550:                return _rch.loadClass(className);
551:            }
552:
553:            /**
554:             * Get a FlowController instance, given a FlowController class.
555:             * 
556:             * @param flowControllerClass the Class, which must be assignable to {@link FlowController}.
557:             * @return a new FlowController instance.
558:             */
559:            public FlowController getFlowControllerInstance(
560:                    Class flowControllerClass) throws InstantiationException,
561:                    IllegalAccessException {
562:                assert FlowController.class
563:                        .isAssignableFrom(flowControllerClass) : "Class "
564:                        + flowControllerClass.getName() + " does not extend "
565:                        + FlowController.class.getName();
566:                return (FlowController) flowControllerClass.newInstance();
567:            }
568:
569:            /* ------------------------------------------------------------------------------
570:
571:                Deprecated APIs
572:
573:               ------------------------------------------------------------------------------ */
574:
575:            /**
576:             * Get the page flow instance that should be associated with the given request.  If it doesn't exist, create it. 
577:             * If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
578:             * stored as the current page flow.
579:             * @deprecated Use {@link #getPageFlowForRequest(RequestContext)} instead.
580:             * 
581:             * @param request the current HttpServletRequest.
582:             * @param response the current HttpServletResponse.
583:             * @param servletContext the current ServletContext.
584:             * @return the {@link PageFlowController} for the request, or <code>null</code> if none was found.
585:             */
586:            public static PageFlowController getPageFlowForRequest(
587:                    HttpServletRequest request, HttpServletResponse response,
588:                    ServletContext servletContext) {
589:                return getPageFlowForRelativeURI(request, response,
590:                        InternalUtils.getDecodedServletPath(request),
591:                        servletContext);
592:            }
593:
594:            /**
595:             * Get the page flow instance that should be associated with the given URI.  If it doesn't exist, create it. 
596:             * If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
597:             * stored as the current page flow.
598:             * @deprecated Use {@link #getPageFlowForPath(RequestContext, String)} instead.  The URI must be stripped of the
599:             *     webapp context path before being passed.
600:             * 
601:             * @param request the current HttpServletRequest.
602:             * @param response the current HttpServletResponse.
603:             * @param uri a server-relative URI.  The URI should contain the webapp context path.
604:             * @param servletContext the current ServletContext.
605:             * @return the {@link PageFlowController} for the given URI, or <code>null</code> if none was found.
606:             */
607:            public static PageFlowController getPageFlowForURI(
608:                    HttpServletRequest request, HttpServletResponse response,
609:                    String uri, ServletContext servletContext) {
610:                return getPageFlowForRelativeURI(request, response,
611:                        PageFlowUtils.getRelativeURI(request, uri, null),
612:                        servletContext);
613:            }
614:
615:            /**
616:             * Get the page flow instance that should be associated with the given path.  If it doesn't exist, create it. 
617:             * If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
618:             * stored as the current page flow.
619:             * @deprecated Use {@link #getPageFlowForPath(RequestContext, String)} instead.
620:             * 
621:             * @param request the current HttpServletRequest.
622:             * @param response the current HttpServletResponse.
623:             * @param path a <strong>webapp-relative</strong> path.  The path should not contain the webapp context path.
624:             * @param servletContext the current ServletContext.
625:             * @return the {@link PageFlowController} for the given path, or <code>null</code> if none was found.
626:             */
627:            public static PageFlowController getPageFlowForRelativeURI(
628:                    HttpServletRequest request, HttpServletResponse response,
629:                    String path, ServletContext servletContext) {
630:                try {
631:                    return get(servletContext).getPageFlowForPath(
632:                            new RequestContext(request, response), path);
633:                } catch (InstantiationException e) {
634:                    LOG.error(
635:                            "Could not instantiate PageFlowController for request "
636:                                    + request.getRequestURI(), e);
637:                    return null;
638:                } catch (IllegalAccessException e) {
639:                    LOG.error(
640:                            "Could not instantiate PageFlowController for request "
641:                                    + request.getRequestURI(), e);
642:                    return null;
643:                }
644:            }
645:
646:            /**
647:             * Create a page flow of the given type.  The page flow stack (for nesting) will be cleared or pushed, and the new
648:             * instance will be stored as the current page flow.
649:             * @deprecated Use {@link #createPageFlow(RequestContext, String)} instead.
650:             * 
651:             * @param request the current HttpServletRequest.
652:             * @param response the current HttpServletResponse.
653:             * @param pageFlowClassName the type name of the desired page flow.
654:             * @param servletContext the current ServletContext.
655:             * @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
656:             */
657:            public static PageFlowController getPageFlow(
658:                    String pageFlowClassName, HttpServletRequest request,
659:                    HttpServletResponse response, ServletContext servletContext) {
660:                try {
661:                    return get(servletContext).createPageFlow(
662:                            new RequestContext(request, response),
663:                            pageFlowClassName);
664:                } catch (ClassNotFoundException e) {
665:                    LOG.error("Requested page flow class " + pageFlowClassName
666:                            + " not found.");
667:                    return null;
668:                } catch (InstantiationException e) {
669:                    LOG.error(
670:                            "Could not instantiate PageFlowController of type "
671:                                    + pageFlowClassName, e);
672:                    return null;
673:                } catch (IllegalAccessException e) {
674:                    LOG.error(
675:                            "Could not instantiate PageFlowController of type "
676:                                    + pageFlowClassName, e);
677:                    return null;
678:                }
679:            }
680:
681:            /**
682:             * Get or create the current user session's GlobalApp instance (from the Global.app file).
683:             * @deprecated Global.app is deprecated; use shared flows and {@link #getSharedFlowsForRequest(RequestContext)}.
684:             * 
685:             * @param request the current HttpServletRequest.
686:             * @param response the current HttpServletResponse.
687:             * @return the current session's {@link GlobalApp} instance, or a new one (based on Global.app) if none is found.
688:             *     If Global.app does not exist in the current webapp, <code>null</code> is returned.
689:             */
690:            public static GlobalApp getGlobalApp(HttpServletRequest request,
691:                    HttpServletResponse response, ServletContext servletContext) {
692:                Boolean noGlobalApp = (Boolean) servletContext
693:                        .getAttribute(NO_GLOBAL_APP_KEY);
694:                if (noGlobalApp != null && noGlobalApp.booleanValue())
695:                    return null;
696:
697:                GlobalApp current = PageFlowUtils.getGlobalApp(request);
698:                if (current != null)
699:                    return current;
700:
701:                try {
702:                    try {
703:                        FlowControllerFactory factory = get(servletContext);
704:                        SharedFlowController sf = factory.createSharedFlow(
705:                                new RequestContext(request, response),
706:                                PageFlowConstants.GLOBALAPP_CLASSNAME);
707:
708:                        if (!(sf instanceof  GlobalApp)) {
709:                            LOG.error("Class "
710:                                    + PageFlowConstants.GLOBALAPP_CLASSNAME
711:                                    + " is not an instance of "
712:                                    + GlobalApp.class.getName());
713:                            return null;
714:                        }
715:
716:                        return (GlobalApp) sf;
717:                    } catch (InstantiationException e) {
718:                        LOG.error("Could not instantiate Global.app.", e);
719:                        return null;
720:                    } catch (IllegalAccessException e) {
721:                        LOG.error("Could not instantiate Global.app", e);
722:                        return null;
723:                    }
724:                }
725:                /*
726:                This is an expected failure.  When no "global/Global.class" is found in classloader, the
727:                ReloadableClassHandler will throw a CNF exception.  When that happens, set a flag that
728:                short-circuits this check on subsequent requests so as to prevent throwing CNF(s) for
729:                every request.
730:
731:                Note, iterative development of "global/Global.class" files doesn't work in "bouncy" mode
732:                and shouldn't -- this is a deprecated feature and just needs to continue to function.
733:                 */
734:                catch (ClassNotFoundException e) {
735:                    LOG.info("No Global.app was found in "
736:                            + request.getContextPath());
737:                    servletContext
738:                            .setAttribute(NO_GLOBAL_APP_KEY, Boolean.TRUE);
739:                    return null;
740:                }
741:            }
742:
743:            /**
744:             * Create a page flow of the given type.  The page flow stack (for nesting) will be cleared or pushed, and the new
745:             * instance will be stored as the current page flow.
746:             * @deprecated Use {@link #createPageFlow(RequestContext, Class)} instead.
747:             * 
748:             * @param request the current HttpServletRequest.
749:             * @param response the current HttpServletResponse.
750:             * @param pageFlowClass the type of the desired page flow.
751:             * @param servletContext the current ServletContext.
752:             * @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
753:             */
754:            public static PageFlowController getPageFlow(Class pageFlowClass,
755:                    HttpServletRequest request, HttpServletResponse response,
756:                    ServletContext servletContext) {
757:                try {
758:                    FlowControllerFactory factory = get(servletContext);
759:                    return factory.createPageFlow(new RequestContext(request,
760:                            response), pageFlowClass);
761:                } catch (InstantiationException e) {
762:                    LOG.error(
763:                            "Could not instantiate PageFlowController of type "
764:                                    + pageFlowClass.getName(), e);
765:                    return null;
766:                } catch (IllegalAccessException e) {
767:                    LOG.error(
768:                            "Could not instantiate PageFlowController of type "
769:                                    + pageFlowClass.getName(), e);
770:                    return null;
771:                }
772:            }
773:
774:            /* ------------------------------------------------------------------------------
775:
776:                Internal APIs
777:
778:               ------------------------------------------------------------------------------ */
779:
780:            LinkedHashMap/*< String, SharedFlowController >*/getDefaultSharedFlows(
781:                    RequestContext context) throws ClassNotFoundException,
782:                    InstantiationException, IllegalAccessException {
783:                SharedFlowRefConfig[] defaultRefs = ConfigUtil.getConfig()
784:                        .getSharedFlowRefs();
785:
786:                if (defaultRefs != null) {
787:                    if (defaultRefs.length > 0) {
788:                        LinkedHashMap/*< String, SharedFlowController >*/sharedFlows = new LinkedHashMap();
789:
790:                        for (int i = 0; i < defaultRefs.length; i++) {
791:                            SharedFlowRefConfig ref = defaultRefs[i];
792:                            if (LOG.isInfoEnabled()) {
793:                                LOG
794:                                        .info("Shared flow of type "
795:                                                + ref.getType()
796:                                                + " is a default shared flow reference "
797:                                                + "with name " + ref.getName());
798:                            }
799:                            addSharedFlow(context, ref.getName(),
800:                                    ref.getType(), sharedFlows);
801:                        }
802:
803:                        return sharedFlows;
804:                    }
805:                }
806:
807:                return null;
808:            }
809:
810:            private void addSharedFlow(RequestContext context, String name,
811:                    String type, LinkedHashMap sharedFlows)
812:                    throws ClassNotFoundException, InstantiationException,
813:                    IllegalAccessException {
814:                HttpServletRequest request = context.getHttpRequest();
815:                SharedFlowController sf = PageFlowUtils.getSharedFlow(type,
816:                        request);
817:
818:                //
819:                // Reinitialize transient data that may have been lost on session failover.
820:                //
821:                if (sf != null) {
822:                    sf.reinitialize(request, context.getHttpResponse(),
823:                            getServletContext());
824:                } else {
825:                    sf = createSharedFlow(context, type);
826:                }
827:
828:                if (!(sf instanceof  GlobalApp))
829:                    sharedFlows.put(name, sf);
830:            }
831:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.