Return-Path: Delivered-To: apmail-incubator-beehive-commits-archive@www.apache.org Received: (qmail 84869 invoked from network); 15 Sep 2004 17:04:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 15 Sep 2004 17:04:55 -0000 Received: (qmail 65162 invoked by uid 500); 15 Sep 2004 17:04:32 -0000 Delivered-To: apmail-incubator-beehive-commits-archive@incubator.apache.org Received: (qmail 65053 invoked by uid 500); 15 Sep 2004 17:04:30 -0000 Mailing-List: contact beehive-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Beehive Dev" Delivered-To: mailing list beehive-commits@incubator.apache.org Received: (qmail 64994 invoked by uid 500); 15 Sep 2004 17:04:30 -0000 Delivered-To: apmail-incubator-beehive-cvs@incubator.apache.org Received: (qmail 64966 invoked by uid 99); 15 Sep 2004 17:04:29 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Wed, 15 Sep 2004 10:04:28 -0700 Received: (qmail 84443 invoked by uid 65534); 15 Sep 2004 17:04:25 -0000 Date: 15 Sep 2004 17:04:25 -0000 Message-ID: <20040915170425.84436.qmail@minotaur.apache.org> From: rich@apache.org To: beehive-cvs@incubator.apache.org Subject: svn commit: rev 46123 - in incubator/beehive/trunk/netui/src: compiler/org/apache/beehive/netui/compiler compiler/org/apache/beehive/netui/compiler/genmodel pageflow/org/apache/beehive/netui/pageflow pageflow/org/apache/beehive/netui/pageflow/annotations pageflow/org/apache/beehive/netui/pageflow/internal X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: rich Date: Wed Sep 15 10:04:24 2004 New Revision: 46123 Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionOutputModel.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/CachedPageFlowInfo.java incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalUtils.java Log: - Added a 'required' attribute on @Jpf.ActionOutput, to replace 'nullable' (deprecated). - Fixed an NPE that occurred when calling FlowControllerFactory.getPageFlow() on a page flow class whose Struts module has not yet been registered. - Re-added some protected methods that were lost when FlowController broke its inheritance from org.apache.struts.action.Action. DRT: netui (WinXP) BB: self (linux) Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java ============================================================================== --- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java (original) +++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java Wed Sep 15 10:04:24 2004 @@ -123,6 +123,7 @@ public static final String BUNDLE_KEY_ATTR = "bundleKey"; public static final String ACTION_OUTPUTS_ATTR = "actionOutputs"; public static final String NULLABLE_ATTR = "nullable"; + public static final String REQUIRED_ATTR = "required"; public static final String USE_FORM_BEAN_ATTR = "useFormBean"; public static final String READONLY_ATTR = "readOnly"; public static final String RESTORE_QUERY_STRING_ATTR = "restoreQueryString"; Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionOutputModel.java ============================================================================== --- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionOutputModel.java (original) +++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionOutputModel.java Wed Sep 15 10:04:24 2004 @@ -34,7 +34,12 @@ public GenActionOutputModel( AnnotationMirror annotation, ClassDeclaration jclass ) { setName( CompilerUtils.getString( annotation, NAME_ATTR, true ) ); - setNullable( CompilerUtils.getBoolean( annotation, NULLABLE_ATTR, false ).booleanValue() ); + + Boolean required = CompilerUtils.getBoolean( annotation, REQUIRED_ATTR, true ); + boolean nullable = + required != null ? ! required : CompilerUtils.getBoolean( annotation, NULLABLE_ATTR, false ); + + setNullable( nullable ); // // Get the base type, and add "[]" to it for arrays. Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java Wed Sep 15 10:04:24 2004 @@ -24,15 +24,20 @@ import org.apache.beehive.netui.pageflow.internal.InternalUtils; import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils; import org.apache.beehive.netui.pageflow.internal.RequestValues; -import org.apache.beehive.netui.pageflow.handler.LoginHandler; +import org.apache.beehive.netui.pageflow.annotations.Jpf;import org.apache.beehive.netui.pageflow.handler.LoginHandler; import org.apache.beehive.netui.pageflow.handler.ExceptionsHandler; import org.apache.beehive.netui.util.cache.ClassLevelCache; import org.apache.beehive.netui.util.logging.Logger; import org.apache.struts.Globals; +import org.apache.struts.util.TokenProcessor; +import org.apache.struts.util.MessageResources; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionServlet; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionMessages; import org.apache.struts.config.ActionConfig; import org.apache.struts.config.ModuleConfig; @@ -42,6 +47,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import javax.sql.DataSource; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; @@ -67,6 +73,26 @@ private static final String DEFAULT_SIMPLE_ACTION_FORWARD_NAME = "_defaultForward"; private static final Locale DEFAULT_LOCALE = Locale.getDefault(); private static final ActionForward NULL_ACTION_FORWARD = new ActionForward(); + private static final TokenProcessor TOKEN_PROCESSOR = TokenProcessor.getInstance(); + + /** + * The system default Locale. + * + * @deprecated Use {@link #getDefaultLocale}. + */ + protected static Locale defaultLocale = DEFAULT_LOCALE; + + + /** + * Get the current Struts ActionServlet. + * + * @deprecated This variable will be removed with no replacement. In most cases, + * {@link FlowController#getServletContext()} is sufficient; for other cases, the ActionServlet itself + * is in the ServletContext attribute {@link Globals#ACTION_SERVLET_KEY}. + */ + protected transient ActionServlet servlet = null; + + static class PerRequestState @@ -133,6 +159,7 @@ // isn't available to do a lazy initialization. // initModuleConfig( servletContext, request ); + servlet = getServlet(); super.reinitialize( request, response, servletContext ); } @@ -192,16 +219,6 @@ InternalUtils.sendError( "PageFlow_Custom_Error", request, response, null, getDisplayName(), errText ); } - public static Locale retrieveUserLocale( HttpServletRequest request, String locale ) - { - if ( locale == null ) locale = Globals.LOCALE_KEY; - HttpSession session = request.getSession( false ); - Locale userLocale = null; - if ( session != null ) userLocale = ( Locale ) session.getAttribute( locale ); - if ( userLocale == null ) userLocale = DEFAULT_LOCALE; - return userLocale; - } - /** * Handle the given exception - invoke user code if appropriate and return a destination URI. * @@ -1495,5 +1512,297 @@ return new Forward( DEFAULT_SIMPLE_ACTION_FORWARD_NAME ); } + + /** + * Get the system default locale. + * + * @return the system default locale. + */ + protected static Locale getDefaultLocale() + { + return defaultLocale; + } + + + /** + * Generate a new transaction token, to be used for enforcing a single request for a particular transaction. + * @deprecated Use + * + * @param request the current request. + */ + protected String generateToken(HttpServletRequest request) { + return TOKEN_PROCESSOR.generateToken(request); + } + + /** + * Return the default data source for the module associated with this page flow. + * + * @param request the current request. + */ + protected DataSource getDataSource(HttpServletRequest request) { + + return getDataSource(request, Globals.DATA_SOURCE_KEY); + + } + + /** + * Return the specified data source for the current module. + * + * @param request The servlet request we are processing + * @param key The key specified in the + * <message-resources> element for the + * requested bundle + */ + protected DataSource getDataSource(HttpServletRequest request, String key) { + + ModuleConfig moduleConfig = getModuleConfig(); + + // Return the requested data source instance + return (DataSource) getServletContext().getAttribute( key + moduleConfig.getPrefix() ); + + } + + + /** + * Return the user's currently selected Locale. + * @deprecated Use {@link #getLocale()}. + * + * @param request the current request. + * @return the user's currently selected Locale, stored in the session. + */ + protected Locale getLocale(HttpServletRequest request) { + + HttpSession session = request.getSession(); + Locale locale = (Locale) session.getAttribute(Globals.LOCALE_KEY); + return locale != null ? locale : DEFAULT_LOCALE; + } + + /** + * Return the user's currently selected Locale. + * + * @return the user's currently selected Locale, stored in the session. + */ + protected Locale getLocale() + { + Locale locale = (Locale) getSession().getAttribute(Globals.LOCALE_KEY); + return locale != null ? locale : DEFAULT_LOCALE; + } + + public static Locale retrieveUserLocale( HttpServletRequest request, String locale ) + { + if ( locale == null ) locale = Globals.LOCALE_KEY; + HttpSession session = request.getSession( false ); + Locale userLocale = null; + if ( session != null ) userLocale = ( Locale ) session.getAttribute( locale ); + if ( userLocale == null ) userLocale = DEFAULT_LOCALE; + return userLocale; + } + + /** + * Return the message resources for the default module. + * + * @deprecated This method can only return the resources for the default + * module. Use getResources(HttpServletRequest) to get the + * resources for the current module. + */ + protected MessageResources getResources() { + + return (MessageResources) + getServletContext().getAttribute(Globals.MESSAGES_KEY); + + } + + + /** + * Return the default message resources for the current module. + * + * @param request The servlet request we are processing + */ + protected MessageResources getResources(HttpServletRequest request) { + + return ((MessageResources) request.getAttribute(Globals.MESSAGES_KEY)); + + } + + + + /** + * Return the specified message resources for the current module. + * + * @param request the current request. + * @param key The bundle key specified in a + * {@link Jpf.MessageResource} annotation. + * <message-resources> element for the + * requested bundle + * + * @since Struts 1.1 + */ + protected MessageResources getResources(HttpServletRequest request, + String key) { + + return ((MessageResources) getServletContext().getAttribute + (key + getModuleConfig().getPrefix())); + + } + + /** + *

