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.jsp.el;
031:
032: import com.caucho.el.AbstractVariableResolver;
033: import com.caucho.jsp.PageContextImpl;
034:
035: import javax.el.*;
036: import javax.servlet.jsp.el.ImplicitObjectELResolver;
037: import javax.servlet.jsp.el.ScopedAttributeELResolver;
038: import java.beans.FeatureDescriptor;
039: import java.util.ArrayList;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.util.Map;
043: import java.util.PropertyResourceBundle;
044:
045: /**
046: * Variable resolution for JSP variables
047: */
048: public class PageContextELResolver extends AbstractVariableResolver {
049: private final PageContextImpl _pageContext;
050:
051: private final ELResolver[] _customResolvers;
052:
053: private final ImplicitObjectELResolver _implicitResolver = new ImplicitObjectELResolver();
054: private final ScopedAttributeELResolver _attrResolver = new ScopedAttributeELResolver();
055:
056: private final MapELResolver _mapResolver = new MapELResolver();
057: private final ListELResolver _listResolver = new ListELResolver();
058: private final ArrayELResolver _arrayResolver = new ArrayELResolver();
059: private final ResourceBundleELResolver _bundleResolver = new ResourceBundleELResolver();
060: private final BeanELResolver _beanResolver = new BeanELResolver();
061:
062: public PageContextELResolver(PageContextImpl pageContext,
063: ELResolver[] customResolvers) {
064: _customResolvers = customResolvers;
065:
066: _pageContext = pageContext;
067: }
068:
069: public ELResolver[] getCustomResolvers() {
070: return _customResolvers;
071: }
072:
073: @Override
074: public Class<?> getCommonPropertyType(ELContext env, Object base) {
075: Class common = null;
076:
077: if (base == null)
078: common = String.class;
079:
080: for (int i = 0; i < _customResolvers.length; i++) {
081: common = common(common, _customResolvers[i]
082: .getCommonPropertyType(env, base));
083: }
084:
085: common = common(common, _mapResolver.getCommonPropertyType(env,
086: base));
087: common = common(common, _listResolver.getCommonPropertyType(
088: env, base));
089: common = common(common, _arrayResolver.getCommonPropertyType(
090: env, base));
091: common = common(common, _beanResolver.getCommonPropertyType(
092: env, base));
093: common = common(common, _bundleResolver.getCommonPropertyType(
094: env, base));
095:
096: return common;
097: }
098:
099: private static Class common(Class a, Class b) {
100: if (a == null)
101: return b;
102: else if (b == null)
103: return a;
104: else if (a.isAssignableFrom(b))
105: return a;
106: else if (b.isAssignableFrom(a))
107: return b;
108: else
109: // XXX:
110: return Object.class;
111: }
112:
113: @Override
114: public Iterator<FeatureDescriptor> getFeatureDescriptors(
115: ELContext env, Object base) {
116: ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
117:
118: for (int i = 0; i < _customResolvers.length; i++) {
119: addDescriptors(descriptors, _customResolvers[i]
120: .getFeatureDescriptors(env, base));
121: }
122:
123: addDescriptors(descriptors, _mapResolver.getFeatureDescriptors(
124: env, base));
125: addDescriptors(descriptors, _beanResolver
126: .getFeatureDescriptors(env, base));
127: addDescriptors(descriptors, _bundleResolver
128: .getFeatureDescriptors(env, base));
129: addDescriptors(descriptors, _implicitResolver
130: .getFeatureDescriptors(env, base));
131: addDescriptors(descriptors, _attrResolver
132: .getFeatureDescriptors(env, base));
133:
134: return descriptors.iterator();
135: }
136:
137: private void addDescriptors(
138: ArrayList<FeatureDescriptor> descriptors,
139: Iterator<FeatureDescriptor> iter) {
140: if (iter == null)
141: return;
142:
143: while (iter.hasNext()) {
144: FeatureDescriptor desc = iter.next();
145:
146: descriptors.add(desc);
147: }
148: }
149:
150: @Override
151: public Object getValue(ELContext env, Object base, Object property) {
152: env.setPropertyResolved(false);
153:
154: for (int i = 0; i < _customResolvers.length; i++) {
155: Object value = _customResolvers[i].getValue(env, base,
156: property);
157:
158: if (env.isPropertyResolved())
159: return value;
160: }
161:
162: if (base != null) {
163: if (base instanceof Map)
164: return _mapResolver.getValue(env, base, property);
165: else if (base instanceof List)
166: return _listResolver.getValue(env, base, property);
167: else if (base.getClass().isArray())
168: return _arrayResolver.getValue(env, base, property);
169: else if (base instanceof PropertyResourceBundle)
170: return _bundleResolver.getValue(env, base, property);
171: else
172: return _beanResolver.getValue(env, base, property);
173: } else if (property instanceof String) {
174: env.setPropertyResolved(true);
175:
176: return _pageContext.findAttribute(property.toString());
177: } else
178: return null;
179: }
180:
181: @Override
182: public boolean isReadOnly(ELContext env, Object base,
183: Object property) {
184: env.setPropertyResolved(false);
185:
186: for (int i = 0; i < _customResolvers.length; i++) {
187: boolean value = _customResolvers[i].isReadOnly(env, base,
188: property);
189:
190: if (env.isPropertyResolved())
191: return value;
192: }
193:
194: env.setPropertyResolved(true);
195:
196: return false;
197: }
198:
199: public void setValue(ELContext env, Object base, Object property,
200: Object value) {
201: env.setPropertyResolved(false);
202:
203: if (base != null) {
204: if (base instanceof Map)
205: _mapResolver.setValue(env, base, property, value);
206: else if (base instanceof List)
207: _listResolver.setValue(env, base, property, value);
208: else if (base.getClass().isArray())
209: _arrayResolver.setValue(env, base, property, value);
210: else
211: _beanResolver.setValue(env, base, property, value);
212: } else if (property instanceof String) {
213: for (int i = 0; i < _customResolvers.length; i++) {
214: _customResolvers[i]
215: .setValue(env, base, property, value);
216:
217: if (env.isPropertyResolved())
218: return;
219: }
220:
221: env.setPropertyResolved(true);
222:
223: _pageContext.setAttribute(property.toString(), value);
224: }
225: }
226: }
|