KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > executor > jsf > FlowPropertyResolver


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.executor.jsf;
17
18 import javax.faces.context.FacesContext;
19 import javax.faces.el.EvaluationException;
20 import javax.faces.el.PropertyNotFoundException;
21 import javax.faces.el.PropertyResolver;
22 import javax.faces.el.ReferenceSyntaxException;
23
24 import org.springframework.util.Assert;
25 import org.springframework.web.context.WebApplicationContext;
26 import org.springframework.web.jsf.FacesContextUtils;
27 import org.springframework.webflow.execution.FlowExecution;
28
29 /**
30  * Custom property resolve that resolves active flow session scope properties
31  * from a thread bound flow execution.
32  * <p>
33  * TODO: this class probably needs to delegate to a strategy object pulled out
34  * of the appcontext, to provide ability to override and configure, as JSF
35  * provides no other way to customize and configure this instance.
36  *
37  * @author Colin Sampaleanu
38  */

39 public class FlowPropertyResolver extends PropertyResolver {
40
41     /**
42      * The standard property resolver to delegate to if this one doesn't apply.
43      */

44     private final PropertyResolver resolverDelegate;
45
46     /**
47      * Create a new PropertyResolver, using the given original PropertyResolver.
48      * <p>
49      * A JSF implementation will automatically pass its original resolver into
50      * the constructor of a configured resolver, provided that there is a
51      * corresponding constructor argument.
52      *
53      * @param resolverDelegate the original VariableResolver
54      */

55     public FlowPropertyResolver(PropertyResolver resolverDelegate) {
56         this.resolverDelegate = resolverDelegate;
57     }
58
59     public Class JavaDoc getType(Object JavaDoc base, int index) throws EvaluationException, PropertyNotFoundException {
60         if (!(base instanceof FlowExecution)) {
61             return resolverDelegate.getType(base, index);
62         }
63         else {
64             // can't access flow scope by index, so can't determine type. Return
65
// null per JSF spec
66
return null;
67         }
68     }
69
70     public Class JavaDoc getType(Object JavaDoc base, Object JavaDoc property) throws EvaluationException, PropertyNotFoundException {
71         if (!(base instanceof FlowExecution)) {
72             return resolverDelegate.getType(base, property);
73         }
74         if (property == null) {
75             throw new PropertyNotFoundException("Unable to get value from Flow, as property (key) is null");
76         }
77         if (!(property instanceof String JavaDoc)) {
78             throw new PropertyNotFoundException("Unable to get value from Flow map, as key is non-String");
79         }
80         FlowExecution execution = (FlowExecution)base;
81         // we want to access flow scope of the active session (conversation)
82
Object JavaDoc value = execution.getActiveSession().getScope().get((String JavaDoc)property);
83         // note that MyFaces returns Object.class for a null value here, but
84
// as I read the JSF spec, null should be returned when the object
85
// type can not be determined this certainly seems to be the case
86
// for a map value which doesn' even exist
87
return (value == null) ? null : value.getClass();
88     }
89
90     public Object JavaDoc getValue(Object JavaDoc base, int index) throws EvaluationException, PropertyNotFoundException {
91         if (!(base instanceof FlowExecution)) {
92             return resolverDelegate.getValue(base, index);
93         }
94         else {
95             throw new ReferenceSyntaxException("Cannot apply an index value to Flow map");
96         }
97     }
98
99     public Object JavaDoc getValue(Object JavaDoc base, Object JavaDoc property) throws EvaluationException, PropertyNotFoundException {
100         if (!(base instanceof FlowExecution)) {
101             return resolverDelegate.getValue(base, property);
102         }
103         if (!(property instanceof String JavaDoc)) {
104             throw new PropertyNotFoundException("Unable to get value from Flow map, as key is non-String");
105         }
106         FlowExecution execution = (FlowExecution)base;
107         String JavaDoc attributeName = (String JavaDoc)property;
108         Object JavaDoc value = execution.getActiveSession().getScope().get(attributeName);
109         if (value == null) {
110             FacesContext context = FacesContext.getCurrentInstance();
111             Assert.notNull(context, "FacesContext must exist during property resolution stage");
112             WebApplicationContext wac = getWebApplicationContext(context);
113             if (wac.containsBean(attributeName)) {
114                 // note: this resolver doesn't care, but this should normally be
115
// either a stateless singleton bean, or a stateful/stateless
116
// prototype
117
value = wac.getBean(attributeName);
118                 execution.getActiveSession().getScope().put(attributeName, value);
119             }
120         }
121         return value;
122     }
123
124     public boolean isReadOnly(Object JavaDoc base, int index) throws EvaluationException, PropertyNotFoundException {
125         if (!(base instanceof FlowExecution)) {
126             return resolverDelegate.isReadOnly(base, index);
127         }
128         return false;
129     }
130
131     public boolean isReadOnly(Object JavaDoc base, Object JavaDoc property) throws EvaluationException, PropertyNotFoundException {
132         if (!(base instanceof FlowExecution)) {
133             return resolverDelegate.isReadOnly(base, property);
134         }
135         return false;
136     }
137
138     public void setValue(Object JavaDoc base, int index, Object JavaDoc value) throws EvaluationException, PropertyNotFoundException {
139         if (!(base instanceof FlowExecution)) {
140             resolverDelegate.setValue(base, index, value);
141         }
142         throw new ReferenceSyntaxException("Can not apply an index value to Flow map");
143     }
144
145     public void setValue(Object JavaDoc base, Object JavaDoc property, Object JavaDoc value) throws EvaluationException,
146             PropertyNotFoundException {
147         if (!(base instanceof FlowExecution)) {
148             resolverDelegate.setValue(base, property, value);
149             return;
150         }
151         if (property == null || !(property instanceof String JavaDoc)
152                 || (property instanceof String JavaDoc && ((String JavaDoc)property).length() == 0)) {
153             throw new PropertyNotFoundException(
154                     "Attempt to set Flow attribute with null name, empty name, or non-String name");
155         }
156         FlowExecution execution = (FlowExecution)base;
157         execution.getActiveSession().getScope().put((String JavaDoc)property, value);
158     }
159
160     /**
161      * Retrieve the web application context to delegate bean name resolution to.
162      * <p>
163      * Default implementation delegates to FacesContextUtils.
164      *
165      * @param facesContext the current JSF context
166      * @return the Spring web application context (never <code>null</code>)
167      * @see FacesContextUtils#getRequiredWebApplicationContext
168      */

169     protected WebApplicationContext getWebApplicationContext(FacesContext facesContext) {
170         return FacesContextUtils.getRequiredWebApplicationContext(facesContext);
171     }
172 }
Popular Tags