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">
<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">
<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">
<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">
<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'"
--
| ed.burns_at_sun.com | office: 408 884 9519 OR x31640
| homepage: | http://ridingthecrest.com/