You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "A. Alonso Domínguez (JIRA)" <ji...@apache.org> on 2006/05/13 16:17:31 UTC

[jira] Commented: (STR-2875) and tags can find the correct bundle in a multimodule webapp

    [ http://issues.apache.org/struts/browse/STR-2875?page=comments#action_37348 ] 

A. Alonso Domínguez commented on STR-2875:
------------------------------------------

This is related to the <s:messages /> tag. The bug responsible of the problem is at the org.apache.struts.faces.renderer.MessagesRenderer class, about line 71:

protected String getText(FacesContext context, UIComponent component) {

        // Look up the MessageResources bundle to be used
        String bundle = (String) component.getAttributes().get("bundle");
        if (bundle == null) {
            bundle = Globals.MESSAGES_KEY;
        }
        MessageResources resources = (MessageResources)
            context.getExternalContext().getApplicationMap().get(bundle);
        if (resources == null) { // FIXME - i18n
            throw new IllegalArgumentException("MessageResources bundle " +
                                               bundle + " not found");
        }

As you can see, the bug is very similar to the one of <s:loadMessages /> tag. The problem is the lookup mechanism again, the following code tries to solve it and actually is working for me:

String bundle = (String) component.getAttributes().get("bundle");
        if (bundle == null) {
            bundle = Globals.MESSAGES_KEY;
        }
        
        ModuleConfig modConfig = (ModuleConfig) context.getExternalContext()
			.getRequestMap().get(Globals.MODULE_KEY);
        
        MessageResources resources = (MessageResources)
            context.getExternalContext().getRequestMap().get(bundle);
        if(resources == null) {
			resources = (MessageResources)
				context.getExternalContext().getApplicationMap().get(bundle + modConfig.getPrefix());
        }
            
        if (resources == null) { // FIXME - i18n
            throw new IllegalArgumentException("MessageResources bundle " +
                                               bundle + " not found");
        }

Regards,
Alonso

> <s:loadMessages /> and <s:messages /> tags can find the correct bundle in a multimodule webapp
> ----------------------------------------------------------------------------------------------
>
>          Key: STR-2875
>          URL: http://issues.apache.org/struts/browse/STR-2875
>      Project: Struts Action 1
>         Type: Bug

>   Components: Faces
>     Versions: 1.3.4
>  Environment: struts multimodule webapp
>     Reporter: A. Alonso Domínguez

>
> Hi there,
> I think that there is a bug in the implementation of the "org.apache.struts.faces.taglib.LoadMessagesTag". When working in a multimodule webapp with several <messages-resources /> per module, the <s:loadMessages /> tag can't find the appropiate MessageResources instance via "messages" attribute.
> The reason for this is the way that the tag uses to locate the appropiate MessageResources instance. This code explains it (line 76):
> public int doStartTag() {
>         // Acquire the Locale to be wrapped
>         Locale locale =
>             FacesContext.getCurrentInstance().getViewRoot().getLocale();
>            
>         // Acquire the MessageResources to be wrapped
>         MessageResources messages = null;
>         if (this.messages == null) {
>             messages = (MessageResources)
>                 pageContext.getAttribute(Globals.MESSAGES_KEY,
>                                          PageContext.REQUEST_SCOPE );
>             if (messages == null) {
>                 messages = (MessageResources)
>                     pageContext.getAttribute(Globals.MESSAGES_KEY,
>                                              PageContext.APPLICATION_SCOPE );
>             }
>         } else {
>             messages = (MessageResources)
>                 pageContext.getAttribute(this.messages,
>                                          PageContext.REQUEST_SCOPE);
>         }
>         // Expose a Map instance under the specified request attribute key
>         pageContext.setAttribute(var,
>                                  new MessagesMap(messages, locale),
>                                  PageContext.APPLICATION_SCOPE);
>         // Skip the body of this tag (if any)
>         return (SKIP_BODY);
>     }
> As you can see, this code doesn't supports modules.
> If we want to load a different bundle than the one configured as the default, we must use the "messages" attribute but this code tries to load that MessageResources instance from the APPLICATION_SCOPE rather that search for it inside the REQUEST_SCOPE.
> In a multimodule webapp the MessageResources instances are loaded on startup inside the APPLICATION_SCOPE with the key:
> org.apache.struts.action/MESSAGE + [modulePrefix]
> If we have more than one MessageResources instance per module the will be loaded with the key:
> [bundleKey] + [modulePrefix]
> So, the above code can't load any of those kind of messages resources. This can be solved easily:
> public int doStartTag() throws JspException {
>         // Acquire the Locale to be wrapped
>         Locale locale =
>             FacesContext.getCurrentInstance().getViewRoot().getLocale();
>            
>         ModuleConfig modConfig = ModuleUtils.getInstance().getModuleConfig(
>             (HttpServletRequest) pageContext.getRequest(), pageContext.getServletContext());
>         // Acquire the MessageResources to be wrapped
>         MessageResources messages = null;
>         if (this.messages == null) {
>             messages = (MessageResources)
>                 pageContext.getAttribute(Globals.MESSAGES_KEY,
>                                          PageContext.REQUEST_SCOPE);
>             if (messages == null) {
>                 messages = (MessageResources)
>                     pageContext.getAttribute(Globals.MESSAGES_KEY + modConfig.getPrefix(),
>                                              PageContext.APPLICATION_SCOPE);
>             }
>         } else {
>             messages = (MessageResources)
>                 pageContext.getAttribute(this.messages,
>                                          PageContext.REQUEST_SCOPE);
>                                         
>             if(messages == null) {
>                 messages = (MessageResources)
>                     pageContext.getAttribute(this.messages + modConfig.getPrefix(),
>                                             PageContext.APPLICATION_SCOPE);
>             }
>         }
>         if(messages == null)
>             throw new JspException("MessageResources bundle " +
>                                                this.messages + " not found");
>         // Expose a Map instance under the specified request attribute key
>         pageContext.setAttribute(var,
>                                  new MessagesMap(messages, locale),
>                                  PageContext.REQUEST_SCOPE);
>         // Skip the body of this tag (if any)
>         return (SKIP_BODY);
>     }
> Something similar happens with the <s:message /> tag but I don't have the solution yet
> Alonso

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira