You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2006/11/23 12:17:12 UTC

svn commit: r478534 - in /myfaces: core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/ tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/ tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/ tomaha...

Author: mmarinschek
Date: Thu Nov 23 03:17:05 2006
New Revision: 478534

URL: http://svn.apache.org/viewvc?view=rev&rev=478534
Log:
TOMAHAWK-798: Implemented an s:loadBundle for better AJAX and PPR handling

Added:
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/FacesEventWrapper.java
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundle.java
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundleTag.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/LoadBundleTag.java
    myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml
    myfaces/tomahawk/trunk/sandbox/core/src/main/tld/myfaces_sandbox.tld

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/LoadBundleTag.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/LoadBundleTag.java?view=diff&rev=478534&r1=478533&r2=478534
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/LoadBundleTag.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/LoadBundleTag.java Thu Nov 23 03:17:05 2006
@@ -77,18 +77,19 @@
             throw new JspException("No faces context?!");
         }
 
-        UIViewRoot viewRoot = facesContext.getViewRoot();
-        if (viewRoot == null)
+        try
         {
-            throw new JspException("No view root! LoadBundle must be nested inside <f:view> action.");
+            resolveBundle(getBasename(facesContext));
         }
-
-        Locale locale = viewRoot.getLocale();
-        if (locale == null)
+        catch(IllegalStateException ex)
         {
-            locale = facesContext.getApplication().getDefaultLocale();
+            throw new JspException(ex);
         }
 
+        return Tag.SKIP_BODY;
+    }
+
+    private String getBasename(FacesContext facesContext) {
         String basename = null;
 
         if (_basename!=null) {
@@ -98,28 +99,58 @@
                 basename = _basename;
             }
         }
+        return basename;
+    }
+
+    /**
+     * This method is copied over to org.apache.myfaces.custom.loadbundle.LoadBundle.
+     * If you change anything here, think about changing it there as well.
+     *
+     * @param resolvedBasename
+     */
+    private void resolveBundle(String resolvedBasename) {
+        //ATTENTION: read comment above before changing this!
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+
+        UIViewRoot viewRoot = facesContext.getViewRoot();
+        if (viewRoot == null)
+        {
+            throw new IllegalStateException("No view root! LoadBundle must be nested inside <f:view> action.");
+        }
+
+        Locale locale = viewRoot.getLocale();
+        if (locale == null)
+        {
+            locale = facesContext.getApplication().getDefaultLocale();
+        }
 
         final ResourceBundle bundle;
         try
         {
-            bundle = ResourceBundle.getBundle(basename,
+            bundle = ResourceBundle.getBundle(resolvedBasename,
                                               locale,
                                               Thread.currentThread().getContextClassLoader());
+
+            facesContext.getExternalContext().getRequestMap().put(_var,
+                                                                  new BundleMap(bundle));
+
         }
         catch (MissingResourceException e)
         {
-            log.error("Resource bundle '" + basename + "' could not be found.");
-            return Tag.SKIP_BODY;
+            log.error("Resource bundle '" + resolvedBasename + "' could not be found.");
         }
-
-        facesContext.getExternalContext().getRequestMap().put(_var,
-                                                              new BundleMap(bundle));
-        return Tag.SKIP_BODY;
+        //ATTENTION: read comment above before changing this!
     }
 
 
+    /**
+     * This class is copied over to org.apache.myfaces.custom.loadbundle.LoadBundle.
+     * If you change anything here, think about changing it there as well.
+     *
+     */
     private static class BundleMap implements Map
     {
+        //ATTENTION: read javadoc
         private ResourceBundle _bundle;
         private List _values;
 
@@ -215,6 +246,7 @@
             }
             return set;
         }
+        //ATTENTION: read javadoc
 
 
         //Unsupported methods
@@ -238,7 +270,7 @@
         {
             throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
         }
