You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by aw...@apache.org on 2007/02/07 23:19:01 UTC
svn commit: r504730 - in
/incubator/adffaces/branches/faces-1_2-070201/trinidad: ./
trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/
trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/
Author: awiner
Date: Wed Feb 7 15:18:58 2007
New Revision: 504730
URL: http://svn.apache.org/viewvc?view=rev&rev=504730
Log:
ADFFACES-373: JSF 1.2: ChildPropertyTreeModel and SortableModel will throw NPE if used outside of the JSF lifecycle
- Switch SortableModel and ChildPropertyTreeModel from using PropertyResolver to ELResolver (far more likely to be successful)
- Since these API classes now use ELResolver, upgrade from Shale Test 1.0.3 to 1.0.4 - we need ELResolver support on MockApplication.
- Add an ELResolver implementation to the renderkit test framework
Added:
incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MELResolver.java
Modified:
incubator/adffaces/branches/faces-1_2-070201/trinidad/pom.xml
incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.java
incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java
incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MApplication.java
Modified: incubator/adffaces/branches/faces-1_2-070201/trinidad/pom.xml
URL: http://svn.apache.org/viewvc/incubator/adffaces/branches/faces-1_2-070201/trinidad/pom.xml?view=diff&rev=504730&r1=504729&r2=504730
==============================================================================
--- incubator/adffaces/branches/faces-1_2-070201/trinidad/pom.xml (original)
+++ incubator/adffaces/branches/faces-1_2-070201/trinidad/pom.xml Wed Feb 7 15:18:58 2007
@@ -363,7 +363,7 @@
<dependency>
<groupId>org.apache.shale</groupId>
<artifactId>shale-test</artifactId>
- <version>1.0.3</version>
+ <version>1.0.4</version>
<scope>test</scope>
<!-- Ignore the references to myfaces and the JSP API -->
<!-- We could force shale to JSF RI 1.2, but it's better
Modified: incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.java?view=diff&rev=504730&r1=504729&r2=504730
==============================================================================
--- incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.java (original)
+++ incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.java Wed Feb 7 15:18:58 2007
@@ -21,8 +21,6 @@
import java.util.ArrayList;
import java.util.List;
-import javax.faces.el.PropertyResolver;
-
/**
* Creates a TreeModel from a List of beans.
* To use this class you must have a tree of beans (or Maps).
@@ -316,8 +314,7 @@
if (prop == null)
return null;
- PropertyResolver resolver = SortableModel.__getPropertyResolver();
- return resolver.getValue(parentData, prop);
+ return SortableModel.__resolveProperty(parentData, prop);
}
/**
Modified: incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java?view=diff&rev=504730&r1=504729&r2=504730
==============================================================================
--- incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java (original)
+++ incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java Wed Feb 7 15:18:58 2007
@@ -23,10 +23,14 @@
import java.util.Comparator;
import java.util.List;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.VariableMapper;
+
import javax.faces.FactoryFinder;
import javax.faces.application.ApplicationFactory;
import javax.faces.context.FacesContext;
-import javax.faces.el.PropertyResolver;
import javax.faces.model.DataModel;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
@@ -151,9 +155,7 @@
Object data = _model.getRowData();
try
{
- PropertyResolver resolver = __getPropertyResolver();
- Object propertyValue = resolver.getValue(data, property);
-
+ Object propertyValue = __resolveProperty(data, property);
// when the value is null, we don't know if we can sort it.
// by default let's support sorting of null values, and let the user
// turn off sorting if necessary:
@@ -251,8 +253,11 @@
// Make sure the model has that row 0! (It could be empty.)
if (_model.isRowAvailable())
{
+ FacesContext context = FacesContext.getCurrentInstance();
+ ELResolver resolver = _getELResolver(context);
+ ELContext elContext = _getELContext(context, resolver);
Comparator<Integer> comp =
- new Comp(__getPropertyResolver(), property);
+ new Comp(resolver, elContext, property);
if (!isAscending)
comp = new Inverter<Integer>(comp);
@@ -331,9 +336,10 @@
private final class Comp implements Comparator<Integer>
{
- public Comp(PropertyResolver resolver, String property)
+ public Comp(ELResolver resolver, ELContext context, String property)
{
_resolver = resolver;
+ _context = context;
_prop = property;
}
@@ -345,11 +351,11 @@
_model.setRowIndex(index1);
Object instance1 = _model.getRowData();
- Object value1 = _resolver.getValue(instance1, _prop);
+ Object value1 = _resolver.getValue(_context, instance1, _prop);
_model.setRowIndex(index2);
Object instance2 = _model.getRowData();
- Object value2 = _resolver.getValue(instance2, _prop);
+ Object value2 = _resolver.getValue(_context, instance2, _prop);
if (value1 == null)
return (value2 == null) ? 0 : -1;
@@ -373,7 +379,8 @@
}
}
- private final PropertyResolver _resolver;
+ private final ELResolver _resolver;
+ private final ELContext _context;
private final String _prop;
}
@@ -392,19 +399,73 @@
private final Comparator<T> _comp;
}
- static PropertyResolver __getPropertyResolver()
+ /**
+ * Quickie implementation of ELContext for use
+ * if we're not being called in the JSF lifecycle
+ */
+ private static final class ELContextImpl extends ELContext
+ {
+ public ELContextImpl(ELResolver resolver)
+ {
+ _resolver = resolver;
+ }
+
+ @Override
+ public ELResolver getELResolver()
+ {
+ return _resolver;
+ }
+
+ @Override
+ public FunctionMapper getFunctionMapper()
+ {
+ // Because we're only really being used to pass
+ // to an ELResolver, no FunctionMapper is needed
+ return null;
+ }
+
+ @Override
+ public VariableMapper getVariableMapper()
+ {
+ // Because we're only really being used to pass
+ // to an ELResolver, no VariableMapper is needed
+ return null;
+ }
+
+ private final ELResolver _resolver;
+ }
+
+ static Object __resolveProperty(Object object, String propertyName)
{
- // First try the FacesContext, which is a faster way to
- // get the PropertyResolver (and the 99.9% scenario)
FacesContext context = FacesContext.getCurrentInstance();
+ ELResolver resolver = _getELResolver(context);
+ ELContext elContext = _getELContext(context, resolver);
+ return resolver.getValue(elContext, object, propertyName);
+ }
+
+ static private ELContext _getELContext(
+ FacesContext context, ELResolver resolver)
+ {
+ // Hopefully, we have a FacesContext. If not, we're
+ // going to have to synthesize one!
+ if (context != null)
+ return context.getELContext();
+
+ return new ELContextImpl(resolver);
+ }
+
+ static private ELResolver _getELResolver(FacesContext context)
+ {
+ // First try the FacesContext, which is a faster way to
+ // get the ELResolver (and the 99.9% scenario)
if (context != null)
- return context.getApplication().getPropertyResolver();
+ return context.getApplication().getELResolver();
// If that fails, then we're likely outside of the JSF lifecycle.
// Look to the ApplicationFactory.
ApplicationFactory factory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
- return factory.getApplication().getPropertyResolver();
+ return factory.getApplication().getELResolver();
}
Modified: incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MApplication.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MApplication.java?view=diff&rev=504730&r1=504729&r2=504730
==============================================================================
--- incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MApplication.java (original)
+++ incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MApplication.java Wed Feb 7 15:18:58 2007
@@ -25,8 +25,10 @@
import java.util.Locale;
import java.util.Map;
+import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.ELContext;
+import javax.el.MapELResolver;
import javax.el.MethodExpression;
import javax.el.MethodInfo;
import javax.el.ValueExpression;
@@ -363,6 +365,13 @@
return _exprFactory;
}
+ @Override
+ public ELResolver getELResolver()
+ {
+ return new MELResolver(
+ getVariableResolver(), getPropertyResolver());
+ }
+
private ExpressionFactory _exprFactory = new ExpressionFactory()
{
public Object coerceToType(Object obj, Class<?> targetType)
@@ -394,7 +403,8 @@
throw new UnsupportedOperationException("Not implemented yet");
}
};
-
+
+
/**
* A very rudimentary implementation, to support
* renderers that might create (but not evaluate) MethodExpressions
Added: incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MELResolver.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MELResolver.java?view=auto&rev=504730
==============================================================================
--- incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MELResolver.java (added)
+++ incubator/adffaces/branches/faces-1_2-070201/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MELResolver.java Wed Feb 7 15:18:58 2007
@@ -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.trinidadinternal.renderkit;
+
+import java.beans.FeatureDescriptor;
+
+import java.lang.reflect.Array;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.PropertyResolver;
+import javax.faces.el.VariableResolver;
+
+public class MELResolver extends ELResolver
+{
+ public MELResolver(VariableResolver vr, PropertyResolver pr)
+ {
+ _vr = vr;
+ _pr = pr;
+ }
+
+ @Override
+ public Class<?> getCommonPropertyType(ELContext context, Object base)
+ {
+ if (base == null)
+ return String.class;
+ if (_isIndexed(base))
+ return Integer.class;
+ if (base instanceof Map)
+ return Object.class;
+
+ return String.class;
+ }
+
+ @Override
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+ Object base)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Class<?> getType(ELContext context, Object base,
+ Object property)
+ {
+ if (base == null)
+ {
+ Object o = getValue(context, base, property);
+ if (o == null)
+ return null;
+ return o.getClass();
+ }
+ else
+ {
+ if (_isIndexed(base))
+ return _pr.getType(base, _getIndex(property));
+ else
+ return _pr.getType(base, property);
+ }
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base,
+ Object property)
+ {
+ if (base == null)
+ {
+ if (property == null)
+ return null;
+ FacesContext fc = (FacesContext) context.getContext(FacesContext.class);
+ return _vr.resolveVariable(fc, property.toString());
+ }
+ else
+ {
+ if (_isIndexed(base))
+ return _pr.getValue(base, _getIndex(property));
+ else
+ return _pr.getValue(base, property);
+ }
+ }
+
+ @Override
+ public boolean isReadOnly(ELContext context, Object base,
+ Object property)
+ {
+ if (base == null)
+ {
+ return true;
+ }
+ else
+ {
+ if (_isIndexed(base))
+ return _pr.isReadOnly(base, _getIndex(property));
+ else
+ return _pr.isReadOnly(base, property);
+ }
+ }
+
+ @Override
+ public void setValue(ELContext eLContext, Object base, Object property,
+ Object value)
+ {
+ if (base == null)
+ {
+ throw new PropertyNotWritableException();
+ }
+ else
+ {
+ if (_isIndexed(base))
+ _pr.setValue(base, _getIndex(property), value);
+ else
+ _pr.setValue(base, property, value);
+ }
+ }
+
+ private int _getIndex(Object property)
+ {
+ if (property == null)
+ throw new PropertyNotFoundException();
+
+ if (property instanceof Number)
+ return ((Number) property).intValue();
+ return Integer.valueOf(property.toString());
+ }
+ private boolean _isIndexed(Object base)
+ {
+ if (base == null)
+ throw new IllegalArgumentException();
+
+ if ((base instanceof List) ||
+ base.getClass().isArray())
+ return true;
+
+ return false;
+ }
+
+ private final PropertyResolver _pr;
+ private final VariableResolver _vr;
+}