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.velocity.context;
23
24 import java.io.IOException;
25 import java.io.StringWriter;
26 import java.io.Writer;
27 import java.util.Map;
28
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31
32 import org.apache.tiles.ArrayStack;
33 import org.apache.velocity.context.Context;
34 import org.apache.velocity.context.InternalContextAdapter;
35 import org.apache.velocity.runtime.Renderable;
36 import org.apache.velocity.runtime.parser.node.ASTBlock;
37 import org.apache.velocity.runtime.parser.node.ASTMap;
38 import org.apache.velocity.runtime.parser.node.Node;
39
40 /***
41 * Utilities for Velocity usage in Tiles.
42 *
43 * @version $Rev: 902965 $ $Date: 2010-01-25 21:12:46 +0100 (lun, 25 gen 2010) $
44 * @since 2.2.0
45 */
46 public final class VelocityUtil {
47
48 /***
49 * A renderable object that does not render anything.
50 *
51 * @since 2.2.0
52 */
53 public static final Renderable EMPTY_RENDERABLE;
54
55 static {
56 EMPTY_RENDERABLE = new Renderable() {
57
58 @Override
59 public String toString() {
60 return "";
61 }
62
63 public boolean render(InternalContextAdapter context, Writer writer) {
64
65 return true;
66 }
67 };
68 }
69
70 /***
71 * The attribute key that will be used to store the parameter map, to use across Velocity tool calls.
72 *
73 * @since 2.2.0
74 */
75 private static final String PARAMETER_MAP_STACK_KEY = "org.apache.tiles.velocity.PARAMETER_MAP_STACK";
76
77 /***
78 * Private constructor to avoid instantiation.
79 */
80 private VelocityUtil() {
81 }
82
83 /***
84 * Null-safe conversion from Boolean to boolean.
85 *
86 * @param obj The Boolean object.
87 * @param defaultValue This value will be returned if <code>obj</code> is null.
88 * @return The boolean value of <code>obj</code> or, if null, <code>defaultValue</code>.
89 * @since 2.2.0
90 */
91 public static boolean toSimpleBoolean(Boolean obj, boolean defaultValue) {
92 return obj != null ? obj : defaultValue;
93 }
94
95 /***
96 * Returns or creates the parameter stack to use. It is useful to store parameters across tool calls.
97 *
98 * @param context The Velocity context.
99 * @return The parameter stack.
100 * @since 2.2.0
101 * @deprecated Use Velocity directives.
102 */
103 @Deprecated
104 @SuppressWarnings("unchecked")
105 public static ArrayStack<Map<String, Object>> getParameterStack(Context context) {
106 ArrayStack<Map<String, Object>> stack = (ArrayStack<Map<String, Object>>) context
107 .get(PARAMETER_MAP_STACK_KEY);
108 if (stack == null) {
109 stack = new ArrayStack<Map<String, Object>>();
110 context.put(PARAMETER_MAP_STACK_KEY, stack);
111 }
112 return stack;
113 }
114
115 /***
116 * Sets an attribute in the desired scope.
117 *
118 * @param velocityContext The Velocity context.
119 * @param request The HTTP request.
120 * @param servletContext The servlet context.
121 * @param name The name of the attribute.
122 * @param obj The value of the attribute.
123 * @param scope The scope. It can be <code>page</code>, <code>request</code>
124 * , <code>session</code>, <code>application</code>.
125 * @since 2.2.0
126 */
127 public static void setAttribute(Context velocityContext,
128 HttpServletRequest request, ServletContext servletContext,
129 String name, Object obj, String scope) {
130 if (scope == null) {
131 scope = "page";
132 }
133 if ("page".equals(scope)) {
134 velocityContext.put(name, obj);
135 } else if ("request".equals(scope)) {
136 request.setAttribute(name, obj);
137 } else if ("session".equals(scope)) {
138 request.getSession().setAttribute(name, obj);
139 } else if ("application".equals(scope)) {
140 servletContext.setAttribute(name, obj);
141 }
142 }
143
144 /***
145 * Evaluates the body (child node at position 1) and returns it as a string.
146 *
147 * @param context The Velocity context.
148 * @param node The node to use.
149 * @return The evaluated body.
150 * @throws IOException If something goes wrong.
151 * @since 2.2.2
152 */
153 public static String getBodyAsString(InternalContextAdapter context, Node node)
154 throws IOException {
155 ASTBlock block = (ASTBlock) node.jjtGetChild(1);
156 StringWriter stringWriter = new StringWriter();
157 block.render(context, stringWriter);
158 stringWriter.close();
159 String body = stringWriter.toString();
160 if (body != null) {
161 body = body.replaceAll("^//s*|//s*$", "");
162 if (body.length() <= 0) {
163 body = null;
164 }
165 }
166 return body;
167 }
168
169 /***
170 * Evaluates the body writing in the passed writer.
171 *
172 * @param context The Velocity context.
173 * @param writer The writer to write into.
174 * @param node The node to use.
175 * @throws IOException If something goes wrong.
176 * @since 2.2.2
177 */
178 public static void evaluateBody(InternalContextAdapter context, Writer writer,
179 Node node) throws IOException {
180 ASTBlock block = (ASTBlock) node.jjtGetChild(1);
181 block.render(context, writer);
182 }
183
184 /***
185 * Extracts the parameters from the directives, by getting the child at
186 * position 0 supposing it is a map.
187 *
188 * @param context The Velocity context.
189 * @param node The node to use.
190 * @return The extracted parameters.
191 * @since 2.2.2
192 */
193 @SuppressWarnings("unchecked")
194 public static Map<String, Object> getParameters(InternalContextAdapter context,
195 Node node) {
196 ASTMap astMap = (ASTMap) node.jjtGetChild(0);
197 Map<String, Object> params = (Map<String, Object>) astMap
198 .value(context);
199 return params;
200 }
201 }