[jsr-314-open-mirror] [jsr-314-open] Proposal: small addition to composite component metadata specification
by Ed Burns
https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1782
The proposed solution is to enhance the composite component metadata
specification to include information about the list of composite
component attributes for which default attribute values have been
declared.
This information is used in the Facelets tag layer in the code that
installs the ValueExpression for any child attributes in the using page.
In this case, the MetadataHandler manually removes the attribute from
the attributes map if there is a ValueExpression for an attribute for
which there also is a composite component attribute.
SECTION: Modified Files
----------------------------
M Spec section 3.6.2.1 Composite Component Metadata
Add a new paragraph at the end of the section, which would fall under
the bullet that describes the runtime representation of the
<cc:attribute> element.
The composite component BeanDescriptior must return a
Collection<String> when its getValue() method is called with an
argument equal to the value of the symbolic constant
UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES. The
Collection<String> must contain the names of any <cc:attribute>
elements for which the default attribute was specified, or null, if
none of the attributes have been given a default value.
M jsf-api/src/main/java/javax/faces/component/UIComponent.java
- Add constant:
+ * <p class="changed_added_2_1">This constant enables one to quickly discover
+ * the names of the declared composite component attributes that have been
+ * given default values by the composite component author. The information
+ * is exposed as a <code>Collection<String></code> returned from the
+ * <code>getValue()</code> method on the <em>composite component
+ * BeanDescriptor</em>, when this constant is passed as the argument.</p>
+ *
+ * @since 2.1
+ */
+ public static final String ATTRS_WITH_DECLARED_DEFAULT_VALUES =
+ "javax.faces.component.ATTR_NAMES_WITH_DEFAULT_VALUES";
M jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java
- Consider the inner class CompositeExpressionMetadata. This class
deals with attributes of a composite component instance in a using
page that are of type ValueExpressionsp For example:
<tmo:block collapsable="#{'true'}"/>
If the corresponding attribute has been declared with a default value
in the composite component declaration, such as:
<composite:interface>
<composite:attribute name="collapsable" required="false"
default="false"/>
</composite:interface>
then the default attribute will have already been stored in the
attributes map of the composite component by the time the
CompositeExpressionMetadata.applyMetadata() method is called. (See
ApplicationImpl.pushDeclaredDefaultValuesToAttributesMap()). This
change uses the new element of composite component metadata to inspect
if the attribute in question has a default value. If so, we remove
the attribute from the component attributes map so that the one from
the using page is used, instead of the default value.
M jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java
- in createComponent(String,Resource), and
pushDeclaredDefaultValuesToAttributesMap(), implement the new portion
of the composite component metadata specification.
M jsf-ri/systest/src/com/sun/faces/composite/CompositeComponentsTestCase.java
- new testcase
SECTION: Diffs
----------------------------
Index: jsf-api/src/main/java/javax/faces/component/UIComponent.java
===================================================================
--- jsf-api/src/main/java/javax/faces/component/UIComponent.java (revision 8566)
+++ jsf-api/src/main/java/javax/faces/component/UIComponent.java (working copy)
@@ -210,6 +210,19 @@
*/
public static final String COMPOSITE_FACET_NAME = "javax.faces.component.COMPOSITE_FACET_NAME";
+ /**
+ * <p class="changed_added_2_1">This constant enables one to quickly discover
+ * the names of the declared composite component attributes that have been
+ * given default values by the composite component author. The information
+ * is exposed as a <code>Collection<String></code> returned from the
+ * <code>getValue()</code> method on the <em>composite component
+ * BeanDescriptor</em>, when this constant is passed as the argument.</p>
+ *
+ * @since 2.1
+ */
+ public static final String ATTRS_WITH_DECLARED_DEFAULT_VALUES =
+ "javax.faces.component.ATTR_NAMES_WITH_DEFAULT_VALUES";
+
enum PropertyKeysPrivate {
attributesThatAreSet
}
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java (revision 8566)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagHandler.java (working copy)
@@ -65,6 +65,7 @@
import com.sun.faces.util.RequestStateManager;
import com.sun.faces.util.Util;
import com.sun.faces.util.FacesLogger;
+import java.beans.BeanDescriptor;
import javax.el.ELException;
import javax.el.ValueExpression;
@@ -95,6 +96,7 @@
import java.beans.IntrospectionException;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -599,6 +601,18 @@
ValueExpression ve = attr.getValueExpression(ctx, type);
UIComponent cc = (UIComponent) instance;
assert (UIComponent.isCompositeComponent(cc));
+ Map<String, Object> attrs = cc.getAttributes();
+ BeanInfo componentMetadata = (BeanInfo) attrs.get(UIComponent.BEANINFO_KEY);
+ BeanDescriptor desc = componentMetadata.getBeanDescriptor();
+ Collection<String> attributesWithDeclaredDefaultValues = (Collection<String>)
+ desc.getValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES);
+ if (null != attributesWithDeclaredDefaultValues &&
+ attributesWithDeclaredDefaultValues.contains(name)) {
+ // It is necessary to remove the value from the attribute
+ // map because the ELexpression transparancy doesn't know
+ // about the value's existence.
+ attrs.remove(name);
+ }
cc.setValueExpression(name, ve);
}
Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (revision 8566)
+++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (working copy)
@@ -1031,6 +1031,8 @@
PropertyDescriptor[] declaredAttributes = componentMetadata.getPropertyDescriptors();
Object defaultValue;
String key;
+ Collection<String> attributesWithDeclaredDefaultValues = null;
+
for (PropertyDescriptor cur : declaredAttributes) {
defaultValue = cur.getValue("default");
if (null != defaultValue) {
@@ -1043,6 +1045,19 @@
// ensure this attribute is not a method-signature. method-signature
// declared default values are handled in retargetMethodExpressions.
if (null == cur.getValue("method-signature") || null != cur.getValue("type")) {
+
+ if (null == attributesWithDeclaredDefaultValues) {
+ BeanDescriptor desc = componentMetadata.getBeanDescriptor();
+ attributesWithDeclaredDefaultValues = (Collection<String>)
+ desc.getValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES);
+ if (null == attributesWithDeclaredDefaultValues) {
+ attributesWithDeclaredDefaultValues = new ArrayList<String>();
+ desc.setValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES,
+ attributesWithDeclaredDefaultValues);
+ }
+ }
+ attributesWithDeclaredDefaultValues.add(key);
+
attrs.put(key, defaultValue);
}
}
Index: jsf-ri/systest/src/com/sun/faces/composite/CompositeComponentsTestCase.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/composite/CompositeComponentsTestCase.java (revision 8566)
+++ jsf-ri/systest/src/com/sun/faces/composite/CompositeComponentsTestCase.java (working copy)
@@ -963,6 +963,13 @@
assertTrue(text.contains("The following facets(s) are required, but no facets have been supplied for them: table."));
}
+ public void testDefaultAttributeValueELOverrides() throws Exception {
+ HtmlPage page = getPage("/faces/composite/issue-1782-using.xhtml");
+ String text = page.asText();
+ System.out.println(text);
+ assertTrue(text.matches("(?s).*collapsable\\s=\\strue.*"));
+ }
+
// --------------------------------------------------------- Private Methods
--
| edward.burns(a)oracle.com | office: +1 407 458 0017
| homepage: | http://ridingthecrest.com/
| 14 work days until JSF 2.1 Milestone 3
14 years, 4 months
[jsr-314-open-mirror] [jsr-314-open] update on Red Hat's participation in JSR-314 and JSF 2.1
by Dan Allen
Ed, Roger and other members of the JSR-314 EG,
Since the JSR-314 leadership has moved to enact the JCP mandate that an EG
is disbanded upon the final release of a specification, we (Red Hat) feel we
have no choice but to acknowledge this dismissal. We have submitted all of
our outstanding change requests for 2.0 Rev a, as itemized on the wiki page
http://seamframework.org/Documentation/JSF21, and have confidence that the
leads will apply these changes to the specification document and API docs,
as necessary.
We can only participate in a JSR Expert Group that is officially recognized
and has all of the standard terms, conditions and electoral rights granted
by the JCP. We cannot support continued compromise of improvements we
believe are needed in JSF in order to fit changes into the restricted scope
of a minor revision. And while a major revision is now being pursued, we
only recognize a minor revision under the JSR-314 specification since we
have no official status to vote otherwise.
Our participation in the development of JSF 2.1 is contingent upon the
submission of a new JSR and approval of our request to become an EG member
of that specification, for which we now call. If we're going to improve JSF,
it needs to be a sincere commitment to do what needs to be done within an
open JCP process.
Serving on the JSR-314 Expert Group has been a true honor for us. We are
proud of the progress that was made in JSF 2.0 and believe that it's become
a cornerstone of the Java EE 6 platform, as well as a solid web framework in
its own right. Together, we have embraced defacto standards, given the
community a voice and set the tone for openness in the JCP. The discussions
were always amicable and enjoyable, and we have developed a strong
camaraderie with the individual members that we hope lasts indefinitely.
We are going to take this opportunity to develop JSF enhancements in the
Seam 3 and RichFaces 4 projects and also explore/study other view layers.
When the time is right again, we will contribute to next generation standard
view layers, JSF 2.1 or otherwise. We eagerly await the next opportunity to
work with the members of this Expert Group.
Sincerely,
Dan Allen, Lincoln Baxter, III and Pete Muir on behalf of Red Hat, Inc.
14 years, 4 months
Re: [jsr-314-open-mirror] [jsr-314-open] Fwd: Fix UIData state saving model
by Ed Burns
>>>>> On Mon, 26 Jul 2010 08:14:42 +0200, Martin Marinschek <mmarinschek(a)apache.org> said:
MM> Hi guys,
MM> sorry, it took me a while to review the patch, but this is Leonardo´s
MM> suggestion for partial state saving in tables. He also included a test
MM> webapp, and a test for Mojarra.
It's no problem. I'm not surprised it took so long. For me, at least,
this is a very complicated issue to understand. At this point in the
life of JSF, it's these kinds of issues that remain unsolved.
Here is my response.
https://javaserverfaces-spec-public.dev.java.net/nonav/issues/showattachm...
Included inline for convenience.
I'm now going to just apply Leonardo's patch and see what happens to our
existing automated tests.
LU> In theory, any solution to this issue must do something like this:
LU> - Save the "initial state" of all component children, excluding
LU> facets of nearest children (usually instances of UIColumn), after
LU> the component tree is build.
This is just the normal mark initial state, right?
LU> - When setRowIndex method is called, it should save the "partial" or
LU> "delta" state of the current row somewhere, change the row, and
LU> finally restore the state using the "initial state" of the row and
LU> the delta saved, if any.
Yes, this makes sense.
LU> Based on the previous ideas, the following (personal) conclusions
LU> arise:
LU> 1. Use a property to enable disable this behavior is preferred,
LU> because it is possible to have a non "reliable" model, or the user
LU> could have situations where it is not required to preserve the state
LU> per component. The patches adds a property called
LU> "preserveRowComponentState".
That's fine with me.
LU> 2. It is necessary to know "when" we can calculate the "initial
LU> state" of the rows: In the proposed patches, the idea is use
LU> UIData.markInitialState and check if we should save the "initial"
LU> state. To do that I'm considering two options:
LU> a. Move markInitialState calls, so they will be called after the
LU> component tree is built by facelets vdl. In this way we can ensure
LU> we are calling from parents to children, and we can call saveState
LU> directly on all children.
LU> b. Do not move the calls, but take into consideration that some
LU> children could already be marked, so for those ones we need to call
LU> clearInitialState, saveState and then markInitialState.
LU> Why two options?.
LU> Some time ago, myfaces used a listener attached to
LU> PostAddToViewEvent for "relocate" components. In theory we have 4
LU> cases: h:outputScript, h:outputStylesheet, cc:insertChildren and
LU> cc:insertFacet.
Mojarra still uses a listener for this.
LU> PostAddToViewEvent listener is used on
LU> h:outputScript and h:outputStylesheet by the spec, but it was
LU> necessary to use it on cc:insertChildren and cc:insertFacet, because
LU> there was a problem with nested composite components. But right now,
LU> after some discussions and new ideas provided, myfaces core 2.0.1
LU> has a algorithm that uses a variant of facelets template client api,
LU> so cc:insertChildren and cc:insertFacet does not use a
LU> PostAddToViewEvent listener anymore.
Andy Schwartz suggested Mojarra move to using the template client
approach for cc:insertChildren and cc:insertFacet in issue 1680 [1]. We
opted for a simpler option to allow the Facelets tagHandler to correctly
locate the relocated child in the postback case. Therefore, I'm very
reluctant to adopt a fix to UIData state saving that will break our fix
for 1680.
LU> Allow component relocation using PostAddToViewEvent causes a lot
LU> of trouble. It is more, add/remove components "programatically"
LU> causes a lot of problems too (that's another discussion). Just one
LU> example: components relocated using cc:insertChildren or
LU> cc:insertFacet does not preserve state, because on each request, the
LU> components are relocated and the ones with the state are removed by
LU> facelets refresh algorithm, used by c:if tag.
This problem with c:if has been fixed with in issue 1527 [2]. If you
find that the solution in that issue is faulty, please let the Mojarra
team know.
LU> The option (a) consider that if PostAddToViewEvent listeners are
LU> used to relocate components, only it is safe to save the "initial
LU> state" after the tree is completely built, so we require a fix for
LU> markInitialState() and some way to indicate we are calling this
LU> method from the specified location.
This sounds reasonable.
LU> The option (b) consider that PostAddToViewEvent should not be used
LU> to relocate components. If components are relocated, the destiny
LU> should be outside a UIData instance (h:outputScript and
LU> h:outputStylesheet usually relocates to "head" or "body"), otherwise
LU> the "initial state" will be invalid. Since latest myfaces code
LU> allows this, the option (b) will work there. Anyway, I provide a
LU> patch for mojarra, so people can see how should looks like, but to
LU> make it work requires some big changes.
Yes, it would. And we're not in a position to want to make big changes
now.
LU> 3. The "delta" state of each row should be saved / restored
LU> somewhere with the page: In the proposed patch the deltas are saved
LU> with the state of UIData.
That is a reasonable place to save it.
LU> 4. A way to save/restore transient variables like UIForm submitted
LU> should be provided. The proposed patch includes two new interfaces
LU> called TransientStateHelper and TransientStateHolder to deal with
LU> this stuff (save/restore and manipulate them). As a curious fact,
LU> some days ago, a non very clean solution was applied on
LU> "TRINIDAD-1849 subform in table not working" that could be solved
LU> better with interfaces like the ones proposed here.
Ok, this sounds good too. I'm going to try to understand the patch now,
but I think you've done some great work. I just hope that it can be
made to apply to Mojarra as well as your MyFaces.
[1] https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1680
[2] https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1527
Ed
--
| edward.burns(a)oracle.com | office: +1 407 458 0017
| homepage: | http://ridingthecrest.com/
| 03 work days until JSF 2.1 Milestone 2
14 years, 4 months
Re: [jsr-314-open-mirror] [jsr-314-open] CDI for Websphere 7
by Ed Burns
>>>>> On Mon, 16 Aug 2010 10:34:22 +0200, Matthias Wessendorf <matzew(a)apache.org> said:
MW> Hi,
MW> isn't this more a user forum type of question?
MW> I think it's probably does not fit here for a few reasons.
MW> Also most users (that had experience with JavaEE5 and CDI) aren't able
MW> to share the experience,
MW> since not everybody is allowed to post to this group, right ?
Matthias is correct on all counts.
Ed
--
| edward.burns(a)oracle.com | office: +1 407 458 0017
| homepage: | http://ridingthecrest.com/
| 23 work days until JavaOne 2010
14 years, 4 months
[jsr-314-open-mirror] [jsr-314-open] Auto Reply: Re: CDI for Websphere 7
by barbara.louis@oracle.com
This is an auto-replied message. I am out of office right now. I will be back in office on Aug 17th.
Contacts for each area listed below:
JAX-WS: Jitu (Jitendra.Kotamraju(a)oracle.com)
109: Rama (Rama.Pulavarthi(a)oracle.COM)/ Bhakti (bhakti.mehta(a)oracle.com)
JSF: Ed Burns (edward.burns(a)oracle.com)
CDI: Siva (Sivakumar.Thyagarajan(a)Sun.COM)
Management issues: Abhijit Kumar
Thanks,
Barbara
14 years, 4 months