-
+        //ATTENTION: read javadoc
     }
 
 }

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/FacesEventWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/FacesEventWrapper.java?view=auto&rev=478534
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/FacesEventWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/FacesEventWrapper.java Thu Nov 23 03:17:05 2006
@@ -0,0 +1,52 @@
+package org.apache.myfaces.custom.loadbundle;
+
+import org.apache.myfaces.custom.aliasbean.AliasBeansScope;
+import org.apache.myfaces.custom.aliasbean.AliasBean;
+
+import javax.faces.event.FacesEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.FacesListener;
+import javax.faces.component.UIComponent;
+
+/**
+ * @author Sylvain Vieujot (latest modification by $Author: grantsmith $)
+ * @version $Revision: 472630 $ $Date: 2006-11-08 21:40:03 +0100 (Mi, 08 Nov 2006) $
+ */
+
+class FacesEventWrapper extends FacesEvent {
+    private static final long serialVersionUID = -6878195444276533114L;
+    private FacesEvent _wrappedFacesEvent;
+
+    public FacesEventWrapper(FacesEvent facesEvent, UIComponent redirectComponent) {
+        super(redirectComponent);
+        _wrappedFacesEvent = facesEvent;
+    }
+
+    public PhaseId getPhaseId() {
+        return _wrappedFacesEvent.getPhaseId();
+    }
+
+    public void setPhaseId(PhaseId phaseId) {
+        _wrappedFacesEvent.setPhaseId(phaseId);
+    }
+
+    public void queue() {
+        _wrappedFacesEvent.queue();
+    }
+
+    public String toString() {
+        return _wrappedFacesEvent.toString();
+    }
+
+    public boolean isAppropriateListener(FacesListener faceslistener) {
+        return _wrappedFacesEvent.isAppropriateListener(faceslistener);
+    }
+
+    public void processListener(FacesListener faceslistener) {
+        _wrappedFacesEvent.processListener(faceslistener);
+    }
+
+    public FacesEvent getWrappedFacesEvent() {
+        return _wrappedFacesEvent;
+    }
+}

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundle.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundle.java?view=auto&rev=478534
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundle.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundle.java Thu Nov 23 03:17:05 2006
@@ -0,0 +1,331 @@
+package org.apache.myfaces.custom.loadbundle;
+
+import org.apache.myfaces.shared_tomahawk.util._ComponentUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * A load-bundle alternative which allows to use load-bundle
+ * even on AJAX-enabled pages.
+ * <p/>
+ * A component that allows to load bundles not only on rendering, but whenever the
+ * page author needs it. By default, it loads it on every lifecycle phase
+ * except restore-state and save-state.* 
+ * <p/>
+ * The core-load-bundle only loads its message-bundle
+ * on rendering - this load-bundle does it on every life-cycle,
+ * and optionally whenever the method loadBundle is called.
+ *
+ * @author Martin Marinschek
+ */
+public class LoadBundle extends UIComponentBase implements StateHolder {
+
+    private static Log log = LogFactory.getLog(LoadBundle.class);
+
+    public static final String COMPONENT_TYPE = "org.apache.myfaces.LoadBundle";
+    public static final String COMPONENT_FAMILY = "org.apache.myfaces.LoadBundle";
+
+    private String basename;
+    private String var;
+
+    private boolean alreadyLoaded = false;
+
+    public LoadBundle()
+    {
+        // Default constructor
+    }
+
+    public String getFamily()
+    {
+        return COMPONENT_FAMILY;
+    }
+
+    public String getBasename()
+    {
+        if (basename != null)
+            return basename;
+        ValueBinding vb = getValueBinding("basename");
+        return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;
+    }
+
+    public void setBasename(String basename)
+    {
+        this.basename = basename;
+    }
+
+    public String getVar()
+    {
+        if (var != null)
+            return var;
+        ValueBinding vb = getValueBinding("var");
+        return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;
+    }
+
+    public void setVar(String var)
+    {
+        this.var = var;
+    }
+
+    public void restoreState(FacesContext context, Object state)
+    {
+        Object values[] = (Object[]) state;
+        this.basename = (String) values[0];
+        this.var = (String) values[1];
+    }
+
+    public Object saveState(FacesContext context)
+    {
+        Object[] values = new Object[2];
+        values[0] = this.basename;
+        values[1] = this.var;
+        return values;
+    }
+
+    public Object processSaveState(FacesContext context)
+    {
+        //intentionally don't do anything special in this phase
+        return super.processSaveState(context);
+    }
+
+    public void processRestoreState(FacesContext context, Object state)
+    {
+        //intentionally don't do anything special in this phase
+        super.processRestoreState(context, state);
+    }
+
+    public void processValidators(FacesContext context)
+    {
+        loadBundle();
+        super.processValidators(context);
+    }
+
+    public void processDecodes(FacesContext context)
+    {
+        loadBundle();
+        super.processDecodes(context);
+    }
+
+    public void processUpdates(FacesContext context)
+    {
+        loadBundle();
+        super.processUpdates(context);
+    }
+
+
+  public void encodeBegin(FacesContext context) throws IOException {
+        loadBundle();
+  }
+
+
+  public void encodeEnd(FacesContext context) throws IOException {
+  }
+
+  public void queueEvent(FacesEvent event)
+    {
+        super.queueEvent(new FacesEventWrapper(event, this));
+    }
+
+    public void broadcast(FacesEvent event) throws AbortProcessingException {
+        loadBundle();
+
+        if (event instanceof FacesEventWrapper)
+        {
+            FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
+            originalEvent.getComponent().broadcast(originalEvent);
+        }
+        else
+        {
+            super.broadcast(event);
+        }
+    }
+
+    public void loadBundle() {
+        if(alreadyLoaded)
+            return;
+
+        resolveBundle(getBasename());
+
+        alreadyLoaded = true;
+    }
+
+    /**
+     * This method is copied over from LoadBundle in core.
+     * If you change anything here, think about changing it there as well.
+     *
+     * @param resolvedBasename
+     */
+    private void resolveBundle(String resolvedBasename) {
+        //ATTENTION: read comment above before changing this!
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+
+        UIViewRoot viewRoot = facesContext.getViewRoot();
+        if (viewRoot == null)
+        {
+            throw new IllegalStateException("No view root! LoadBundle must be nested inside <f:view> action.");
+        }
+
+        Locale locale = viewRoot.getLocale();
+        if (locale == null)
+        {
+            locale = facesContext.getApplication().getDefaultLocale();
+        }
+
+        final ResourceBundle bundle;
+        try
+        {
+            bundle = ResourceBundle.getBundle(resolvedBasename,
+                                              locale,
+                                              Thread.currentThread().getContextClassLoader());
+
+            facesContext.getExternalContext().getRequestMap().put(getVar(),
+                                                                  new BundleMap(bundle));
+
+        }
+        catch (MissingResourceException e)
+        {
+            log.error("Resource bundle '" + resolvedBasename + "' could not be found.");
+        }
+        //ATTENTION: read comment above before changing this!
+    }
+
+
+    /**
+     * This class is copied over from LoadBundle in myfaces-api.
+     * If you change anything here, think about changing it there as well.
+     *
+     */
+    private static class BundleMap implements Map
+    {
+        //ATTENTION: read javadoc
+        private ResourceBundle _bundle;
+        private List _values;
+
+        public BundleMap(ResourceBundle bundle)
+        {
+            _bundle = bundle;
+        }
+
+        //Optimized methods
+
+        public Object get(Object key)
+        {
+            try {
+                return _bundle.getObject(key.toString());
+            } catch (Exception e) {
+                return "MISSING: " + key + " :MISSING";
+            }
+        }
+
+        public boolean isEmpty()
+        {
+            return !_bundle.getKeys().hasMoreElements();
+        }
+
+        public boolean containsKey(Object key)
+        {
+        	try {
+                return _bundle.getObject(key.toString()) != null;
+        	} catch (MissingResourceException e) {
+        		return false;
+        	}
+        }
+
+
+        //Unoptimized methods
+
+        public Collection values()
+        {
+            if (_values == null)
+            {
+                _values = new ArrayList();
+                for (Enumeration enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
+                {
+                    String v = _bundle.getString((String)enumer.nextElement());
+                    _values.add(v);
+                }
+            }
+            return _values;
+        }
+
+        public int size()
+        {
+            return values().size();
+        }
+
+        public boolean containsValue(Object value)
+        {
+            return values().contains(value);
+        }
+
+        public Set entrySet()
+        {
+            Set set = new HashSet();
+            for (Enumeration enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
+            {
+                final String k = (String)enumer.nextElement();
+                set.add(new Map.Entry() {
+                    public Object getKey()
+                    {
+                        return k;
+                    }
+
+                    public Object getValue()
+                    {
+                        return _bundle.getObject(k);
+                    }
+
+                    public Object setValue(Object value)
+                    {
+                        throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
+                    }
+                });
+            }
+            return set;
+        }
+
+        public Set keySet()
+        {
+            Set set = new HashSet();
+            for (Enumeration enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
+            {
+                set.add(enumer.nextElement());
+            }
+            return set;
+        }
+        //ATTENTION: read javadoc
+
+
+        //Unsupported methods
+
+        public Object remove(Object key)
+        {
+            throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
+        }
+
+        public void putAll(Map t)
+        {
+            throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
+        }
+
+        public Object put(Object key, Object value)
+        {
+            throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
+        }
+
+        public void clear()
+        {
+            throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
+        }
+        //ATTENTION: read javadoc
+    }
+}

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundleTag.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundleTag.java?view=auto&rev=478534
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundleTag.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/loadbundle/LoadBundleTag.java Thu Nov 23 03:17:05 2006
@@ -0,0 +1,79 @@
+package org.apache.myfaces.custom.loadbundle;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.shared_tomahawk.taglib.UIComponentTagBase;
+
+import javax.faces.component.UIComponent;
+import javax.servlet.jsp.JspException;
+
+/**
+ * A load-bundle alternative which allows to use load-bundle
+ * even on AJAX-enabled pages.
+ * <p/>
+ * A tag that allows to load bundles not only on rendering, but whenever the
+ * page author needs it. By default, it loads it on every lifecycle phase
+ * except restore-state and save-state.
+ *
+ * The core-load-bundle only loads its message-bundle
+ * on rendering - this load-bundle does it on every life-cycle,
+ * and optionally whenever the method loadBundle is called.
+
+ * @author Martin Marinschek
+ */
+public class LoadBundleTag extends UIComponentTagBase {
+    
+    private Log log = LogFactory.getLog(LoadBundleTag.class);
+
+    private String basename;
+    private String var;
+
+    public void release() {
+        super.release();
+
+        basename=null;
+        var=null;
+
+    }
+
+    protected void setProperties(UIComponent component) {
+        super.setProperties(component);
+
+        setStringProperty(component, "basename", basename);
+        setStringProperty(component, "var", var);
+    }
+
+    public String getComponentType() {
+        return LoadBundle.COMPONENT_TYPE;
+    }
+
+    public String getRendererType() {
+        return null;
+    }
+
+    public void setBasename(String basename){
+        this.basename = basename;
+    }
+
+    public void setVar(String var){
+        this.var = var;
+    }
+
+    public int doStartTag() throws JspException
+    {
+        int retVal= super.doStartTag();
+
+        UIComponent comp = getComponentInstance();
+
+        if(comp instanceof LoadBundle)
+        {
+            ((LoadBundle) comp).loadBundle();
+        }
+        else
+        {
+            log.warn("associated component is no loadbundle.");
+        }
+
+        return retVal;
+    }
+}

Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml?view=diff&rev=478534&r1=478533&r2=478534
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml Thu Nov 23 03:17:05 2006
@@ -28,6 +28,11 @@
   <!-- sandbox components -->
 
   <component>
+    <component-type>org.apache.myfaces.LoadBundle</component-type>
+    <component-class>org.apache.myfaces.custom.loadbundle.LoadBundle</component-class>
+  </component>
+
+  <component>
     <component-type>org.apache.myfaces.InputSuggestAjax</component-type>
     <component-class>org.apache.myfaces.custom.suggestajax.inputsuggestajax.InputSuggestAjax</component-class>
   </component>

Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/tld/myfaces_sandbox.tld
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/tld/myfaces_sandbox.tld?view=diff&rev=478534&r1=478533&r2=478534
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/tld/myfaces_sandbox.tld (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/tld/myfaces_sandbox.tld Thu Nov 23 03:17:05 2006
@@ -158,6 +158,27 @@
         Enhanced standard JSP actions and custom MyFaces actions.
     </description>
 
+    <!-- inputSuggest -->
+	<tag>
+		<name>loadBundle</name>
+		<tag-class>org.apache.myfaces.custom.loadbundle.LoadBundleTag</tag-class>
+		<body-content>JSP</body-content>
+		<description>Extended loadbundle which does its job in all life-cycle phases or even on calling LoadBundle.loadBundle()
+            - not only when rendering happens...</description>
+        <attribute>
+            <name>var</name>
+            <required>true</required>
+            <rtexprvalue>false</rtexprvalue>
+            <description>Variable this bundle will be stored under, e.g. mybundle. Use #{mybundle.propertykey} or #{mybundle['propertykey']} to access the keys of the bundle.</description>            
+        </attribute>
+        <attribute>
+            <name>basename</name>
+            <required>true</required>
+            <rtexprvalue>false</rtexprvalue>
+            <description>Path to the bundle-file in the class-path, e.g.: org.apache.myfaces.i18n.myprops</description>
+    	</attribute>
+    </tag>
+
     <!-- xmlTemplate -->
 	<tag>
 		<name>xmlTemplate</name>