1/*2 * $Id: FreeMarkerUtil.java 797765 2009-07-25 13:20:26Z apetrelli $3 *4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122package org.apache.tiles.freemarker.context;
2324import java.io.IOException;
25import java.io.StringWriter;
2627import javax.servlet.http.HttpServletRequest;
2829import org.apache.tiles.ArrayStack;
30import org.apache.tiles.TilesContainer;
31import org.apache.tiles.access.TilesAccess;
32import org.apache.tiles.freemarker.FreeMarkerTilesException;
33import org.apache.tiles.freemarker.io.NullWriter;
34import org.apache.tiles.impl.NoSuchContainerException;
35import org.apache.tiles.servlet.context.ServletUtil;
3637import freemarker.core.Environment;
38import freemarker.ext.servlet.FreemarkerServlet;
39import freemarker.ext.servlet.HttpRequestHashModel;
40import freemarker.ext.servlet.ServletContextHashModel;
41import freemarker.template.TemplateDirectiveBody;
42import freemarker.template.TemplateException;
43import freemarker.template.TemplateModel;
44import freemarker.template.TemplateModelException;
45import freemarker.template.utility.DeepUnwrap;
4647/***48 * Utilities for FreeMarker usage in Tiles.49 *50 * @version $Rev: 797765 $ $Date: 2009-07-25 15:20:26 +0200 (sab, 25 lug 2009) $51 * @since 2.2.052 */53publicfinalclassFreeMarkerUtil {
5455/***56 * The name of the attribute that holds the compose stack.57 */58publicstaticfinal String COMPOSE_STACK_ATTRIBUTE_NAME = "org.apache.tiles.template.COMPOSE_STACK";
5960/***61 * Private constructor to avoid instantiation.62 */63privateFreeMarkerUtil() {
64 }
6566/***67 * Returns true if forced include of the result is needed.68 *69 * @param env The current FreeMarker environment.70 * @return If <code>true</code> the include operation must be forced.71 * @since 2.2.072 */73publicstaticboolean isForceInclude(Environment env) {
74return ServletUtil
75 .isForceInclude(getRequestHashModel(env).getRequest());
76 }
7778/***79 * Sets the option that enables the forced include of the response.80 *81 * @param env The current FreeMarker environment.82 * @param forceInclude If <code>true</code> the include operation must be83 * forced.84 * @since 2.2.085 */86publicstaticvoid setForceInclude(Environment env, boolean forceInclude) {
87 ServletUtil.setForceInclude(getRequestHashModel(env).getRequest(),
88 forceInclude);
89 }
9091/***92 * Returns a specific Tiles container.93 *94 * @param env The current FreeMarker environment.95 * @param key The key under which the container is stored. If null, the96 * default container will be returned.97 * @return The requested Tiles container.98 * @since 2.2.099 */100publicstatic TilesContainer getContainer(Environment env, String key) {
101if (key == null) {
102 key = TilesAccess.CONTAINER_ATTRIBUTE;
103 }
104return (TilesContainer) getServletContextHashModel(env).getServlet()
105 .getServletContext().getAttribute(key);
106 }
107108/***109 * Sets the current container to use in web pages.110 *111 * @param env The current FreeMarker environment.112 * @param key The key under which the container is stored.113 * @since 2.2.0114 */115publicstaticvoid setCurrentContainer(Environment env, String key) {
116 TilesContainer container = getContainer(env, key);
117if (container != null) {
118 getRequestHashModel(env).getRequest().setAttribute(
119 ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
120 } else {
121thrownew NoSuchContainerException("The container with the key '"122 + key + "' cannot be found");
123 }
124 }
125126/***127 * Sets the current container to use in web pages.128 *129 * @param env The current FreeMarker environment.130 * @param container The container to use as the current container.131 * @since 2.2.0132 */133publicstaticvoid setCurrentContainer(Environment env,
134 TilesContainer container) {
135 ServletUtil.setCurrentContainer(getRequestHashModel(env).getRequest(),
136 getServletContextHashModel(env).getServlet()
137 .getServletContext(), container);
138 }
139140/***141 * Returns the current container that has been set, or the default one.142 *143 * @param env The current FreeMarker environment.144 * @return The current Tiles container to use in web pages.145 * @since 2.2.0146 */147publicstatic TilesContainer getCurrentContainer(Environment env) {
148return ServletUtil.getCurrentContainer(getRequestHashModel(env)
149 .getRequest(), getServletContextHashModel(env).getServlet()
150 .getServletContext());
151 }
152153/***154 * Returns the HTTP request hash model.155 *156 * @param env The current FreeMarker environment.157 * @return The request hash model.158 * @since 2.2.0159 */160publicstatic HttpRequestHashModel getRequestHashModel(Environment env) {
161try {
162return (HttpRequestHashModel) env.getDataModel().get(
163 FreemarkerServlet.KEY_REQUEST);
164 } catch (TemplateModelException e) {
165thrownewFreeMarkerTilesException(
166"Exception got when obtaining the request hash model", e);
167 }
168 }
169170/***171 * Returns the servlet context hash model.172 *173 * @param env The current FreeMarker environment.174 * @return The servlet context hash model.175 * @since 2.2.0176 */177publicstatic ServletContextHashModel getServletContextHashModel(
178 Environment env) {
179try {
180return (ServletContextHashModel) env.getDataModel().get(
181 FreemarkerServlet.KEY_APPLICATION);
182 } catch (TemplateModelException e) {
183thrownewFreeMarkerTilesException(
184"Exception got when obtaining the application hash model",
185 e);
186 }
187 }
188189/***190 * Unwraps a TemplateModel to extract a string.191 *192 * @param model The TemplateModel to unwrap.193 * @return The unwrapped string.194 * @since 2.2.0195 */196publicstatic String getAsString(TemplateModel model) {
197try {
198return (String) DeepUnwrap.unwrap(model);
199 } catch (TemplateModelException e) {
200thrownewFreeMarkerTilesException("Cannot unwrap a model", e);
201 }
202 }
203204/***205 * Unwraps a TemplateModel to extract a boolean.206 *207 * @param model The TemplateModel to unwrap.208 * @param defaultValue If the value is null, this value will be returned.209 * @return The unwrapped boolean.210 * @since 2.2.0211 */212publicstaticboolean getAsBoolean(TemplateModel model, boolean defaultValue) {
213try {
214 Boolean retValue = (Boolean) DeepUnwrap.unwrap(model);
215return retValue != null ? retValue : defaultValue;
216 } catch (TemplateModelException e) {
217thrownewFreeMarkerTilesException("Cannot unwrap a model", e);
218 }
219 }
220221/***222 * Unwraps a TemplateModel to extract an object.223 *224 * @param model The TemplateModel to unwrap.225 * @return The unwrapped object.226 * @since 2.2.0227 */228publicstatic Object getAsObject(TemplateModel model) {
229try {
230return DeepUnwrap.unwrap(model);
231 } catch (TemplateModelException e) {
232thrownewFreeMarkerTilesException("Cannot unwrap a model", e);
233 }
234 }
235236/***237 * Sets an attribute in the desired scope.238 *239 * @param env The FreeMarker current environment.240 * @param name The name of the attribute.241 * @param obj The value of the attribute.242 * @param scope The scope. It can be <code>page</code>, <code>request</code>243 * , <code>session</code>, <code>application</code>.244 * @since 2.2.0245 */246publicstaticvoid setAttribute(Environment env, String name, Object obj,
247 String scope) {
248if (scope == null) {
249 scope = "page";
250 }
251if ("page".equals(scope)) {
252try {
253 TemplateModel model = env.getObjectWrapper().wrap(obj);
254 env.setVariable(name, model);
255 } catch (TemplateModelException e) {
256thrownewFreeMarkerTilesException(
257"Error when wrapping an object", e);
258 }
259 } elseif ("request".equals(scope)) {
260 getRequestHashModel(env).getRequest().setAttribute(name, obj);
261 } elseif ("session".equals(scope)) {
262 getRequestHashModel(env).getRequest().getSession().setAttribute(
263 name, obj);
264 } elseif ("application".equals(scope)) {
265 getServletContextHashModel(env).getServlet().getServletContext()
266 .setAttribute(name, obj);
267 }
268 }
269270/***271 * Returns the current compose stack, or creates a new one if not present.272 *273 * @param env The current FreeMarker environment.274 * @return The compose stack.275 * @since 2.2.0276 */277 @SuppressWarnings("unchecked")
278publicstatic ArrayStack<Object> getComposeStack(Environment env) {
279 HttpServletRequest request = getRequestHashModel(env).getRequest();
280 ArrayStack<Object> composeStack = (ArrayStack<Object>) request
281 .getAttribute(COMPOSE_STACK_ATTRIBUTE_NAME);
282if (composeStack == null) {
283 composeStack = new ArrayStack<Object>();
284 request.setAttribute(COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
285 }
286return composeStack;
287 }
288289/***290 * Evaluates the body without rendering it.291 *292 * @param body The body to evaluate.293 * @throws TemplateException If something goes wrong during evaluation.294 * @throws IOException If something goes wrong during writing the result.295 * @since 2.2.0296 */297publicstaticvoid evaluateBody(TemplateDirectiveBody body)
298 throws TemplateException, IOException {
299if (body != null) {
300NullWriter writer = newNullWriter();
301try {
302 body.render(writer);
303 } finally {
304 writer.close();
305 }
306 }
307 }
308309/***310 * Renders the body as a string.311 *312 * @param body The body to render.313 * @return The rendered string.314 * @throws TemplateException If something goes wrong during evaluation.315 * @throws IOException If something goes wrong during writing the result.316 * @since 2.2.0317 */318publicstatic String renderAsString(TemplateDirectiveBody body)
319 throws TemplateException, IOException {
320 String bodyString = null;
321if (body != null) {
322 StringWriter stringWriter = new StringWriter();
323try {
324 body.render(stringWriter);
325 } finally {
326 stringWriter.close();
327 }
328 bodyString = stringWriter.toString();
329 }
330return bodyString;
331 }
332 }