001: /*
002: * Copyright 2002-2005 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;
018:
019: import javax.faces.context.FacesContext;
020: import javax.faces.el.EvaluationException;
021: import javax.faces.el.VariableResolver;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: import org.springframework.beans.factory.BeanFactory;
027: import org.springframework.util.Assert;
028: import org.springframework.web.context.WebApplicationContext;
029:
030: /**
031: * JSF VariableResolver that first delegates to the original resolver of the
032: * underlying JSF implementation, then to the Spring root WebApplicationContext.
033: *
034: * <p>Configure this resolver in your <code>faces-config.xml</code> file as follows:
035: *
036: * <pre>
037: * <application>
038: * ...
039: * <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
040: * </application></pre>
041: *
042: * All your JSF expressions can then implicitly refer to the names of
043: * Spring-managed service layer beans, for example in property values of
044: * JSF-managed beans:
045: *
046: * <pre>
047: * <managed-bean>
048: * <managed-bean-name>myJsfManagedBean</managed-bean-name>
049: * <managed-bean-class>example.MyJsfManagedBean</managed-bean-class>
050: * <managed-bean-scope>session</managed-bean-scope>
051: * <managed-property>
052: * <property-name>mySpringManagedBusinessObject</property-name>
053: * <value>#{mySpringManagedBusinessObject}</value>
054: * </managed-property>
055: * </managed-bean></pre>
056: *
057: * with "mySpringManagedBusinessObject" defined as Spring bean in
058: * applicationContext.xml:
059: *
060: * <pre>
061: * <bean id="mySpringManagedBusinessObject" class="example.MySpringManagedBusinessObject">
062: * ...
063: * </bean></pre>
064: *
065: * @author Juergen Hoeller
066: * @since 1.1
067: * @see WebApplicationContextVariableResolver
068: * @see FacesContextUtils#getRequiredWebApplicationContext
069: */
070: public class DelegatingVariableResolver extends VariableResolver {
071:
072: /** Logger available to subclasses */
073: protected final Log logger = LogFactory.getLog(getClass());
074:
075: protected final VariableResolver originalVariableResolver;
076:
077: /**
078: * Create a new DelegatingVariableResolver, using the given original VariableResolver.
079: * <p>A JSF implementation will automatically pass its original resolver into the
080: * constructor of a configured resolver, provided that there is a corresponding
081: * constructor argument.
082: * @param originalVariableResolver the original VariableResolver
083: */
084: public DelegatingVariableResolver(
085: VariableResolver originalVariableResolver) {
086: Assert.notNull(originalVariableResolver,
087: "Original JSF VariableResolver must not be null");
088: this .originalVariableResolver = originalVariableResolver;
089: }
090:
091: /**
092: * Return the original JSF VariableResolver that this resolver delegates to.
093: * Used to resolve standard JSF-managed beans.
094: */
095: protected final VariableResolver getOriginalVariableResolver() {
096: return originalVariableResolver;
097: }
098:
099: /**
100: * Delegate to the original VariableResolver first, then try to
101: * resolve the variable as Spring bean in the root WebApplicationContext.
102: */
103: public Object resolveVariable(FacesContext facesContext, String name)
104: throws EvaluationException {
105: // Ask original JSF variable resolver.
106: if (logger.isDebugEnabled()) {
107: logger.debug("Attempting to resolve variable '" + name
108: + "' in via original VariableResolver");
109: }
110: Object originalResult = getOriginalVariableResolver()
111: .resolveVariable(facesContext, name);
112: if (originalResult != null) {
113: return originalResult;
114: }
115:
116: // Ask Spring root application context.
117: if (logger.isDebugEnabled()) {
118: logger.debug("Attempting to resolve variable '" + name
119: + "' in root WebApplicationContext");
120: }
121: BeanFactory bf = getBeanFactory(facesContext);
122: if (bf.containsBean(name)) {
123: if (logger.isDebugEnabled()) {
124: logger.debug("Successfully resolved variable '" + name
125: + "' in root WebApplicationContext");
126: }
127: return bf.getBean(name);
128: }
129:
130: if (logger.isDebugEnabled()) {
131: logger.debug("Could not resolve variable '" + name + "'");
132: }
133: return null;
134: }
135:
136: /**
137: * Retrieve the Spring BeanFactory to delegate bean name resolution to.
138: * <p>Default implementation delegates to <code>getWebApplicationContext</code>.
139: * Can be overridden to provide an arbitrary BeanFactory reference to resolve
140: * against; usually, this will be a full Spring ApplicationContext.
141: * @param facesContext the current JSF context
142: * @return the Spring BeanFactory (never <code>null</code>)
143: * @see #getWebApplicationContext
144: */
145: protected BeanFactory getBeanFactory(FacesContext facesContext) {
146: return getWebApplicationContext(facesContext);
147: }
148:
149: /**
150: * Retrieve the web application context to delegate bean name resolution to.
151: * <p>Default implementation delegates to FacesContextUtils.
152: * @param facesContext the current JSF context
153: * @return the Spring web application context (never <code>null</code>)
154: * @see FacesContextUtils#getRequiredWebApplicationContext
155: */
156: protected WebApplicationContext getWebApplicationContext(
157: FacesContext facesContext) {
158: return FacesContextUtils
159: .getRequiredWebApplicationContext(facesContext);
160: }
161:
162: }
|