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>