You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/08/16 00:33:50 UTC
svn commit: r1158046 - in /myfaces/core/trunk/impl/src:
main/java/org/apache/myfaces/view/facelets/
main/java/org/apache/myfaces/view/facelets/tag/composite/
main/java/org/apache/myfaces/view/facelets/tag/jsf/
test/java/org/apache/myfaces/view/facelets...
Author: lu4242
Date: Mon Aug 15 22:33:50 2011
New Revision: 1158046
URL: http://svn.apache.org/viewvc?rev=1158046&view=rev
Log:
MYFACES-3281 cc:attribute "targets" and cc attached object "targets" should follow strictly the spec
Added:
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentConditionalButtonTestCase.java
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleConditionalButtonTargets.xhtml
myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testConditionalButtonTargets.xhtml
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=1158046&r1=1158045&r2=1158046&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Mon Aug 15 22:33:50 2011
@@ -115,6 +115,7 @@ import org.apache.myfaces.view.facelets.
import org.apache.myfaces.view.facelets.tag.composite.ClientBehaviorRedirectEventComponentWrapper;
import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
import org.apache.myfaces.view.facelets.tag.composite.CompositeResourceLibrary;
+import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
import org.apache.myfaces.view.facelets.tag.jsf.html.HtmlLibrary;
@@ -1125,10 +1126,12 @@ public class FaceletViewDeclarationLangu
}
// Otherwise keep the current ValueExpression, because it will be used chain other value expressions
}
+
+ UIComponent topLevelComponentBase = topLevelComponent.getFacet(UIComponent.COMPOSITE_FACET_NAME);
for (String target : targetsArray)
{
- UIComponent innerComponent = topLevelComponent.findComponent(target);
+ UIComponent innerComponent = ComponentSupport.findComponentChildOrFacetFrom(context, topLevelComponentBase, target);
if (innerComponent == null)
{
@@ -1274,9 +1277,11 @@ public class FaceletViewDeclarationLangu
methodExpression = reWrapMethodExpression(methodExpression, attributeNameValueExpression);
+ UIComponent topLevelComponentBase = topLevelComponent.getFacet(UIComponent.COMPOSITE_FACET_NAME);
+
for (String target : targetsArray)
{
- UIComponent innerComponent = topLevelComponent.findComponent(target);
+ UIComponent innerComponent = ComponentSupport.findComponentChildOrFacetFrom(context, topLevelComponentBase, target);
if (innerComponent == null)
{
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java?rev=1158046&r1=1158045&r2=1158046&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java Mon Aug 15 22:33:50 2011
@@ -25,10 +25,12 @@ import java.util.List;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.view.AttachedObjectTarget;
import org.apache.myfaces.shared.util.StringUtils;
+import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
/**
*
@@ -67,9 +69,24 @@ public class AttachedObjectTargetImpl im
if (targetsArray.length > 0)
{
List<UIComponent> targetsList = new ArrayList<UIComponent>(targetsArray.length);
+ final char separatorChar = UINamingContainer.getSeparatorChar(facesContext);
+ UIComponent facetBase = topLevelComponent.getFacet(UIComponent.COMPOSITE_FACET_NAME);
for (String target : targetsArray)
{
- UIComponent innerComponent = topLevelComponent.findComponent(target);
+ //UIComponent innerComponent = topLevelComponent.findComponent(
+ // topLevelComponent.getId() + UINamingContainer.getSeparatorChar(facesContext) + target);
+ int separator = target.indexOf(separatorChar);
+ UIComponent innerComponent = null;
+ if (separator == -1)
+ {
+ innerComponent = ComponentSupport.findComponentChildOrFacetFrom(
+ facetBase, target, null);
+ }
+ else
+ {
+ innerComponent = ComponentSupport.findComponentChildOrFacetFrom(
+ facetBase, target.substring(0,separator), target);
+ }
if (innerComponent != null)
{
@@ -87,7 +104,11 @@ public class AttachedObjectTargetImpl im
String name = getName();
if (name != null)
{
- UIComponent innerComponent = topLevelComponent.findComponent(getName());
+ //UIComponent innerComponent = topLevelComponent.findComponent(
+ // topLevelComponent.getId() + UINamingContainer.getSeparatorChar(facesContext) + getName());
+ UIComponent innerComponent = ComponentSupport.findComponentChildOrFacetFrom(
+ topLevelComponent.getFacet(UIComponent.COMPOSITE_FACET_NAME),
+ name, null);
if (innerComponent != null)
{
List<UIComponent> targetsList = new ArrayList<UIComponent>(1);
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java?rev=1158046&r1=1158045&r2=1158046&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java Mon Aug 15 22:33:50 2011
@@ -25,7 +25,9 @@ import java.util.Locale;
import java.util.Map;
import javax.faces.FacesException;
+import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
import javax.faces.component.UIPanel;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
@@ -430,4 +432,84 @@ public final class ComponentSupport
FaceletViewDeclarationLanguage.cleanTransientBuildOnRestore(context);
}
}
+
+ public static UIComponent findComponentChildOrFacetFrom(FacesContext facesContext, UIComponent parent, String expr)
+ {
+ final char separatorChar = UINamingContainer.getSeparatorChar(facesContext);
+ int separator = expr.indexOf(separatorChar);
+ if (separator == -1)
+ {
+ return ComponentSupport.findComponentChildOrFacetFrom(
+ parent, expr, null);
+ }
+ else
+ {
+ return ComponentSupport.findComponentChildOrFacetFrom(
+ parent, expr.substring(0,separator), expr);
+ }
+ }
+
+ public static UIComponent findComponentChildOrFacetFrom(UIComponent parent, String id, String innerExpr)
+ {
+ if (parent.getFacetCount() > 0)
+ {
+ for (UIComponent facet : parent.getFacets().values())
+ {
+ if (id.equals(facet.getId()))
+ {
+ if (innerExpr == null)
+ {
+ return facet;
+ }
+ else if (facet instanceof NamingContainer)
+ {
+ UIComponent find = facet.findComponent(innerExpr);
+ if (find != null)
+ {
+ return find;
+ }
+ }
+ }
+ else if (!(facet instanceof NamingContainer))
+ {
+ UIComponent find = findComponentChildOrFacetFrom(facet, id, innerExpr);
+ if (find != null)
+ {
+ return find;
+ }
+ }
+ }
+ }
+ if (parent.getChildCount() > 0)
+ {
+ for (int i = 0, childCount = parent.getChildCount(); i < childCount; i++)
+ {
+ UIComponent child = parent.getChildren().get(i);
+ if (id.equals(child.getId()))
+ {
+ if (innerExpr == null)
+ {
+ return child;
+ }
+ else if (child instanceof NamingContainer)
+ {
+ UIComponent find = child.findComponent(innerExpr);
+ if (find != null)
+ {
+ return find;
+ }
+ }
+ }
+ else if (!(child instanceof NamingContainer))
+ {
+ UIComponent find = findComponentChildOrFacetFrom(child, id, innerExpr);
+ if (find != null)
+ {
+ return find;
+ }
+ }
+ }
+ }
+ return null;
+ }
}
Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentConditionalButtonTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentConditionalButtonTestCase.java?rev=1158046&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentConditionalButtonTestCase.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentConditionalButtonTestCase.java Mon Aug 15 22:33:50 2011
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.view.facelets.tag.composite;
+
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIViewRoot;
+import javax.faces.event.ActionEvent;
+
+import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.test.mock.MockExternalContext;
+import org.apache.myfaces.view.facelets.FaceletTestCase;
+import org.apache.myfaces.view.facelets.bean.HelloWorld;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CompositeComponentConditionalButtonTestCase extends FaceletTestCase
+{
+
+ @Override
+ protected void setupComponents() throws Exception
+ {
+ super.setupComponents();
+ }
+
+ @Override
+ protected void setUpExternalContext() throws Exception
+ {
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+
+ //RuntimeConfig.getCurrentInstance(externalContext).setPropertyResolver(
+ // new PropertyResolverImpl());
+ //RuntimeConfig.getCurrentInstance(externalContext).setVariableResolver(
+ // new VariableResolverImpl());
+ // For this test we need the a real one, because the Mock does not
+ // handle VariableMapper stuff properly and ui:param logic will not work
+ RuntimeConfig.getCurrentInstance(externalContext).setExpressionFactory(
+ new org.apache.el.ExpressionFactoryImpl());
+ }
+
+ @Test
+ public void testConditionalButtonTargets() throws Exception
+ {
+ HelloWorld helloWorld = new HelloWorld();
+
+ facesContext.getExternalContext().getRequestMap().put("helloWorldBean",
+ helloWorld);
+
+ UIViewRoot root = facesContext.getViewRoot();
+ vdl.buildView(facesContext, root, "testConditionalButtonTargets.xhtml");
+
+ //The first component has a default command button
+ UIComponent form = root.findComponent("testForm1");
+ Assert.assertNotNull(form);
+ UINamingContainer compositeComponent1 = (UINamingContainer) form.findComponent("actionSource1");
+ Assert.assertNotNull(compositeComponent1);
+ UICommand button1 = (UICommand) compositeComponent1.findComponent("button");
+ Assert.assertNotNull(button1);
+ Assert.assertEquals("submit", button1.getActionExpression().invoke(facesContext.getELContext(), null));
+
+ Assert.assertNotNull(button1.getActionListeners());
+ Assert.assertEquals(1, button1.getActionListeners().length);
+
+ UINamingContainer compositeComponent2 = (UINamingContainer) form.findComponent("actionSource2");
+ Assert.assertNotNull(compositeComponent2);
+ UICommand button2 = (UICommand) compositeComponent2.findComponent("button");
+ Assert.assertNotNull(button2);
+ //Since the button is outside cc:implementation, by the spec it cannot be taken into account as a valid "targets" value.
+ Assert.assertEquals("fail", button2.getActionExpression().invoke(facesContext.getELContext(), null));
+ //It also cannot be target of cc:actionSource
+ Assert.assertNotNull(button2.getActionListeners());
+ Assert.assertEquals(0, button2.getActionListeners().length);
+
+ //StringWriter sw = new StringWriter();
+ //MockResponseWriter mrw = new MockResponseWriter(sw);
+ //facesContext.setResponseWriter(mrw);
+
+ //root.encodeAll(facesContext);
+ //sw.flush();
+ //System.out.print(sw.toString());
+ }
+}
Added: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleConditionalButtonTargets.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleConditionalButtonTargets.xhtml?rev=1158046&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleConditionalButtonTargets.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleConditionalButtonTargets.xhtml Mon Aug 15 22:33:50 2011
@@ -0,0 +1,38 @@
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id: defineInclude.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jsp/jstl/core"
+ xmlns:cc="http://java.sun.com/jsf/composite">
+<head>
+</head>
+<body>
+<cc:interface>
+ <cc:attribute name="action" targets="button" default="submit"/>
+ <cc:actionSource name="button"/>
+</cc:interface>
+<cc:implementation>
+ <c:if test="#{empty cc.facets.defaultAction}">
+ <h:commandButton id="button" action="#{cc.attrs.customMethod}"/>
+ </c:if>
+ <c:if test="#{!empty cc.facets.defaultAction}">
+ <cc:renderFacet name="defaultAction"/>
+ </c:if>
+</cc:implementation>
+</body>
+</html>
\ No newline at end of file
Added: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testConditionalButtonTargets.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testConditionalButtonTargets.xhtml?rev=1158046&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testConditionalButtonTargets.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testConditionalButtonTargets.xhtml Mon Aug 15 22:33:50 2011
@@ -0,0 +1,36 @@
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id: defineInclude.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:testComposite="http://java.sun.com/jsf/composite/testComposite">
+<head>
+</head>
+<body>
+<h:form id="testForm1">
+<testComposite:simpleConditionalButtonTargets id="actionSource1">
+ <f:actionListener for="button" binding="#{helloWorldBean.actionListener}"/>
+</testComposite:simpleConditionalButtonTargets>
+<testComposite:simpleConditionalButtonTargets id="actionSource2">
+ <f:actionListener for="button" binding="#{helloWorldBean.actionListener}"/>
+ <f:facet name="defaultAction">
+ <h:commandButton id="button" action="fail"/>
+ </f:facet>
+</testComposite:simpleConditionalButtonTargets>
+</h:form>
+</body>
+</html>
\ No newline at end of file