There's context on this thread that ya'll don't have, but you can just
look it as a code review request.
Jim, here's the change-bundle I needed to do to implement your feature.
It's less ugly than it looks.
>>>>> On Thu, 13 Nov 2008 04:07:27 -0800, Ed Burns <ed.burns_at_sun.com> said:
>>>>> On Wed, 12 Nov 2008 15:42:40 -0800, Jim Driscoll
EB> <Jim.Driscoll_at_Sun.COM> said:
JD> Is perfectly understandable. One comment on that though - why have the
JD> separate method-expression-name attribute, when you can just use the
JD> currently ignored methodname within the method signature? i.e., instead
JD> say:
EB> Yes, that's a better idea. I'll do that.
Turns out I didn't need to do that, so I dropped it.
JD> Now, let's discuss how it's applied against the implementation section.
JD> I really, really don't like the idea that in order to understand the
JD> implementation section, you have to know to refer to the interface
JD> section, without any hints to do so.
Ok, I did this by special casing the TagAttribute.java. Here goes.
Jim, I also fixed the XHTML for switchlist and now it works!
I'm checking this in now, and we can make changes as necessary.
Automated tests still run successfully.
SECTION: Modified Files
----------------------------
M jsf-api/src/javax/faces/application/ViewHandler.java
- retargetMethodExpressions()
* Update spec reference section for metadata
* rename the "applyTo" to "targets" for consistency with other
elements.
* assertion about method signature
M jsf-ri/conf/share/composite.tld
* document "targets" attribute
M jsf-ri/src/com/sun/faces/facelets/tag/TagAttribute.java
- This special behavior is specified in section 10.2.4.3. Here's the text.
For code that handles tag attributes on UIComponent XHTML elements
special action must be taken regarding composite
components. [P1_start_composite_component_method_expression]If the
type of the attribute is a MethodExpression, the code that takes the
value of the attribute and creates an actual MethodExpression instance
around it must take the following special action. Inspect the value of
the attribute. If the EL expression string starts with the
compositeComponent implicit object, is followed by the special string
?attrs? (without the quotes), as specified in Section 5.6.2.2
?Composite Component Attributes ELResolver?, and is followed by a
single remaining expression segment, let the value of that remaining
expression segment be attrName. In this case, the runtime must
guarantee that the actual MethodExpression instance that is created
for the tag attribute have the following behavior in its invoke()
method.
Obtain a reference to the current composite component by calling
UIComponent.getCurrentCompositeComponent().
Look in the attribute of the component for a key under the value
attrName.
There must be a value and it must be of type MethodExpression. If
either of these conditions are false allow the ensuing exception to be
thrown.
Call invoke() on the discovered MethodExpression, passing the
arguments passed to our invoke()
method.[P1_end_composite_component_method_expression]
[P1_start_composite_component_retargeting]Once the composite component
has been populated with children, the runtime must ensure that
ViewHandler.retargetAttachedObjects() and then
ViewHandler.retargetMethodExpressions() is called, passing the top
level component.[P1_end_composite_component_retargeting] The actions
taken in these methods set the stage for the tag attribute behavior
and the special MethodExpression handling behavior described
previously.
M jsf-ri/src/com/sun/faces/facelets/tag/composite/AttributeHandler.java
- This is what handles the <composite:attribute> element. It's
specified in the TLDDocs.
M jsf-ri/src/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java
- special case the handling of MethodExpressions found it tag
attributes. This is specified in section 10.2.4.3. Here's the text.
Special handling is required for attributes declared on the composite
component tag instance in the using
page. [P1_start_composite_component_tag_attributes]The runtime must
ensure that all such attributes are copied to the attributes map of
the top level component instance in the following manner.
Obtain a reference to the ExpressionFactory, for discussion called
expressionFactory.
Let the value of the attribute in the using page be value.
if value is ?id? or ?binding? without the quotes, skip to the next
attribute.
If the value of the attribute starts with ?#{? (without the quotes)
call expressionFactory.createValueExpression(elContext, value,
Object.class)
If the value of the attribute does not start with ?#{?, call
expressionFactory.createValueExpression(value, Object.class)
If there already is a key in the map for value, inspect the type of
the value at that key. If the type is MethodExpression take no
action. [P1_end_composite_component_tag_attributes]
M jsf-ri/src/com/sun/faces/application/view/MultiViewHandler.java
- Comply with the new definition of retargetMethodExpressions
M jsf-ri/src/com/sun/faces/util/Util.java
- Add getTypeFromString
M jsf-demo/ezcomp02/src/main/webapp/WEB-INF/composite-test.taglib.xml
M jsf-demo/ezcomp02/src/main/webapp/WEB-INF/web.xml
M jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml
M jsf-demo/ajax-switchlist/web/resources/switchlist/switchlist.xhtml
- Fix these to be compliant.
SECTION: Diffs
----------------------------
Index: jsf-api/src/javax/faces/application/ViewHandler.java
===================================================================
--- jsf-api/src/javax/faces/application/ViewHandler.java (revision 5806)
+++ jsf-api/src/javax/faces/application/ViewHandler.java (working copy)
-493,7 +493,7 @@
/**
* <p class="changed_added_2_0">Leverage the component metadata
- * specified in section 4.3.2 for the purpose of re-targeting any
+ * specified in section 3.6.2.1 for the purpose of re-targeting any
* method expressions from the top level component to the
* appropriate inner component. For each attribute that is a
* <code>MethodExpression</code> (as indicated by the presence of a
-505,13 +505,20 @@
*
* <ul>
*
- * <li><p>Get the value of the <em>applyTo</em> attribute. If
- * not found, log an error and continue to the next
- * attribute.</p></li>
+ * <li><p>Get the value of the <em>targets</em> attribute. If the
+ * value is a <code>ValueExpression</code> evaluate it. If there is
+ * no <em>targets</em> attribute, let the name of the metadata
+ * element be the evaluated value of the <em>targets
+ * attribute.</em></p></li>
+ *
+ * <li><p>Interpret <em>targets</em> as a comma separated list of ids. For
+ * each entry in the list:</p>
+ *
+ * <ul>
*
* <li><p>Find the inner component of the
* <em>topLevelComponent</em> with the id equal to
- * <em>applyTo</em>. For discussion, this component is called
+ * the current list entry. For discussion, this component is called
* <em>target</em>. If not found, log and error and continue to
* the next attribute.</p></li>
*
-574,15 +581,17 @@
* <em>target</em>, passing <em>attributeMethodExpression</em> wrapped in a
* {_at_link javax.faces.event.MethodExpressionValueChangeListener}.</p></li>
*
- * <li><p>Otherwise, look for a JavaBeans setter that matches
- * <em>name</em> and assume it takes a
- * <code>MethodExpression</code>, passing
- * <em>attributeMethodExpression</em> as that expression. If
- * such a setter does not exist, or does not take a
- * <code>MethodExpression</code>, log an error and continue to
- * the next attribute.</p></li>
- *
+ * <li><p>Otherwise, assume that the <code>MethodExpression</code>
+ * should be placed in the components attribute set. The runtme
+ * must create the <code>MethodExpression</code> instance based on
+ * the value of the "<code>method-signature</code>"
+ * attribute.</p></li>
+
* </ul>
+ *
+ * </li>
+ *
+ * </ul>
*
* <p>An implementation is provided that will throw
* <code>UnsupportedOperationException</code>. A Faces implementation
Index: jsf-ri/conf/share/composite.tld
===================================================================
--- jsf-ri/conf/share/composite.tld (revision 5806)
+++ jsf-ri/conf/share/composite.tld (working copy)
-532,6 +532,39 @@
<![CDATA[
<div class="changed_added_2_0">
+
+<p>If the this element has a <code>method-signature</code> attribute,
+the value of the <code>targets</code> attribute must be interpreted as a
+comma separated list of component ids of components within the
+<code><composite:implementation></code> section. Each entry in
+the list must be interpreted as the id of an inner component to which
+the <code>MethodExpression</code> from the <em>composite component
+tag</em> in the <em>using page</em> must be applied. If the this
+element has a <code>method-signature</code> attribute, but no
+<code>targets</code> attribute, the value of the <code>name</code>
+attribute is used as the single entry in the list.</p>
+
+</div>]]>
+
+ </description>
+ <name>
+ targets
+ </name>
+ <required>
+ true
+ </required>
+ <deferred-value>
+ <type>
+ java.lang.String
+ </type>
+ </deferred-value>
+ </attribute>
+
+ <attribute>
+ <description>
+
+ <![CDATA[
+<div class="changed_added_2_0">
<p>If this attribute is not required, and a
value is not supplied by the page author, use this as
the default value.</p></div>]]>
Index: jsf-ri/src/com/sun/faces/facelets/tag/TagAttribute.java
===================================================================
--- jsf-ri/src/com/sun/faces/facelets/tag/TagAttribute.java (revision 5806)
+++ jsf-ri/src/com/sun/faces/facelets/tag/TagAttribute.java (working copy)
-51,15 +51,20 @@
package com.sun.faces.facelets.tag;
+import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
+import javax.el.MethodInfo;
import javax.el.ValueExpression;
import javax.faces.webapp.pdl.facelets.FaceletContext;
import com.sun.faces.facelets.el.ELText;
import com.sun.faces.facelets.el.TagMethodExpression;
import com.sun.faces.facelets.el.TagValueExpression;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
/**
* Representation of a Tag's attribute in a Facelet File
-173,15 +178,119 @@
*/
public MethodExpression getMethodExpression(FaceletContext ctx, Class type,
Class[] paramTypes) {
+ MethodExpression result = null;
+ final String specialPrefix = "#{compositeComponent.attrs.";
+ final int specialPrefixLen = specialPrefix.length();
+ int i;
try {
ExpressionFactory f = ctx.getExpressionFactory();
- return new TagMethodExpression(this, f.createMethodExpression(ctx,
- this.value, type, paramTypes));
+ // Determine if this is a composite component attribute lookup.
+ // If so, look for a MethodExpression under the attribute key
+ if (this.value.startsWith(specialPrefix)) {
+ // Make sure this is *only* an attribute lookup
+ if (specialPrefixLen < this.value.length() &&
+ -1 == this.value.indexOf(".", specialPrefixLen)) {
+ String attrName = this.value.substring(specialPrefixLen,
+ this.value.length() - 1);
+ result = new AttributeLookupMethodExpression(this.value, attrName);
+ }
+ }
+ if (null == result) {
+ result = new TagMethodExpression(this, f.createMethodExpression(ctx,
+ this.value, type, paramTypes));
+ }
} catch (Exception e) {
throw new TagAttributeException(this, e);
}
+ return result;
}
+
+ private static class AttributeLookupMethodExpression extends MethodExpression implements StateHolder {
+ private String attrName = null;
+ private String expressionString = null;
+ private boolean isTransient = false;
+
+ public AttributeLookupMethodExpression(String expressionString,
+ String attrName) {
+ if (null == expressionString || null == attrName) {
+ throw new NullPointerException("null MethodExpression");
+ }
+ this.expressionString = expressionString;
+ this.attrName = attrName;
+ }
+
+ public AttributeLookupMethodExpression() {}
+
+ public boolean isTransient() {
+ return isTransient;
+ }
+
+ public void setTransient(boolean isTransient) {
+ this.isTransient = isTransient;
+ }
+
+ public void restoreState(FacesContext context, Object stateObj) {
+ String [] state = (String []) stateObj;
+ this.attrName = state[0];
+ this.expressionString = state[1];
+ }
+
+ public Object saveState(FacesContext arg0) {
+ String [] state = new String[2];
+ state[0] = this.attrName;
+ state[1] = this.expressionString;
+ return state;
+ }
+
+ @Override
+ public MethodInfo getMethodInfo(ELContext arg0) {
+ return null;
+ }
+
+ @Override
+ public Object invoke(ELContext elContext, Object[] arg1) {
+ Object result = null;
+ FacesContext context = (FacesContext) elContext.getContext(FacesContext.class);
+ // NPE is ok here.
+ UIComponent composite = UIComponent.getCurrentCompositeComponent(context);
+ MethodExpression me = null;
+ me = (MethodExpression) composite.getAttributes().get(attrName);
+ result = me.invoke(elContext, arg1);
+ return result;
+ }
+
+ @Override
+ public String getExpressionString() {
+ return expressionString;
+ }
+
+ @Override
+ public boolean equals(Object otherObj) {
+ boolean result = false;
+ if (otherObj instanceof AttributeLookupMethodExpression) {
+ AttributeLookupMethodExpression other =
+ (AttributeLookupMethodExpression) otherObj;
+ result = this.expressionString.equals(other.expressionString);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isLiteralText() {
+ boolean result = false;
+
+ result = (this.expressionString.startsWith("#{") &&
+ (this.expressionString.endsWith("}")));
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.expressionString.hashCode();
+ }
+ }
+
/**
* The resolved Namespace for this attribute
*
Index: jsf-ri/src/com/sun/faces/facelets/tag/composite/AttributeHandler.java
===================================================================
--- jsf-ri/src/com/sun/faces/facelets/tag/composite/AttributeHandler.java (revision 5806)
+++ jsf-ri/src/com/sun/faces/facelets/tag/composite/AttributeHandler.java (working copy)
-163,9 +163,9 @@
propertyDescriptor.setValue("method-signature", ve);
}
}
- if (null != (attr = this.getAttribute("applyTo"))) {
+ if (null != (attr = this.getAttribute("targets"))) {
ve = attr.getValueExpression(ctx, String.class);
- propertyDescriptor.setValue("applyTo", ve);
+ propertyDescriptor.setValue("targets", ve);
}
Index: jsf-ri/src/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java
===================================================================
--- jsf-ri/src/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java (revision 5806)
+++ jsf-ri/src/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java (working copy)
-79,6 +79,7 @@
import com.sun.faces.facelets.tag.TagAttribute;
import com.sun.faces.facelets.tag.TagAttributes;
import com.sun.faces.util.RequestStateManager;
+import javax.el.MethodExpression;
import javax.faces.application.ViewHandler;
/**
-110,7 +111,6 @@
expressionFactory = ctx.getFacesContext().getApplication().
getExpressionFactory();
}
- // PENDING(edburns): deal with methodExpressions
if (value.startsWith("#{")) {
expression = expressionFactory.
createValueExpression(ctx, value, Object.class);
-118,7 +118,22 @@
expression = expressionFactory.
createValueExpression(value, Object.class);
}
- compositeComponent.getAttributes().put(name, expression);
+ // PENDING: I don't think copyTagAttributesIntoComponentAttributes
+ // should be getting called
+ // on postback, yet it is. In lieu of a real fix, I'll
+ // make sure I'm not overwriting a MethodExpression with a
+ // ValueExpression.
+ Map<String, Object> map = compositeComponent.getAttributes();
+ boolean doPut = true;
+ if (map.containsKey(name)) {
+ Object curVal = map.get(name);
+ if (curVal instanceof MethodExpression) {
+ doPut = false;
+ }
+ }
+ if (doPut) {
+ map.put(name, expression);
+ }
}
}
}
Index: jsf-ri/src/com/sun/faces/application/view/MultiViewHandler.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/view/MultiViewHandler.java (revision 5806)
+++ jsf-ri/src/com/sun/faces/application/view/MultiViewHandler.java (working copy)
-260,14 +260,14 @@
return;
}
PropertyDescriptor attributes[] = componentBeanInfo.getPropertyDescriptors();
- String applyTo = null, strValue = null;
+ String targets = null, attrName = null, strValue = null,
+ methodSignature = null;
UIComponent target = null;
ExpressionFactory expressionFactory = null;
ValueExpression valueExpression = null;
MethodExpression toApply = null;
Class expectedReturnType = null;
Class expectedParameters[] = null;
- boolean logError = false;
for (PropertyDescriptor cur : attributes) {
// If the current attribute represents a ValueExpression
-278,105 +278,179 @@
}
// If the current attribute representes a MethodExpression
if (null != (valueExpression = (ValueExpression) cur.getValue("method-signature"))) {
- strValue = (String) valueExpression.getValue(context.getELContext());
- if (null != strValue) {
+ methodSignature = (String) valueExpression.getValue(context.getELContext());
+ if (null != methodSignature) {
// This is the name of the attribute on the top level component,
// and on the inner component.
- logError = false;
- if (null != (valueExpression = (ValueExpression) cur.getValue("applyTo"))) {
- applyTo = (String) valueExpression.getValue(context.getELContext());
- if (null == applyTo) {
- logError = true;
- }
+ if (null != (valueExpression = (ValueExpression) cur.getValue("targets"))) {
+ targets = (String) valueExpression.getValue(context.getELContext());
}
- if (logError) {
- // PENDING error message in page?
- logger.severe("Unable to retarget MethodExpression. " +
- "Please specify \"applyTo\" attribute on <composite:attribute />");
- continue;
+ if (null == targets) {
+ targets = cur.getName();
}
- // This is the inner component to which the attribute should
- // be applied
- target = topLevelComponent.findComponent(applyTo);
- if (null == applyTo) {
+ if (null == targets || 0 == targets.length()) {
// PENDING error message in page?
- logger.severe("Unable to retarget MethodExpression. " +
- "Unable to find inner component with id " +
- applyTo + ".");
+ logger.severe("Unable to retarget MethodExpression: " +
+ methodSignature);
continue;
}
+
+
+ String[] targetIds = targets.split(",");
+
+ for (String curTarget : targetIds) {
+
+ // This is the inner component to which the attribute should
+ // be applied
+ target = topLevelComponent.findComponent(curTarget);
+ if (null == targets) {
+ // PENDING error message in page?
+ logger.severe("Unable to retarget MethodExpression. " +
+ "Unable to find inner component with id " +
+ targets + ".");
+ continue;
+ }
- strValue = cur.getName();
+ attrName = cur.getName();
- // Find the attribute on the top level component
- valueExpression = (ValueExpression) topLevelComponent.getAttributes().
- get(strValue);
- if (null == valueExpression) {
- // PENDING error message in page?
- logger.severe("Unable to find attribute with name \""
- + strValue
- + "\" in top level component in consuming page. "
- + "Page author error.");
- continue;
- }
+ // Find the attribute on the top level component
+ valueExpression = (ValueExpression) topLevelComponent.getAttributes().
+ get(attrName);
+ if (null == valueExpression) {
+ // PENDING error message in page?
+ logger.severe("Unable to find attribute with name \""
+ + attrName
+ + "\" in top level component in consuming page. "
+ + "Page author error.");
+ continue;
+ }
- // lazily initialize this local variable
- if (null == expressionFactory) {
- expressionFactory = context.getApplication().getExpressionFactory();
- }
+ // lazily initialize this local variable
+ if (null == expressionFactory) {
+ expressionFactory = context.getApplication().getExpressionFactory();
+ }
- // If the attribute is one of the pre-defined
- // MethodExpression attributes
- if (strValue.equals("action")) {
+ // If the attribute is one of the pre-defined
+ // MethodExpression attributes
+ if (attrName.equals("action")) {
expectedReturnType = Object.class;
expectedParameters = new Class[]{};
toApply = expressionFactory.createMethodExpression(context.getELContext(),
valueExpression.getExpressionString(),
expectedReturnType, expectedParameters);
((ActionSource2) target).setActionExpression(toApply);
- } else if (strValue.equals("actionListener")) {
- expectedReturnType = Void.TYPE;
- expectedParameters = new Class[]{
- ActionEvent.class
- };
- toApply = expressionFactory.createMethodExpression(context.getELContext(),
- valueExpression.getExpressionString(),
- expectedReturnType, expectedParameters);
- ((ActionSource2) target).addActionListener(new MethodExpressionActionListener(toApply));
- } else if (strValue.equals("validator")) {
- expectedReturnType = Void.TYPE;
- expectedParameters = new Class[]{
- FacesContext.class,
- UIComponent.class,
- Object.class
- };
- toApply = expressionFactory.createMethodExpression(context.getELContext(),
- valueExpression.getExpressionString(),
- expectedReturnType, expectedParameters);
- ((EditableValueHolder) target).addValidator(new MethodExpressionValidator(toApply));
- } else if (strValue.equals("valueChangeListener")) {
- expectedReturnType = Void.TYPE;
- expectedParameters = new Class[]{
- ValueChangeEvent.class
- };
- toApply = expressionFactory.createMethodExpression(context.getELContext(),
- valueExpression.getExpressionString(),
- expectedReturnType, expectedParameters);
- ((EditableValueHolder) target).addValueChangeListener(new MethodExpressionValueChangeListener(toApply));
- } else {
- // If the attribute is not one of the pre-defined
- // MethodExpression attributes, look it up reflectively,
- // assuming there is a setter of type MethodExpression
+ } else if (attrName.equals("actionListener")) {
+ expectedReturnType = Void.TYPE;
+ expectedParameters = new Class[]{
+ ActionEvent.class
+ };
+ toApply = expressionFactory.createMethodExpression(context.getELContext(),
+ valueExpression.getExpressionString(),
+ expectedReturnType, expectedParameters);
+ ((ActionSource2) target).addActionListener(new MethodExpressionActionListener(toApply));
+ } else if (attrName.equals("validator")) {
+ expectedReturnType = Void.TYPE;
+ expectedParameters = new Class[]{
+ FacesContext.class,
+ UIComponent.class,
+ Object.class
+ };
+ toApply = expressionFactory.createMethodExpression(context.getELContext(),
+ valueExpression.getExpressionString(),
+ expectedReturnType, expectedParameters);
+ ((EditableValueHolder) target).addValidator(new MethodExpressionValidator(toApply));
+ } else if (attrName.equals("valueChangeListener")) {
+ expectedReturnType = Void.TYPE;
+ expectedParameters = new Class[]{
+ ValueChangeEvent.class
+ };
+ toApply = expressionFactory.createMethodExpression(context.getELContext(),
+ valueExpression.getExpressionString(),
+ expectedReturnType, expectedParameters);
+ ((EditableValueHolder) target).addValueChangeListener(new MethodExpressionValueChangeListener(toApply));
+ } else {
+ // There is no explicit methodExpression property on
+ // an inner component to which this MethodExpression
+ // should be retargeted. In this case, replace the
+ // ValueExpression with a method expresson.
+
+ // Pull apart the methodSignature to derive the
+ // expectedReturnType and expectedParameters
+ // PENDING(rlubke,jimdriscoll) bulletproof this
+
+ assert(null != methodSignature);
+ methodSignature = methodSignature.trim();
+
+ // Get expectedReturnType
+ int j, i = methodSignature.indexOf(" ");
+ if (-1 != i) {
+ strValue = methodSignature.substring(0, i);
+ try {
+ expectedReturnType = Util.getTypeFromString(strValue);
+ } catch (ClassNotFoundException cnfe) {
+ logger.log(Level.SEVERE,
+ "Unable to determine expected return type for " +
+ methodSignature, cnfe);
+ continue;
+ }
+ } else {
+ logger.severe("Unable to determine expected return type for " +
+ methodSignature);
+ continue;
+ }
+
+ // derive the arguments
+ i = methodSignature.indexOf("(");
+ if (-1 != i) {
+ j = methodSignature.indexOf(")", i+1);
+ if (-1 != j) {
+ strValue = methodSignature.substring(i + 1, j);
+ if (0 < strValue.length()) {
+ String [] params = strValue.split(",");
+ expectedParameters = new Class[params.length];
+ boolean exceptionThrown = false;
+ for (i = 0; i < params.length; i++) {
+ try {
+ expectedParameters[i] =
+ Util.getTypeFromString(params[i]);
+ } catch (ClassNotFoundException cnfe) {
+ logger.log(Level.SEVERE,
+ "Unable to determine expected return type for " +
+ methodSignature, cnfe);
+ exceptionThrown = true;
+ break;
+ }
+ }
+ if (exceptionThrown) {
+ continue;
+ }
+
+ } else {
+ expectedParameters = new Class[]{};
+ }
+ }
+
+ }
+
+ assert(null != expectedReturnType);
+ assert(null != expectedParameters);
+
+ toApply = expressionFactory.createMethodExpression(context.getELContext(),
+ valueExpression.getExpressionString(),
+ expectedReturnType, expectedParameters);
+ topLevelComponent.getAttributes().put(attrName, toApply);
+
+
+ }
}
}
}
-
}
-
+
}
Index: jsf-ri/src/com/sun/faces/util/Util.java
===================================================================
--- jsf-ri/src/com/sun/faces/util/Util.java (revision 5806)
+++ jsf-ri/src/com/sun/faces/util/Util.java (working copy)
-280,8 +280,35 @@
throws FacesException {
return (context.getApplication().getStateManager());
}
+
+ public static Class getTypeFromString(String type) throws ClassNotFoundException {
+ Class result = null;
+ if (type.equals("byte")) {
+ result = Byte.TYPE;
+ } else if (type.equals("short")) {
+ result = Short.TYPE;
+ } else if (type.equals("int")) {
+ result = Integer.TYPE;
+ } else if (type.equals("long")) {
+ result = Long.TYPE;
+ } else if (type.equals("float")) {
+ result = Float.TYPE;
+ } else if (type.equals("double")) {
+ result = Double.TYPE;
+ } else if (type.equals("boolean")) {
+ result = Boolean.TYPE;
+ } else if (type.equals("char")) {
+ result = Character.TYPE;
+ } else if (type.equals("void")) {
+ result = Void.TYPE;
+ } else {
+ result = Util.loadClass(type, Void.TYPE);
+ }
+ return result;
+ }
+
public static ViewHandler getViewHandler(FacesContext context)
throws FacesException {
// Get Application instance
Index: jsf-demo/ezcomp02/src/main/webapp/WEB-INF/composite-test.taglib.xml
===================================================================
--- jsf-demo/ezcomp02/src/main/webapp/WEB-INF/composite-test.taglib.xml (revision 5806)
+++ jsf-demo/ezcomp02/src/main/webapp/WEB-INF/composite-test.taglib.xml (working copy)
-38,11 +38,10 @@
-->
-<!DOCTYPE facelet-taglib PUBLIC
- "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
- "
http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
-
-<facelet-taglib>
+<facelet-taglib xmlns="
http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibary_2_0.xsd"
+ version="2.0">
<namespace>
http://domain.com/path</namespace>
<composite-library-name>compositeTest</composite-library-name>
</facelet-taglib>
Index: jsf-demo/ezcomp02/src/main/webapp/WEB-INF/web.xml
===================================================================
--- jsf-demo/ezcomp02/src/main/webapp/WEB-INF/web.xml (revision 5806)
+++ jsf-demo/ezcomp02/src/main/webapp/WEB-INF/web.xml (working copy)
-70,7 +70,7 @@
</context-param>
<context-param>
<param-name>facelets.LIBRARIES</param-name>
- <param-value>/WEB-INF/composite-test.taglib.xml</param-value>
+ <param-value>/WEB-INF/composite-test.taglib.xml;/WEB-INF/test-schema.taglib.xml</param-value>
</context-param>
Index: jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml
===================================================================
--- jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml (revision 5806)
+++ jsf-demo/ezcomp02/src/main/webapp/resources/ezcomp/loginPanel.xhtml (working copy)
-59,7 +59,7 @@
<composite:attribute name="pinLabel" default="PIN" />
<composite:attribute name="loginLabel" default="Login" />
<composite:attribute name="model" required="true"/>
- <composite:attribute name="action" method-signature="java.lang.Object action()" applyTo="loginEvent"/>
+ <composite:attribute name="action" method-signature="java.lang.Object action()" targets="loginEvent"/>
<composite:editableValueHolder name="usernameInput" />
Index: jsf-demo/ajax-switchlist/web/resources/switchlist/switchlist.xhtml
===================================================================
--- jsf-demo/ajax-switchlist/web/resources/switchlist/switchlist.xhtml (revision 5806)
+++ jsf-demo/ajax-switchlist/web/resources/switchlist/switchlist.xhtml (working copy)
-57,8 +57,8 @@
<composite:attribute name="selected2" required="true"/>
<composite:attribute name="items1" required="true"/>
<composite:attribute name="items2" required="true"/>
- <composite:attribute name="move1to2" required="true" method-signature="void f1(javax.faces.event.ActionEvent)" />
- <composite:attribute name="move2to1" required="true" method-signature="void f2(javax.faces.event.ActionEvent)" />
+ <composite:attribute name="move1to2" targets="move1to2" required="true" method-signature="void f1(javax.faces.event.ActionEvent)" />
+ <composite:attribute name="move2to1" targets="move2to1" required="true" method-signature="void f2(javax.faces.event.ActionEvent)" />
</composite:interface>
--
| ed.burns_at_sun.com | office: 408 884 9519 OR x31640
| homepage: | http://ridingthecrest.com/