This project has retired. For details please refer to its Attic page.
FreeMarkerUtil xref
View Javadoc

1   /*
2    * $Id: FreeMarkerUtil.java 797765 2009-07-25 13:20:26Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.tiles.freemarker.context;
23  
24  import java.io.IOException;
25  import java.io.StringWriter;
26  
27  import javax.servlet.http.HttpServletRequest;
28  
29  import org.apache.tiles.ArrayStack;
30  import org.apache.tiles.TilesContainer;
31  import org.apache.tiles.access.TilesAccess;
32  import org.apache.tiles.freemarker.FreeMarkerTilesException;
33  import org.apache.tiles.freemarker.io.NullWriter;
34  import org.apache.tiles.impl.NoSuchContainerException;
35  import org.apache.tiles.servlet.context.ServletUtil;
36  
37  import freemarker.core.Environment;
38  import freemarker.ext.servlet.FreemarkerServlet;
39  import freemarker.ext.servlet.HttpRequestHashModel;
40  import freemarker.ext.servlet.ServletContextHashModel;
41  import freemarker.template.TemplateDirectiveBody;
42  import freemarker.template.TemplateException;
43  import freemarker.template.TemplateModel;
44  import freemarker.template.TemplateModelException;
45  import freemarker.template.utility.DeepUnwrap;
46  
47  /***
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.0
52   */
53  public final class FreeMarkerUtil {
54  
55      /***
56       * The name of the attribute that holds the compose stack.
57       */
58      public static final String COMPOSE_STACK_ATTRIBUTE_NAME = "org.apache.tiles.template.COMPOSE_STACK";
59  
60      /***
61       * Private constructor to avoid instantiation.
62       */
63      private FreeMarkerUtil() {
64      }
65  
66      /***
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.0
72       */
73      public static boolean isForceInclude(Environment env) {
74          return ServletUtil
75                  .isForceInclude(getRequestHashModel(env).getRequest());
76      }
77  
78      /***
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 be
83       * forced.
84       * @since 2.2.0
85       */
86      public static void setForceInclude(Environment env, boolean forceInclude) {
87          ServletUtil.setForceInclude(getRequestHashModel(env).getRequest(),
88                  forceInclude);
89      }
90  
91      /***
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, the
96       * default container will be returned.
97       * @return The requested Tiles container.
98       * @since 2.2.0
99       */
100     public static TilesContainer getContainer(Environment env, String key) {
101         if (key == null) {
102             key = TilesAccess.CONTAINER_ATTRIBUTE;
103         }
104         return (TilesContainer) getServletContextHashModel(env).getServlet()
105                 .getServletContext().getAttribute(key);
106     }
107 
108     /***
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.0
114      */
115     public static void setCurrentContainer(Environment env, String key) {
116         TilesContainer container = getContainer(env, key);
117         if (container != null) {
118             getRequestHashModel(env).getRequest().setAttribute(
119                     ServletUtil.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
120         } else {
121             throw new NoSuchContainerException("The container with the key '"
122                     + key + "' cannot be found");
123         }
124     }
125 
126     /***
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.0
132      */
133     public static void setCurrentContainer(Environment env,
134             TilesContainer container) {
135         ServletUtil.setCurrentContainer(getRequestHashModel(env).getRequest(),
136                 getServletContextHashModel(env).getServlet()
137                         .getServletContext(), container);
138     }
139 
140     /***
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.0
146      */
147     public static TilesContainer getCurrentContainer(Environment env) {
148         return ServletUtil.getCurrentContainer(getRequestHashModel(env)
149                 .getRequest(), getServletContextHashModel(env).getServlet()
150                 .getServletContext());
151     }
152 
153     /***
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.0
159      */
160     public static HttpRequestHashModel getRequestHashModel(Environment env) {
161         try {
162             return (HttpRequestHashModel) env.getDataModel().get(
163                     FreemarkerServlet.KEY_REQUEST);
164         } catch (TemplateModelException e) {
165             throw new FreeMarkerTilesException(
166                     "Exception got when obtaining the request hash model", e);
167         }
168     }
169 
170     /***
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.0
176      */
177     public static ServletContextHashModel getServletContextHashModel(
178             Environment env) {
179         try {
180             return (ServletContextHashModel) env.getDataModel().get(
181                     FreemarkerServlet.KEY_APPLICATION);
182         } catch (TemplateModelException e) {
183             throw new FreeMarkerTilesException(
184                     "Exception got when obtaining the application hash model",
185                     e);
186         }
187     }
188 
189     /***
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.0
195      */
196     public static String getAsString(TemplateModel model) {
197         try {
198             return (String) DeepUnwrap.unwrap(model);
199         } catch (TemplateModelException e) {
200             throw new FreeMarkerTilesException("Cannot unwrap a model", e);
201         }
202     }
203 
204     /***
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.0
211      */
212     public static boolean getAsBoolean(TemplateModel model, boolean defaultValue) {
213         try {
214             Boolean retValue = (Boolean) DeepUnwrap.unwrap(model);
215             return retValue != null ? retValue : defaultValue;
216         } catch (TemplateModelException e) {
217             throw new FreeMarkerTilesException("Cannot unwrap a model", e);
218         }
219     }
220 
221     /***
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.0
227      */
228     public static Object getAsObject(TemplateModel model) {
229         try {
230             return DeepUnwrap.unwrap(model);
231         } catch (TemplateModelException e) {
232             throw new FreeMarkerTilesException("Cannot unwrap a model", e);
233         }
234     }
235 
236     /***
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.0
245      */
246     public static void setAttribute(Environment env, String name, Object obj,
247             String scope) {
248         if (scope == null) {
249             scope = "page";
250         }
251         if ("page".equals(scope)) {
252             try {
253                 TemplateModel model = env.getObjectWrapper().wrap(obj);
254                 env.setVariable(name, model);
255             } catch (TemplateModelException e) {
256                 throw new FreeMarkerTilesException(
257                         "Error when wrapping an object", e);
258             }
259         } else if ("request".equals(scope)) {
260             getRequestHashModel(env).getRequest().setAttribute(name, obj);
261         } else if ("session".equals(scope)) {
262             getRequestHashModel(env).getRequest().getSession().setAttribute(
263                     name, obj);
264         } else if ("application".equals(scope)) {
265             getServletContextHashModel(env).getServlet().getServletContext()
266                     .setAttribute(name, obj);
267         }
268     }
269 
270     /***
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.0
276      */
277     @SuppressWarnings("unchecked")
278     public static ArrayStack<Object> getComposeStack(Environment env) {
279         HttpServletRequest request = getRequestHashModel(env).getRequest();
280         ArrayStack<Object> composeStack = (ArrayStack<Object>) request
281                 .getAttribute(COMPOSE_STACK_ATTRIBUTE_NAME);
282         if (composeStack == null) {
283             composeStack = new ArrayStack<Object>();
284             request.setAttribute(COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
285         }
286         return composeStack;
287     }
288 
289     /***
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.0
296      */
297     public static void evaluateBody(TemplateDirectiveBody body)
298             throws TemplateException, IOException {
299         if (body != null) {
300             NullWriter writer = new NullWriter();
301             try {
302                 body.render(writer);
303             } finally {
304                 writer.close();
305             }
306         }
307     }
308 
309     /***
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.0
317      */
318     public static String renderAsString(TemplateDirectiveBody body)
319             throws TemplateException, IOException {
320         String bodyString = null;
321         if (body != null) {
322             StringWriter stringWriter = new StringWriter();
323             try {
324                 body.render(stringWriter);
325             } finally {
326                 stringWriter.close();
327             }
328             bodyString = stringWriter.toString();
329         }
330         return bodyString;
331     }
332 }