dev@javaserverfaces.java.net

Re: [280-EZComp] Seeking Retroactive Review

From: Jacob Hookom <jacob_at_hookom.net>
Date: Fri, 26 Sep 2008 17:31:11 -0500

getAttrs() => getAttributeValues()

Ed Burns wrote:
> Issue: 280-ComponentResources
>
> To enable <ez:loginPanel action="#{bean.loginAction}" />, where the
> action is re-targeted to be an attribute on an inner component inside of
> the composite component, at the discretion of the composite component
> author, I needed to change the special case clause in
> component.getAttributes().get().
>
> Before this change, calling component.getAttributes().get() would cause
> any result that is a ValueExpression to have its getValue() called
> before return from component.getAttributes.get() if and only if the
> component was a composite component. This change reverts this behavior.
>
> Instead, I've added a new method to UIComponent, getAttrs(). getAttrs()
> is just like getAttributes() except that its get method *always* will
> cause any results that are ValueExpressions to have their getValue()
> called before return.
>
>
> SECTION: Modified Files
> ----------------------------
> M jsf-api/src/javax/faces/component/UIComponent.java
>
> - add getAttrs()
>
> * <p class="changed_added_2_0">Like {_at_link #getAttributes}, except
> * that the <code>get()</code> implementation must call
> * <code>getValue()</code> on any result whose type is
> * <code>ValueExpression</code> and return the evaluated result.
> * </p>
>
> M jsf-api/src/javax/faces/component/UIComponentBase.java
>
> - remove special case behavior in getAttributes().get().
>
> M jsf-demo/ezcomp00/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> M jsf-demo/ezcomp01/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> M jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml
> M jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> M jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml
> M jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanel.xhtml
>
> - change any expressions that start with "#{compositeComponent.attributes"
> to start with "#{compositeComponent.attrs" instead.
>
> SECTION: Diffs
> ----------------------------
> Index: jsf-api/src/javax/faces/component/UIComponent.java
> ===================================================================
> --- jsf-api/src/javax/faces/component/UIComponent.java (revision 5480)
> +++ jsf-api/src/javax/faces/component/UIComponent.java (working copy)
> -45,6 +45,7 @@
> import java.io.InputStream;
> import java.util.ArrayList;
> import java.util.Arrays;
> +import java.util.Collection;
> import java.util.Collections;
> import java.util.Enumeration;
> import java.util.HashMap;
> -54,6 +55,7 @@
> import java.util.Locale;
> import java.util.Map;
>
> +import java.util.Map.Entry;
> import java.util.MissingResourceException;
> import java.util.PropertyResourceBundle;
> import java.util.ResourceBundle;
> -247,8 +249,86 @@
> * </p>
> */
> public abstract Map<String, Object> getAttributes();
> +
> +
> + private transient Map<String, Object> valueExpressionEvaluatingAttrsMap;
> +
> + /**
> + * <p class="changed_added_2_0">Like {_at_link #getAttributes}, except that the
> + * <code>get()</code> implementation must call <code>getValue()</code> on
> + * any result whose type is <code>ValueExpression</code> before returning.
> + * </p>
> + *
> + * @since 2.0
> + */
> + public Map<String, Object> getAttrs() {
> +
> + if (null == valueExpressionEvaluatingAttrsMap) {
> + valueExpressionEvaluatingAttrsMap = new Map<String, Object>() {
> +
> + private Map<String, Object> attrs = UIComponent.this.getAttributes();
>
> + public void clear() {
> + attrs.clear();
> + }
>
> + public boolean containsKey(Object key) {
> + return attrs.containsKey(key);
> + }
> +
> + public boolean containsValue(Object value) {
> + return attrs.containsValue(value);
> + }
> +
> + public Set<Entry<String, Object>> entrySet() {
> + return attrs.entrySet();
> + }
> +
> + public Object get(Object key) {
> + Object result = attrs.get(key);
> + // check if the result is an expression
> + if (result instanceof ValueExpression) {
> + ValueExpression ve = (ValueExpression) result;
> + result = ve.getValue(FacesContext.getCurrentInstance().getELContext());
> + }
> + return result;
> + }
> +
> + public boolean isEmpty() {
> + return attrs.isEmpty();
> + }
> +
> + public Set<String> keySet() {
> + return attrs.keySet();
> + }
> +
> + public Object put(String key, Object value) {
> + return attrs.put(key, value);
> + }
> +
> + public void putAll(Map<? extends String, ? extends Object> t) {
> + attrs.putAll(t);
> + }
> +
> + public Object remove(Object key) {
> + return attrs.remove(key);
> + }
> +
> + public int size() {
> + return attrs.size();
> + }
> +
> + public Collection<Object> values() {
> + return attrs.values();
> + }
> +
> + };
> + }
> +
> + return valueExpressionEvaluatingAttrsMap;
> + }
> +
> +
> // ---------------------------------------------------------------- Bindings
>
>
> Index: jsf-api/src/javax/faces/component/UIComponentBase.java
> ===================================================================
> --- jsf-api/src/javax/faces/component/UIComponentBase.java (revision 5480)
> +++ jsf-api/src/javax/faces/component/UIComponentBase.java (working copy)
> -1697,16 +1697,7 @@
> }
> } else if (attributes != null) {
> if (attributes.containsKey(key)) {
> - result = (attributes.get(key));
> - // If we have a non-null result and
> - // this is a composite component
> - if (null != result && attributes.containsKey(Resource.COMPONENT_RESOURCE_KEY)) {
> - // check if the result is an expression
> - if (result instanceof ValueExpression) {
> - ValueExpression ve = (ValueExpression) result;
> - result = ve.getValue(FacesContext.getCurrentInstance().getELContext());
> - }
> - }
> + result = attributes.get(key);
> }
> }
> }
> Index: jsf-demo/ezcomp00/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> ===================================================================
> --- jsf-demo/ezcomp00/src/main/webapp/resources/ezcomp/loginPanel.xhtml (revision 5480)
> +++ jsf-demo/ezcomp00/src/main/webapp/resources/ezcomp/loginPanel.xhtml (working copy)
> -108,7 +108,7 @@
>
> <p>
>
> - <h:commandButton id="loginEvent" value="Login" action="#{compositeComponent.attributes.model.loginAction}">
> + <h:commandButton id="loginEvent" value="Login" action="#{compositeComponent.attrs.model.loginAction}">
>
> </h:commandButton>
>
> Index: jsf-demo/ezcomp01/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> ===================================================================
> --- jsf-demo/ezcomp01/src/main/webapp/resources/ezcomp/loginPanel.xhtml (revision 5480)
> +++ jsf-demo/ezcomp01/src/main/webapp/resources/ezcomp/loginPanel.xhtml (working copy)
> -96,7 +96,7 @@
>
> <p>
>
> - <h:commandButton id="loginEvent" value="Login" action="#{compositeComponent.attributes.model.loginAction}">
> + <h:commandButton id="loginEvent" value="Login" action="#{compositeComponent.attrs.model.loginAction}">
>
> </h:commandButton>
>
> Index: jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml
> ===================================================================
> --- jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml (revision 5480)
> +++ jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml (working copy)
> -84,7 +84,7 @@
> <tr><td nowrap="nowrap"><div class="logLbl">
> &nbsp;<span class="LblLev2Txt">
> <label id="sun_label17" for="Login.username" class="LblLev2Txt_sun4">
> -<h:outputText value="#{compositeComponent.attributes.usernameLabel}" />
> +<h:outputText value="#{compositeComponent.attrs.usernameLabel}" />
> </label>
> </span></div></td>
>
> -97,7 +97,7 @@
> <tr><td nowrap="nowrap"><div class="logLblLst">
> &nbsp;<span class="LblLev2Txt">
> <label id="sun_label19" for="Login.pin" class="LblLev2Txt_sun4">
> -<h:outputText value="#{compositeComponent.attributes.pinLabel}" />
> +<h:outputText value="#{compositeComponent.attrs.pinLabel}" />
> </label>
> </span></div></td>
> <td><div class="logInpLst">
> Index: jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> ===================================================================
> --- jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml (revision 5480)
> +++ jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml (working copy)
> -85,8 +85,8 @@
>
> <ui:define name="loginEvent">
>
> - <h:commandButton id="loginEvent" value="#{compositeComponent.attributes.loginLabel}"
> - action="#{compositeComponent.attributes.model.loginAction}"
> + <h:commandButton id="loginEvent" value="#{compositeComponent.attrs.loginLabel}"
> + action="#{compositeComponent.attrs.model.loginAction}"
> onkeypress="javascript: submitenter(event, 'loginButton', Login');"
> onclick="javascript: submitAndDisable(this, 'Login');"
> onfocus="javascript: if (this.disabled==0) this.className='Btn1Hov'"
> Index: jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml
> ===================================================================
> --- jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml (revision 5480)
> +++ jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanelTemplate.xhtml (working copy)
> -84,7 +84,7 @@
> <tr><td nowrap="nowrap"><div class="logLbl">
> &nbsp;<span class="LblLev2Txt">
> <label id="sun_label17" for="Login.username" class="LblLev2Txt_sun4">
> -<h:outputText value="#{compositeComponent.attributes.usernameLabel}" />
> +<h:outputText value="#{compositeComponent.attrs.usernameLabel}" />
> </label>
> </span></div></td>
>
> -97,7 +97,7 @@
> <tr><td nowrap="nowrap"><div class="logLblLst">
> &nbsp;<span class="LblLev2Txt">
> <label id="sun_label19" for="Login.pin" class="LblLev2Txt_sun4">
> -<h:outputText value="#{compositeComponent.attributes.pinLabel}" />
> +<h:outputText value="#{compositeComponent.attrs.pinLabel}" />
> </label>
> </span></div></td>
> <td><div class="logInpLst">
> Index: jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanel.xhtml
> ===================================================================
> --- jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanel.xhtml (revision 5480)
> +++ jsf-demo/ezcomp03/src/main/webapp/resources/ezcomp/loginPanel.xhtml (working copy)
> -85,8 +85,8 @@
>
> <ui:define name="loginEvent">
>
> - <h:commandButton id="loginEvent" value="#{compositeComponent.attributes.loginLabel}"
> - action="#{compositeComponent.attributes.model.loginAction}"
> + <h:commandButton id="loginEvent" value="#{compositeComponent.attrs.loginLabel}"
> + action="#{compositeComponent.attrs.model.loginAction}"
> onkeypress="javascript: submitenter(event, 'loginButton', Login');"
> onclick="javascript: submitAndDisable(this, 'Login');"
> onfocus="javascript: if (this.disabled==0) this.className='Btn1Hov'"
>
>
> ------------------------------------------------------------------------
>
>
> No virus found in this incoming message.
> Checked by AVG - http://www.avg.com
> Version: 8.0.169 / Virus Database: 270.7.3/1693 - Release Date: 9/26/2008 7:35 AM
>
>