1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.tiles.jsp.context;
23
24 import java.io.IOException;
25 import java.io.StringWriter;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import javax.servlet.jsp.JspContext;
30 import javax.servlet.jsp.JspException;
31 import javax.servlet.jsp.PageContext;
32 import javax.servlet.jsp.tagext.JspFragment;
33
34 import org.apache.tiles.ArrayStack;
35 import org.apache.tiles.TilesContainer;
36 import org.apache.tiles.access.TilesAccess;
37 import org.apache.tiles.impl.NoSuchContainerException;
38 import org.apache.tiles.jsp.taglib.TilesJspException;
39 import org.apache.tiles.servlet.context.ServletUtil;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /***
44 * Utility class for working within a Jsp environment.
45 *
46 * @version $Rev: 797765 $ $Date: 2009-07-25 15:20:26 +0200 (sab, 25 lug 2009) $
47 */
48 public final class JspUtil {
49
50 /***
51 * The name of the attribute that will contain the compose stack.
52 */
53 public static final String COMPOSE_STACK_ATTRIBUTE_NAME = "org.apache.tiles.template.COMPOSE_STACK";
54
55 /***
56 * Maps scope names to their constants.
57 */
58 private static final Map<String, Integer> SCOPES =
59 new HashMap<String, Integer>();
60
61 static {
62 JspUtil.SCOPES.put("page", PageContext.PAGE_SCOPE);
63 JspUtil.SCOPES.put("request", PageContext.REQUEST_SCOPE);
64 JspUtil.SCOPES.put("session", PageContext.SESSION_SCOPE);
65 JspUtil.SCOPES.put("application", PageContext.APPLICATION_SCOPE);
66 }
67
68 /***
69 * Constructor, private to avoid instantiation.
70 */
71 private JspUtil() {
72 }
73
74 /***
75 * Returns true if forced include of the result is needed.
76 *
77 * @param context The page context.
78 * @return If <code>true</code> the include operation must be forced.
79 * @since 2.0.6
80 */
81 public static boolean isForceInclude(JspContext context) {
82 Boolean retValue = (Boolean) context.getAttribute(
83 ServletUtil.FORCE_INCLUDE_ATTRIBUTE_NAME,
84 PageContext.REQUEST_SCOPE);
85 return retValue != null && retValue.booleanValue();
86 }
87
88 /***
89 * Sets the option that enables the forced include of the response.
90 *
91 * @param context The page context.
92 * @param forceInclude If <code>true</code> the include operation must be
93 * forced.
94 * @since 2.0.6
95 */
96 public static void setForceInclude(JspContext context, boolean forceInclude) {
97 Boolean retValue = Boolean.valueOf(forceInclude);
98 context.setAttribute(
99 ServletUtil.FORCE_INCLUDE_ATTRIBUTE_NAME,
100 retValue, PageContext.REQUEST_SCOPE);
101 }
102
103 /***
104 * Returns the default Tiles container.
105 *
106 * @param context The page context to use.
107 * @return The default Tiles container.
108 * @since 2.1.2
109 */
110 public static TilesContainer getContainer(JspContext context) {
111 return getContainer(context, TilesAccess.CONTAINER_ATTRIBUTE);
112 }
113
114 /***
115 * Returns a specific Tiles container.
116 *
117 * @param context The page context to use.
118 * @param key The key under which the container is stored. If null, the
119 * default container will be returned.
120 * @return The requested Tiles container.
121 * @since 2.1.2
122 */
123 public static TilesContainer getContainer(JspContext context, String key) {
124 if (key == null) {
125 key = TilesAccess.CONTAINER_ATTRIBUTE;
126 }
127 return (TilesContainer) context.getAttribute(key,
128 PageContext.APPLICATION_SCOPE);
129 }
130
131 /***
132 * Configures the default container to be used in the application.
133 *
134 * @param context The page context object to use.
135 * @param container The container object to set.
136 * @since 2.1.2
137 */
138 public static void setContainer(JspContext context,
139 TilesContainer container) {
140 setContainer(context, container, TilesAccess.CONTAINER_ATTRIBUTE);
141 }
142
143 /***
144 * Configures the container to be used in the application.
145 *
146 * @param context The page context object to use.
147 * @param container The container object to set.
148 * @param key The key under which the container will be stored.
149 * @since 2.1.2
150 */
151 public static void setContainer(JspContext context,
152 TilesContainer container, String key) {
153 Logger log = LoggerFactory.getLogger(ServletUtil.class);
154 if (key == null) {
155 key = TilesAccess.CONTAINER_ATTRIBUTE;
156 }
157
158 if (container == null) {
159 if (log.isInfoEnabled()) {
160 log.info("Removing TilesContext for context: " + context.getClass().getName());
161 }
162 context.removeAttribute(key, PageContext.APPLICATION_SCOPE);
163 }
164 if (container != null && log.isInfoEnabled()) {
165 log.info("Publishing TilesContext for context: " + context.getClass().getName());
166 }
167 context.setAttribute(key, container, PageContext.APPLICATION_SCOPE);
168 }
169
170 /***
171 * Sets the current container to use in web pages.
172 *
173 * @param context The page context to use.
174 * @param key The key under which the container is stored.
175 * @since 2.1.0
176 */
177 public static void setCurrentContainer(JspContext context, String key) {
178 TilesContainer container = getContainer(context, key);
179 if (container != null) {
180 context.setAttribute(ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME,
181 container, PageContext.REQUEST_SCOPE);
182 } else {
183 throw new NoSuchContainerException("The container with the key '"
184 + key + "' cannot be found");
185 }
186 }
187
188 /***
189 * Sets the current container to use in web pages.
190 *
191 * @param context The page context to use.
192 * @param container The container to use as the current container.
193 * @since 2.1.0
194 */
195 public static void setCurrentContainer(JspContext context,
196 TilesContainer container) {
197 if (container != null) {
198 context.setAttribute(ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME,
199 container, PageContext.REQUEST_SCOPE);
200 } else {
201 throw new NoSuchContainerException("The container cannot be null");
202 }
203 }
204
205 /***
206 * Returns the current container that has been set, or the default one.
207 *
208 * @param context The page context to use.
209 * @return The current Tiles container to use in web pages.
210 * @since 2.1.0
211 */
212 public static TilesContainer getCurrentContainer(JspContext context) {
213 TilesContainer container = (TilesContainer) context.getAttribute(
214 ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME,
215 PageContext.REQUEST_SCOPE);
216 if (container == null) {
217 container = getContainer(context);
218 context.setAttribute(ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME,
219 container, PageContext.REQUEST_SCOPE);
220 }
221
222 return container;
223 }
224
225 /***
226 * Returns the compose stack, that is used by the tags to compose
227 * definitions, attributes, etc.
228 *
229 * @param context The page context.
230 * @return The compose stack.
231 * @since 2.2.0
232 */
233 @SuppressWarnings("unchecked")
234 public static ArrayStack<Object> getComposeStack(JspContext context) {
235 ArrayStack<Object> composeStack = (ArrayStack<Object>) context.getAttribute(
236 COMPOSE_STACK_ATTRIBUTE_NAME, PageContext.REQUEST_SCOPE);
237 if (composeStack == null) {
238 composeStack = new ArrayStack<Object>();
239 context.setAttribute(COMPOSE_STACK_ATTRIBUTE_NAME, composeStack,
240 PageContext.REQUEST_SCOPE);
241 }
242 return composeStack;
243 }
244
245 /***
246 * Converts the scope name into its corresponding PageContext constant value.
247 *
248 * @param scopeName Can be "page", "request", "session", or "application" in any
249 * case.
250 * @return The constant representing the scope (ie. PageContext.REQUEST_SCOPE).
251 * @throws TilesJspException if the scopeName is not a valid name.
252 * @since 2.2.0
253 */
254 public static int getScope(String scopeName) throws TilesJspException {
255 if (scopeName == null) {
256 return PageContext.PAGE_SCOPE;
257 }
258
259 Integer scope = JspUtil.SCOPES.get(scopeName.toLowerCase());
260
261 if (scope == null) {
262 throw new TilesJspException("Unable to retrieve the scope "
263 + scopeName);
264 }
265
266 return scope;
267 }
268
269 /***
270 * Evaluates the fragment (invokes it with a null Writer) if not null.
271 *
272 * @param fragment The fragment to evaluate.
273 * @throws JspException If the fragment invocation fails.
274 * @throws IOException If the fragment invocation fails.
275 * @since 2.2.0
276 */
277 public static void evaluateFragment(JspFragment fragment) throws JspException, IOException {
278 if (fragment != null) {
279 fragment.invoke(null);
280 }
281 }
282
283 /***
284 * Evaluates the fragment and returns its content as a string.
285 *
286 * @param fragment The fragment to evaluate.
287 * @return The fragment evaluated as a string.
288 * @throws JspException If the fragment invocation fails.
289 * @throws IOException If the fragment invocation fails with an I/O error.
290 * @since 2.2.0
291 */
292 public static String evaluateFragmentAsString(JspFragment fragment) throws JspException, IOException {
293 String body = null;
294 if (fragment != null) {
295 StringWriter writer = new StringWriter();
296 try {
297 fragment.invoke(writer);
298 } finally {
299 writer.close();
300 }
301 body = writer.toString();
302 }
303 return body;
304 }
305 }