Source Code Cross Referenced for PageFlowUtils.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) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         *
0017:         * $Header:$
0018:         */
0019:        package org.apache.beehive.netui.pageflow;
0020:
0021:        import org.apache.beehive.netui.core.urls.FreezableMutableURI;
0022:        import org.apache.beehive.netui.core.urls.MutableURI;
0023:        import org.apache.beehive.netui.core.urls.URIContext;
0024:        import org.apache.beehive.netui.core.urls.URLRewriterService;
0025:        import org.apache.beehive.netui.core.urls.URLType;
0026:        import org.apache.beehive.netui.core.urltemplates.URLTemplatesFactory;
0027:        import org.apache.beehive.netui.pageflow.internal.ActionResultImpl;
0028:        import org.apache.beehive.netui.pageflow.internal.InternalUtils;
0029:        import org.apache.beehive.netui.pageflow.internal.InternalConstants;
0030:        import org.apache.beehive.netui.pageflow.internal.AdapterManager;
0031:        import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
0032:        import org.apache.beehive.netui.pageflow.internal.URIContextFactory;
0033:        import org.apache.beehive.netui.pageflow.internal.DefaultURLTemplatesFactory;
0034:        import org.apache.beehive.netui.pageflow.scoping.ScopedRequest;
0035:        import org.apache.beehive.netui.pageflow.scoping.ScopedResponse;
0036:        import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
0037:        import org.apache.beehive.netui.pageflow.handler.StorageHandler;
0038:        import org.apache.beehive.netui.pageflow.handler.Handlers;
0039:        import org.apache.beehive.netui.util.internal.InternalStringBuilder;
0040:        import org.apache.beehive.netui.util.internal.FileUtils;
0041:        import org.apache.beehive.netui.util.internal.ServletUtils;
0042:        import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
0043:        import org.apache.beehive.netui.util.config.ConfigUtil;
0044:        import org.apache.beehive.netui.util.config.bean.UrlConfig;
0045:        import org.apache.beehive.netui.util.logging.Logger;
0046:        import org.apache.beehive.netui.script.common.ImplicitObjectUtil;
0047:        import org.apache.struts.action.ActionForm;
0048:        import org.apache.struts.action.ActionMapping;
0049:        import org.apache.struts.action.ActionServlet;
0050:        import org.apache.struts.action.ActionMessage;
0051:        import org.apache.struts.config.FormBeanConfig;
0052:        import org.apache.struts.config.ModuleConfig;
0053:        import org.apache.struts.upload.MultipartRequestWrapper;
0054:        import org.apache.struts.util.RequestUtils;
0055:
0056:        import javax.servlet.RequestDispatcher;
0057:        import javax.servlet.ServletContext;
0058:        import javax.servlet.ServletRequest;
0059:        import javax.servlet.http.HttpServletRequest;
0060:        import javax.servlet.http.HttpServletResponse;
0061:        import java.io.PrintStream;
0062:        import java.net.URISyntaxException;
0063:        import java.util.Collections;
0064:        import java.util.HashMap;
0065:        import java.util.Map;
0066:        import java.util.Stack;
0067:        import java.util.List;
0068:        import java.util.ArrayList;
0069:        import java.util.Iterator;
0070:
0071:        /**
0072:         * Utility methods related to Page Flow.
0073:         */
0074:        public class PageFlowUtils implements  PageFlowConstants,
0075:                InternalConstants {
0076:            private static final Logger _log = Logger
0077:                    .getInstance(PageFlowUtils.class);
0078:
0079:            private static final String PREVENT_CACHE_ATTR = InternalConstants.ATTR_PREFIX
0080:                    + "preventCache";
0081:            private static final String ACTION_URI_ATTR = ATTR_PREFIX
0082:                    + "_actionURI";
0083:            private static final int PAGEFLOW_EXTENSION_LEN = PAGEFLOW_EXTENSION
0084:                    .length();
0085:            private static final String DEFAULT_AUTORESOLVE_EXTENSIONS[] = new String[] {
0086:                    ACTION_EXTENSION, PAGEFLOW_EXTENSION };
0087:
0088:            /** Map of Struts module prefix to Map of form-type-name to form-name. */
0089:            private static Map/*< String, Map< String, List< String > > >*/_formNameMaps = new InternalConcurrentHashMap/*< String, Map< String, List< String > > >*/();
0090:
0091:            /**
0092:             * Get the Struts module path for a URI.  This is the parent directory, relative to the web
0093:             * application root, of the file referenced by the URI.
0094:             * 
0095:             * @param request the current HttpServletRequest.
0096:             * @param requestURI the URI for which to get the Struts module path.
0097:             */
0098:            public static String getModulePath(HttpServletRequest request,
0099:                    String requestURI) {
0100:                return getModulePathForRelativeURI(getRelativeURI(request,
0101:                        requestURI, null));
0102:            }
0103:
0104:            /**
0105:             * Get the Struts module path for the current request URI.  This is the parent directory,
0106:             * relative to the web application root, of the file referenced by the request URI.
0107:             * 
0108:             * @param request the current HttpServletRequest.
0109:             */
0110:            public static String getModulePath(HttpServletRequest request) {
0111:                return getModulePathForRelativeURI(InternalUtils
0112:                        .getDecodedServletPath(request));
0113:            }
0114:
0115:            /**
0116:             * Get the Struts module path for a URI that is relative to the web application root.
0117:             * 
0118:             * @param uri the URI for which to get the module path.
0119:             */
0120:            public static String getModulePathForRelativeURI(String uri) {
0121:                if (uri == null)
0122:                    return null;
0123:                assert uri.length() > 0;
0124:                assert uri.charAt(0) == '/' : uri;
0125:
0126:                // Strip off the actual page name (e.g., some_page.jsp)
0127:                int slash = uri.lastIndexOf('/');
0128:                uri = uri.substring(0, slash);
0129:
0130:                return uri;
0131:            }
0132:
0133:            /**
0134:             * Get the request URI, relative to the URI of the given PageFlowController.
0135:             *
0136:             * @param request the current HttpServletRequest.
0137:             * @param relativeTo a PageFlowController to which the returned URI should be relative, or
0138:             *        <code>null</code> if the returned URI should be relative to the webapp root.
0139:             */
0140:            public static String getRelativeURI(HttpServletRequest request,
0141:                    PageFlowController relativeTo) {
0142:                if (relativeTo == null)
0143:                    return InternalUtils.getDecodedServletPath(request);
0144:                return getRelativeURI(request, InternalUtils
0145:                        .getDecodedURI(request), relativeTo);
0146:            }
0147:
0148:            /**
0149:             * Get a URI relative to the URI of the given PageFlowController.
0150:             *
0151:             * @param request the current HttpServletRequest.
0152:             * @param uri the URI which should be made relative.
0153:             * @param relativeTo a PageFlowController to which the returned URI should be relative, or
0154:             *        <code>null</code> if the returned URI should be relative to the webapp root.
0155:             */
0156:            public static String getRelativeURI(HttpServletRequest request,
0157:                    String uri, PageFlowController relativeTo) {
0158:                String contextPath = request.getContextPath();
0159:                if (relativeTo != null)
0160:                    contextPath += relativeTo.getModulePath();
0161:                int overlap = uri.indexOf(contextPath + '/');
0162:                if (overlap == -1)
0163:                    return null;
0164:                return uri.substring(overlap + contextPath.length());
0165:            }
0166:
0167:            /**
0168:             * Get a URI for the "begin" action in the PageFlowController associated with the given
0169:             * request URI.
0170:             * 
0171:             * @return a String that is the URI for the "begin" action in the PageFlowController associated
0172:             * with the given request URI.
0173:             */
0174:            public static String getBeginActionURI(String requestURI) {
0175:                // Translate this to a request for the begin action ("begin.do") for this PageFlowController.
0176:                InternalStringBuilder retVal = new InternalStringBuilder();
0177:                int lastSlash = requestURI.lastIndexOf('/');
0178:
0179:                if (lastSlash != -1) {
0180:                    retVal.append(requestURI.substring(0, lastSlash));
0181:                }
0182:
0183:                retVal.append('/').append(BEGIN_ACTION_NAME).append(
0184:                        ACTION_EXTENSION);
0185:                return retVal.toString();
0186:            }
0187:
0188:            /**
0189:             * Get the stack of nested page flows for the current user session.  Create and store an empty
0190:             * stack if none exists.
0191:             * 
0192:             * @deprecated Use {@link PageFlowStack#get(HttpServletRequest, ServletContext)} instead.
0193:             * 
0194:             * @param request the current HttpServletRequest
0195:             * @return a {@link PageFlowStack} of nested page flows ({@link PageFlowController}s) for the current user session.
0196:             */
0197:            public static Stack getPageFlowStack(HttpServletRequest request) {
0198:                ServletContext servletContext = InternalUtils
0199:                        .getServletContext(request);
0200:                return PageFlowStack.get(request, servletContext, true)
0201:                        .getLegacyStack();
0202:            }
0203:
0204:            /**
0205:             * Destroys the stack of {@link PageFlowController}s that have invoked nested page flows.
0206:             * 
0207:             * @deprecated Use {@link PageFlowStack#destroy} instead.
0208:             * 
0209:             * @param request the current HttpServletRequest.
0210:             */
0211:            public static void destroyPageFlowStack(HttpServletRequest request) {
0212:                ServletContext servletContext = InternalUtils
0213:                        .getServletContext(request);
0214:                PageFlowStack.get(request, servletContext).destroy(request);
0215:            }
0216:
0217:            /**
0218:             * Get the {@link PageFlowController} that is nesting the current one.
0219:             * @deprecated Use {@link #getNestingPageFlow(HttpServletRequest, ServletContext)} instead.
0220:             * 
0221:             * @param request the current HttpServletRequest.
0222:             * @return the nesting {@link PageFlowController}, or <code>null</code> if the current one
0223:             *         is not being nested.
0224:             */
0225:            public static PageFlowController getNestingPageFlow(
0226:                    HttpServletRequest request) {
0227:                ServletContext servletContext = InternalUtils
0228:                        .getServletContext(request);
0229:                return getNestingPageFlow(request, servletContext);
0230:            }
0231:
0232:            /**
0233:             * Get the {@link PageFlowController} that is nesting the current one.
0234:             * 
0235:             * @param request the current HttpServletRequest.
0236:             * @param servletContext the current ServletContext.
0237:             * @return the nesting {@link PageFlowController}, or <code>null</code> if the current one
0238:             *         is not being nested.
0239:             */
0240:            public static PageFlowController getNestingPageFlow(
0241:                    HttpServletRequest request, ServletContext servletContext) {
0242:                PageFlowStack jpfStack = PageFlowStack.get(request,
0243:                        servletContext, false);
0244:
0245:                if (jpfStack != null && !jpfStack.isEmpty()) {
0246:                    PageFlowController top = jpfStack.peek().getPageFlow();
0247:                    return top;
0248:                }
0249:
0250:                return null;
0251:            }
0252:
0253:            /**
0254:             * Get the current {@link PageFlowController}.
0255:             * 
0256:             * @param request the current HttpServletRequest.
0257:             * @param servletContext the current ServletContext.
0258:             * @return the current PageFlowController from the user session, or <code>null</code> if there is none.
0259:             */
0260:            public static PageFlowController getCurrentPageFlow(
0261:                    HttpServletRequest request, ServletContext servletContext) {
0262:                ActionResolver cur = getCurrentActionResolver(request,
0263:                        servletContext);
0264:
0265:                if (cur != null && cur.isPageFlow()) {
0266:                    PageFlowController pfc = (PageFlowController) cur;
0267:                    pfc.reinitializeIfNecessary(request, null, servletContext);
0268:                    return pfc;
0269:                }
0270:
0271:                return null;
0272:            }
0273:
0274:            /**
0275:            /**
0276:             * Get the current PageFlowController.
0277:             * @deprecated Use {@link #getCurrentPageFlow(HttpServletRequest, ServletContext)} instead.
0278:             * 
0279:             * @param request the current HttpServletRequest.
0280:             * @return the current PageFlowController from the user session, or <code>null</code>
0281:             *         if there is none.
0282:             */
0283:            public static PageFlowController getCurrentPageFlow(
0284:                    HttpServletRequest request) {
0285:                ActionResolver cur = getCurrentActionResolver(request);
0286:                return cur != null && cur.isPageFlow() ? (PageFlowController) cur
0287:                        : null;
0288:            }
0289:
0290:            /**
0291:             * Get the current ActionResolver.
0292:             * @deprecated Use {@link #getCurrentPageFlow(HttpServletRequest, ServletContext)} instead.
0293:             * 
0294:             * @return the current ActionResolver from the user session, or <code>null</code> if there is none.
0295:             */
0296:            public static ActionResolver getCurrentActionResolver(
0297:                    HttpServletRequest request) {
0298:                ServletContext servletContext = InternalUtils
0299:                        .getServletContext(request);
0300:                return getCurrentActionResolver(request, servletContext);
0301:            }
0302:
0303:            /**
0304:             * Get the current ActionResolver.
0305:             * @deprecated Use {@link #getCurrentPageFlow(HttpServletRequest, ServletContext)} instead.
0306:             * 
0307:             * 
0308:             * @param request the current HttpServletRequest.
0309:             * @param servletContext the current ServletContext.
0310:             * @return the current ActionResolver from the user session, or <code>null</code> if there is none.
0311:             */
0312:            public static ActionResolver getCurrentActionResolver(
0313:                    HttpServletRequest request, ServletContext servletContext) {
0314:                StorageHandler sh = Handlers.get(servletContext)
0315:                        .getStorageHandler();
0316:                HttpServletRequest unwrappedRequest = unwrapMultipart(request);
0317:                RequestContext rc = new RequestContext(unwrappedRequest, null);
0318:
0319:                //
0320:                // First see if the current page flow is a long-lived, which is stored in its own attribute.
0321:                //
0322:                String currentLongLivedAttrName = ScopedServletUtils
0323:                        .getScopedSessionAttrName(CURRENT_LONGLIVED_ATTR,
0324:                                unwrappedRequest);
0325:                String currentLongLivedModulePath = (String) sh.getAttribute(
0326:                        rc, currentLongLivedAttrName);
0327:
0328:                if (currentLongLivedModulePath != null) {
0329:                    return getLongLivedPageFlow(currentLongLivedModulePath,
0330:                            unwrappedRequest);
0331:                } else {
0332:                    String currentJpfAttrName = ScopedServletUtils
0333:                            .getScopedSessionAttrName(CURRENT_JPF_ATTR,
0334:                                    unwrappedRequest);
0335:                    return (ActionResolver) sh.getAttribute(rc,
0336:                            currentJpfAttrName);
0337:                }
0338:            }
0339:
0340:            /**
0341:             * Get the current {@link GlobalApp} instance.
0342:             * 
0343:             * @deprecated Use {@link #getSharedFlow} instead.
0344:             * @param request the current HttpServletRequest.
0345:             * @return the current {@link GlobalApp} from the user session, or <code>null</code> if none
0346:             *         exists.
0347:             */
0348:            public static GlobalApp getGlobalApp(HttpServletRequest request) {
0349:                SharedFlowController sf = getSharedFlow(
0350:                        InternalConstants.GLOBALAPP_CLASSNAME, request);
0351:                return sf instanceof  GlobalApp ? (GlobalApp) sf : null;
0352:            }
0353:
0354:            /**
0355:             * Get the a map of shared flow name to shared flow instance, based on the names defined in the
0356:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller#sharedFlowRefs sharedFlowRefs} attribute
0357:             * of the {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller &#64;Jpf.Controller} annotation on the
0358:             * <strong>current page flow</strong>.
0359:             * 
0360:             * @param request the current HttpServletRequest, which is used to determine the current page flow.
0361:             * @return a Map of shared flow name (string) to shared flow instance ({@link SharedFlowController}).
0362:             */
0363:            public static Map/*< String, SharedFlowController >*/getSharedFlows(
0364:                    HttpServletRequest request) {
0365:                Map/*< String, SharedFlowController >*/sharedFlows = ImplicitObjectUtil
0366:                        .getSharedFlow(request);
0367:                return sharedFlows != null ? sharedFlows
0368:                        : Collections.EMPTY_MAP;
0369:            }
0370:
0371:            /**
0372:             * Get the shared flow with the given class name.
0373:             * @deprecated Use {@link #getSharedFlow(String, HttpServletRequest, ServletContext)} instead.
0374:             * 
0375:             * @param sharedFlowClassName the class name of the shared flow to retrieve.
0376:             * @param request the current HttpServletRequest.
0377:             * @return the {@link SharedFlowController} of the given class name which is stored in the user session.
0378:             */
0379:            public static SharedFlowController getSharedFlow(
0380:                    String sharedFlowClassName, HttpServletRequest request) {
0381:                ServletContext servletContext = InternalUtils
0382:                        .getServletContext(request);
0383:                return getSharedFlow(sharedFlowClassName, request,
0384:                        servletContext);
0385:            }
0386:
0387:            /**
0388:             * Get the shared flow with the given class name.
0389:             * 
0390:             * @param sharedFlowClassName the class name of the shared flow to retrieve.
0391:             * @param request the current HttpServletRequest.
0392:             * @return the {@link SharedFlowController} of the given class name which is stored in the user session.
0393:             */
0394:            public static SharedFlowController getSharedFlow(
0395:                    String sharedFlowClassName, HttpServletRequest request,
0396:                    ServletContext servletContext) {
0397:                StorageHandler sh = Handlers.get(servletContext)
0398:                        .getStorageHandler();
0399:                HttpServletRequest unwrappedRequest = unwrapMultipart(request);
0400:                RequestContext rc = new RequestContext(unwrappedRequest, null);
0401:                String attrName = ScopedServletUtils.getScopedSessionAttrName(
0402:                        InternalConstants.SHARED_FLOW_ATTR_PREFIX
0403:                                + sharedFlowClassName, request);
0404:                SharedFlowController sf = (SharedFlowController) sh
0405:                        .getAttribute(rc, attrName);
0406:                if (sf != null) {
0407:                    sf.reinitializeIfNecessary(request, null, servletContext);
0408:                }
0409:                return sf;
0410:            }
0411:
0412:            /**
0413:             * Destroy the current {@link SharedFlowController} of the given class name.
0414:             * @deprecated Use {@link #removeSharedFlow(String, HttpServletRequest, ServletContext)} instead.
0415:             * @param sharedFlowClassName the class name of the current SharedFlowController to destroy.
0416:             * @param request the current HttpServletRequest.
0417:             */
0418:            public static void removeSharedFlow(String sharedFlowClassName,
0419:                    HttpServletRequest request) {
0420:                ServletContext servletContext = InternalUtils
0421:                        .getServletContext(request);
0422:                removeSharedFlow(sharedFlowClassName, request, servletContext);
0423:            }
0424:
0425:            /**
0426:             * Destroy the current {@link SharedFlowController} of the given class name.
0427:             * @param sharedFlowClassName the class name of the current SharedFlowController to destroy.
0428:             * @param request the current HttpServletRequest.
0429:             */
0430:            public static void removeSharedFlow(String sharedFlowClassName,
0431:                    HttpServletRequest request, ServletContext servletContext) {
0432:                StorageHandler sh = Handlers.get(servletContext)
0433:                        .getStorageHandler();
0434:                HttpServletRequest unwrappedRequest = unwrapMultipart(request);
0435:                RequestContext rc = new RequestContext(unwrappedRequest, null);
0436:                String attrName = ScopedServletUtils.getScopedSessionAttrName(
0437:                        InternalConstants.SHARED_FLOW_ATTR_PREFIX
0438:                                + sharedFlowClassName, request);
0439:                sh.removeAttribute(rc, attrName);
0440:            }
0441:
0442:            /**
0443:             * Remove a "long-lived" page flow from the session. Once it is created, a long-lived page flow
0444:             * is never removed from the session unless this method or {@link PageFlowController#remove} is
0445:             * called.  Navigating to another page flow hides the current long-lived controller, but does not
0446:             * remove it.
0447:             * @deprecated Use {@link #removeLongLivedPageFlow(String, HttpServletRequest, ServletContext)} instead.
0448:             */
0449:            public static void removeLongLivedPageFlow(String modulePath,
0450:                    HttpServletRequest request) {
0451:                ServletContext servletContext = InternalUtils
0452:                        .getServletContext(request);
0453:                removeLongLivedPageFlow(modulePath, request, servletContext);
0454:            }
0455:
0456:            /**
0457:             * Remove a "long-lived" page flow from the session. Once it is created, a long-lived page flow
0458:             * is never removed from the session unless this method or {@link PageFlowController#remove} is
0459:             * called.  Navigating to another page flow hides the current long-lived controller, but does not
0460:             * remove it.
0461:             */
0462:            public static void removeLongLivedPageFlow(String modulePath,
0463:                    HttpServletRequest request, ServletContext servletContext) {
0464:                StorageHandler sh = Handlers.get(servletContext)
0465:                        .getStorageHandler();
0466:                HttpServletRequest unwrappedRequest = unwrapMultipart(request);
0467:                RequestContext rc = new RequestContext(unwrappedRequest, null);
0468:
0469:                String attrName = InternalUtils
0470:                        .getLongLivedFlowAttr(modulePath);
0471:                attrName = ScopedServletUtils.getScopedSessionAttrName(
0472:                        attrName, unwrappedRequest);
0473:                sh.removeAttribute(rc, attrName);
0474:
0475:                //
0476:                // Now, if the current page flow is long-lived, remove the reference.
0477:                //
0478:                String currentLongLivedAttrName = ScopedServletUtils
0479:                        .getScopedSessionAttrName(CURRENT_LONGLIVED_ATTR,
0480:                                unwrappedRequest);
0481:                String currentLongLivedModulePath = (String) sh.getAttribute(
0482:                        rc, currentLongLivedAttrName);
0483:
0484:                if (modulePath.equals(currentLongLivedModulePath)) {
0485:                    sh.removeAttribute(rc, currentLongLivedAttrName);
0486:                }
0487:            }
0488:
0489:            /**
0490:             * Get the long-lived page flow instance associated with the given module (directory) path.
0491:             * @deprecated Use {@link #getLongLivedPageFlow(String, HttpServletRequest, ServletContext)} instead.
0492:             * 
0493:             * @param modulePath the webapp-relative path to the directory containing the long-lived page flow.
0494:             * @param request the current HttpServletRequest.
0495:             * @return the long-lived page flow instance associated with the given module, or <code>null</code> if none is found.
0496:             */
0497:            public static PageFlowController getLongLivedPageFlow(
0498:                    String modulePath, HttpServletRequest request) {
0499:                ServletContext servletContext = InternalUtils
0500:                        .getServletContext(request);
0501:                return getLongLivedPageFlow(modulePath, request, servletContext);
0502:            }
0503:
0504:            /**
0505:             * Get the long-lived page flow instance associated with the given module (directory) path.
0506:             * 
0507:             * @param modulePath the webapp-relative path to the directory containing the long-lived page flow.
0508:             * @param request the current HttpServletRequest.
0509:             * @param servletContext the current ServletContext.
0510:             * @return the long-lived page flow instance associated with the given module, or <code>null</code> if none is found.
0511:             */
0512:            public static PageFlowController getLongLivedPageFlow(
0513:                    String modulePath, HttpServletRequest request,
0514:                    ServletContext servletContext) {
0515:                StorageHandler sh = Handlers.get(servletContext)
0516:                        .getStorageHandler();
0517:                HttpServletRequest unwrappedRequest = unwrapMultipart(request);
0518:                RequestContext rc = new RequestContext(unwrappedRequest, null);
0519:
0520:                String attrName = InternalUtils
0521:                        .getLongLivedFlowAttr(modulePath);
0522:                attrName = ScopedServletUtils.getScopedSessionAttrName(
0523:                        attrName, unwrappedRequest);
0524:                PageFlowController retVal = (PageFlowController) sh
0525:                        .getAttribute(rc, attrName);
0526:                return retVal;
0527:            }
0528:
0529:            /**
0530:             * Make any form beans in the given {@link Forward} object available as attributets in the
0531:             * request/session (as appropriate).
0532:             * 
0533:             * @param mapping the ActionMapping for the current Struts action being processed.
0534:             * @param fwd the {@link Forward} object that contains the ActionForm instances to be
0535:             *            made available in the request/session (as appropriate).
0536:             * @param request the current HttpServletRequest.
0537:             * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
0538:             *            in the request if there is no existing form with the same name.
0539:             */
0540:            public static void setOutputForms(ActionMapping mapping,
0541:                    Forward fwd, HttpServletRequest request, boolean overwrite) {
0542:                if (fwd == null)
0543:                    return;
0544:
0545:                //
0546:                // *If* there is a target action mapping, set output forms for it.
0547:                //
0548:                if (mapping != null)
0549:                    setOutputForms(mapping, fwd.getOutputForms(), request,
0550:                            overwrite);
0551:
0552:                InternalUtils.setForwardedFormBean(request, fwd
0553:                        .getFirstOutputForm(request));
0554:            }
0555:
0556:            /**
0557:             * Make any form beans in the given {@link Forward} object available as attributets in the
0558:             * request/session (as appropriate).
0559:             * 
0560:             * @param mapping the ActionMapping for the current Struts action being processed.
0561:             * @param fwd the {@link Forward} object that contains the ActionForm instances to be
0562:             *            made available in the request/session (as appropriate).
0563:             * @param request the current HttpServletRequest.
0564:             */
0565:            public static void setOutputForms(ActionMapping mapping,
0566:                    Forward fwd, HttpServletRequest request) {
0567:                if (fwd == null) {
0568:                    return;
0569:                }
0570:
0571:                if (mapping != null) {
0572:                    setOutputForms(mapping, fwd.getOutputForms(), request);
0573:                }
0574:
0575:                InternalUtils.setForwardedFormBean(request, fwd
0576:                        .getFirstOutputForm(request));
0577:            }
0578:
0579:            /**
0580:             * Make a set of form beans available as attributets in the request/session (as appropriate).
0581:             * 
0582:             * @param mapping the ActionMapping for the current Struts action being processed.
0583:             * @param outputForms an array of ActionForm instances to be made available in the
0584:             *            request/session (as appropriate).
0585:             * @param request the current HttpServletRequest.
0586:             */
0587:            public static void setOutputForms(ActionMapping mapping,
0588:                    ActionForm[] outputForms, HttpServletRequest request) {
0589:                setOutputForms(mapping, outputForms, request, true);
0590:            }
0591:
0592:            /**
0593:             * Make a set of form beans available as attributets in the request/session (as appropriate).
0594:             * 
0595:             * @param mapping the ActionMapping for the current Struts action being processed.
0596:             * @param outputForms an array of ActionForm instances to be made available in the
0597:             *            request/session (as appropriate).
0598:             * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
0599:             *            in the request if there is no existing form with the same name.
0600:             * @param request the current HttpServletRequest.
0601:             */
0602:            public static void setOutputForms(ActionMapping mapping,
0603:                    ActionForm[] outputForms, HttpServletRequest request,
0604:                    boolean overwrite) {
0605:                try {
0606:                    //
0607:                    // Now set any output forms in the request or session, as appropriate.
0608:                    //
0609:                    assert mapping.getScope() == null
0610:                            || mapping.getScope().equals("request")
0611:                            || mapping.getScope().equals("session") : mapping
0612:                            .getScope();
0613:
0614:                    for (int i = 0; i < outputForms.length; ++i) {
0615:                        setOutputForm(mapping, outputForms[i], request,
0616:                                overwrite);
0617:                    }
0618:                } catch (Exception e) {
0619:                    _log.error("Error while setting Struts form-beans", e);
0620:                }
0621:            }
0622:
0623:            private static List/*< String >*/getFormNamesFromModuleConfig(
0624:                    String formBeanClassName, ModuleConfig moduleConfig) {
0625:                String modulePrefix = moduleConfig.getPrefix();
0626:                Map/*< String, List< String > >*/formNameMap = (Map) _formNameMaps
0627:                        .get(modulePrefix); // map of form-type-name to form-name
0628:
0629:                if (formNameMap == null) {
0630:                    formNameMap = new HashMap/*< String, List< String > >*/();
0631:                    FormBeanConfig[] formBeans = moduleConfig
0632:                            .findFormBeanConfigs();
0633:
0634:                    for (int j = 0; j < formBeans.length; ++j) {
0635:                        assert formBeans[j] != null;
0636:                        String formBeanType = InternalUtils
0637:                                .getFormBeanType(formBeans[j]);
0638:                        List/*< String >*/formBeanNames = (List) formNameMap
0639:                                .get(formBeanType);
0640:
0641:                        if (formBeanNames == null) {
0642:                            formBeanNames = new ArrayList/*< String >*/();
0643:                            formNameMap.put(formBeanType, formBeanNames);
0644:                        }
0645:
0646:                        formBeanNames.add(formBeans[j].getName());
0647:                    }
0648:
0649:                    _formNameMaps.put(modulePrefix, formNameMap);
0650:                }
0651:
0652:                return (List) formNameMap.get(formBeanClassName);
0653:            }
0654:
0655:            /**
0656:             * Make a form bean available as an attributet in the request/session (as appropriate).
0657:             * 
0658:             * @param mapping the ActionMapping for the current Struts action being processed.
0659:             * @param form an ActionForm instance to be made available in the request/session
0660:             *           (as appropriate).
0661:             * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
0662:             *           in the request if there is no existing form with the same name.
0663:             * @param request the current HttpServletRequest.
0664:             */
0665:            public static void setOutputForm(ActionMapping mapping,
0666:                    ActionForm form, HttpServletRequest request,
0667:                    boolean overwrite) {
0668:                if (form != null) {
0669:                    ModuleConfig moduleConfig = mapping.getModuleConfig();
0670:                    Class formClass = InternalUtils.unwrapFormBean(form)
0671:                            .getClass();
0672:
0673:                    //
0674:                    // Get the names of *all* form beans of the desired type, and blast out this instance under all those names.
0675:                    //
0676:                    List formNames = getFormNamesFromModuleConfig(formClass
0677:                            .getName(), moduleConfig);
0678:                    List additionalFormNames = null;
0679:
0680:                    //
0681:                    // formNames is a statically-scoped list.  Below, we create a dynamic list of form names that correspond
0682:                    // to *implemented interfaces* of the given form bean class.
0683:                    //
0684:                    Class[] interfaces = formClass.getInterfaces();
0685:                    for (int i = 0; i < interfaces.length; i++) {
0686:                        Class formInterface = interfaces[i];
0687:                        List toAdd = getFormNamesFromModuleConfig(formInterface
0688:                                .getName(), moduleConfig);
0689:                        if (toAdd != null) {
0690:                            if (additionalFormNames == null)
0691:                                additionalFormNames = new ArrayList();
0692:                            additionalFormNames.addAll(toAdd);
0693:                        }
0694:                    }
0695:
0696:                    // Do the same for all superclasses of the form bean class.
0697:                    for (Class i = formClass.getSuperclass(); i != null; i = i
0698:                            .getSuperclass()) {
0699:                        List toAdd = getFormNamesFromModuleConfig(i.getName(),
0700:                                moduleConfig);
0701:                        if (toAdd != null) {
0702:                            if (additionalFormNames == null)
0703:                                additionalFormNames = new ArrayList();
0704:                            additionalFormNames.addAll(toAdd);
0705:                        }
0706:                    }
0707:
0708:                    if (formNames == null && additionalFormNames == null) {
0709:                        String formName = generateFormBeanName(formClass,
0710:                                request);
0711:                        InternalUtils.setFormInScope(formName, form, mapping,
0712:                                request, overwrite);
0713:                    } else {
0714:                        if (formNames != null) {
0715:                            for (Iterator i = formNames.iterator(); i.hasNext();) {
0716:                                String formName = (String) i.next();
0717:                                InternalUtils.setFormInScope(formName, form,
0718:                                        mapping, request, overwrite);
0719:                            }
0720:                        }
0721:
0722:                        if (additionalFormNames != null) {
0723:                            for (Iterator i = additionalFormNames.iterator(); i
0724:                                    .hasNext();) {
0725:                                String formName = (String) i.next();
0726:                                InternalUtils.setFormInScope(formName, form,
0727:                                        mapping, request, overwrite);
0728:                            }
0729:                        }
0730:                    }
0731:                }
0732:            }
0733:
0734:            /**
0735:             * Get the name for the type of a ActionForm instance.  Use a name looked up from
0736:             * the current Struts module, or, if none is found, create one.
0737:             * 
0738:             * @param formInstance the ActionForm instance whose type will determine the name.
0739:             * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
0740:             * @return the name found in the Struts module, or, if none is found, a name that is either:
0741:             *     <ul>
0742:             *         <li>a camel-cased version of the base class name (minus any package or outer-class
0743:             *             qualifiers, or, if that name is already taken,</li>
0744:             *         <li>the full class name, with '.' and '$' replaced by '_'.</li>
0745:             *     </ul>
0746:             */
0747:            public static String getFormBeanName(ActionForm formInstance,
0748:                    HttpServletRequest request) {
0749:                return getFormBeanName(formInstance.getClass(), request);
0750:            }
0751:
0752:            /**
0753:             * Get the name for an ActionForm type.  Use a name looked up from the current Struts module, or,
0754:             * if none is found, create one.
0755:             * 
0756:             * @param formBeanClass the ActionForm-derived class whose type will determine the name.
0757:             * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
0758:             * @return the name found in the Struts module, or, if none is found, a name that is either:
0759:             *     <ul>
0760:             *         <li>a camel-cased version of the base class name (minus any package or outer-class
0761:             *             qualifiers, or, if that name is already taken,</li>
0762:             *         <li>the full class name, with '.' and '$' replaced by '_'.</li>
0763:             *     </ul>
0764:             */
0765:            public static String getFormBeanName(Class formBeanClass,
0766:                    HttpServletRequest request) {
0767:                ModuleConfig moduleConfig = RequestUtils
0768:                        .getRequestModuleConfig(request);
0769:                List/*< String >*/names = getFormNamesFromModuleConfig(
0770:                        formBeanClass.getName(), moduleConfig);
0771:
0772:                if (names != null) {
0773:                    assert names.size() > 0; // getFormNamesFromModuleConfig returns null or a nonempty list
0774:                    return (String) names.get(0);
0775:                }
0776:
0777:                return generateFormBeanName(formBeanClass, request);
0778:            }
0779:
0780:            /**
0781:             * Create the name for a form bean type.
0782:             * 
0783:             * @param formBeanClass the class whose type will determine the name.
0784:             * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
0785:             * @return the name found in the Struts module, or, if none is found, a name that is either:
0786:             *     <ul>
0787:             *         <li>a camel-cased version of the base class name (minus any package or outer-class
0788:             *             qualifiers, or, if that name is already taken,</li>
0789:             *         <li>the full class name, with '.' and '$' replaced by '_'.</li>
0790:             *     </ul>
0791:             */
0792:            private static String generateFormBeanName(Class formBeanClass,
0793:                    HttpServletRequest request) {
0794:                ModuleConfig moduleConfig = RequestUtils
0795:                        .getRequestModuleConfig(request);
0796:                String formBeanClassName = formBeanClass.getName();
0797:
0798:                //
0799:                // A form-bean wasn't found for this type, so we'll create a name.  First try and create
0800:                // name that is a camelcased version of the classname without all of its package/outer-class
0801:                // qualifiers.  If one with that name already exists, munge the fully-qualified classname.
0802:                //
0803:                String formType = formBeanClassName;
0804:                int lastQualifier = formType.lastIndexOf('$');
0805:
0806:                if (lastQualifier == -1) {
0807:                    lastQualifier = formType.lastIndexOf('.');
0808:                }
0809:
0810:                String formName = formType.substring(lastQualifier + 1);
0811:                formName = Character.toLowerCase(formName.charAt(0))
0812:                        + formName.substring(1);
0813:
0814:                if (moduleConfig.findFormBeanConfig(formName) != null) {
0815:                    formName = formType.replace('.', '_').replace('$', '_');
0816:                    assert moduleConfig.findFormBeanConfig(formName) == null : formName;
0817:                }
0818:
0819:                return formName;
0820:            }
0821:
0822:            /**
0823:             * Get the class name of a {@link PageFlowController}, given the URI to it.
0824:             * 
0825:             * @param uri the URI to the {@link PageFlowController}, which should be relative to the
0826:             *            web application root (i.e., it should not include the context path).
0827:             */
0828:            public static String getPageFlowClassName(String uri) {
0829:                assert uri != null;
0830:                assert uri.length() > 0;
0831:
0832:                if (uri.charAt(0) == '/')
0833:                    uri = uri.substring(1);
0834:
0835:                assert FileUtils.osSensitiveEndsWith(uri, PAGEFLOW_EXTENSION) : uri;
0836:                if (FileUtils.osSensitiveEndsWith(uri, PAGEFLOW_EXTENSION)) {
0837:                    uri = uri.substring(0, uri.length()
0838:                            - PAGEFLOW_EXTENSION_LEN);
0839:                }
0840:
0841:                return uri.replace('/', '.');
0842:            }
0843:
0844:            /**
0845:             * Get the class name of a {@link PageFlowController}, given the URI to it.
0846:             * 
0847:             * @deprecated Use {@link #getPageFlowClassName(String)} instead.
0848:             * 
0849:             * @param uri the URI to the {@link PageFlowController}, which should be relative to the
0850:             *            web application root (i.e., it should not include the context path).
0851:             */
0852:            public static String getJpfClassName(String uri) {
0853:                return getPageFlowClassName(uri);
0854:            }
0855:
0856:            /**
0857:             * Get the URI for a {@link PageFlowController}, given its class name.
0858:             * 
0859:             * @param className the name of the {@link PageFlowController} class.
0860:             * @return a String that is the URI for the {@link PageFlowController}, relative to the web
0861:             *         application root (i.e., not including the context path).
0862:             */
0863:            public static String getPageFlowURI(String className) {
0864:                return '/' + className.replace('.', '/') + PAGEFLOW_EXTENSION;
0865:            }
0866:
0867:            /**
0868:             * @deprecated Use {@link PageFlowActionServlet#getModuleConfPath} instead.
0869:             * 
0870:             * Get the path to the Struts module configration file (e.g.,
0871:             * "/WEB-INF/classes/_pageflow/struts-config-someModule") for a given module
0872:             * path (e.g., "someModule"), according to the PageFlow convention.
0873:             * 
0874:             * @param modulePath the Struts module path.
0875:             * @return a String that is the path to the Struts configuration file, relative to the
0876:             *         web application root.
0877:             */
0878:            public static String getModuleConfPath(String modulePath) {
0879:                return new PageFlowActionServlet.DefaultModuleConfigLocator()
0880:                        .getModuleConfigPath(modulePath);
0881:            }
0882:
0883:            /**
0884:             * Get the most recent action URI that was processed by {@link FlowController#execute}.
0885:             * 
0886:             * @param request the current ServletRequest.
0887:             * @return a String that is the most recent action URI.  This is only valid during a request
0888:             *         that has been forwarded from the action URI.
0889:             */
0890:            public static String getActionURI(ServletRequest request) {
0891:                return (String) request.getAttribute(ACTION_URI_ATTR);
0892:            }
0893:
0894:            /**
0895:             * Sets the most recent action URI that was processed by {@link FlowController#execute}.
0896:             */
0897:            static void setActionURI(HttpServletRequest request) {
0898:                request.setAttribute(ACTION_URI_ATTR, InternalUtils
0899:                        .getDecodedURI(request));
0900:            }
0901:
0902:            /**
0903:             * Tell whether a web application resource requires a secure transport protocol.  This is
0904:             * determined from web.xml; for example, the following block specifies that all resources under
0905:             * /login require a secure transport protocol.
0906:             * <pre>
0907:             *    &lt;security-constraint&gt;
0908:             *        &lt;web-resource-collection&gt;
0909:             *          &lt;web-resource-name&gt;Secure PageFlow - begin&lt;/web-resource-name&gt; 
0910:             *          &lt;url-pattern&gt;/login/*&lt;/url-pattern&gt;
0911:             *        &lt;/web-resource-collection&gt;
0912:             *        &lt;user-data-constraint&gt;
0913:             *           &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
0914:             *        &lt;/user-data-constraint&gt;
0915:             *    &lt;/security-constraint&gt;
0916:             * </pre>
0917:             * 
0918:             * @param uri a webapp-relative URI for a resource.  There must not be query parameters or a scheme
0919:             *            on the URI.
0920:             * @param request the current request.
0921:             * @return <code>Boolean.TRUE</code> if a transport-guarantee of <code>CONFIDENTIAL</code> or
0922:             *         <code>INTEGRAL</code> is associated with the given resource; <code>Boolean.FALSE</code> 
0923:             *         a transport-guarantee of <code>NONE</code> is associated with the given resource; or
0924:             *         <code>null</code> if there is no transport-guarantee associated with the given resource.
0925:             */
0926:            public static SecurityProtocol getSecurityProtocol(String uri,
0927:                    ServletContext servletContext, HttpServletRequest request) {
0928:                return AdapterManager
0929:                        .getServletContainerAdapter(servletContext)
0930:                        .getSecurityProtocol(uri, request);
0931:            }
0932:
0933:            /**
0934:             * @deprecated Use {@link #getSecurityProtocol(String, ServletContext, HttpServletRequest)} instead.
0935:             */
0936:            public static Boolean isSecureResource(String uri,
0937:                    ServletContext context) {
0938:                // TODO: once DefaultServletContainerAdapter has this functionality, delegate to it.
0939:                return null;
0940:            }
0941:
0942:            /**
0943:             * Set a named action output, which corresponds to an input declared by the <code>pageInput</code> JSP tag.
0944:             * The actual value can be read from within a JSP using the <code>"pageInput"</code> databinding context.
0945:             * 
0946:             * @deprecated Use {@link #addActionOutput} instead.
0947:             * @param name the name of the action output.
0948:             * @param value the value of the action output.
0949:             * @param request the current ServletRequest.
0950:             */
0951:            public static void addPageInput(String name, Object value,
0952:                    ServletRequest request) {
0953:                addActionOutput(name, value, request);
0954:            }
0955:
0956:            /**
0957:             * Set a named action output, which corresponds to an input declared by the <code>pageInput</code> JSP tag.
0958:             * The actual value can be read from within a JSP using the <code>"pageInput"</code> databinding context.
0959:             * 
0960:             * @param name the name of the action output.
0961:             * @param value the value of the action output.
0962:             * @param request the current ServletRequest.
0963:             */
0964:            public static void addActionOutput(String name, Object value,
0965:                    ServletRequest request) {
0966:                Map map = InternalUtils.getActionOutputMap(request, true);
0967:
0968:                if (map.containsKey(name)) {
0969:                    if (_log.isWarnEnabled()) {
0970:                        _log.warn("Overwriting action output\"" + name + "\".");
0971:                    }
0972:                }
0973:
0974:                map.put(name, value);
0975:            }
0976:
0977:            /**
0978:             * Get a named action output that was registered in the current request.
0979:             * 
0980:             * @deprecated Use {@link #getActionOutput} instead.
0981:             * @param name the name of the action output.
0982:             * @param request the current ServletRequest
0983:             * @see #addActionOutput
0984:             */
0985:            public static Object getPageInput(String name,
0986:                    ServletRequest request) {
0987:                return getActionOutput(name, request);
0988:            }
0989:
0990:            /**
0991:             * Get a named action output that was registered in the current request.
0992:             * 
0993:             * @param name the name of the action output.
0994:             * @param request the current ServletRequest
0995:             * @see #addActionOutput
0996:             */
0997:            public static Object getActionOutput(String name,
0998:                    ServletRequest request) {
0999:                Map map = InternalUtils.getActionOutputMap(request, false);
1000:                return map != null ? map.get(name) : null;
1001:            }
1002:
1003:            /**
1004:             * Add a validation error that will be shown with the Errors and Error tags.
1005:             * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
1006:             * 
1007:             * @param propertyName the name of the property with which to associate this error.
1008:             * @param messageKey the message-resources key for the error message.
1009:             * @param messageArgs an array of arguments for the error message.
1010:             * @param request the current ServletRequest.
1011:             */
1012:            public static void addValidationError(String propertyName,
1013:                    String messageKey, Object[] messageArgs,
1014:                    ServletRequest request) {
1015:                InternalUtils.addActionError(propertyName, new ActionMessage(
1016:                        messageKey, messageArgs), request);
1017:            }
1018:
1019:            /**
1020:             * Add a validation error that will be shown with the Errors and Error tags.
1021:             * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
1022:             * 
1023:             * @param propertyName the name of the property with which to associate this error.
1024:             * @param messageKey the message-resources key for the error message.
1025:             * @param messageArg an argument for the error message.
1026:             * @param request the current ServletRequest.
1027:             */
1028:            public static void addValidationError(String propertyName,
1029:                    String messageKey, Object messageArg, ServletRequest request) {
1030:                addActionError(request, propertyName, messageKey,
1031:                        new Object[] { messageArg });
1032:            }
1033:
1034:            /**
1035:             * Add a validation error that will be shown with the Errors and Error tags.
1036:             * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
1037:             * 
1038:             * @param propertyName the name of the property with which to associate this error.
1039:             * @param messageKey the message-resources key for the error message.
1040:             * @param request the current ServletRequest.
1041:             */
1042:            public static void addValidationError(String propertyName,
1043:                    String messageKey, ServletRequest request) {
1044:                addActionError(request, propertyName, messageKey);
1045:            }
1046:
1047:            /**
1048:             * Add a property-related message that will be shown with the Errors and Error tags.
1049:             * 
1050:             * @param request the current ServletRequest.
1051:             * @param propertyName the name of the property with which to associate this error.
1052:             * @param messageKey the message-resources key for the message.
1053:             * @param messageArgs zero or more arguments to the message.
1054:             */
1055:            public static void addActionError(ServletRequest request,
1056:                    String propertyName, String messageKey, Object[] messageArgs) {
1057:                InternalUtils.addActionError(propertyName, new ActionMessage(
1058:                        messageKey, messageArgs), request);
1059:            }
1060:
1061:            /**
1062:             * Add a property-related message that will be shown with the Errors and Error tags.
1063:             * 
1064:             * @param request the current ServletRequest.
1065:             * @param propertyName the name of the property with which to associate this error.
1066:             * @param messageKey the message-resources key for the message.
1067:             */
1068:            public static void addActionError(ServletRequest request,
1069:                    String propertyName, String messageKey) {
1070:                InternalUtils.addActionError(propertyName, new ActionMessage(
1071:                        messageKey, null), request);
1072:            }
1073:
1074:            /**
1075:             * Add a property-related message that will be shown with the Errors and Error tags.
1076:             * 
1077:             * @param request the current ServletRequest.
1078:             * @param propertyName the name of the property with which to associate this error.
1079:             * @param messageKey the message-resources key for the message.
1080:             * @param messageArg an argument to the message
1081:             */
1082:            public static void addActionError(ServletRequest request,
1083:                    String propertyName, String messageKey, Object messageArg) {
1084:                Object[] messageArgs = new Object[] { messageArg };
1085:                InternalUtils.addActionError(propertyName, new ActionMessage(
1086:                        messageKey, messageArgs), request);
1087:            }
1088:
1089:            /**
1090:             * Add a property-related message that will be shown with the Errors and Error tags.
1091:             * 
1092:             * @param request the current ServletRequest.
1093:             * @param propertyName the name of the property with which to associate this error.
1094:             * @param messageKey the message-resources key for the message.
1095:             * @param messageArg1 the first argument to the message
1096:             * @param messageArg2 the second argument to the message
1097:             */
1098:            public static void addActionError(ServletRequest request,
1099:                    String propertyName, String messageKey, Object messageArg1,
1100:                    Object messageArg2) {
1101:                Object[] messageArgs = new Object[] { messageArg1, messageArg2 };
1102:                InternalUtils.addActionError(propertyName, new ActionMessage(
1103:                        messageKey, messageArgs), request);
1104:            }
1105:
1106:            /**
1107:             * Add a property-related message that will be shown with the Errors and Error tags.
1108:             * 
1109:             * @param request the current ServletRequest.
1110:             * @param propertyName the name of the property with which to associate this error.
1111:             * @param messageKey the message-resources key for the message.
1112:             * @param messageArg1 the first argument to the message
1113:             * @param messageArg2 the second argument to the message
1114:             * @param messageArg3 the third argument to the message
1115:             */
1116:            public static void addActionError(ServletRequest request,
1117:                    String propertyName, String messageKey, Object messageArg1,
1118:                    Object messageArg2, Object messageArg3) {
1119:                Object[] messageArgs = new Object[] { messageArg1, messageArg2,
1120:                        messageArg3 };
1121:                InternalUtils.addActionError(propertyName, new ActionMessage(
1122:                        messageKey, messageArgs), request);
1123:            }
1124:
1125:            /**
1126:             * Add a property-related message as an expression that will be evaluated and shown with the Errors and Error tags.
1127:             * 
1128:             * @param request the current ServletRequest.
1129:             * @param propertyName the name of the property with which to associate this error.
1130:             * @param expression the JSP 2.0-style expression (e.g., <code>${pageFlow.myProperty}</code>) or literal string
1131:             *            that will be used as the message.
1132:             * @param messageArgs zero or more arguments to the message.
1133:             */
1134:            public static void addActionErrorExpression(
1135:                    HttpServletRequest request, String propertyName,
1136:                    String expression, Object[] messageArgs) {
1137:                ExpressionMessage msg = new ExpressionMessage(expression,
1138:                        messageArgs);
1139:                InternalUtils.addActionError(propertyName, msg, request);
1140:            }
1141:
1142:            /**
1143:             * Resolve the given action to a URI by running an entire request-processing cycle on the given ScopedRequest
1144:             * and ScopedResponse.
1145:             * @exclude
1146:             * 
1147:             * @param context the current ServletContext
1148:             * @param request the ServletRequest, which must be a {@link ScopedRequest}.
1149:             * @param response the ServletResponse, which must be a {@link ScopedResponse}.
1150:             * @param actionOverride if not <code>null</code>, this qualified action-path is used to construct an action
1151:             *                       URI which is set as the request URI.  The action-path <strong>must</strong> begin with '/',
1152:             *                       which makes it qualified from the webapp root.
1153:             * @param autoResolveExtensions a list of URI extensions (e.g., ".do", ".jpf") that will be auto-resolved, i.e.,
1154:             *                              on which this method will be recursively called.  If <code>null</code>, the
1155:             *                              default extensions ".do" and ".jpf" will be used.
1156:             */
1157:            public static ActionResult strutsLookup(ServletContext context,
1158:                    ServletRequest request, HttpServletResponse response,
1159:                    String actionOverride, String[] autoResolveExtensions)
1160:                    throws Exception {
1161:                ScopedRequest scopedRequest = ScopedServletUtils
1162:                        .unwrapRequest(request);
1163:                ScopedResponse scopedResponse = ScopedServletUtils
1164:                        .unwrapResponse(response);
1165:                assert scopedRequest != null : request.getClass().getName();
1166:                assert scopedResponse != null : response.getClass().getName();
1167:                assert request instanceof  HttpServletRequest : request
1168:                        .getClass().getName();
1169:
1170:                if (scopedRequest == null) {
1171:                    throw new IllegalArgumentException(
1172:                            "request must be of type "
1173:                                    + ScopedRequest.class.getName());
1174:                }
1175:                if (scopedResponse == null) {
1176:                    throw new IllegalArgumentException(
1177:                            "response must be of type "
1178:                                    + ScopedResponse.class.getName());
1179:                }
1180:
1181:                ActionServlet as = InternalUtils.getActionServlet(context);
1182:
1183:                if (actionOverride != null) {
1184:                    // The action must be fully-qualified with its module path.
1185:                    assert actionOverride.charAt(0) == '/' : actionOverride;
1186:                    InternalStringBuilder uri = new InternalStringBuilder(
1187:                            scopedRequest.getContextPath());
1188:                    uri.append(actionOverride);
1189:                    uri.append(PageFlowConstants.ACTION_EXTENSION);
1190:                    scopedRequest.setRequestURI(uri.toString());
1191:                }
1192:
1193:                //
1194:                // In case the request was already forwarded once, clear out the recorded forwarded-URI.  This
1195:                // will allow us to tell whether processing the request actually forwarded somewhere.
1196:                //
1197:                scopedRequest.setForwardedURI(null);
1198:
1199:                //
1200:                // Now process the request.  We create a PageFlowRequestWrapper for pageflow-specific request-scoped info.
1201:                //
1202:                PageFlowRequestWrapper wrappedRequest = PageFlowRequestWrapper
1203:                        .wrapRequest((HttpServletRequest) request);
1204:                wrappedRequest.setScopedLookup(true);
1205:
1206:                if (as != null) {
1207:                    as.doGet(wrappedRequest, scopedResponse); // this just calls process() -- same as doPost()
1208:                } else {
1209:                    // The normal servlet initialization has not completed yet
1210:                    // so rather than call doGet() directly, aquire the request
1211:                    // dispatcher from the unwrapped outer request and call
1212:                    // forward to trigger the servlet initialization.
1213:                    HttpServletRequest req = scopedRequest.getOuterRequest();
1214:                    RequestDispatcher rd = req
1215:                            .getRequestDispatcher(scopedRequest.getRequestURI());
1216:                    rd.forward(wrappedRequest, scopedResponse);
1217:                }
1218:
1219:                String returnURI;
1220:
1221:                if (!scopedResponse.didRedirect()) {
1222:                    returnURI = scopedRequest.getForwardedURI();
1223:
1224:                    if (autoResolveExtensions == null) {
1225:                        autoResolveExtensions = DEFAULT_AUTORESOLVE_EXTENSIONS;
1226:                    }
1227:
1228:                    if (returnURI != null) {
1229:                        for (int i = 0; i < autoResolveExtensions.length; ++i) {
1230:                            if (FileUtils.uriEndsWith(returnURI,
1231:                                    autoResolveExtensions[i])) {
1232:                                scopedRequest.doForward();
1233:                                return strutsLookup(context, wrappedRequest,
1234:                                        scopedResponse, null,
1235:                                        autoResolveExtensions);
1236:                            }
1237:                        }
1238:                    }
1239:                } else {
1240:                    returnURI = scopedResponse.getRedirectURI();
1241:                }
1242:
1243:                RequestContext requestContext = new RequestContext(
1244:                        scopedRequest, scopedResponse);
1245:                Handlers.get(context).getStorageHandler().applyChanges(
1246:                        requestContext);
1247:
1248:                if (returnURI != null) {
1249:                    return new ActionResultImpl(returnURI, scopedResponse
1250:                            .didRedirect(), scopedResponse.getStatusCode(),
1251:                            scopedResponse.getStatusMessage(), scopedResponse
1252:                                    .isError());
1253:                } else {
1254:                    return null;
1255:                }
1256:            }
1257:
1258:            /**
1259:             * If the given request is a MultipartRequestWrapper (Struts class that doesn't extend
1260:             * HttpServletRequestWrapper), return the wrapped request; otherwise, return the given request.
1261:             * @exclude
1262:             */
1263:            public static HttpServletRequest unwrapMultipart(
1264:                    HttpServletRequest request) {
1265:                if (request instanceof  MultipartRequestWrapper) {
1266:                    request = ((MultipartRequestWrapper) request).getRequest();
1267:                }
1268:
1269:                return request;
1270:            }
1271:
1272:            /**
1273:             * Get or create the current {@link GlobalApp} instance.
1274:             * @deprecated Use {@link #getGlobalApp} instead.
1275:             * 
1276:             * @param request the current HttpServletRequest.
1277:             * @param response the current HttpServletResponse
1278:             * @return the current {@link GlobalApp} from the user session, or a newly-instantiated one
1279:             *         (based on the user's Global.app file) if none was in the session.  Failing that,
1280:             *         return <code>null</code>.
1281:             */
1282:            public static GlobalApp ensureGlobalApp(HttpServletRequest request,
1283:                    HttpServletResponse response) {
1284:                ServletContext servletContext = InternalUtils
1285:                        .getServletContext(request);
1286:                return ensureGlobalApp(request, response, servletContext);
1287:            }
1288:
1289:            /**
1290:             * Get or create the current {@link GlobalApp} instance.
1291:             * @deprecated Use {@link #getSharedFlow} instead.
1292:             * 
1293:             * @param request the current HttpServletRequest.
1294:             * @param response the current HttpServletResponse
1295:             * @return the current {@link GlobalApp} from the user session, or a newly-instantiated one
1296:             *         (based on the user's Global.app file) if none was in the session.  Failing that,
1297:             *         return <code>null</code>.
1298:             */
1299:            public static GlobalApp ensureGlobalApp(HttpServletRequest request,
1300:                    HttpServletResponse response, ServletContext servletContext) {
1301:                GlobalApp ga = getGlobalApp(request);
1302:
1303:                if (ga != null) {
1304:                    ga.reinitialize(request, response, servletContext);
1305:                } else {
1306:                    ga = FlowControllerFactory.getGlobalApp(request, response,
1307:                            servletContext);
1308:                }
1309:
1310:                return ga;
1311:            }
1312:
1313:            /**
1314:             * @deprecated This is an internal utility.  {@link InternalUtils#getBindingUpdateErrors} can be used, but it is
1315:             *             not guaranteed to be supported in the future.
1316:             */
1317:            public static Map getBindingUpdateErrors(ServletRequest request) {
1318:                return InternalUtils.getBindingUpdateErrors(request);
1319:            }
1320:
1321:            /**
1322:             * @deprecated This is an internal utility.  {@link InternalUtils#ensureModuleConfig} can be used, but it is
1323:             *             not guaranteed to be supported in the future.
1324:             */
1325:            public static ModuleConfig ensureModuleConfig(String modulePath,
1326:                    ServletRequest request, ServletContext context) {
1327:                return InternalUtils.ensureModuleConfig(modulePath, context);
1328:            }
1329:
1330:            /**
1331:             * @deprecated This will be removed with no replacement in a future release.
1332:             */
1333:            public static ModuleConfig getGlobalAppConfig(
1334:                    ServletContext servletContext) {
1335:                return InternalUtils.getModuleConfig(
1336:                        GLOBALAPP_MODULE_CONTEXT_PATH, servletContext);
1337:            }
1338:
1339:            /**
1340:             * @deprecated This is an internal utility.  {@link InternalUtils#getModuleConfig} can be used, but it is
1341:             *             not guaranteed to be supported in the future.
1342:             */
1343:            public static ModuleConfig getModuleConfig(String modulePath,
1344:                    ServletContext context) {
1345:                return InternalUtils.getModuleConfig(modulePath, context);
1346:            }
1347:
1348:            /**
1349:             * Get the file extension from a file name.
1350:             * @deprecated Use {@link FileUtils#getFileExtension} instead.
1351:             * 
1352:             * @param filename the file name.
1353:             * @return the file extension (everything after the last '.'), or the empty string if there is no file extension.
1354:             */
1355:            public static String getFileExtension(String filename) {
1356:                return FileUtils.getFileExtension(filename);
1357:            }
1358:
1359:            /**
1360:             * @deprecated This is an internal utility.  {@link InternalUtils#getFlowControllerClassName} can be used, but it is
1361:             *             not guaranteed to be supported in the future.
1362:             */
1363:            public static String getPageFlowClassName(String modulePath,
1364:                    ServletRequest request, ServletContext context) {
1365:                return InternalUtils.getFlowControllerClassName(modulePath,
1366:                        request, context);
1367:            }
1368:
1369:            /**
1370:             * @deprecated This method no longer has any effect, and will be removed without replacement in a future release.
1371:             */
1372:            public static boolean ensureAppDeployment(
1373:                    HttpServletRequest request, HttpServletResponse response,
1374:                    ServletContext servletContext) {
1375:                return false;
1376:            }
1377:
1378:            /**
1379:             * Tell whether a given URI is absolute, i.e., whether it contains a scheme-part (e.g., "http:").
1380:             * @deprecated Use {@link FileUtils#isAbsoluteURI} instead.
1381:             * 
1382:             * @param uri the URI to test.
1383:             * @return <code>true</code> if the given URI is absolute.
1384:             */
1385:            public static boolean isAbsoluteURI(String uri) {
1386:                return FileUtils.isAbsoluteURI(uri);
1387:            }
1388:
1389:            /**
1390:             * @deprecated Use {@link #getCurrentPageFlow} instead.
1391:             */
1392:            public static final PageFlowController ensureCurrentPageFlow(
1393:                    HttpServletRequest request, HttpServletResponse response,
1394:                    ServletContext servletContext) {
1395:                try {
1396:                    FlowControllerFactory factory = FlowControllerFactory
1397:                            .get(servletContext);
1398:                    return factory.getPageFlowForRequest(new RequestContext(
1399:                            request, response));
1400:                } catch (InstantiationException e) {
1401:                    _log.error(
1402:                            "Could not instantiate PageFlowController for request "
1403:                                    + request.getRequestURI(), e);
1404:                } catch (IllegalAccessException e) {
1405:                    _log.error(
1406:                            "Could not instantiate PageFlowController for request "
1407:                                    + request.getRequestURI(), e);
1408:                }
1409:
1410:                return null;
1411:            }
1412:
1413:            /**
1414:             * @deprecated Use {@link #getCurrentPageFlow} instead.
1415:             */
1416:            public static final PageFlowController ensureCurrentPageFlow(
1417:                    HttpServletRequest request, HttpServletResponse response) {
1418:                ServletContext servletContext = InternalUtils
1419:                        .getServletContext(request);
1420:
1421:                if (servletContext == null && _log.isWarnEnabled()) {
1422:                    _log.warn("could not get ServletContext from request "
1423:                            + request);
1424:                }
1425:
1426:                return ensureCurrentPageFlow(request, response, servletContext);
1427:            }
1428:
1429:            /**
1430:             * @deprecated This is an internal utility.  {@link InternalUtils#addBindingUpdateError} can be used, but it is
1431:             *             not guaranteed to be supported in the future.
1432:             */
1433:            public static void addBindingUpdateError(ServletRequest request,
1434:                    String expression, String message, Throwable e) {
1435:                InternalUtils.addBindingUpdateError(request, expression,
1436:                        message, e);
1437:            }
1438:
1439:            /**
1440:             * @deprecated This is an internal utility.  {@link ServletUtils#dumpRequest} can be used, but it is
1441:             *             not guaranteed to be supported in the future.
1442:             */
1443:            public static void dumpRequest(HttpServletRequest request,
1444:                    PrintStream output) {
1445:                ServletUtils.dumpRequest(request, output);
1446:            }
1447:
1448:            /**
1449:             * @deprecated This is an internal utility.  {@link ServletUtils#dumpServletContext} can be used, but it is
1450:             *             not guaranteed to be supported in the future.
1451:             */
1452:            public static void dumpServletContext(ServletContext context,
1453:                    PrintStream output) {
1454:                ServletUtils.dumpServletContext(context, output);
1455:            }
1456:
1457:            /**
1458:             * @deprecated Use {@link ServletUtils#preventCache} instead.
1459:             */
1460:            public static void preventCache(HttpServletResponse response) {
1461:                ServletUtils.preventCache(response);
1462:            }
1463:
1464:            /**
1465:             * @deprecated This is an internal utility.  {@link InternalUtils#setCurrentActionResolver} can be used, but it is
1466:             *             not guaranteed to be supported in the future.  This method will be removed in the next version.
1467:             */
1468:            public static void setCurrentActionResolver(
1469:                    ActionResolver resolver, HttpServletRequest request) {
1470:                ServletContext servletContext = InternalUtils
1471:                        .getServletContext(request);
1472:                InternalUtils.setCurrentActionResolver(resolver, request,
1473:                        servletContext);
1474:            }
1475:
1476:            /**
1477:             * Create a raw action URI, which can be modified before being sent through the registered URL rewriting chain
1478:             * using {@link URLRewriterService#rewriteURL}.  Use {@link #getRewrittenActionURI} to get a fully-rewritten URI.
1479:             *
1480:             * @param servletContext the current ServletContext.
1481:             * @param request the current HttpServletRequest.
1482:             * @param response the current HttpServletResponse.
1483:             * @param actionName the action name to convert into a MutableURI; may be qualified with a path from the webapp
1484:             *            root, in which case the parent directory from the current request is <i>not</i> used.
1485:             * @return a MutableURI for the given action, suitable for URL rewriting.
1486:             * @throws URISyntaxException if there is a problem converting the action URI (derived from processing the given
1487:             *             action name) into a MutableURI.
1488:             */
1489:            public static MutableURI getActionURI(
1490:                    ServletContext servletContext, HttpServletRequest request,
1491:                    HttpServletResponse response, String actionName)
1492:                    throws URISyntaxException {
1493:                if (actionName.length() < 1)
1494:                    throw new IllegalArgumentException(
1495:                            "actionName must be non-empty");
1496:
1497:                /*
1498:                 * The implementation for HttpServletRequest method getContextPath()
1499:                 * is not consistant across containers. The spec says the "container
1500:                 * does not decode this string." However, the string returned in
1501:                 * Tomcat is decoded. (See Tomcat bugzilla bug 39503) Also this method
1502:                 * returns a decoded string in some containers if the request is a
1503:                 * forward where the RequestDispatcher was acquired using a relative
1504:                 * path. It seems that it is only the space character in the context
1505:                 * path that causes us issues using the java.net.URI class in our
1506:                 * MutableURI.setURI(). So,... check for a decoded space and encode it.
1507:                 */
1508:                String contextPath = request.getContextPath();
1509:                if (contextPath.indexOf(' ') != -1) {
1510:                    contextPath = contextPath.replace(" ", "%20");
1511:                }
1512:                InternalStringBuilder actionURI = new InternalStringBuilder(
1513:                        contextPath);
1514:
1515:                if (actionName.charAt(0) != '/') {
1516:                    actionURI.append(InternalUtils
1517:                            .getModulePathFromReqAttr(request));
1518:                    actionURI.append('/');
1519:                }
1520:
1521:                actionURI.append(actionName);
1522:                if (!actionName.endsWith(ACTION_EXTENSION))
1523:                    actionURI.append(ACTION_EXTENSION);
1524:
1525:                FreezableMutableURI uri = new FreezableMutableURI();
1526:                uri.setEncoding(response.getCharacterEncoding());
1527:                uri.setPath(actionURI.toString());
1528:                return uri;
1529:            }
1530:
1531:            /**
1532:             * Create a fully-rewritten URI given an action name and parameters.
1533:             *
1534:             * @param servletContext the current ServletContext.
1535:             * @param request the current HttpServletRequest.
1536:             * @param response the current HttpServletResponse.
1537:             * @param actionName the action name to convert into a fully-rewritten URI; may be qualified with a path from the
1538:             *            webapp root, in which case the parent directory from the current request is <i>not</i> used.
1539:             * @param params the additional parameters to include in the URI query.
1540:             * @param fragment the fragment (anchor or location) for this url.
1541:             * @param forXML flag indicating that the query of the uri should be written
1542:             *               using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1543:             * @return a fully-rewritten URI for the given action.
1544:             * @throws URISyntaxException if there is a problem converting the action URI (derived
1545:             *                            from processing the given action name) into a MutableURI.
1546:             */
1547:            public static String getRewrittenActionURI(
1548:                    ServletContext servletContext, HttpServletRequest request,
1549:                    HttpServletResponse response, String actionName,
1550:                    Map params, String fragment, boolean forXML)
1551:                    throws URISyntaxException {
1552:                MutableURI uri = getActionURI(servletContext, request,
1553:                        response, actionName);
1554:                if (params != null)
1555:                    uri.addParameters(params, false);
1556:                if (fragment != null)
1557:                    uri.setFragment(uri.encode(fragment));
1558:
1559:                boolean needsToBeSecure = needsToBeSecure(servletContext,
1560:                        request, uri.getPath(), true);
1561:                URLRewriterService.rewriteURL(servletContext, request,
1562:                        response, uri, URLType.ACTION, needsToBeSecure);
1563:                String key = getURLTemplateKey(URLType.ACTION, needsToBeSecure);
1564:                URIContext uriContext = URIContextFactory.getInstance(forXML);
1565:
1566:                return URLRewriterService.getTemplatedURL(servletContext,
1567:                        request, uri, key, uriContext);
1568:            }
1569:
1570:            /**
1571:             * Create a fully-rewritten URI given a path and parameters.
1572:             *
1573:             * <p> Calls the rewriter service using a type of {@link URLType#RESOURCE}. </p>
1574:             *
1575:             * @param servletContext the current ServletContext.
1576:             * @param request the current HttpServletRequest.
1577:             * @param response the current HttpServletResponse.
1578:             * @param path the path to process into a fully-rewritten URI.
1579:             * @param params the additional parameters to include in the URI query.
1580:             * @param fragment the fragment (anchor or location) for this URI.
1581:             * @param forXML flag indicating that the query of the uri should be written
1582:             *               using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1583:             * @return a fully-rewritten URI for the given action.
1584:             * @throws URISyntaxException if there's a problem converting the action URI (derived
1585:             *                            from processing the given action name) into a MutableURI.
1586:             */
1587:            public static String getRewrittenResourceURI(
1588:                    ServletContext servletContext, HttpServletRequest request,
1589:                    HttpServletResponse response, String path, Map params,
1590:                    String fragment, boolean forXML) throws URISyntaxException {
1591:                return rewriteResourceOrHrefURL(servletContext, request,
1592:                        response, path, params, fragment, forXML,
1593:                        URLType.RESOURCE);
1594:            }
1595:
1596:            /**
1597:             * Create a fully-rewritten URI given a path and parameters.
1598:             *
1599:             * <p> Calls the rewriter service using a type of {@link URLType#ACTION}. </p>
1600:             *
1601:             * @param servletContext the current ServletContext.
1602:             * @param request the current HttpServletRequest.
1603:             * @param response the current HttpServletResponse.
1604:             * @param path the path to process into a fully-rewritten URI.
1605:             * @param params the additional parameters to include in the URI query.
1606:             * @param fragment the fragment (anchor or location) for this URI.
1607:             * @param forXML flag indicating that the query of the uri should be written
1608:             *               using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1609:             * @return a fully-rewritten URI for the given action.
1610:             * @throws URISyntaxException if there's a problem converting the action URI (derived
1611:             *                            from processing the given action name) into a MutableURI.
1612:             */
1613:            public static String getRewrittenHrefURI(
1614:                    ServletContext servletContext, HttpServletRequest request,
1615:                    HttpServletResponse response, String path, Map params,
1616:                    String fragment, boolean forXML) throws URISyntaxException {
1617:                return rewriteResourceOrHrefURL(servletContext, request,
1618:                        response, path, params, fragment, forXML,
1619:                        URLType.ACTION);
1620:            }
1621:
1622:            private static String rewriteResourceOrHrefURL(
1623:                    ServletContext servletContext, HttpServletRequest request,
1624:                    HttpServletResponse response, String path, Map params,
1625:                    String fragment, boolean forXML, URLType urlType)
1626:                    throws URISyntaxException {
1627:                boolean encoded = false;
1628:                UrlConfig urlConfig = ConfigUtil.getConfig().getUrlConfig();
1629:
1630:                if (urlConfig != null) {
1631:                    encoded = !urlConfig.isUrlEncodeUrls();
1632:                }
1633:
1634:                FreezableMutableURI uri = new FreezableMutableURI();
1635:                uri.setEncoding(response.getCharacterEncoding());
1636:                uri.setURI(path, encoded);
1637:
1638:                if (params != null) {
1639:                    uri.addParameters(params, false);
1640:                }
1641:
1642:                if (fragment != null) {
1643:                    uri.setFragment(uri.encode(fragment));
1644:                }
1645:
1646:                URIContext uriContext = URIContextFactory.getInstance(forXML);
1647:                if (uri.isAbsolute()) {
1648:                    return uri.getURIString(uriContext);
1649:                }
1650:
1651:                if (path.length() != 0 && path.charAt(0) != '/') {
1652:                    String reqUri = request.getRequestURI();
1653:                    String reqPath = reqUri.substring(0, reqUri
1654:                            .lastIndexOf('/') + 1);
1655:                    uri.setPath(reqPath + uri.getPath());
1656:                }
1657:
1658:                boolean needsToBeSecure = needsToBeSecure(servletContext,
1659:                        request, uri.getPath(), true);
1660:                URLRewriterService.rewriteURL(servletContext, request,
1661:                        response, uri, urlType, needsToBeSecure);
1662:                String key = getURLTemplateKey(urlType, needsToBeSecure);
1663:
1664:                return URLRewriterService.getTemplatedURL(servletContext,
1665:                        request, uri, key, uriContext);
1666:            }
1667:
1668:            /**
1669:             * Tell whether a given URI should be written to be secure.
1670:             * @param context          the current ServletContext.
1671:             * @param request          the current HttpServletRequest.
1672:             * @param uri              the URI to check.
1673:             * @param stripContextPath if <code>true</code>, strip the webapp context path from the URI before
1674:             *                         processing it.
1675:             * @return <code>true</code> when:
1676:             *         <ul>
1677:             *         <li>the given URI is configured in the deployment descriptor to be secure (according to
1678:             *         {@link SecurityProtocol}), or
1679:             *         <li>the given URI is not configured in the deployment descriptor, and the current request
1680:             *         is secure ({@link HttpServletRequest#isSecure} returns
1681:             *         <code>true</code>).
1682:             *         </ul>
1683:             *         <code>false</code> when:
1684:             *         <ul>
1685:             *         <li>the given URI is configured explicitly in the deployment descriptor to be unsecure
1686:             *         (according to {@link SecurityProtocol}), or
1687:             *         <li>the given URI is not configured in the deployment descriptor, and the current request
1688:             *         is unsecure ({@link HttpServletRequest#isSecure} returns
1689:             *         <code>false</code>).
1690:             *         </ul>
1691:             */
1692:            public static boolean needsToBeSecure(ServletContext context,
1693:                    ServletRequest request, String uri, boolean stripContextPath) {
1694:                // Get the web-app relative path for security check
1695:                String secureCheck = uri;
1696:                if (stripContextPath) {
1697:                    String contextPath = ((HttpServletRequest) request)
1698:                            .getContextPath();
1699:                    if (secureCheck.startsWith(contextPath)) {
1700:                        secureCheck = secureCheck.substring(contextPath
1701:                                .length());
1702:                    }
1703:                }
1704:
1705:                boolean secure = false;
1706:                if (secureCheck.indexOf('?') > -1) {
1707:                    secureCheck = secureCheck.substring(0, secureCheck
1708:                            .indexOf('?'));
1709:                }
1710:
1711:                SecurityProtocol sp = getSecurityProtocol(secureCheck, context,
1712:                        (HttpServletRequest) request);
1713:                if (sp.equals(SecurityProtocol.UNSPECIFIED)) {
1714:                    secure = request.isSecure();
1715:                } else {
1716:                    secure = sp.equals(SecurityProtocol.SECURE);
1717:                }
1718:
1719:                return secure;
1720:            }
1721:
1722:            /**
1723:             * Returns a key for the URL template type given the URL type and a
1724:             * flag indicating a secure URL or not.
1725:             *
1726:             * @param urlType the type of URL (ACTION, RESOURCE).
1727:             * @param needsToBeSecure indicates that the template should be for a secure URL.
1728:             * @return the key/type of template to use.
1729:             */
1730:            public static String getURLTemplateKey(URLType urlType,
1731:                    boolean needsToBeSecure) {
1732:                String key = URLTemplatesFactory.ACTION_TEMPLATE;
1733:                if (urlType.equals(URLType.ACTION)) {
1734:                    if (needsToBeSecure) {
1735:                        key = URLTemplatesFactory.SECURE_ACTION_TEMPLATE;
1736:                    } else {
1737:                        key = URLTemplatesFactory.ACTION_TEMPLATE;
1738:                    }
1739:                } else if (urlType.equals(URLType.RESOURCE)) {
1740:                    if (needsToBeSecure) {
1741:                        key = URLTemplatesFactory.SECURE_RESOURCE_TEMPLATE;
1742:                    } else {
1743:                        key = URLTemplatesFactory.RESOURCE_TEMPLATE;
1744:                    }
1745:                }
1746:
1747:                return key;
1748:            }
1749:
1750:            /**
1751:             * Get an uninitialized instance of a container specific URLTemplatesFactory
1752:             * from the ServletContainerAdapter. If none exists, this returns an instance
1753:             * of {@link DefaultURLTemplatesFactory}. Caller should then set the known
1754:             * and required tokens, call the {@link URLTemplatesFactory#load(javax.servlet.ServletContext)}
1755:             * method and {@link URLTemplatesFactory#initServletContext(javax.servlet.ServletContext,
1756:             * org.apache.beehive.netui.core.urltemplates.URLTemplatesFactory)}. 
1757:             *
1758:             * <p>
1759:             * IMPORTANT NOTE - Always try to get the application instance from the ServletContext
1760:             * by calling {@link URLTemplatesFactory#getURLTemplatesFactory(javax.servlet.ServletContext)}.
1761:             * Then, if a new URLTemplatesFactory must be created, call this method.
1762:             * </p>
1763:             *
1764:             * @param servletContext
1765:             * @return a container specific implementation of URLTemplatesFactory, or
1766:             *         {@link DefaultURLTemplatesFactory}.
1767:             */
1768:            public static URLTemplatesFactory createURLTemplatesFactory(
1769:                    ServletContext servletContext) {
1770:                // get the URLTemplatesFactory from the containerAdapter.
1771:                ServletContainerAdapter containerAdapter = AdapterManager
1772:                        .getServletContainerAdapter(servletContext);
1773:                URLTemplatesFactory factory = (URLTemplatesFactory) containerAdapter
1774:                        .getFactory(URLTemplatesFactory.class, null, null);
1775:
1776:                // if there's no URLTemplatesFactory, use our default impl.
1777:                if (factory == null) {
1778:                    factory = new DefaultURLTemplatesFactory();
1779:                }
1780:
1781:                return factory;
1782:            }
1783:
1784:            /**
1785:             * Make sure that when this page is rendered, it will set headers in the response to prevent caching.
1786:             * Because these headers are lost on server forwards, we set a request attribute to cause the headers
1787:             * to be set right before the page is rendered.  This attribute can be read via
1788:             * {@link #isPreventCache(javax.servlet.ServletRequest)}.
1789:             *
1790:             * @param request the servlet request
1791:             */
1792:            static void setPreventCache(ServletRequest request) {
1793:                assert request != null;
1794:                request.setAttribute(PREVENT_CACHE_ATTR, Boolean.TRUE);
1795:            }
1796:
1797:            /**
1798:             * Internal getter that reports whether this request should prevent caching.  This flag is set via the
1799:             * {@link #setPreventCache(javax.servlet.ServletRequest)} attribute.
1800:             * @param request the servlet request
1801:             * @return <code>true</code> if the framework has set the prevent cache flag
1802:             */
1803:            static boolean isPreventCache(ServletRequest request) {
1804:                assert request != null;
1805:                return request.getAttribute(PREVENT_CACHE_ATTR) != null;
1806:            }
1807:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.