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.el.AbstractVariableResolver;
033: import com.caucho.jsp.el.*;
034: import com.caucho.jsf.cfg.*;
035: import com.caucho.util.*;
036:
037: import javax.el.*;
038: import javax.faces.application.*;
039: import javax.faces.component.*;
040: import javax.faces.context.*;
041: import javax.servlet.*;
042: import javax.servlet.http.*;
043:
044: import java.beans.FeatureDescriptor;
045: import java.util.*;
046:
047: /**
048: * Variable resolution for JSF managed beans
049: */
050: public class ManagedBeanELResolver extends ELResolver {
051: private static final L10N L = new L10N(ManagedBeanELResolver.class);
052:
053: private final HashMap<String, ManagedBeanConfig> _managedBeanMap = new HashMap<String, ManagedBeanConfig>();
054:
055: private HashSet<String> _managedBeanInitSet;
056:
057: public ManagedBeanELResolver() {
058: }
059:
060: public void addManagedBean(String name,
061: ManagedBeanConfig managedBean) {
062: _managedBeanMap.put(name, managedBean);
063: }
064:
065: @Override
066: public Iterator<FeatureDescriptor> getFeatureDescriptors(
067: ELContext env, Object base) {
068: ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
069:
070: return descriptors.iterator();
071: }
072:
073: @Override
074: public Class getType(ELContext env, Object base, Object property) {
075: if (base == null && property instanceof String) {
076: String key = property.toString();
077:
078: if (_managedBeanMap.get(key) != null) {
079: env.setPropertyResolved(true);
080:
081: return Object.class;
082: }
083: }
084:
085: return null;
086: }
087:
088: @Override
089: public Object getValue(ELContext env, Object base, Object property) {
090: if (base == null && property instanceof String) {
091: String key = property.toString();
092:
093: ManagedBeanConfig managedBean = _managedBeanMap.get(key);
094:
095: if (managedBean != null) {
096: env.setPropertyResolved(true);
097:
098: FacesContext facesContext = FacesContext
099: .getCurrentInstance();
100:
101: ExternalContext extContext = facesContext
102: .getExternalContext();
103:
104: Map requestMap = extContext.getRequestMap();
105: Object value = requestMap.get(key);
106:
107: if (value != null)
108: return value;
109:
110: value = extContext.getSessionMap().get(key);
111:
112: if (value != null)
113: return value;
114:
115: value = extContext.getApplicationMap().get(key);
116:
117: if (value != null)
118: return value;
119:
120: Scope oldScope = (Scope) env.getContext(Scope.class);
121: Scope scope = oldScope;
122:
123: if (scope == null) {
124: scope = new Scope();
125: env.putContext(Scope.class, scope);
126: }
127:
128: int oldScopeValue = scope.getScope();
129:
130: try {
131: if (scope.containsBean(key))
132: throw new ELException(
133: L
134: .l(
135: "'{0}' is a circular managed bean reference.",
136: key));
137:
138: scope.addBean(key);
139:
140: return managedBean.create(facesContext, scope);
141: } finally {
142: scope.removeBean(key);
143: scope.setScope(oldScopeValue);
144: env.putContext(Scope.class, oldScope);
145: }
146: }
147: }
148:
149: return null;
150: }
151:
152: @Override
153: public boolean isReadOnly(ELContext env, Object base,
154: Object property) {
155: if (base == null && property instanceof String) {
156: String key = property.toString();
157:
158: ManagedBeanConfig managedBean = _managedBeanMap.get(key);
159:
160: if (managedBean != null) {
161: env.setPropertyResolved(true);
162:
163: return true;
164: }
165: }
166:
167: return false;
168: }
169:
170: @Override
171: public Class getCommonPropertyType(ELContext env, Object base) {
172: if (base == null)
173: return Object.class;
174: else
175: return null;
176: }
177:
178: @Override
179: public void setValue(ELContext env, Object base, Object property,
180: Object value) {
181: if (base == null && property instanceof String) {
182: String key = property.toString();
183:
184: ManagedBeanConfig managedBean = _managedBeanMap.get(key);
185:
186: if (managedBean != null) {
187: throw new PropertyNotWritableException(L.l(
188: "Managed bean ${{0}} is not writable", key));
189: }
190: }
191: }
192:
193: public static class Scope {
194: private int _scope = Integer.MAX_VALUE;
195:
196: private HashSet<String> _initSet = new HashSet<String>();
197:
198: public int getScope() {
199: return _scope;
200: }
201:
202: public int setScope(int scope) {
203: int oldScope = _scope;
204:
205: _scope = scope;
206:
207: return oldScope;
208: }
209:
210: public boolean containsBean(String name) {
211: return _initSet.contains(name);
212: }
213:
214: public void addBean(String name) {
215: _initSet.add(name);
216: }
217:
218: public void removeBean(String name) {
219: _initSet.remove(name);
220: }
221: }
222: }
|