You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2009/03/01 22:57:03 UTC
svn commit: r749124 - in
/myfaces/extensions/validator/branches/branch_for_jsf_1_1:
core/src/main/java/org/apache/myfaces/extensions/validator/core/el/
validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/
Author: gpetracek
Date: Sun Mar 1 21:57:03 2009
New Revision: 749124
URL: http://svn.apache.org/viewvc?rev=749124&view=rev
Log:
EXTVAL-37: support for dynamic map el-syntax with custom facelets components
Added:
myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/
myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/ValueBindingExpressionTestCase.java
Modified:
myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java
myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java
myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java
Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java?rev=749124&r1=749123&r2=749124&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java Sun Mar 1 21:57:03 2009
@@ -20,7 +20,10 @@
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -29,6 +32,8 @@
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import java.io.Externalizable;
+import java.lang.reflect.Method;
+import java.util.Map;
/**
* in order to centralize the jsf version dependency within the core
@@ -133,8 +138,10 @@
return new ValueBindingExpression(valueBindingExpression);
}
+ //keep in sync with DefaultELHelper#getPropertyDetailsViaReflectionFallback of trunk!!!
public PropertyDetails getPropertyDetailsOfValueBinding(UIComponent uiComponent)
{
+ FacesContext facesContext = FacesContext.getCurrentInstance();
ValueBindingExpression valueBindingExpression = getValueBindingExpression(uiComponent, false);
ValueBindingExpression currentValueBindingExpression =
new ValueBindingExpression(valueBindingExpression.getExpressionString());
@@ -145,11 +152,11 @@
{
if(path == null)
{
- path = currentValueBindingExpression.getProperty();
+ path = getPropertyName(currentValueBindingExpression);
}
else
{
- path = currentValueBindingExpression.getProperty() + "." + path;
+ path = getPropertyName(currentValueBindingExpression) + "." + path;
}
currentValueBindingExpression = currentValueBindingExpression.getBaseExpression();
@@ -157,9 +164,67 @@
path = currentValueBindingExpression.getProperty() + "." + path;
- Object baseObject = getValueOfExpression(
- FacesContext.getCurrentInstance(), valueBindingExpression.getBaseExpression());
- return new PropertyDetails(path, baseObject, valueBindingExpression.getProperty());
+ Object baseObject = getValueOfExpression(facesContext, valueBindingExpression.getBaseExpression());
+
+ //in case of e.g.: #{bean[bean.passwordRepeatedPropertyName]}
+ //-> bean.passwordRepeatedPropertyName is not the final property name
+ return new PropertyDetails(path, baseObject, getPropertyName(valueBindingExpression));
+ }
+
+ private String getPropertyName(ValueBindingExpression valueBindingExpression)
+ {
+ String propertyName = valueBindingExpression.getProperty();
+
+ if(propertyName.contains("."))
+ {
+ propertyName = extractPropertyNameOfPropertyPath(propertyName);
+ }
+
+ return propertyName;
+ }
+
+ @ToDo(value = Priority.MEDIUM, description = "support for more dynamic bindings - details see inline")
+ private String extractPropertyNameOfPropertyPath(String propertyChain)
+ {
+ String[] properties = propertyChain.split("\\.");
+
+ Object currentPropertyValue = ExtValUtils.getELHelper().getBean(properties[0]);
+
+ Method currentMethod;
+ String currentPropertyName;
+ for(int i = 1; i < properties.length; i++)
+ {
+ currentPropertyName = properties[i];
+ currentMethod = ReflectionUtils.tryToGetMethod(currentPropertyValue.getClass(),
+ "get" + currentPropertyName.substring(0, 1).toUpperCase() + currentPropertyName.substring(1));
+
+ if(currentMethod == null && currentPropertyValue instanceof Map)
+ {
+ //it's ok for the simple map case - but not for e.g.:
+ //#{bean1[bean2.propertyNameProvider[ bean3.index]]}
+ //or every other complex replacement for bean3.index
+ //it might also require an adjustment at FaceletsTaglibExpressionHelper#tryToTransformToRealBinding
+ ((Map)currentPropertyValue).get(currentPropertyName);
+ }
+ else
+ {
+ currentPropertyValue = ReflectionUtils.tryToInvokeMethod(currentPropertyValue, currentMethod);
+ }
+ }
+
+ if(currentPropertyValue instanceof String)
+ {
+ return (String)currentPropertyValue;
+ }
+ else
+ {
+ if(this.logger.isErrorEnabled())
+ {
+ this.logger.error("unexpected value within map syntax: " + propertyChain +
+ " last property name: " + currentPropertyValue);
+ }
+ return null;
+ }
}
static String getOriginalValueBindingExpression(UIComponent uiComponent)
Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java?rev=749124&r1=749123&r2=749124&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java Sun Mar 1 21:57:03 2009
@@ -135,10 +135,11 @@
String originalBinding = addedVirtualNames.get("value");
originalBinding = originalBinding.substring(originalBinding.indexOf("{") + 1, originalBinding.indexOf("}"));
addedVirtualNames.remove("value");
- return tryToTransformToRealBinding(originalBinding, addedVirtualNames);
+ return tryToTransformToRealBinding(originalBinding, addedVirtualNames, virtualVars);
}
- private static String tryToTransformToRealBinding(String originalBinding, Map<String, String> addedVirtualNames)
+ private static String tryToTransformToRealBinding(
+ String originalBinding, Map<String, String> addedVirtualNames, Map<String, String> virtualVars)
{
originalBinding = "#{" + originalBinding + "}";
Iterator nameIterator = addedVirtualNames.keySet().iterator();
@@ -148,12 +149,44 @@
while(nameIterator.hasNext())
{
currentKey = (String) nameIterator.next();
- currentValue = addedVirtualNames.get(currentKey);
+ currentValue = addedVirtualNames.get(currentKey);
currentValue = currentValue.substring(currentValue.indexOf("{") + 1, currentValue.indexOf("}"));
+
originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");
+
originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");
- originalBinding = originalBinding.replace("[" + currentKey + "]", "[" + currentValue + "]");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");
+
+ originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");
+ originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");
+ }
+
+ nameIterator = virtualVars.keySet().iterator();
+
+ while(nameIterator.hasNext())
+ {
+ currentKey = (String) nameIterator.next();
+
+ currentValue = virtualVars.get(currentKey);
+
+ originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");
+
+ originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");
+
+ originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");
+ //dynamic base and property
+ originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");
+ originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");
}
return originalBinding.substring(2, originalBinding.length() - 1);
Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java?rev=749124&r1=749123&r2=749124&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java Sun Mar 1 21:57:03 2009
@@ -53,6 +53,7 @@
public static ValueBindingExpression replaceProperty(ValueBindingExpression valueBindingExpression,
String newProperty)
{
+ //TODO adjustments for isDynamicBaseAndProperty
if(valueBindingExpression.getProperty().endsWith("']"))
{
valueBindingExpression = valueBindingExpression.getBaseExpression();
@@ -73,6 +74,7 @@
String sourceExpression = valueBindingExpression.getExpressionString();
String result = sourceExpression.substring(0, sourceExpression.length() - 1);
+ //TODO adjustments for isDynamicBaseAndProperty
if(newProperty.startsWith("['"))
{
return new ValueBindingExpression(result + newProperty + "}");
@@ -90,7 +92,8 @@
throw new IllegalStateException(expression + " is no valid el-expression");
}
- int index1 = expression.lastIndexOf("']");
+ boolean isDynamicBaseAndProperty = expression.lastIndexOf("']") == -1;
+ int index1 = isDynamicBaseAndProperty ? expression.lastIndexOf("]") : expression.lastIndexOf("']");
int index2 = expression.lastIndexOf(".");
if(index1 > index2)
@@ -98,9 +101,18 @@
expression = expression.substring(0, index1);
int index3 = findIndexOfStartingBracket(expression);
- this.value = expression.substring(index3 + 2, index1);
+ if(isDynamicBaseAndProperty)
+ {
+ this.value = expression.substring(index3 + 1, index1);
+
+ }
+ else
+ {
+ this.value = expression.substring(index3 + 2, index1);
+ }
+
this.base = new ValueBindingExpression(expression.substring(0, index3) + "}");
- this.token = "['";
+ this.token = isDynamicBaseAndProperty ? "[" : "['";
}
else if( index2 > index1)
{
@@ -125,7 +137,7 @@
{
return this.value.substring(1, this.value.length() - 1);
}
- return this.base.value + this.token + this.value.substring(0, this.value.length()) + "']";
+ //return this.base.value + this.token + this.value.substring(0, this.value.length()) + "']";
}
return value;
}
@@ -145,6 +157,10 @@
{
return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "']}";
}
+ else if("[".equals(this.token))
+ {
+ return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "]}";
+ }
return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "}";
}
else
Added: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/ValueBindingExpressionTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/ValueBindingExpressionTestCase.java?rev=749124&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/ValueBindingExpressionTestCase.java (added)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/el/ValueBindingExpressionTestCase.java Sun Mar 1 21:57:03 2009
@@ -0,0 +1,165 @@
+/*
+ * 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.extensions.validator.test.el;
+
+import org.apache.myfaces.extensions.validator.test.AbstractExValViewControllerTestCase;
+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.2
+ */
+public class ValueBindingExpressionTestCase extends AbstractExValViewControllerTestCase
+{
+ public ValueBindingExpressionTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(ValueBindingExpressionTestCase.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ public void testStandardSyntax() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression = new ValueBindingExpression("#{bean1.property1}");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1.property1}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['property1']}");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1['property1']}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['bean2'].property1}");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1['bean2'].property1}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1['bean2']}");
+ assertEquals(valueBindingExpression.getBaseExpression().getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+ }
+
+ public void testStandardSyntaxReplaceProperty() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression = new ValueBindingExpression("#{bean1.property1}");
+
+ valueBindingExpression = ValueBindingExpression.replaceProperty(valueBindingExpression, "property2");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1.property2}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property2");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['property1']}");
+
+ valueBindingExpression = ValueBindingExpression.replaceProperty(valueBindingExpression, "property2");
+
+ //TODO restore original syntax
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1.property2}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property2");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['bean2'].property1}");
+
+ valueBindingExpression = ValueBindingExpression.replaceProperty(valueBindingExpression, "property2");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1['bean2'].property2}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1['bean2']}");
+ assertEquals(valueBindingExpression.getBaseExpression().getBaseExpression().getExpressionString(), "#{bean1}");
+ assertEquals(valueBindingExpression.getProperty(), "property2");
+ }
+
+ public void testStandardSyntaxAddProperty() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression = new ValueBindingExpression("#{bean1.bean2}");
+
+ valueBindingExpression = ValueBindingExpression.addProperty(valueBindingExpression, "property1");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1.bean2.property1}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1.bean2}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['bean2']}");
+
+ valueBindingExpression = ValueBindingExpression.addProperty(valueBindingExpression, "property1");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1['bean2'].property1}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1['bean2']}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+
+ valueBindingExpression = new ValueBindingExpression("#{bean1['bean2'].bean3}");
+
+ valueBindingExpression = ValueBindingExpression.addProperty(valueBindingExpression, "property1");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{bean1['bean2'].bean3.property1}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{bean1['bean2'].bean3}");
+ assertEquals(valueBindingExpression
+ .getBaseExpression().getBaseExpression().getExpressionString(), "#{bean1['bean2']}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+ }
+
+ public void testFaceletsCustomComponentSyntax() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression = new ValueBindingExpression("#{entity[fieldName]}");
+
+ assertEquals(valueBindingExpression.getExpressionString(), "#{entity[fieldName]}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{entity}");
+ assertEquals(valueBindingExpression.getProperty(), "fieldName");
+ }
+
+ public void testFaceletsCustomComponentSyntaxReplaceProperty() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression = new ValueBindingExpression("#{entity[fieldName]}");
+
+ valueBindingExpression = ValueBindingExpression.replaceProperty(valueBindingExpression, "newFieldName");
+
+ //TODO restore original syntax
+ assertEquals(valueBindingExpression.getExpressionString(), "#{entity.newFieldName}");
+ assertEquals(valueBindingExpression.getBaseExpression().getExpressionString(), "#{entity}");
+ assertEquals(valueBindingExpression.getProperty(), "newFieldName");
+ }
+
+ public void testComplexMapSyntax() throws Exception
+ {
+ ValueBindingExpression valueBindingExpression
+ = new ValueBindingExpression("#{bean1[bean2[bean3['key1']]].property1}");
+
+ //TODO
+ //assertEquals(valueBindingExpression.getExpressionString(), "#{bean1[bean2[bean3['key1']]].property1}");
+ assertEquals(valueBindingExpression.getProperty(), "property1");
+ }
+
+}