001: /*
002: * Copyright 2002-2007 the original author or authors.
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.springframework.web.jsf.el;
018:
019: import java.beans.FeatureDescriptor;
020: import java.util.Iterator;
021:
022: import javax.el.ELContext;
023: import javax.el.ELException;
024: import javax.el.ELResolver;
025: import javax.faces.context.FacesContext;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029:
030: import org.springframework.beans.factory.BeanFactory;
031: import org.springframework.web.context.WebApplicationContext;
032: import org.springframework.web.jsf.FacesContextUtils;
033:
034: /**
035: * JSF 1.2 <code>ELResolver</code> that delegates to the Spring root
036: * <code>WebApplicationContext</code>, resolving name references to
037: * Spring-defined beans.
038: *
039: * <p>Configure this resolver in your <code>faces-config.xml</code> file as follows:
040: *
041: * <pre>
042: * <application>
043: * ...
044: * <el-resolver>org.springframework.web.jsf.el.DelegatingFacesELResolver</el-resolver>
045: * </application></pre>
046: *
047: * All your JSF expressions can then implicitly refer to the names of
048: * Spring-managed service layer beans, for example in property values of
049: * JSF-managed beans:
050: *
051: * <pre>
052: * <managed-bean>
053: * <managed-bean-name>myJsfManagedBean</managed-bean-name>
054: * <managed-bean-class>example.MyJsfManagedBean</managed-bean-class>
055: * <managed-bean-scope>session</managed-bean-scope>
056: * <managed-property>
057: * <property-name>mySpringManagedBusinessObject</property-name>
058: * <value>#{mySpringManagedBusinessObject}</value>
059: * </managed-property>
060: * </managed-bean></pre>
061: *
062: * with "mySpringManagedBusinessObject" defined as Spring bean in
063: * applicationContext.xml:
064: *
065: * <pre>
066: * <bean id="mySpringManagedBusinessObject" class="example.MySpringManagedBusinessObject">
067: * ...
068: * </bean></pre>
069: *
070: * @author Juergen Hoeller
071: * @since 2.5
072: * @see org.springframework.web.jsf.WebApplicationContextVariableResolver
073: * @see org.springframework.web.jsf.FacesContextUtils#getRequiredWebApplicationContext
074: */
075: public class SpringBeanFacesELResolver extends ELResolver {
076:
077: /** Logger available to subclasses */
078: protected final Log logger = LogFactory.getLog(getClass());
079:
080: public Object getValue(ELContext elContext, Object base,
081: Object property) throws ELException {
082: if (base == null) {
083: // Ask Spring root application context.
084: String beanName = property.toString();
085: if (logger.isTraceEnabled()) {
086: logger.trace("Attempting to resolve variable '"
087: + beanName + "' in Spring ApplicationContext");
088: }
089: BeanFactory bf = getBeanFactory(elContext);
090: if (bf.containsBean(beanName)) {
091: if (logger.isDebugEnabled()) {
092: logger.debug("Successfully resolved variable '"
093: + beanName
094: + "' in Spring ApplicationContext");
095: }
096: elContext.setPropertyResolved(true);
097: return bf.getBean(beanName);
098: }
099: }
100:
101: return null;
102: }
103:
104: public Class<?> getType(ELContext elContext, Object base,
105: Object property) throws ELException {
106: if (base == null) {
107: // Ask Spring root application context.
108: String name = property.toString();
109: if (logger.isDebugEnabled()) {
110: logger.debug("Attempting to resolve variable '" + name
111: + "' in root WebApplicationContext");
112: }
113: BeanFactory bf = getBeanFactory(elContext);
114: if (bf.containsBean(name)) {
115: if (logger.isDebugEnabled()) {
116: logger.debug("Successfully resolved variable '"
117: + name + "' in root WebApplicationContext");
118: }
119: elContext.setPropertyResolved(true);
120: return bf.getType(name);
121: }
122: }
123:
124: return null;
125: }
126:
127: public void setValue(ELContext elContext, Object base,
128: Object property, Object value) throws ELException {
129: }
130:
131: public boolean isReadOnly(ELContext elContext, Object base,
132: Object property) throws ELException {
133: return false;
134: }
135:
136: public Iterator<FeatureDescriptor> getFeatureDescriptors(
137: ELContext elContext, Object base) {
138: return null;
139: }
140:
141: public Class<?> getCommonPropertyType(ELContext elContext,
142: Object base) {
143: return Object.class;
144: }
145:
146: /**
147: * Retrieve the Spring BeanFactory to delegate bean name resolution to.
148: * <p>The default implementation delegates to <code>getWebApplicationContext</code>.
149: * Can be overridden to provide an arbitrary BeanFactory reference to resolve
150: * against; usually, this will be a full Spring ApplicationContext.
151: * @param elContext the current JSF ELContext
152: * @return the Spring BeanFactory (never <code>null</code>)
153: * @see #getWebApplicationContext
154: */
155: protected BeanFactory getBeanFactory(ELContext elContext) {
156: return getWebApplicationContext(elContext);
157: }
158:
159: /**
160: * Retrieve the web application context to delegate bean name resolution to.
161: * <p>The default implementation delegates to FacesContextUtils.
162: * @param elContext the current JSF ELContext
163: * @return the Spring web application context (never <code>null</code>)
164: * @see org.springframework.web.jsf.FacesContextUtils#getRequiredWebApplicationContext
165: */
166: protected WebApplicationContext getWebApplicationContext(
167: ELContext elContext) {
168: FacesContext facesContext = FacesContext.getCurrentInstance();
169: return FacesContextUtils
170: .getRequiredWebApplicationContext(facesContext);
171: }
172:
173: }
|