Returns true if the current form's cancel button was + * pressed. This method will check if the Globals.CANCEL_KEY + * request attribute has been set, which normally occurs if the cancel + * button generated by CancelTag was pressed by the user + * in the current request. If true, validation performed + * by an ActionForm's validate() method + * will have been skipped by the controller servlet.

+ * + * @param request The servlet request we are processing + * @see org.apache.struts.taglib.html.CancelTag + */ + protected boolean isCancelled(HttpServletRequest request) { + + return (request.getAttribute(Globals.CANCEL_KEY) != null); + + } + + + /** + * Return true if there is a transaction token stored in + * the user's current session, and the value submitted as a request + * parameter with this action matches it. Returns false + * under any of the following circumstances: + *
    + *
  • No session associated with this request
  • + *
  • No transaction token saved in the session
  • + *
  • No transaction token included as a request parameter
  • + *
  • The included transaction token value does not match the + * transaction token in the user's session
  • + *
+ * + * @param request The servlet request we are processing + */ + protected boolean isTokenValid(HttpServletRequest request) { + + return TOKEN_PROCESSOR.isTokenValid(request, false); + + } + + + /** + * Return true if there is a transaction token stored in + * the user's current session, and the value submitted as a request + * parameter with this action matches it. Returns false + *
    + *
  • No session associated with this request
  • + *
  • No transaction token saved in the session
  • + *
  • No transaction token included as a request parameter
  • + *
  • The included transaction token value does not match the + * transaction token in the user's session
  • + *
+ * + * @param request The servlet request we are processing + * @param reset Should we reset the token after checking it? + */ + protected boolean isTokenValid( + HttpServletRequest request, + boolean reset) { + + return TOKEN_PROCESSOR.isTokenValid(request, reset); + } + + + /** + * Reset the saved transaction token in the user's session. This + * indicates that transactional token checking will not be needed + * on the next request that is submitted. + * + * @param request The servlet request we are processing + */ + protected void resetToken(HttpServletRequest request) { + TOKEN_PROCESSOR.resetToken(request); + } + + + /** + * Save the specified error messages keys into the appropriate request + * attribute for use by the <html:errors> tag, if any messages + * are required. Otherwise, ensure that the request attribute is not + * created. + * + * @param request The servlet request we are processing + * @param errors Error messages object + */ + protected void saveErrors(HttpServletRequest request, + ActionErrors errors) { + + // Remove any error messages attribute if none are required + if (errors == null || errors.isEmpty()) { + request.removeAttribute(Globals.ERROR_KEY); + return; + } + + // Save the error messages we need + request.setAttribute(Globals.ERROR_KEY, errors); + + } + + + /** + * Save the specified messages keys into the appropriate request + * attribute for use by the <html:messages> tag (if + * messages="true" is set), if any messages are required. Otherwise, + * ensure that the request attribute is not created. + * + * @param request The servlet request we are processing + * @param messages Messages object + * @since Struts 1.1 + */ + protected void saveMessages(HttpServletRequest request, + ActionMessages messages) { + + // Remove any messages attribute if none are required + if (messages == null || messages.isEmpty()) { + request.removeAttribute(Globals.MESSAGE_KEY); + return; + } + + // Save the messages we need + request.setAttribute(Globals.MESSAGE_KEY, messages); + + } + + + /** + * Save a new transaction token in the user's current session, creating + * a new session if necessary. + * + * @param request The servlet request we are processing + */ + protected void saveToken(HttpServletRequest request) { + TOKEN_PROCESSOR.saveToken(request); + } + + + /** + * Set the user's currently selected Locale. + * @deprecated Use {@link #setLocale(java.util.Locale)}. + * + * @param request The request we are processing + * @param locale The user's selected Locale to be set, or null + * to select the server's default Locale + */ + protected void setLocale(HttpServletRequest request, Locale locale) { + + HttpSession session = request.getSession(); + if (locale == null) { + locale = defaultLocale; + } + session.setAttribute(Globals.LOCALE_KEY, locale); + + } + + protected void setLocale( Locale locale ) + { + if ( locale == null ) locale = getDefaultLocale(); + getSession().setAttribute( Globals.LOCALE_KEY, locale ); + } } Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java Wed Sep 15 10:04:24 2004 @@ -25,8 +25,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; +import javax.servlet.ServletException; import org.apache.struts.config.ModuleConfig; +import org.apache.struts.action.ActionServlet; + +import java.io.IOException; /** @@ -178,6 +182,37 @@ } } + private static ModuleConfig ensureModule( String modulePath, HttpServletRequest request, + ServletContext servletContext ) + { + ModuleConfig mc = InternalUtils.getModuleConfig( modulePath, servletContext ); + + if ( mc == null ) + { + ActionServlet as = InternalUtils.getActionServlet( servletContext ); + + if ( as instanceof AutoRegisterActionServlet ) + { + AutoRegisterActionServlet das = ( AutoRegisterActionServlet ) as; + + try + { + return das.ensureModuleRegistered( modulePath, request ); + } + catch ( IOException e ) + { + _log.error( "Could not register Struts module for path " + modulePath, e ); + } + catch ( ServletException e ) + { + _log.error( "Could not register Struts module for path " + modulePath, e.getRootCause() ); + } + } + } + + return null; + } + /** * Get the {@link PageFlowController} for the given type. The PageFlowController stack (for * nesting) will be cleared or pushed, and the new instance will be stored as the current @@ -203,10 +238,15 @@ // PageFlowUtils.getCurrentPageFlow again, with the singleton flag. // PageFlowController retVal = null; - String modulePath = PageFlowUtils.getModulePath( request ); - ModuleConfig mc = InternalUtils.getModuleConfig( modulePath, servletContext ); - boolean createdNew = false; - assert mc != null : "no module config for page flow class " + jpfClass.getName(); + String modulePath = InternalUtils.inferModulePathFromClassName( jpfClass.getName() ); + ModuleConfig mc = ensureModule( modulePath, request, servletContext ); + + if ( mc == null ) + { + _log.error( "Struts module " + modulePath + " not found for " + jpfClass.getName() + + "; cannot create page flow."); + return null; + } if ( InternalUtils.isSingleton( mc ) ) { @@ -233,6 +273,7 @@ // PageFlowController.forwardTo(). Nested page flows can only self-nest by forwarding to the .jpf URI, not // indirectly by executing actions on themselves (think about it -- that would be a disaster). // + boolean createdNew = false; boolean isNestable = InternalUtils.isNestable( mc ); PageFlowStack pfStack = PageFlowStack.get( request, false ); Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java Wed Sep 15 10:04:24 2004 @@ -388,6 +388,8 @@ { String name(); Class type(); + boolean required() default true; + /** @deprecated Use {@link #required}. **/ boolean nullable() default false; } Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/CachedPageFlowInfo.java ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/CachedPageFlowInfo.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/CachedPageFlowInfo.java Wed Sep 15 10:04:24 2004 @@ -73,17 +73,7 @@ // // module path // - int lastDot = className.lastIndexOf( '.' ); - - if ( lastDot != -1 ) - { - className = className.substring( 0, lastDot ); - _modulePath = "/" + className.replace( '.', '/' ); - } - else - { - _modulePath = ""; - } + _modulePath = InternalUtils.inferModulePathFromClassName( className ); } public String getModulePath() Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalUtils.java ============================================================================== --- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalUtils.java (original) +++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalUtils.java Wed Sep 15 10:04:24 2004 @@ -1003,4 +1003,19 @@ return null; } + + public static String inferModulePathFromClassName( String className ) + { + int lastDot = className.lastIndexOf( '.' ); + + if ( lastDot != -1 ) + { + className = className.substring( 0, lastDot ); + return '/' + className.replace( '.', '/' ); + } + else + { + return ""; + } + } }