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.template;
23
24 import java.io.IOException;
25
26 import org.apache.tiles.ArrayStack;
27 import org.apache.tiles.Attribute;
28 import org.apache.tiles.TilesContainer;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /***
33 * <p>
34 * <strong>Inserts the value of an attribute into the page.</strong>
35 * </p>
36 * <p>
37 * This tag can be flexibly used to insert the value of an attribute into a
38 * page. As in other usages in Tiles, every attribute can be determined to have
39 * a "type", either set explicitly when it was defined, or "computed". If the
40 * type is not explicit, then if the attribute value is a valid definition, it
41 * will be inserted as such. Otherwise, if it begins with a "/" character, it
42 * will be treated as a "template". Finally, if it has not otherwise been
43 * assigned a type, it will be treated as a String and included without any
44 * special handling.
45 * </p>
46 *
47 * <p>
48 * <strong>Example : </strong>
49 * </p>
50 *
51 * <pre>
52 * <code>
53 * <tiles:insertAttribute name="body" />
54 * </code>
55 * </pre>
56 *
57 * @version $Rev: 797765 $ $Date: 2009-07-25 15:20:26 +0200 (sab, 25 lug 2009) $
58 * @since 2.2.0
59 */
60 public class InsertAttributeModel {
61
62 /***
63 * The logging object.
64 */
65 private Logger log = LoggerFactory.getLogger(getClass());
66
67 /***
68 * The attribute resolver to use.
69 */
70 private AttributeResolver attributeResolver;
71
72 /***
73 * Constructor.
74 *
75 * @param attributeResolver The attribute resolver to use.
76 * @since 2.2.0
77 */
78 public InsertAttributeModel(AttributeResolver attributeResolver) {
79 this.attributeResolver = attributeResolver;
80 }
81
82 /***
83 * Starts the operation.
84 *
85 * @param composeStack The compose stack,
86 * @param container The Tiles container to use.
87 * @param ignore If <code>true</code>, if an exception happens during
88 * rendering, of if the attribute is null, the problem will be ignored.
89 * @param preparer The preparer to invoke before rendering the attribute.
90 * @param role A comma-separated list of roles. If present, the attribute
91 * will be rendered only if the current user belongs to one of the roles.
92 * @param defaultValue The default value of the attribute. To use only if
93 * the attribute was not computed.
94 * @param defaultValueRole The default comma-separated list of roles. To use
95 * only if the attribute was not computed.
96 * @param defaultValueType The default type of the attribute. To use only if
97 * the attribute was not computed.
98 * @param name The name of the attribute.
99 * @param value The attribute to use immediately, if not null.
100 * @param requestItems The request objects.
101 * @since 2.2.0
102 */
103 public void start(ArrayStack<Object> composeStack, TilesContainer container,
104 boolean ignore, String preparer, String role, Object defaultValue,
105 String defaultValueRole, String defaultValueType, String name,
106 Attribute value, Object... requestItems) {
107 Attribute attribute = resolveAttribute(container, ignore, preparer,
108 role, defaultValue, defaultValueRole, defaultValueType, name,
109 value, requestItems);
110 composeStack.push(attribute);
111 }
112
113 /***
114 * Ends the operation.
115 *
116 * @param composeStack The compose stack,
117 * @param container The Tiles container to use.
118 * @param ignore If <code>true</code>, if an exception happens during
119 * rendering, of if the attribute is null, the problem will be ignored.
120 * @param requestItems The request objects.
121 * @throws IOException If an I/O error happens during rendering.
122 */
123 public void end(ArrayStack<Object> composeStack, TilesContainer container,
124 boolean ignore, Object... requestItems) throws IOException {
125 Attribute attribute = (Attribute) composeStack.pop();
126 renderAttribute(container, ignore, attribute, requestItems);
127 }
128
129 /***
130 * Executes the operation.
131 *
132 * @param container The Tiles container to use.
133 * @param ignore If <code>true</code>, if an exception happens during
134 * rendering, of if the attribute is null, the problem will be ignored.
135 * @param preparer The preparer to invoke before rendering the attribute.
136 * @param role A comma-separated list of roles. If present, the attribute
137 * will be rendered only if the current user belongs to one of the roles.
138 * @param defaultValue The default value of the attribute. To use only if
139 * the attribute was not computed.
140 * @param defaultValueRole The default comma-separated list of roles. To use
141 * only if the attribute was not computed.
142 * @param defaultValueType The default type of the attribute. To use only if
143 * the attribute was not computed.
144 * @param name The name of the attribute.
145 * @param value The attribute to use immediately, if not null.
146 * @param requestItems The request objects.
147 * @throws IOException If an I/O error happens during rendering.
148 * @since 2.2.0
149 */
150 public void execute(TilesContainer container, boolean ignore,
151 String preparer, String role, Object defaultValue,
152 String defaultValueRole, String defaultValueType, String name,
153 Attribute value, Object... requestItems) throws IOException {
154 Attribute attribute = resolveAttribute(container, ignore, preparer,
155 role, defaultValue, defaultValueRole, defaultValueType, name,
156 value, requestItems);
157 renderAttribute(container, ignore, attribute, requestItems);
158 }
159
160 /***
161 * Resolves the attribute. and starts the context.
162 *
163 * @param container The Tiles container to use.
164 * @param ignore If <code>true</code>, if an exception happens during
165 * rendering, of if the attribute is null, the problem will be ignored.
166 * @param preparer The preparer to invoke before rendering the attribute.
167 * @param role A comma-separated list of roles. If present, the attribute
168 * will be rendered only if the current user belongs to one of the roles.
169 * @param defaultValue The default value of the attribute. To use only if
170 * the attribute was not computed.
171 * @param defaultValueRole The default comma-separated list of roles. To use
172 * only if the attribute was not computed.
173 * @param defaultValueType The default type of the attribute. To use only if
174 * the attribute was not computed.
175 * @param name The name of the attribute.
176 * @param value The attribute to use immediately, if not null.
177 * @param requestItems The request objects.
178 * @return The resolved attribute.
179 */
180 private Attribute resolveAttribute(TilesContainer container,
181 boolean ignore, String preparer, String role, Object defaultValue,
182 String defaultValueRole, String defaultValueType, String name,
183 Attribute value, Object... requestItems) {
184 if (preparer != null) {
185 container.prepare(preparer, requestItems);
186 }
187 Attribute attribute = attributeResolver.computeAttribute(container,
188 value, name, role, ignore, defaultValue, defaultValueRole,
189 defaultValueType, requestItems);
190 container.startContext(requestItems);
191 return attribute;
192 }
193
194 /***
195 * Renders the attribute as a string.
196 *
197 * @param attribute The attribute to use, previously resolved.
198 * @param container The Tiles container to use.
199 * @param ignore If <code>true</code>, if an exception happens during
200 * rendering, of if the attribute is null, the problem will be ignored.
201 * @param requestItems The request objects.
202 * @throws IOException If an I/O error happens during rendering.
203 */
204 private void renderAttribute(TilesContainer container, boolean ignore,
205 Attribute attribute, Object... requestItems) throws IOException {
206 try {
207 if (attribute == null && ignore) {
208 return;
209 }
210 container.render(attribute, requestItems);
211 } catch (IOException e) {
212 if (!ignore) {
213 throw e;
214 } else if (log.isDebugEnabled()) {
215 log.debug("Ignoring exception", e);
216 }
217 } catch (RuntimeException e) {
218 if (!ignore) {
219 throw e;
220 } else if (log.isDebugEnabled()) {
221 log.debug("Ignoring exception", e);
222 }
223 } finally {
224 container.endContext(requestItems);
225 }
226 }
227 }