Source code: com/sun/facelets/impl/DefaultFaceletContext.java
1 /**
2 * Licensed under the Common Development and Distribution License,
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.sun.com/cddl/
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15 package com.sun.facelets.impl;
16
17 import java.io.IOException;
18 import java.net.URL;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import javax.el.ELContext;
29 import javax.el.ELException;
30 import javax.el.ELResolver;
31 import javax.el.ExpressionFactory;
32 import javax.el.FunctionMapper;
33 import javax.el.ValueExpression;
34 import javax.el.VariableMapper;
35 import javax.faces.FacesException;
36 import javax.faces.component.UIComponent;
37 import javax.faces.context.FacesContext;
38
39 import com.sun.facelets.Facelet;
40 import com.sun.facelets.FaceletContext;
41 import com.sun.facelets.FaceletException;
42 import com.sun.facelets.FaceletHandler;
43 import com.sun.facelets.TemplateClient;
44 import com.sun.facelets.el.DefaultVariableMapper;
45 import com.sun.facelets.el.ELAdaptor;
46
47 /**
48 * Default FaceletContext implementation.
49 *
50 * A single FaceletContext is used for all Facelets involved in an invocation of
51 * {@link com.sun.facelets.Facelet#apply(FacesContext, UIComponent) Facelet#apply(FacesContext, UIComponent)}.
52 * This means that included Facelets are treated the same as the JSP include
53 * directive.
54 *
55 * @author Jacob Hookom
56 * @version $Id: DefaultFaceletContext.java,v 1.4.4.3 2006/03/25 01:01:53 jhook
57 * Exp $
58 */
59 final class DefaultFaceletContext extends FaceletContext {
60
61 private final FacesContext faces;
62
63 private final ELContext ctx;
64
65 private final DefaultFacelet facelet;
66
67 private VariableMapper varMapper;
68
69 private FunctionMapper fnMapper;
70
71 private final Map ids;
72
73 public DefaultFaceletContext(DefaultFaceletContext ctx,
74 DefaultFacelet facelet) {
75 this.ctx = ctx.ctx;
76 this.facelet = facelet;
77 this.clients = ctx.clients;
78 this.faces = ctx.faces;
79 this.fnMapper = ctx.fnMapper;
80 this.ids = ctx.ids;
81 this.varMapper = ctx.varMapper;
82 }
83
84 public DefaultFaceletContext(FacesContext faces, DefaultFacelet facelet) {
85 this.ctx = ELAdaptor.getELContext(faces);
86 this.ids = new HashMap();
87 this.clients = new ArrayList(5);
88 this.faces = faces;
89 this.facelet = facelet;
90 this.varMapper = this.ctx.getVariableMapper();
91 if (this.varMapper == null) {
92 this.varMapper = new DefaultVariableMapper();
93 }
94 this.fnMapper = this.ctx.getFunctionMapper();
95 }
96
97 /*
98 * (non-Javadoc)
99 *
100 * @see com.sun.facelets.FaceletContext#getFacesContext()
101 */
102 public FacesContext getFacesContext() {
103 return this.faces;
104 }
105
106 /*
107 * (non-Javadoc)
108 *
109 * @see com.sun.facelets.FaceletContext#getExpressionFactory()
110 */
111 public ExpressionFactory getExpressionFactory() {
112 return this.facelet.getExpressionFactory();
113 }
114
115 /*
116 * (non-Javadoc)
117 *
118 * @see com.sun.facelets.FaceletContext#setVariableMapper(javax.el.VariableMapper)
119 */
120 public void setVariableMapper(VariableMapper varMapper) {
121 // Assert.param("varMapper", varMapper);
122 this.varMapper = varMapper;
123 }
124
125 /*
126 * (non-Javadoc)
127 *
128 * @see com.sun.facelets.FaceletContext#setFunctionMapper(javax.el.FunctionMapper)
129 */
130 public void setFunctionMapper(FunctionMapper fnMapper) {
131 // Assert.param("fnMapper", fnMapper);
132 this.fnMapper = fnMapper;
133 }
134
135 /*
136 * (non-Javadoc)
137 *
138 * @see com.sun.facelets.FaceletContext#includeFacelet(javax.faces.component.UIComponent,
139 * java.lang.String)
140 */
141 public void includeFacelet(UIComponent parent, String relativePath)
142 throws IOException, FaceletException, FacesException, ELException {
143 this.facelet.include(this, parent, relativePath);
144 }
145
146 /*
147 * (non-Javadoc)
148 *
149 * @see javax.el.ELContext#getFunctionMapper()
150 */
151 public FunctionMapper getFunctionMapper() {
152 return this.fnMapper;
153 }
154
155 /*
156 * (non-Javadoc)
157 *
158 * @see javax.el.ELContext#getVariableMapper()
159 */
160 public VariableMapper getVariableMapper() {
161 return this.varMapper;
162 }
163
164 /*
165 * (non-Javadoc)
166 *
167 * @see javax.el.ELContext#getContext(java.lang.Class)
168 */
169 public Object getContext(Class key) {
170 return this.ctx.getContext(key);
171 }
172
173 /*
174 * (non-Javadoc)
175 *
176 * @see javax.el.ELContext#putContext(java.lang.Class, java.lang.Object)
177 */
178 public void putContext(Class key, Object contextObject) {
179 this.ctx.putContext(key, contextObject);
180 }
181
182 /*
183 * (non-Javadoc)
184 *
185 * @see com.sun.facelets.FaceletContext#generateUniqueId(java.lang.String)
186 */
187 public String generateUniqueId(String base) {
188 Integer cnt = (Integer) this.ids.get(base);
189 if (cnt == null) {
190 this.ids.put(base, new Integer(0));
191 return base;
192 } else {
193 int i = cnt.intValue() + 1;
194 this.ids.put(base, new Integer(i));
195 return base + "_" + i;
196 }
197 }
198
199 /*
200 * (non-Javadoc)
201 *
202 * @see com.sun.facelets.FaceletContext#getAttribute(java.lang.String)
203 */
204 public Object getAttribute(String name) {
205 if (this.varMapper != null) {
206 ValueExpression ve = this.varMapper.resolveVariable(name);
207 if (ve != null) {
208 return ve.getValue(this);
209 }
210 }
211 return null;
212 }
213
214 /*
215 * (non-Javadoc)
216 *
217 * @see com.sun.facelets.FaceletContext#setAttribute(java.lang.String,
218 * java.lang.Object)
219 */
220 public void setAttribute(String name, Object value) {
221 if (this.varMapper != null) {
222 if (value == null) {
223 this.varMapper.setVariable(name, null);
224 } else {
225 this.varMapper.setVariable(name, this.facelet
226 .getExpressionFactory().createValueExpression(value,
227 Object.class));
228 }
229 }
230 }
231
232 /*
233 * (non-Javadoc)
234 *
235 * @see com.sun.facelets.FaceletContext#includeFacelet(javax.faces.component.UIComponent,
236 * java.net.URL)
237 */
238 public void includeFacelet(UIComponent parent, URL absolutePath)
239 throws IOException, FaceletException, FacesException, ELException {
240 this.facelet.include(this, parent, absolutePath);
241 }
242
243 public ELResolver getELResolver() {
244 return this.ctx.getELResolver();
245 }
246
247 private final List clients;
248
249 public void popClient(TemplateClient client) {
250 if (!this.clients.isEmpty()) {
251 Iterator itr = this.clients.iterator();
252 while (itr.hasNext()) {
253 if (itr.next().equals(client)) {
254 itr.remove();
255 return;
256 }
257 }
258 }
259 throw new IllegalStateException(client + " not found");
260 }
261
262 public void pushClient(final TemplateClient client) {
263 this.clients.add(0, new TemplateManager(this.facelet, client));
264 }
265
266 public void extendClient(final TemplateClient client) {
267 this.clients.add(new TemplateManager(this.facelet, client));
268 }
269
270 public boolean includeDefinition(UIComponent parent, String name)
271 throws IOException, FaceletException, FacesException, ELException {
272 boolean found = false;
273 TemplateClient client;
274
275 for (int i = 0; i < this.clients.size() && found == false; i++) {
276 client = ((TemplateClient) this.clients.get(i));
277 if (client.equals(this.facelet))
278 continue;
279 found = client.apply(this, parent, name);
280 }
281
282 return found;
283 }
284
285 private final static class TemplateManager implements TemplateClient {
286 private final DefaultFacelet owner;
287
288 private final TemplateClient target;
289
290 private final Set names = new HashSet();
291
292 public TemplateManager(DefaultFacelet owner, TemplateClient target) {
293 this.owner = owner;
294 this.target = target;
295 }
296
297 public boolean apply(FaceletContext ctx, UIComponent parent, String name)
298 throws IOException, FacesException, FaceletException,
299 ELException {
300 String testName = (name != null) ? name : "facelets._NULL_DEF_";
301 if (this.names.contains(testName)) {
302 return false;
303 } else {
304 this.names.add(testName);
305 boolean found = false;
306 found = this.target.apply(new DefaultFaceletContext(
307 (DefaultFaceletContext) ctx, this.owner), parent, name);
308 this.names.remove(testName);
309 return found;
310 }
311 }
312
313 public boolean equals(Object o) {
314 // System.out.println(this.owner.getAlias() + " == " +
315 // ((DefaultFacelet) o).getAlias());
316 return this.owner == o || this.target == o;
317 }
318 }
319 }