001: /*
002: * Copyright 2006 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.myfaces.el.convert;
018:
019: import javax.el.ELContext;
020: import javax.el.ELException;
021: import javax.el.ELResolver;
022: import javax.el.ExpressionFactory;
023: import javax.el.PropertyNotFoundException;
024: import javax.el.PropertyNotWritableException;
025: import javax.faces.FactoryFinder;
026: import javax.faces.application.ApplicationFactory;
027: import javax.faces.el.EvaluationException;
028: import javax.faces.el.PropertyResolver;
029:
030: import java.beans.FeatureDescriptor;
031: import java.util.Iterator;
032: import java.util.List;
033:
034: /**
035: * Wrapper that converts a VariableResolver into an ELResolver. See JSF 1.2 spec section 5.6.1.6
036: *
037: * @author Stan Silvert (latest modification by $Author$)
038: * @author Mathias Broekelmann
039: * @version $Revision$ $Date$
040: */
041: @SuppressWarnings("deprecation")
042: public class PropertyResolverToELResolver extends ELResolver {
043: private PropertyResolver propertyResolver;
044:
045: private ExpressionFactory expressionFactory;
046:
047: /**
048: * Creates a new instance of PropertyResolverToELResolver
049: */
050: public PropertyResolverToELResolver(
051: PropertyResolver propertyResolver) {
052: this .propertyResolver = propertyResolver;
053: }
054:
055: @Override
056: public void setValue(ELContext context, Object base,
057: Object property, final Object value)
058: throws NullPointerException, PropertyNotFoundException,
059: PropertyNotWritableException, ELException {
060: invoke(context, base, property, new ResolverInvoker<Object>() {
061: @Override
062: public Object invoke(Object base, Object property) {
063: if (needsCoersion(base)) {
064: propertyResolver.setValue(base,
065: coerceToInt(property), value);
066: } else {
067: propertyResolver.setValue(base, property, value);
068: }
069: return null;
070: }
071: });
072: }
073:
074: @Override
075: public boolean isReadOnly(ELContext context, Object base,
076: Object property) throws NullPointerException,
077: PropertyNotFoundException, ELException {
078: return invoke(context, base, property,
079: new ResolverInvoker<Boolean>() {
080: @Override
081: public Boolean invoke(Object base, Object property) {
082: if (needsCoersion(base)) {
083: return propertyResolver.isReadOnly(base,
084: coerceToInt(property));
085: }
086: return propertyResolver.isReadOnly(base,
087: property);
088: }
089:
090: @Override
091: Boolean getValueIfBaseAndPropertyIsNull() {
092: return true;
093: }
094: });
095: }
096:
097: @Override
098: public Object getValue(ELContext context, Object base,
099: Object property) throws NullPointerException,
100: PropertyNotFoundException, ELException {
101: return invoke(context, base, property,
102: new ResolverInvoker<Object>() {
103: @Override
104: Object invoke(Object base, Object property) {
105: if (needsCoersion(base)) {
106: return propertyResolver.getValue(base,
107: coerceToInt(property));
108: }
109: return propertyResolver
110: .getValue(base, property);
111: }
112: });
113: }
114:
115: @Override
116: public Class<?> getType(ELContext context, Object base,
117: Object property) throws NullPointerException,
118: PropertyNotFoundException, ELException {
119: return invoke(context, base, property,
120: new ResolverInvoker<Class<?>>() {
121: @Override
122: Class<?> invoke(Object base, Object property) {
123: if (needsCoersion(base)) {
124: return propertyResolver.getType(base,
125: coerceToInt(property));
126: }
127:
128: return propertyResolver.getType(base, property);
129: }
130: });
131: }
132:
133: @Override
134: public Iterator<FeatureDescriptor> getFeatureDescriptors(
135: ELContext context, Object base) {
136: return null;
137: }
138:
139: @Override
140: public Class<?> getCommonPropertyType(ELContext context, Object base) {
141:
142: if (base == null)
143: return null;
144:
145: return Object.class;
146: }
147:
148: private boolean needsCoersion(Object base) {
149: return (base instanceof List) || base.getClass().isArray();
150: }
151:
152: protected ExpressionFactory getExpressionFactory() {
153: if (expressionFactory == null) {
154: ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder
155: .getFactory(FactoryFinder.APPLICATION_FACTORY);
156: expressionFactory = appFactory.getApplication()
157: .getExpressionFactory();
158: }
159: return expressionFactory;
160: }
161:
162: public void setExpressionFactory(ExpressionFactory expressionFactory) {
163: this .expressionFactory = expressionFactory;
164: }
165:
166: private int coerceToInt(Object property) {
167: Integer coerced = (Integer) getExpressionFactory()
168: .coerceToType(property, Integer.class);
169: return coerced.intValue();
170: }
171:
172: private <T> T invoke(ELContext context, Object base,
173: Object property, ResolverInvoker<T> invoker)
174: throws PropertyNotFoundException, ELException {
175: if (base == null || property == null) {
176: return invoker.getValueIfBaseAndPropertyIsNull();
177: }
178:
179: try {
180: context.setPropertyResolved(true);
181: return invoker.invoke(base, property);
182: } catch (javax.faces.el.PropertyNotFoundException e) {
183: context.setPropertyResolved(false);
184: throw new PropertyNotFoundException(e.getMessage(), e);
185: } catch (EvaluationException e) {
186: context.setPropertyResolved(false);
187: throw new ELException(e.getMessage(), e);
188: } catch (RuntimeException e) {
189: context.setPropertyResolved(false);
190: throw e;
191: }
192: }
193:
194: private abstract class ResolverInvoker<T> {
195: abstract T invoke(Object base, Object property)
196: throws PropertyNotFoundException, EvaluationException,
197: RuntimeException;
198:
199: T getValueIfBaseAndPropertyIsNull() {
200: return null;
201: }
202: }
203:
204: public PropertyResolver getPropertyResolver() {
205: return propertyResolver;
206: }
207: }
|