001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsf.el;
031:
032: import com.caucho.jsf.cfg.*;
033: import com.caucho.util.*;
034: import com.caucho.webbeans.el.*;
035:
036: import javax.el.*;
037: import javax.faces.component.*;
038: import javax.faces.context.*;
039:
040: import java.beans.FeatureDescriptor;
041: import java.util.*;
042:
043: /**
044: * Variable resolution for JSF variables
045: */
046: public class FacesContextELResolver extends CompositeELResolver {
047: private static final L10N L = new L10N(FacesContextELResolver.class);
048:
049: private static final ArrayList<FeatureDescriptor> _implicitFeatureDescriptors = new ArrayList<FeatureDescriptor>();
050:
051: private ELResolver[] _customResolvers;
052:
053: /*
054: private final ImplicitObjectELResolver _implicitResolver
055: = new ImplicitObjectELResolver();
056: private final ScopedAttributeELResolver _attrResolver
057: = new ScopedAttributeELResolver();
058: */
059:
060: private final MapELResolver _mapResolver = new MapELResolver();
061: private final ListELResolver _listResolver = new ListELResolver();
062: private final ArrayELResolver _arrayResolver = new ArrayELResolver();
063: private final JsfResourceBundleELResolver _jsfBundleResolver;
064: private final BeanELResolver _beanResolver = new BeanELResolver();
065: private final ResourceBundleELResolver _bundleResolver = new ResourceBundleELResolver();
066:
067: private final WebBeansELResolver _webBeansResolver = new WebBeansELResolver();
068:
069: private final ManagedBeanELResolver _managedBeanResolver = new ManagedBeanELResolver();
070:
071: public FacesContextELResolver(ELResolver[] customResolvers,
072: JsfResourceBundleELResolver jsfBundleResolver) {
073: _customResolvers = customResolvers;
074: _jsfBundleResolver = jsfBundleResolver;
075: }
076:
077: public void addManagedBean(String name,
078: ManagedBeanConfig managedBean) {
079: _managedBeanResolver.addManagedBean(name, managedBean);
080: }
081:
082: public ManagedBeanELResolver getManagedBeanResolver() {
083: return _managedBeanResolver;
084: }
085:
086: public ELResolver getResourceBundleResolver() {
087: return _jsfBundleResolver;
088: }
089:
090: public void addELResolver(ELResolver elResolver) {
091: ELResolver[] elResolvers = new ELResolver[_customResolvers.length + 1];
092:
093: System.arraycopy(_customResolvers, 0, elResolvers, 0,
094: _customResolvers.length);
095:
096: elResolvers[elResolvers.length - 1] = elResolver;
097:
098: _customResolvers = elResolvers;
099: }
100:
101: public ELResolver[] getCustomResolvers() {
102: return _customResolvers;
103: }
104:
105: @Override
106: public Class<?> getCommonPropertyType(ELContext env, Object base) {
107: Class common = null;
108:
109: if (base == null)
110: common = String.class;
111:
112: for (int i = 0; i < _customResolvers.length; i++) {
113: common = common(common, _customResolvers[i]
114: .getCommonPropertyType(env, base));
115: }
116:
117: common = common(common, _mapResolver.getCommonPropertyType(env,
118: base));
119: common = common(common, _listResolver.getCommonPropertyType(
120: env, base));
121: common = common(common, _arrayResolver.getCommonPropertyType(
122: env, base));
123: common = common(common, _beanResolver.getCommonPropertyType(
124: env, base));
125: common = common(common, _jsfBundleResolver
126: .getCommonPropertyType(env, base));
127: common = common(common, _bundleResolver.getCommonPropertyType(
128: env, base));
129:
130: return common;
131: }
132:
133: private static Class common(Class a, Class b) {
134: if (a == null)
135: return b;
136: else if (b == null)
137: return a;
138: else if (a.isAssignableFrom(b))
139: return a;
140: else if (b.isAssignableFrom(a))
141: return b;
142: else
143: // XXX:
144: return Object.class;
145: }
146:
147: @Override
148: public Iterator<FeatureDescriptor> getFeatureDescriptors(
149: ELContext env, Object base) {
150: ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
151:
152: if (base == null)
153: descriptors.addAll(_implicitFeatureDescriptors);
154:
155: for (int i = 0; i < _customResolvers.length; i++) {
156: addDescriptors(descriptors, _customResolvers[i]
157: .getFeatureDescriptors(env, base));
158: }
159:
160: if (base == null) {
161: addDescriptors(descriptors, _webBeansResolver
162: .getFeatureDescriptors(env, base));
163:
164: addDescriptors(descriptors, _managedBeanResolver
165: .getFeatureDescriptors(env, base));
166:
167: addDescriptors(descriptors, _jsfBundleResolver
168: .getFeatureDescriptors(env, base));
169: }
170:
171: addDescriptors(descriptors, _mapResolver.getFeatureDescriptors(
172: env, base));
173: addDescriptors(descriptors, _beanResolver
174: .getFeatureDescriptors(env, base));
175: addDescriptors(descriptors, _jsfBundleResolver
176: .getFeatureDescriptors(env, base));
177: /*
178: addDescriptors(descriptors,
179: _implicitResolver.getFeatureDescriptors(env, base));
180: addDescriptors(descriptors,
181: _attrResolver.getFeatureDescriptors(env, base));
182: */
183:
184: return descriptors.iterator();
185: }
186:
187: private void addDescriptors(
188: ArrayList<FeatureDescriptor> descriptors,
189: Iterator<FeatureDescriptor> iter) {
190: if (iter == null)
191: return;
192:
193: while (iter.hasNext()) {
194: FeatureDescriptor desc = iter.next();
195:
196: descriptors.add(desc);
197: }
198: }
199:
200: @Override
201: public Class getType(ELContext env, Object base, Object property) {
202: if (base != null) {
203: if (base instanceof Map)
204: return _mapResolver.getType(env, base, property);
205: else if (base instanceof List)
206: return _listResolver.getType(env, base, property);
207: else if (base.getClass().isArray())
208: return _arrayResolver.getType(env, base, property);
209: else if (base instanceof ResourceBundle)
210: return _bundleResolver.getType(env, base, property);
211: else
212: return _beanResolver.getType(env, base, property);
213: } else if (base == null && property instanceof String) {
214: ImplicitObjectExpr expr = ImplicitObjectExpr
215: .create((String) property);
216:
217: if (expr != null) {
218: env.setPropertyResolved(true);
219:
220: return Object.class;
221: }
222:
223: Class type = _jsfBundleResolver
224: .getType(env, base, property);
225:
226: if (env.isPropertyResolved())
227: return type;
228: }
229:
230: Object value = getValue(env, base, property);
231:
232: if (value != null)
233: return value.getClass();
234: else
235: return null;
236: }
237:
238: @Override
239: public Object getValue(ELContext env, Object base, Object property) {
240: env.setPropertyResolved(false);
241:
242: if (base == null && property instanceof String) {
243: ImplicitObjectExpr expr = ImplicitObjectExpr
244: .create((String) property);
245:
246: if (expr != null) {
247: env.setPropertyResolved(true);
248:
249: return expr.getValue(env);
250: }
251:
252: Object value = _jsfBundleResolver.getValue(env, base,
253: property);
254: if (env.isPropertyResolved())
255: return value;
256: }
257:
258: for (int i = 0; i < _customResolvers.length; i++) {
259: Object value = _customResolvers[i].getValue(env, base,
260: property);
261:
262: if (env.isPropertyResolved())
263: return value;
264: }
265:
266: if (base != null) {
267: if (base instanceof Map)
268: return _mapResolver.getValue(env, base, property);
269: else if (base instanceof List)
270: return _listResolver.getValue(env, base, property);
271: else if (base.getClass().isArray())
272: return _arrayResolver.getValue(env, base, property);
273: else if (base instanceof ResourceBundle)
274: return _bundleResolver.getValue(env, base, property);
275: else
276: return _beanResolver.getValue(env, base, property);
277: } else if (property instanceof String) {
278:
279: FacesContext facesContext = (FacesContext) env
280: .getContext(FacesContext.class);
281: ExternalContext ec = facesContext.getExternalContext();
282:
283: Object value = ec.getRequestMap().get(property);
284:
285: if (value != null) {
286: env.setPropertyResolved(true);
287: return value;
288: }
289:
290: value = ec.getSessionMap().get(property);
291:
292: if (value != null) {
293: env.setPropertyResolved(true);
294: return value;
295: }
296:
297: value = ec.getApplicationMap().get(property);
298:
299: if (value != null) {
300: env.setPropertyResolved(true);
301: return value;
302: }
303:
304: value = _webBeansResolver.getValue(env, base, property);
305:
306: if (env.isPropertyResolved())
307: return value;
308:
309: value = _managedBeanResolver.getValue(env, base, property);
310:
311: if (env.isPropertyResolved())
312: return value;
313:
314: return null;
315: } else
316: return null;
317: }
318:
319: @Override
320: public boolean isReadOnly(ELContext env, Object base,
321: Object property) {
322: env.setPropertyResolved(false);
323:
324: if (base != null) {
325: if (base instanceof Map) {
326: env.setPropertyResolved(true);
327:
328: return _mapResolver.isReadOnly(env, base, property);
329: } else if (base instanceof List) {
330: env.setPropertyResolved(true);
331:
332: return _listResolver.isReadOnly(env, base, property);
333: } else if (base.getClass().isArray()) {
334: env.setPropertyResolved(true);
335:
336: return _arrayResolver.isReadOnly(env, base, property);
337: } else if (base instanceof ResourceBundle) {
338: env.setPropertyResolved(true);
339:
340: return _jsfBundleResolver.isReadOnly(env, base,
341: property);
342: } else {
343: env.setPropertyResolved(true);
344:
345: return _beanResolver.isReadOnly(env, base, property);
346: }
347: } else if (base == null && property instanceof String) {
348: ImplicitObjectExpr expr = ImplicitObjectExpr
349: .create((String) property);
350:
351: if (expr != null) {
352: env.setPropertyResolved(true);
353:
354: return true;
355: }
356:
357: boolean value = _jsfBundleResolver.isReadOnly(env, base,
358: property);
359: if (env.isPropertyResolved())
360: return value;
361: }
362:
363: for (int i = 0; i < _customResolvers.length; i++) {
364: boolean value = _customResolvers[i].isReadOnly(env, base,
365: property);
366:
367: if (env.isPropertyResolved())
368: return value;
369: }
370:
371: env.setPropertyResolved(true);
372:
373: return false;
374: }
375:
376: public void setValue(ELContext env, Object base, Object property,
377: Object value) {
378: env.setPropertyResolved(false);
379:
380: if (base != null) {
381: if (base instanceof Map)
382: _mapResolver.setValue(env, base, property, value);
383: else if (base instanceof List)
384: _listResolver.setValue(env, base, property, value);
385: else if (base.getClass().isArray())
386: _arrayResolver.setValue(env, base, property, value);
387: else if (base instanceof ResourceBundle)
388: _jsfBundleResolver.setValue(env, base, property, value);
389: else
390: _beanResolver.setValue(env, base, property, value);
391: } else if (property instanceof String) {
392: String key = (String) property;
393: ImplicitObjectExpr expr = ImplicitObjectExpr.create(key);
394:
395: if (expr != null)
396: throw new PropertyNotWritableException(key);
397:
398: _jsfBundleResolver.setValue(env, base, property, value);
399: if (env.isPropertyResolved())
400: return;
401:
402: FacesContext facesContext = (FacesContext) env
403: .getContext(FacesContext.class);
404: ExternalContext ec = facesContext.getExternalContext();
405:
406: Object oldValue = ec.getRequestMap().get(key);
407:
408: if (oldValue != null) {
409: ec.getRequestMap().put(key, value);
410: env.setPropertyResolved(true);
411: return;
412: }
413:
414: oldValue = ec.getSessionMap().get(key);
415:
416: if (oldValue != null) {
417: ec.getSessionMap().put(key, value);
418: env.setPropertyResolved(true);
419: return;
420: }
421:
422: oldValue = ec.getApplicationMap().get(key);
423:
424: if (oldValue != null) {
425: ec.getApplicationMap().put(key, value);
426: env.setPropertyResolved(true);
427: return;
428: }
429:
430: ec.getRequestMap().put(key, value);
431: env.setPropertyResolved(true);
432: return;
433: }
434: }
435:
436: private static void addDescriptor(String name, Class type) {
437: FeatureDescriptor desc = new FeatureDescriptor();
438: desc.setName(name);
439: desc.setDisplayName(name);
440: desc.setExpert(false);
441: desc.setHidden(false);
442: desc.setPreferred(true);
443: desc.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME,
444: Boolean.TRUE);
445: desc.setValue(ELResolver.TYPE, type);
446:
447: _implicitFeatureDescriptors.add(desc);
448: }
449:
450: static {
451: addDescriptor("application", Object.class);
452: addDescriptor("applicationScope", Map.class);
453: addDescriptor("cookie", Map.class);
454: addDescriptor("facesContext", FacesContext.class);
455: addDescriptor("header", Map.class);
456: addDescriptor("headerValues", Map.class);
457: addDescriptor("initParam", Map.class);
458: addDescriptor("param", Map.class);
459: addDescriptor("paramValues", Map.class);
460: addDescriptor("request", Object.class);
461: addDescriptor("requestScope", Map.class);
462: addDescriptor("session", Object.class);
463: addDescriptor("sessionScope", Map.class);
464: addDescriptor("view", UIViewRoot.class);
465: }
466: }
|