[ 
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

Reply via email to