3 Replies Latest reply on Apr 18, 2007 7:12 PM by alexsmirnov

    a4j:loadBundle and f:loadBundle problem with facelet

    andrew.rw.robinson

      I have realized that neither the a4j:loadBundle or f:loadBundle is sufficient for my needs with my custom component/facelet. The main problem is that my component needs to evaluate a message bundle value during the PROCESS_VALIDATIONS phase.

      Problems:

      1) f:loadBundle uses a tag handler to set the variable during apply. This is required in my facelet as I need my message bundle during the facelets compilation stage. The problem is that apply is not called before PROCESS_VALIDATIONS

      2) a4j:loadBundle is quite insufficient for my needs as it only applies the value during encoding. Therefore it is unavailable during facelet compilation as well as PROCESS_VALIDATIONS.

      Temporarily (or permanently), I am going to create my own load bundle component with a tag handler that uses the facelet code and then override processValidations, processDecodes and processUpdates to ensure the bundle is loaded for all phases for the component.

      I am just wondering if there is already a solution like this, and if not that this functionality be incorporated into the a4j:loadBundle code.

        • 1. Re: a4j:loadBundle and f:loadBundle problem with facelet

          Can you share your code with us? It will be great if we can incorporate this into future releases.

          • 2. Re: a4j:loadBundle and f:loadBundle problem with facelet
            andrew.rw.robinson

            New code for the taglib file:

             <tag>
             <tag-name>loadBundle</tag-name>
             <component>
             <component-type>example.Bundle</component-type>
             <handler-class>
             example.LoadBundleHandler
             </handler-class>
             </component>
             </tag>
            

            New code for the faces-config.xml:
             <component>
             <component-type>example.Bundle</component-type>
             <component-class>
             example.AjaxLoadBundle
             </component-class>
             </component>
            

            LoadBundleHandler.java:
            /**
             *
             */
            package example;
            
            import java.io.IOException;
            import java.util.ResourceBundle;
            
            import javax.el.ELException;
            import javax.faces.FacesException;
            import javax.faces.component.UIComponent;
            import javax.faces.context.FacesContext;
            
            import org.ajax4jsf.ajax.ResourceBundleMap;
            
            import com.sun.facelets.FaceletContext;
            import com.sun.facelets.tag.TagAttribute;
            import com.sun.facelets.tag.TagAttributeException;
            import com.sun.facelets.tag.jsf.ComponentConfig;
            import com.sun.facelets.tag.jsf.ComponentHandler;
            
            /**
             * @author arobinson
             */
            public class LoadBundleHandler
             extends ComponentHandler
            {
             private final TagAttribute basename;
             private final TagAttribute var;
            
             /**
             * @param config
             */
             public LoadBundleHandler(ComponentConfig config)
             {
             super(config);
             this.basename = this.getRequiredAttribute("basename");
             this.var = this.getRequiredAttribute("var");
             }
            
             /**
             * @see com.sun.facelets.tag.jsf.ComponentHandler#applyNextHandler(com.sun.facelets.FaceletContext,
             * javax.faces.component.UIComponent)
             */
             @Override @SuppressWarnings("unchecked")
             protected void applyNextHandler(FaceletContext ctx, UIComponent c)
             throws IOException, FacesException, ELException
             {
             ResourceBundle bundle = null;
             try
             {
             String name = this.basename.getValue(ctx);
             ClassLoader cl = Thread.currentThread().getContextClassLoader();
             Locale locale = null;
             UIViewRoot viewRoot = ctx.getFacesContext().getViewRoot();
             if (viewRoot != null)
             locale = viewRoot.getLocale();
             if (locale == null)
             locale = Locale.getDefault();
             bundle = ResourceBundle.getBundle(name, locale, cl);
             }
             catch (Exception e)
             {
             throw new TagAttributeException(this.tag, this.basename, e);
             }
             ResourceBundleMap map = new ResourceBundleMap(bundle);
             FacesContext faces = ctx.getFacesContext();
             faces.getExternalContext().getRequestMap().put(this.var.getValue(ctx), map);
             super.applyNextHandler(ctx, c);
             }
            }
            

            AjaxLoadBundle.java:
            /**
             *
             */
            package example;
            
            import java.io.IOException;
            
            import javax.faces.FacesException;
            import javax.faces.context.FacesContext;
            
            /**
             *
             *
             * @author arobinson
             */
            public class AjaxLoadBundle
             extends org.ajax4jsf.ajax.html.AjaxLoadBundle
            {
             public final static String COMPONENT_TYPE = "com.outlooksoft.Bundle";
            
             /**
             * @see javax.faces.component.UIComponentBase#processDecodes(javax.faces.context.FacesContext)
             */
             @Override
             public void processDecodes(FacesContext context)
             {
             super.processDecodes(context);
             // ensure that the bundle is available through all phases
             try
             {
             encodeBegin(context);
             }
             catch (IOException ex)
             {
             throw new FacesException(ex);
             }
             }
            }
            


            • 3. Re: a4j:loadBundle and f:loadBundle problem with facelet
              alexsmirnov

              we will text this case and add to the codebase is everything is OK.

              a4j:loadBundle is only workaround for JSF 1.1. You can use facelets with JSF 1.2 and define bundles in faces-config.xml