Source Code Cross Referenced for Forward.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.struts.action.ActionForward;
0022:        import org.apache.struts.action.ActionMapping;
0023:        import org.apache.struts.action.ActionForm;
0024:        import org.apache.struts.config.ModuleConfig;
0025:
0026:        import javax.servlet.http.HttpServletRequest;
0027:        import javax.servlet.ServletContext;
0028:        import javax.servlet.ServletRequest;
0029:        import java.util.List;
0030:        import java.util.ArrayList;
0031:        import java.util.Map;
0032:        import java.util.HashMap;
0033:        import java.lang.reflect.Field;
0034:        import java.lang.reflect.Modifier;
0035:        import java.net.URI;
0036:        import java.net.URL;
0037:
0038:        import org.apache.beehive.netui.pageflow.config.PageFlowActionForward;
0039:        import org.apache.beehive.netui.pageflow.internal.InternalUtils;
0040:        import org.apache.beehive.netui.pageflow.internal.AdapterManager;
0041:        import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
0042:        import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
0043:        import org.apache.beehive.netui.pageflow.handler.Handlers;
0044:        import org.apache.beehive.netui.util.internal.FileUtils;
0045:        import org.apache.beehive.netui.util.internal.InternalStringBuilder;
0046:        import org.apache.beehive.netui.util.logging.Logger;
0047:
0048:        /**
0049:         * An object of this type is returned from an action methods in a {@link PageFlowController} to
0050:         * determine the next URI to be displayed.  It is constructed on the name of a forward defined
0051:         * by the @{@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward @Jpf.Forward} annotation, and resolves to the URI
0052:         * specified in that forward.
0053:         */
0054:        public class Forward extends ActionForward {
0055:            private static final ActionForm[] EMPTY_ACTION_FORM_ARRAY = new ActionForm[0];
0056:
0057:            public static final int RETURN_TO_NONE = 0;
0058:            public static final int RETURN_TO_CURRENT_PAGE = 1;
0059:            public static final int RETURN_TO_PREVIOUS_PAGE = 2;
0060:            public static final int RETURN_TO_PREVIOUS_ACTION = 3;
0061:
0062:            /**
0063:             * @deprecated Use {@link #RETURN_TO_CURRENT_PAGE} or {@link #RETURN_TO_PREVIOUS_PAGE} instead.
0064:             */
0065:            public static final int RETURN_TO_PAGE = -1;
0066:
0067:            /**
0068:             * @deprecated Use {@link #RETURN_TO_PREVIOUS_ACTION} instead.
0069:             */
0070:            public static final int RETURN_TO_ACTION = -2;
0071:
0072:            private static final Logger _log = Logger
0073:                    .getInstance(Forward.class);
0074:
0075:            private static final String RETURN_TO_CURRENT_PAGE_STR = "currentPage";
0076:            private static final String RETURN_TO_PREVIOUS_PAGE_STR = "previousPage";
0077:            private static final String RETURN_TO_PAGE_LEGACY_STR = "page";
0078:            private static final String RETURN_TO_PREVIOUS_ACTION_STR = "previousAction";
0079:            private static final String RETURN_TO_ACTION_LEGACY_STR = "action";
0080:
0081:            private static final Map/*< String, Class >*/PRIMITIVE_TYPES = new HashMap/*< String, Class >*/();
0082:
0083:            static {
0084:                PRIMITIVE_TYPES.put("boolean", boolean.class);
0085:                PRIMITIVE_TYPES.put("byte", byte.class);
0086:                PRIMITIVE_TYPES.put("char", char.class);
0087:                PRIMITIVE_TYPES.put("double", double.class);
0088:                PRIMITIVE_TYPES.put("float", float.class);
0089:                PRIMITIVE_TYPES.put("int", int.class);
0090:                PRIMITIVE_TYPES.put("long", long.class);
0091:                PRIMITIVE_TYPES.put("short", short.class);
0092:            }
0093:
0094:            private List _outputForms;
0095:
0096:            private boolean _isNestedReturn = false;
0097:            private boolean _init = false;
0098:            private transient ActionMapping _mapping = null; // will be reinitialized as necessary by PreviousPageInfo
0099:            private transient FlowController _flowController = null; // will be reinitialized as necessary by PreviousPageInfo
0100:            private transient ServletContext _servletContext = null; // will be reinitialized as necessary by PreviousPageInfo
0101:            private String _mappingPath;
0102:            private InternalStringBuilder _queryString;
0103:            private boolean _explicitPath = false;
0104:            private String _outputFormBeanType = null;
0105:            private Map _actionOutputs = null;
0106:            private int _returnToType;
0107:            private boolean _redirectSpecifiedOnAnnotation = false;
0108:            private boolean _redirectSetThroughMethod = false;
0109:            private boolean _restoreQueryString = false;
0110:            private boolean _externalRedirect = false;
0111:            private boolean _outsidePageFlowDirectory = false;
0112:            private String _relativeTo;
0113:
0114:            /**
0115:             * An alternate ModuleConfig from which to resolve forwards if they are not resolved
0116:             * from the stored ActionMapping (and its stored ModuleConfig).
0117:             */
0118:            private ModuleConfig _altModuleConfig;
0119:
0120:            /**
0121:             * Construct based on an initializer Forward.  This is a framework-invoked constructor that should not normally
0122:             * be called directly.
0123:             */
0124:            protected Forward(Forward init) {
0125:                _outputForms = init._outputForms;
0126:                _init = init._init;
0127:                _mapping = init._mapping;
0128:                _mappingPath = init._mappingPath;
0129:                _queryString = init._queryString;
0130:                _explicitPath = init._explicitPath;
0131:                _flowController = init._flowController;
0132:                _servletContext = init._servletContext;
0133:                _outputFormBeanType = init._outputFormBeanType;
0134:                _actionOutputs = init._actionOutputs;
0135:                _returnToType = init._returnToType;
0136:                _restoreQueryString = init._restoreQueryString;
0137:                _externalRedirect = init._externalRedirect;
0138:                _redirectSpecifiedOnAnnotation = init._redirectSpecifiedOnAnnotation;
0139:                _redirectSetThroughMethod = init._redirectSetThroughMethod;
0140:            }
0141:
0142:            /**
0143:             * Construct based on a given request.  This is a framework-invoked constructor that should not normally
0144:             * be called directly.
0145:             */
0146:            protected Forward(HttpServletRequest request) {
0147:                setPath(InternalUtils.getDecodedServletPath(request));
0148:                setContextRelative(true);
0149:                _explicitPath = true;
0150:            }
0151:
0152:            /**
0153:             * Constructor which accepts the name of a forward defined by the
0154:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}
0155:             * annotation.  The values returned from {@link #getPath}, {@link #getRedirect} and
0156:             * {@link #contextRelative} are resolved from this forward.
0157:             * 
0158:             * @param forwardName the name of the forward
0159:             *            ({@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}) to resolve.
0160:             */
0161:            public Forward(String forwardName) {
0162:                setName(forwardName);
0163:            }
0164:
0165:            /**
0166:             * Constructor which accepts the name of a forward defined by the
0167:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}
0168:             * annotation.  The values returned from {@link #getPath}, {@link #getRedirect} and
0169:             * {@link #contextRelative} are resolved from this forward.  Also accepts a form bean
0170:             * to make available in the request (or user session, as appropriate).
0171:             * 
0172:             * @param forwardName the name of the forward
0173:             * ({@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}) to resolve.
0174:             * @param outputFormBean a form bean instance to make available in the request (or user session, as appropriate).
0175:             *            See {@link #addOutputForm} for details about how this manifests itself.
0176:             */
0177:            public Forward(String forwardName, Object outputFormBean) {
0178:                this (forwardName);
0179:
0180:                if (outputFormBean != null) {
0181:                    addOutputForm(outputFormBean);
0182:                }
0183:            }
0184:
0185:            /**
0186:             * Constructor which accepts the name of a forward defined by the
0187:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}
0188:             * annotation.  The values returned from {@link #getPath}, {@link #getRedirect} and
0189:             * {@link #contextRelative} are resolved from this forward.  Also accepts a named action output
0190:             * to make available in the request, through {@link PageFlowUtils#getActionOutput}..
0191:             * 
0192:             * @param forwardName the name of the forward
0193:             * ({@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}) to resolve.
0194:             * @param actionOutputName the name of a action output to make available in the request.
0195:             * @param actionOutputValue the action output object to make available in the request.
0196:             */
0197:            public Forward(String forwardName, String actionOutputName,
0198:                    Object actionOutputValue) {
0199:                this (forwardName);
0200:                addActionOutput(actionOutputName, actionOutputValue);
0201:            }
0202:
0203:            /**
0204:             * Constructs a Forward that returns the given URI for {@link #getPath}.  By default
0205:             * the Forward will cause server forward (not a browser redirect); to change this, use
0206:             * {@link #setRedirect}.
0207:             * 
0208:             * @param uri the URI to return for {@link #getPath}.
0209:             */
0210:            public Forward(URI uri) {
0211:                setPath(uri.toString());
0212:                setContextRelative(uri.getPath().startsWith("/"));
0213:                if (uri.isAbsolute())
0214:                    super .setRedirect(true);
0215:                _explicitPath = true;
0216:            }
0217:
0218:            /**
0219:             * Constructs a Forward that returns the given URI for {@link #getPath}.
0220:             * 
0221:             * @param uri the URI to return for {@link #getPath}.
0222:             * @param doRedirect set to <code>true</code> if this Forward should cause a browser redirect;
0223:             *                 <code>false</code> if it should cause a server forward.
0224:             */
0225:            public Forward(URI uri, boolean doRedirect) {
0226:                if (!doRedirect && uri.isAbsolute()) {
0227:                    throw new IllegalStateException(
0228:                            "Redirect value cannot be set to false for an absolute URI.");
0229:                }
0230:
0231:                setPath(uri.toString());
0232:                setRedirect(doRedirect);
0233:                setContextRelative(uri.getPath().startsWith("/"));
0234:                _explicitPath = true;
0235:            }
0236:
0237:            /**
0238:             * Construct based on the given <strong>webapp-relative</strong> path.  This is a framework-invoked constructor that
0239:             * should not normally be called directly.
0240:             */
0241:            protected Forward(String path, boolean doRedirect) {
0242:                setPath(path);
0243:                setContextRelative(true);
0244:                setRedirect(doRedirect);
0245:                _explicitPath = true;
0246:            }
0247:
0248:            /**
0249:             * Constructs a Forward that returns the given URL for {@link #getPath}.  Because the URL path
0250:             * is absolute by nature, this Forward will cause a browser redirect.
0251:             * 
0252:             * @param url the URL to return for {@link #getPath}.
0253:             */
0254:            public Forward(URL url) {
0255:                setPath(url.toString());
0256:                super .setRedirect(true);
0257:                _explicitPath = true;
0258:            }
0259:
0260:            /**
0261:             * Internal.  Initialize from an existing Struts ActionForward.
0262:             */
0263:            protected Forward(ActionForward initFwd,
0264:                    ServletContext servletContext) {
0265:                _servletContext = servletContext;
0266:                setName(initFwd.getName());
0267:                initFrom(initFwd);
0268:            }
0269:
0270:            /**
0271:             * Set whether the URI resolved by this Forward should be redirected to.
0272:             * 
0273:             * @param doRedirect if <code>true</code>, the controller will send a browser redirect to
0274:             *                 the URI for this Forward; otherwise, it will do a server forward to
0275:             *                 the URI.
0276:             */
0277:            public void setRedirect(boolean doRedirect) {
0278:                super .setRedirect(doRedirect);
0279:                _redirectSetThroughMethod = true;
0280:            }
0281:
0282:            /**
0283:             * Tell whether the URI resolved by this Forward should be redirected to.
0284:             * 
0285:             * @return <code>true</code> if the controller will send a browser redirect to the URI for
0286:             *         this Forward; <code>false</code> if it will do a server forward to the URI.
0287:             */
0288:            public boolean isRedirect() {
0289:                return super .getRedirect();
0290:            }
0291:
0292:            /**
0293:             * Add a form bean that will be made available in the request (or user session, as
0294:             * appropriate) if this Forward is returned by an action method in a {@link PageFlowController}.
0295:             * Specifically, each form bean is stored as a request attribute with a name determined by
0296:             * {@link PageFlowUtils#getFormBeanName}.
0297:             * 
0298:             * @param formBean the form bean instance to add.
0299:             */
0300:            public final void addOutputForm(Object formBean) {
0301:                assert formBean != null : "The output form bean may not me null.";
0302:
0303:                if (formBean == null)
0304:                    throw new IllegalArgumentException(
0305:                            "The output form bean may not be null.");
0306:                if (_outputForms == null)
0307:                    _outputForms = new ArrayList();
0308:
0309:                //
0310:                // Throw an exception if this is a redirect, and if there was an output form added.  Output forms are carried
0311:                // in the request, and will be lost on redirects.
0312:                //
0313:                if (_init && getRedirect()) {
0314:                    String actionPath = _mappingPath != null ? _mappingPath
0315:                            : "";
0316:                    String descrip = getName() != null ? getName() : getPath();
0317:                    PageFlowException ex = new IllegalRedirectOutputFormException(
0318:                            descrip, actionPath, _flowController, formBean
0319:                                    .getClass().getName());
0320:                    InternalUtils.throwPageFlowException(ex);
0321:                }
0322:
0323:                _outputForms.add(InternalUtils.wrapFormBean(formBean));
0324:            }
0325:
0326:            /**
0327:             * Get all form-beans attached to this forward through {@link #addOutputForm} or {@link #Forward(String, Object)}.
0328:             * 
0329:             * @return an array of ActionForm instances that are attached to this forward.
0330:             */
0331:            public final ActionForm[] getOutputForms() {
0332:                if (_outputForms == null)
0333:                    return EMPTY_ACTION_FORM_ARRAY;
0334:                return (ActionForm[]) _outputForms
0335:                        .toArray(EMPTY_ACTION_FORM_ARRAY);
0336:            }
0337:
0338:            /**
0339:             * Get the first output form bean that was added to this Forward.
0340:             */
0341:            public ActionForm getFirstOutputForm(HttpServletRequest request) {
0342:                if (_outputForms == null || _outputForms.size() == 0) {
0343:                    if (_outputFormBeanType != null) {
0344:                        try {
0345:                            if (_log.isDebugEnabled()) {
0346:                                _log.debug("Creating form bean of type "
0347:                                        + _outputFormBeanType);
0348:                            }
0349:
0350:                            ServletContext servletContext = InternalUtils
0351:                                    .getServletContext(request);
0352:                            ReloadableClassHandler rch = Handlers.get(
0353:                                    servletContext).getReloadableClassHandler();
0354:                            Object formBean = rch
0355:                                    .newInstance(_outputFormBeanType);
0356:                            ActionForm wrappedFormBean = InternalUtils
0357:                                    .wrapFormBean(formBean);
0358:                            addOutputForm(wrappedFormBean);
0359:                            return wrappedFormBean;
0360:                        } catch (Exception e) {
0361:                            _log.error(
0362:                                    "Could not create form bean instance of "
0363:                                            + _outputFormBeanType, e);
0364:                        }
0365:                    }
0366:
0367:                    return null;
0368:                } else {
0369:                    return (ActionForm) _outputForms.get(0);
0370:                }
0371:            }
0372:
0373:            /**
0374:             * Tell whether {@link #getPath} will be successful, i.e., whether one of the following two
0375:             * conditions is met:
0376:             *     <ul>
0377:             *         <li>the name around which this object was constructed resolves to a path defined
0378:             *             by a {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}, or</li>
0379:             *         <li>this object was constructed around an explicit path, by
0380:             *             {@link #Forward(URI)} or {@link #Forward(URL)}.</li>
0381:             *     </ul>
0382:             * 
0383:             * @return <code>true</code> if this forward does resolve to a URI path.
0384:             */
0385:            public boolean doesResolve() {
0386:                if (_explicitPath) {
0387:                    return true;
0388:                }
0389:
0390:                assert _mapping != null || _altModuleConfig != null : "PageFlow.Forward.doesResolve() called outside of request";
0391:                return findForward(getName()) != null;
0392:            }
0393:
0394:            /**
0395:             * Resolves the forward with the given name, from the stored ActionMapping if possible, or
0396:             * from the stored alternate ModuleConfig as a last resort.
0397:             * 
0398:             * @param forwardName the name of the forward to resolve.
0399:             * @return the resolved ActionForward, or <code>null</code> if none is found.
0400:             */
0401:            protected ActionForward findForward(String forwardName) {
0402:                ActionForward fwd = _mapping != null ? _mapping
0403:                        .findForward(forwardName) : null;
0404:
0405:                if (fwd != null) {
0406:                    return fwd;
0407:                } else if (_altModuleConfig != null) {
0408:                    return (ActionForward) _altModuleConfig
0409:                            .findForwardConfig(forwardName);
0410:                }
0411:
0412:                return null;
0413:            }
0414:
0415:            /**
0416:             * Set an alternate ModuleConfig from which to resolve forwards if they are not resolved
0417:             * from the stored ActionMapping (and its stored ModuleConfig).
0418:             */
0419:            public void setAlternateModuleConfig(ModuleConfig mc) {
0420:                _altModuleConfig = mc;
0421:            }
0422:
0423:            private void init() {
0424:                if (!_init) {
0425:                    if (_mappingPath == null && _altModuleConfig == null) {
0426:                        throw new IllegalStateException(
0427:                                "Forward is not initialized.  Use initialize().");
0428:                    }
0429:
0430:                    ActionForward fwd = findForward(getName());
0431:
0432:                    if (fwd == null) {
0433:                        PageFlowException ex = new UnresolvableForwardException(
0434:                                getName(), _mappingPath, _flowController);
0435:                        InternalUtils.throwPageFlowException(ex);
0436:                    }
0437:
0438:                    initFrom(fwd);
0439:
0440:                    //
0441:                    // Throw an exception if this is a redirect, and if there was an output form or an action output added.
0442:                    // Output forms and action outputs are carried in the request, and will be lost on redirects.
0443:                    //
0444:                    if (getRedirect()) {
0445:                        if (_actionOutputs != null && !_actionOutputs.isEmpty()) {
0446:                            PageFlowException ex = new IllegalActionOutputException(
0447:                                    getName(), _mappingPath, _flowController,
0448:                                    (String) _actionOutputs.keySet().iterator()
0449:                                            .next());
0450:                            InternalUtils.throwPageFlowException(ex);
0451:                        }
0452:
0453:                        if (_outputForms != null && !_outputForms.isEmpty()) {
0454:                            PageFlowException ex = new IllegalRedirectOutputFormException(
0455:                                    getName(), _mappingPath, _flowController,
0456:                                    _outputForms.get(0).getClass().getName());
0457:                            InternalUtils.throwPageFlowException(ex);
0458:                        }
0459:                    }
0460:                }
0461:            }
0462:
0463:            private void initFrom(ActionForward fwd) {
0464:                setContextRelative(fwd.getContextRelative());
0465:
0466:                //
0467:                // Add query params to the path.
0468:                //
0469:                path = fwd.getPath();
0470:                if (_queryString != null)
0471:                    path += _queryString.toString();
0472:
0473:                if (fwd instanceof  PageFlowActionForward) {
0474:                    PageFlowActionForward fc = (PageFlowActionForward) fwd;
0475:                    _isNestedReturn = fc.isNestedReturn();
0476:                    _outputFormBeanType = fc.getReturnFormType();
0477:                    _redirectSpecifiedOnAnnotation = fc
0478:                            .hasExplicitRedirectValue();
0479:                    _restoreQueryString = fc.isRestoreQueryString();
0480:                    _externalRedirect = fc.isExternalRedirect();
0481:                    _relativeTo = fc.getRelativeTo();
0482:
0483:                    Class returnFormClass = null;
0484:
0485:                    if (_outputFormBeanType != null) {
0486:                        try {
0487:                            ReloadableClassHandler rch = Handlers.get(
0488:                                    _servletContext)
0489:                                    .getReloadableClassHandler();
0490:                            returnFormClass = rch
0491:                                    .loadClass(_outputFormBeanType);
0492:                        } catch (ClassNotFoundException e) {
0493:                            // This should never happen -- the JPF compiler ensures that it's a valid class.
0494:                            assert false : e;
0495:                        }
0496:                    }
0497:
0498:                    if (fc.isReturnToPage() || fc.isReturnToAction()) {
0499:                        String fwdPath = fc.getPath();
0500:
0501:                        if (fwdPath.equals(RETURN_TO_PREVIOUS_PAGE_STR)) {
0502:                            _returnToType = RETURN_TO_PREVIOUS_PAGE;
0503:                        } else if (fwdPath.equals(RETURN_TO_CURRENT_PAGE_STR)) {
0504:                            _returnToType = RETURN_TO_CURRENT_PAGE;
0505:                        } else if (fwdPath.equals(RETURN_TO_PAGE_LEGACY_STR)) {
0506:                            _returnToType = RETURN_TO_PAGE; // legacy
0507:                        } else if (fwdPath
0508:                                .equals(RETURN_TO_PREVIOUS_ACTION_STR)) {
0509:                            _returnToType = RETURN_TO_PREVIOUS_ACTION;
0510:                        } else if (fwdPath.equals(RETURN_TO_ACTION_LEGACY_STR)) {
0511:                            _returnToType = RETURN_TO_ACTION; // legacy
0512:                        } else {
0513:                            assert false : "invalid return-to type for forward "
0514:                                    + fc.getName() + ": " + fwdPath;
0515:                            _returnToType = RETURN_TO_CURRENT_PAGE;
0516:                        }
0517:                    }
0518:
0519:                    String retFormMember = fc.getReturnFormMember();
0520:
0521:                    if (retFormMember != null) {
0522:                        try {
0523:                            assert _flowController != null; // should be set in initialize()
0524:                            Field field = _flowController.getClass()
0525:                                    .getDeclaredField(retFormMember);
0526:                            returnFormClass = field.getType();
0527:                            if (!Modifier.isPublic(field.getModifiers()))
0528:                                field.setAccessible(true);
0529:                            Object form = field.get(_flowController);
0530:
0531:                            if (form != null) {
0532:                                if (_log.isDebugEnabled()) {
0533:                                    _log.debug("using member " + retFormMember
0534:                                            + " for Forward " + getName());
0535:                                }
0536:
0537:                                addOutputForm(form);
0538:                            } else {
0539:                                if (_log.isInfoEnabled()) {
0540:                                    _log.info("returnFormMember "
0541:                                            + retFormMember + " was null.");
0542:                                }
0543:                            }
0544:                        } catch (NoSuchFieldException e) {
0545:                            assert false : "could not find field "
0546:                                    + retFormMember; // compiler should catch this
0547:                        } catch (IllegalAccessException e) {
0548:                            assert false; // should not get here -- field is accessible.
0549:                        }
0550:                    }
0551:
0552:                    //
0553:                    // Make sure that if there's currently an output form, that it confirms to the return-form-type.
0554:                    //
0555:                    if (returnFormClass != null && _outputForms != null
0556:                            && _outputForms.size() > 0) {
0557:                        Object outputForm = InternalUtils
0558:                                .unwrapFormBean((ActionForm) _outputForms
0559:                                        .get(0));
0560:
0561:                        if (!returnFormClass.isInstance(outputForm)) {
0562:                            PageFlowException ex = new IllegalOutputFormTypeException(
0563:                                    getName(), _mappingPath, _flowController,
0564:                                    outputForm.getClass().getName(),
0565:                                    returnFormClass.getName());
0566:                            InternalUtils.throwPageFlowException(ex);
0567:                        }
0568:                    }
0569:
0570:                    checkActionOutputs(fc);
0571:                }
0572:
0573:                if (!_redirectSetThroughMethod)
0574:                    setRedirect(fwd.getRedirect());
0575:
0576:                _init = true;
0577:            }
0578:
0579:            /**
0580:             * Make sure required action outputs are present, and are of the right type (only make the latter check when not
0581:             * in production mode
0582:             */
0583:            private void checkActionOutputs(PageFlowActionForward fc) {
0584:                PageFlowActionForward.ActionOutput[] actionOutputs = fc
0585:                        .getActionOutputs();
0586:                boolean doExpensiveChecks = _actionOutputs != null
0587:                        && !AdapterManager.getServletContainerAdapter(
0588:                                _servletContext).isInProductionMode();
0589:
0590:                for (int i = 0; i < actionOutputs.length; ++i) {
0591:                    PageFlowActionForward.ActionOutput actionOutput = actionOutputs[i];
0592:
0593:                    if (!actionOutput.getNullable()) {
0594:                        String actionOutputName = actionOutput.getName();
0595:                        if (_actionOutputs == null
0596:                                || !_actionOutputs
0597:                                        .containsKey(actionOutputName)) {
0598:                            PageFlowException ex = new MissingActionOutputException(
0599:                                    _mappingPath, _flowController, actionOutput
0600:                                            .getName(), getName());
0601:                            InternalUtils.throwPageFlowException(ex);
0602:                        } else if (_actionOutputs.get(actionOutputName) == null) {
0603:                            PageFlowException ex = new NullActionOutputException(
0604:                                    _mappingPath, _flowController, actionOutput
0605:                                            .getName(), getName());
0606:                            InternalUtils.throwPageFlowException(ex);
0607:                        }
0608:                    }
0609:
0610:                    //
0611:                    // If we're *not* in production mode, do some (expensive) checks to ensure that the types for the
0612:                    // action outputs match their declared types.
0613:                    //
0614:                    if (doExpensiveChecks) {
0615:                        Object actualActionOutput = _actionOutputs
0616:                                .get(actionOutput.getName());
0617:
0618:                        if (actualActionOutput != null) {
0619:                            String expectedTypeName = actionOutput.getType();
0620:                            int expectedArrayDims = 0;
0621:
0622:                            while (expectedTypeName.endsWith("[]")) {
0623:                                ++expectedArrayDims;
0624:                                expectedTypeName = expectedTypeName.substring(
0625:                                        0, expectedTypeName.length() - 2);
0626:                            }
0627:
0628:                            Class expectedType = (Class) PRIMITIVE_TYPES
0629:                                    .get(expectedTypeName);
0630:
0631:                            if (expectedType == null) {
0632:                                try {
0633:                                    ReloadableClassHandler rch = Handlers.get(
0634:                                            _servletContext)
0635:                                            .getReloadableClassHandler();
0636:                                    expectedType = rch
0637:                                            .loadClass(expectedTypeName);
0638:                                } catch (ClassNotFoundException e) {
0639:                                    _log
0640:                                            .error("Could not load expected action output type "
0641:                                                    + expectedTypeName
0642:                                                    + " for action output '"
0643:                                                    + actionOutput.getName()
0644:                                                    + "' on forward '"
0645:                                                    + fc.getName()
0646:                                                    + "'; skipping type check.");
0647:                                    continue;
0648:                                }
0649:                            }
0650:
0651:                            Class actualType = actualActionOutput.getClass();
0652:                            int actualArrayDims = 0;
0653:                            InternalStringBuilder arraySuffix = new InternalStringBuilder();
0654:
0655:                            while (actualType.isArray()
0656:                                    && actualArrayDims <= expectedArrayDims) {
0657:                                ++actualArrayDims;
0658:                                arraySuffix.append("[]");
0659:                                actualType = actualType.getComponentType();
0660:                            }
0661:
0662:                            if (actualArrayDims != expectedArrayDims
0663:                                    || !expectedType
0664:                                            .isAssignableFrom(actualType)) {
0665:                                PageFlowException ex = new MismatchedActionOutputException(
0666:                                        _mappingPath, _flowController,
0667:                                        actionOutput.getName(), getName(),
0668:                                        expectedTypeName, actualType.getName()
0669:                                                + arraySuffix);
0670:                                InternalUtils.throwPageFlowException(ex);
0671:                            }
0672:                        }
0673:                    }
0674:                }
0675:            }
0676:
0677:            /**
0678:             * Set the current ActionMapping and associated FlowController.  Normally, this method is called
0679:             * by the framework, but you can use it to initialize the Forward object in order to call {@link #getPath}.
0680:             * 
0681:             * @deprecated Use {@link #initialize(ActionMapping, FlowController, ServletRequest)} instead.
0682:             * @param mapping the current ActionMapping; this can be obtained from {@link FlowController#getMapping}.
0683:             * @param flowController the object in which to look for referenced return-form members.
0684:             */
0685:            public void initialize(ActionMapping mapping,
0686:                    FlowController flowController) {
0687:                _mapping = mapping;
0688:                _mappingPath = mapping != null ? mapping.getPath() : null;
0689:                _flowController = flowController;
0690:                _servletContext = flowController.getServletContext();
0691:            }
0692:
0693:            /**
0694:             * Set the current ActionMapping and associated FlowController.  Normally, this method is called
0695:             * by the framework, but you can use it to initialize the Forward object in order to call {@link #getPath}.
0696:             * 
0697:             * @param mapping the current ActionMapping; this can be obtained from {@link FlowController#getMapping}.
0698:             * @param flowController the object in which to look for referenced return-form members.
0699:             */
0700:            public void initialize(ActionMapping mapping,
0701:                    FlowController flowController, ServletRequest request) {
0702:                _mapping = mapping;
0703:                _mappingPath = mapping != null ? mapping.getPath() : null;
0704:                _flowController = flowController;
0705:                _servletContext = flowController.getServletContext();
0706:            }
0707:
0708:            /**
0709:             * Set the path to be returned by {@link #getPath}.  This overrides any path or forward name
0710:             * set in a constructor.
0711:             * 
0712:             * @param contextRelativePath the path to be returned by {@link #getPath}.
0713:             */
0714:            public void setPath(String contextRelativePath) {
0715:                path = contextRelativePath;
0716:                _init = true;
0717:            }
0718:
0719:            boolean isExplicitPath() {
0720:                return _explicitPath;
0721:            }
0722:
0723:            /**
0724:             * Tell whether this Forward was configured explicitly (through
0725:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward#redirect &#64;Jpf.Forward(redirect=...)},
0726:             * {@link #setRedirect}, or {@link #Forward(URI, boolean)}) to perform a redirect.  Otherwise, a redirect is
0727:             * implied by a URI that does not resolve to the current server.
0728:             */
0729:            public boolean hasExplicitRedirectValue() {
0730:                return _redirectSetThroughMethod
0731:                        || _redirectSpecifiedOnAnnotation;
0732:            }
0733:
0734:            /**
0735:             * Get the URI path associated with this object.  Resolve it from the name of a forward
0736:             * ({@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward}) if necessary.
0737:             * 
0738:             * @return a String that is the URI path.
0739:             * @see #Forward(String)
0740:             * @see #Forward(String, Object)
0741:             * @see #Forward(URI)
0742:             * @see #Forward(URL)
0743:             * @see #setPath
0744:             */
0745:            public String getPath() {
0746:                init();
0747:                return super .getPath();
0748:            }
0749:
0750:            /**
0751:             * Tell whether returning this forward from an action method will cause a return from
0752:             * a nested {@link PageFlowController}.
0753:             * 
0754:             * @return <code>true</code> if this forward will cause a return from nesting.
0755:             */
0756:            public boolean isNestedReturn() {
0757:                init();
0758:                return _isNestedReturn;
0759:            }
0760:
0761:            /**
0762:             * Tell whether returning this forward from an action method will cause a previous page
0763:             * to be displayed.
0764:             * 
0765:             * @return <code>true</code> if returning this forward from an action method will cause
0766:             *         a previous page to be displayed.
0767:             */
0768:            public boolean isReturnToPage() {
0769:                init();
0770:                return _returnToType == RETURN_TO_PREVIOUS_PAGE
0771:                        || _returnToType == RETURN_TO_CURRENT_PAGE
0772:                        || _returnToType == RETURN_TO_PAGE;
0773:            }
0774:
0775:            /**
0776:             * Tell whether returning this forward from an action method will cause the previous action
0777:             * to be re-run.
0778:             * 
0779:             * @return <code>true</code> if returning this forward from an action method will cause the
0780:             * previous action to be re-run, i.e., whether the URI returned by {@link #getPath} will end
0781:             * in "<i>previous-action-name</i>.do".
0782:             */
0783:            public boolean isReturnToAction() {
0784:                init();
0785:                return _returnToType == RETURN_TO_PREVIOUS_ACTION
0786:                        || _returnToType == RETURN_TO_ACTION;
0787:            }
0788:
0789:            /**
0790:             * Tell whether this is a redirect to a URI outside of the current web application.
0791:             */
0792:            public boolean isExternalRedirect() {
0793:                return _externalRedirect;
0794:            }
0795:
0796:            /**
0797:             * Specify that this is a redirect to a URI outside of the current web application.
0798:             */
0799:            public void setExternalRedirect(boolean externalRedirect) {
0800:                _externalRedirect = externalRedirect;
0801:                if (externalRedirect)
0802:                    setRedirect(true);
0803:            }
0804:
0805:            /**
0806:             * Tell whether this Forward will restore the original query string on the page restored when a
0807:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward},
0808:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.SimpleAction &#64;Jpf.SimpleAction},
0809:             * or {@link org.apache.beehive.netui.pageflow.annotations.Jpf.ConditionalForward &#64;Jpf.ConditionalForward}
0810:             * with <code>navigateTo={@link org.apache.beehive.netui.pageflow.annotations.Jpf.NavigateTo#previousAction Jpf.NavigateTo.previousAction}
0811:             * </code> is used.
0812:             */
0813:            public boolean doesRestoreQueryString() {
0814:                init();
0815:                return _restoreQueryString;
0816:            }
0817:
0818:            /**
0819:             * Set whether this Forward will restore the original query string query string on the page restored when a
0820:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Forward &#64;Jpf.Forward},
0821:             * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.SimpleAction &#64;Jpf.SimpleAction},
0822:             * or {@link org.apache.beehive.netui.pageflow.annotations.Jpf.ConditionalForward &#64;Jpf.ConditionalForward}
0823:             * with <code>navigateTo={@link org.apache.beehive.netui.pageflow.annotations.Jpf.NavigateTo#previousAction Jpf.NavigateTo.previousAction}
0824:             * </code> is used.
0825:             */
0826:            public void setRestoreQueryString(boolean doesRestoreQueryString) {
0827:                _restoreQueryString = doesRestoreQueryString;
0828:            }
0829:
0830:            /**
0831:             * Tell whether the URI returned by {@link #getPath} is for a page flow.
0832:             * 
0833:             * @return <code>true</code> if the URI returned by {@link #getPath} is for a page flow, i.e., 
0834:             * if it ends in ".jpf".
0835:             */
0836:            public boolean forwardsToPageFlow() {
0837:                return FileUtils.osSensitiveEndsWith(getPath(),
0838:                        PageFlowConstants.PAGEFLOW_EXTENSION);
0839:            }
0840:
0841:            /**
0842:             * Set the query string that will be appended to the URI returned by {@link #getPath}.
0843:             * 
0844:             * @param queryString the query string that will be appended to the URI.  If this string does not
0845:             *            start with <code>'?'</code>, then this character will be prepended; if the string is
0846:             *            <code>null</code>, the query string will be removed.
0847:             */
0848:            public void setQueryString(String queryString) {
0849:                if (queryString == null || queryString.length() == 0) {
0850:                    _queryString = null;
0851:                } else if (queryString.charAt(0) == '?') {
0852:                    _queryString = new InternalStringBuilder(queryString);
0853:                } else {
0854:                    _queryString = new InternalStringBuilder("?")
0855:                            .append(queryString);
0856:                }
0857:            }
0858:
0859:            /**
0860:             * Get the query string that will be appended to the URI returned by {@link #getPath}.
0861:             * 
0862:             * @return the query string that will be appended to the URI, or <code>null</code> if there
0863:             *         is no query string.
0864:             */
0865:            public String getQueryString() {
0866:                return _queryString != null ? _queryString.toString() : null;
0867:            }
0868:
0869:            /**
0870:             * Add a query parameter to the URI returned by {@link #getPath}.
0871:             * 
0872:             * @param paramName the name of the query parameter.
0873:             * @param value the value of the query parameter, or <code>null</code> if there is no value.
0874:             */
0875:            public void addQueryParam(String paramName, String value) {
0876:                if (_queryString == null) {
0877:                    _queryString = new InternalStringBuilder("?");
0878:                } else {
0879:                    _queryString.append('&');
0880:                }
0881:
0882:                _queryString.append(paramName);
0883:
0884:                if (value != null) {
0885:                    _queryString.append('=').append(value);
0886:                }
0887:            }
0888:
0889:            /**
0890:             * Add a query parameter with no value to the URI returned by {@link #getPath}.
0891:             * 
0892:             * @param paramName the name of the query parameter.
0893:             */
0894:            public final void addQueryParam(String paramName) {
0895:                addQueryParam(paramName, null);
0896:            }
0897:
0898:            /**
0899:             * Adds an action output that will be made available in the request, through {@link PageFlowUtils#getActionOutput}.
0900:             * 
0901:             * @deprecated Use {@link #addActionOutput} instead.
0902:             * @param paramName the name of the action output.
0903:             * @param value the action output value.
0904:             */
0905:            public void addPageInput(String paramName, Object value) {
0906:                addActionOutput(paramName, value);
0907:            }
0908:
0909:            /**
0910:             * Adds an action output that will be made available in the request, through {@link PageFlowUtils#getActionOutput}.
0911:             * 
0912:             * @param paramName the name of the action output.
0913:             * @param value the action output value.
0914:             */
0915:            public void addActionOutput(String paramName, Object value) {
0916:                if (paramName == null || paramName.length() == 0) {
0917:                    throw new IllegalArgumentException(
0918:                            "An action output name may not be null or empty.");
0919:                }
0920:
0921:                if (_actionOutputs == null) {
0922:                    _actionOutputs = new HashMap();
0923:                }
0924:
0925:                //
0926:                // Throw an exception if this is a redirect, and if there was an action output.  Action outputs are carried
0927:                // in the request, and will be lost on redirects.
0928:                //
0929:                if (_init && getRedirect()) {
0930:                    String actionPath = _mappingPath != null ? _mappingPath
0931:                            : "";
0932:                    String descrip = getName() != null ? getName() : getPath();
0933:                    PageFlowException ex = new IllegalActionOutputException(
0934:                            descrip, actionPath, _flowController, paramName);
0935:                    InternalUtils.throwPageFlowException(ex);
0936:                }
0937:
0938:                _actionOutputs.put(paramName, value);
0939:            }
0940:
0941:            /**
0942:             * Get all action outputs that have been set on this Forward.
0943:             * 
0944:             * @deprecated Use {@link #getActionOutputs} instead.
0945:             * @return a Map of name/value pairs representing all action outputs.
0946:             * @see #addActionOutput
0947:             */
0948:            public Map getPageInputs() {
0949:                return getActionOutputs();
0950:            }
0951:
0952:            /**
0953:             * Get all action outputs that have been set on this Forward.
0954:             * 
0955:             * @return a Map of name/value pairs representing all action outputs.
0956:             * @see #addActionOutput
0957:             */
0958:            public Map getActionOutputs() {
0959:                return _actionOutputs;
0960:            }
0961:
0962:            /**
0963:             * Get the type of return, if this is a <code>return-to</code> type.
0964:             * 
0965:             * @return one of the following values: {@link #RETURN_TO_CURRENT_PAGE}, {@link #RETURN_TO_PREVIOUS_PAGE},
0966:             *         {@link #RETURN_TO_PAGE}, {@link #RETURN_TO_PREVIOUS_ACTION}, {@link #RETURN_TO_ACTION}, or
0967:             *         {@link #RETURN_TO_NONE} if this Forward is not a <code>return-to</code> type.
0968:             * @see #isReturnToAction
0969:             * @see #isReturnToPage
0970:             */
0971:            public int getReturnToType() {
0972:                return _returnToType;
0973:            }
0974:
0975:            /**
0976:             * Get the type of return as a String, if this is a <code>return-to</code> type.
0977:             * 
0978:             * @return one of the following values: <code>currentPage</code>, <code>previousPage</code>, <code>page</code>,
0979:             *         (deprecated), <code>previousAction</code>, <code>action</code> (deprecated), or <code>null</code>
0980:             *         if this is not a <code>return-to</code> type.
0981:             * @see #isReturnToAction
0982:             * @see #isReturnToPage
0983:             */
0984:            public String getReturnToTypeAsString() {
0985:                switch (_returnToType) {
0986:                case RETURN_TO_CURRENT_PAGE:
0987:                    return RETURN_TO_CURRENT_PAGE_STR;
0988:
0989:                case RETURN_TO_PREVIOUS_PAGE:
0990:                    return RETURN_TO_PREVIOUS_PAGE_STR;
0991:
0992:                case RETURN_TO_PAGE:
0993:                    return RETURN_TO_PAGE_LEGACY_STR;
0994:
0995:                case RETURN_TO_PREVIOUS_ACTION:
0996:                    return RETURN_TO_PREVIOUS_ACTION_STR;
0997:
0998:                case RETURN_TO_ACTION:
0999:                    return RETURN_TO_ACTION_LEGACY_STR;
1000:                }
1001:
1002:                return null;
1003:            }
1004:
1005:            void reinitialize(FlowController fc) {
1006:                _flowController = fc;
1007:                _servletContext = fc.getServletContext();
1008:
1009:                if (_mapping == null && _mappingPath != null) {
1010:                    ModuleConfig mc = fc.getModuleConfig();
1011:                    assert mc != null : "no ModuleConfig found for "
1012:                            + fc.getClass().getName();
1013:                    _mapping = (ActionMapping) mc
1014:                            .findActionConfig(_mappingPath);
1015:                }
1016:            }
1017:
1018:            /**
1019:             * Tell whether this Forward is relative to a particular directory path
1020:             * (as is the case when inheriting local paths from base classes). If
1021:             * this is true, it implies the forward is an inherited global forward,
1022:             * with a &quot;relativeTo&quot; path given in a &lt;set-property&gt;
1023:             * in the forward config.
1024:             * 
1025:             * <p>
1026:             * This is a framework-invoked method that should not normally be called
1027:             * directly.
1028:             * </p>
1029:             */
1030:            public boolean hasRelativeToPath() {
1031:                return _relativeTo != null;
1032:            }
1033:
1034:            /**
1035:             * If this is a local path, change it so it's relative to the given path prefix, and remember that we did it in
1036:             * a flag (_outsidePageFlowDirectory).  This is a framework-invoked method that should not normally be called
1037:             * directly.
1038:             */
1039:            public void initializeRelativePath(ServletRequest request,
1040:                    String relativeTo) {
1041:                if (relativeTo == null) {
1042:                    relativeTo = _relativeTo;
1043:                }
1044:
1045:                if (relativeTo == null)
1046:                    return;
1047:
1048:                assert !relativeTo.endsWith("/") : relativeTo;
1049:                String path = getPath();
1050:
1051:                // If this is a local (relative) path, prefix it with the given 'relativeTo' path, and save a flag.
1052:                // We save this flag in a local variable because the Forward object may be saved/restored for use again.
1053:                if (!getContextRelative() && !FileUtils.isAbsoluteURI(path)) {
1054:                    assert path.startsWith("/") : path;
1055:                    setPath(relativeTo + path);
1056:                    setContextRelative(true);
1057:                    _outsidePageFlowDirectory = true;
1058:                }
1059:
1060:                // Store a flag in the request that will prevent another page flow from being initialized implicitly because
1061:                // we're hitting a path within it.  We want to stay in the context of the current page flow.
1062:                if (_outsidePageFlowDirectory) {
1063:                    PageFlowRequestWrapper.get(request).setStayInCurrentModule(
1064:                            true);
1065:                }
1066:            }
1067:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.