1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.el;
20
21 import java.lang.reflect.Array;
22 import java.util.List;
23
24 import javax.el.ELContext;
25 import javax.el.ELException;
26 import javax.el.ELResolver;
27 import javax.faces.context.FacesContext;
28 import javax.faces.el.EvaluationException;
29 import javax.faces.el.PropertyNotFoundException;
30 import javax.faces.el.PropertyResolver;
31
32
33
34
35
36
37 @SuppressWarnings("deprecation")
38 public final class PropertyResolverImpl extends PropertyResolver
39 {
40
41
42
43 @Override
44 public Object getValue(final Object base, final Object property) throws EvaluationException,
45 PropertyNotFoundException
46 {
47 if (base == null)
48 {
49 return null;
50 }
51 if (property == null)
52 {
53 return null;
54 }
55 return invokeResolver(new ResolverInvoker<Object>(base, property)
56 {
57 @Override
58 public Object invoke(ELResolver resolver, ELContext context)
59 {
60 return getELResolver().getValue(getELContext(), base, property);
61 }
62 });
63 }
64
65 @Override
66 public Object getValue(final Object base, final int index) throws EvaluationException, PropertyNotFoundException
67 {
68 return getValue(base, Integer.valueOf(index));
69 }
70
71 @Override
72 public void setValue(final Object base, final Object property, final Object newValue) throws EvaluationException,
73 PropertyNotFoundException
74 {
75 if (base == null || property == null || isReadOnly (base, property))
76 {
77 throw new PropertyNotFoundException();
78 }
79
80 invokeResolver(new ResolverInvoker<Object>(base, property)
81 {
82 @Override
83 public Object invoke(ELResolver resolver, ELContext context)
84 {
85 resolver.setValue(context, base, property, newValue);
86 return null;
87 }
88
89 @Override
90 String getMessage()
91 {
92 return super.getMessage() + " newValue: '" + newValue + "'";
93 }
94 });
95 }
96
97 @Override
98 public void setValue(Object base, int index, Object newValue) throws EvaluationException, PropertyNotFoundException
99 {
100 if (base == null)
101 {
102 throw new PropertyNotFoundException();
103 }
104
105 Class baseType = base.getClass();
106 if (base instanceof Object[])
107 {
108 if (index < 0 || index >= ((Object[])base).length)
109 {
110 throw new PropertyNotFoundException();
111 }
112 setValue(base, Integer.valueOf(index), newValue);
113 }
114 else if (base instanceof List)
115 {
116 if (index < 0 || index >= ((List<?>)base).size())
117 {
118 throw new PropertyNotFoundException();
119 }
120 setValue(base, Integer.valueOf(index), newValue);
121 }
122 else if (baseType.isArray())
123 {
124 if (index < 0 || index >= Array.getLength(base))
125 {
126 throw new PropertyNotFoundException();
127 }
128 Array.set(base, index, getFacesContext().getApplication().
129 getExpressionFactory().coerceToType(newValue, baseType.getComponentType()));
130 }
131 else
132 {
133 setValue(base, Integer.valueOf(index), newValue);
134 }
135
136 }
137
138 @Override
139 public boolean isReadOnly(final Object base, final Object property)
140 {
141 return invokeResolver(new ResolverInvoker<Boolean>(base, property)
142 {
143 @Override
144 public Boolean invoke(ELResolver resolver, ELContext context)
145 {
146 return Boolean.valueOf(getELResolver().isReadOnly(getELContext(), base, property));
147 }
148 });
149 }
150
151 @Override
152 public boolean isReadOnly(final Object base, final int index)
153 {
154 return isReadOnly(base, Integer.valueOf(index));
155 }
156
157 @Override
158 public Class getType(final Object base, final Object property)
159 {
160 if (base == null || property == null)
161 {
162 throw new PropertyNotFoundException();
163 }
164
165 return invokeResolver(new ResolverInvoker<Class<?>>(base, property)
166 {
167 @Override
168 public Class<?> invoke(final ELResolver resolver, final ELContext context)
169 {
170 return resolver.getType(context, base, property);
171 }
172 });
173 }
174
175 @Override
176 public Class getType(Object base, int index)
177 {
178 if (base == null)
179 {
180 throw new PropertyNotFoundException();
181 }
182
183 if (base instanceof Object[])
184 {
185 if (index < 0 || index >= ((Object[])base).length)
186 {
187 throw new PropertyNotFoundException();
188 }
189 }
190 else if (base instanceof List)
191 {
192 if (index < 0 || index >= ((List<?>)base).size())
193 {
194 throw new PropertyNotFoundException();
195 }
196 }
197
198 return getType(base, Integer.valueOf(index));
199 }
200
201
202
203
204 ELContext getELContext()
205 {
206 return getFacesContext().getELContext();
207 }
208
209 ELResolver getELResolver()
210 {
211 return getFacesContext().getApplication().getELResolver();
212 }
213
214 FacesContext getFacesContext()
215 {
216 return FacesContext.getCurrentInstance();
217 }
218
219 <T> T invokeResolver(ResolverInvoker<T> invoker) throws EvaluationException, PropertyNotFoundException
220 {
221 try
222 {
223 return invoker.invoke(getELResolver(), getELContext());
224 }
225 catch (javax.el.PropertyNotFoundException e)
226 {
227 throw new PropertyNotFoundException("property not found: " + invoker.getMessage() + ": " + e.getMessage(),
228 e);
229 }
230 catch (ELException e)
231 {
232 throw new EvaluationException("exception: " + invoker.getMessage() + ": " + e.getMessage(), e);
233 }
234 catch (RuntimeException e)
235 {
236 throw new RuntimeException("runtime exception: " + invoker.getMessage() + ": " + e.getMessage(), e);
237 }
238 }
239
240 abstract static class ResolverInvoker<T>
241 {
242 private final Object _base;
243 private final Object _property;
244
245 ResolverInvoker(final Object base, final Object property)
246 {
247 _base = base;
248 _property = property;
249 }
250
251 abstract T invoke(ELResolver resolver, ELContext context);
252
253 String getMessage()
254 {
255 return "base: '" + _base + "' property/index: '" + _property + "'";
256 }
257 }
258 }