1 /*
2 * $Id: Attribute.java 1035061 2010-11-14 20:32:50Z 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;
23
24 import static org.apache.tiles.CompareUtil.*;
25
26 import java.io.Serializable;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.Set;
30
31 import org.apache.tiles.request.Request;
32
33 /**
34 * Common implementation of attribute definition.
35 *
36 * @version $Rev: 1035061 $ $Date: 2010-11-15 07:32:50 +1100 (Mon, 15 Nov 2010) $
37 */
38 public class Attribute implements Serializable, Cloneable {
39
40 /**
41 * The name of the template renderer.
42 */
43 private static final String TEMPLATE_RENDERER = "template";
44
45 /**
46 * The roles that can render this attribute.
47 * @since 2.0.6
48 */
49 protected Set<String> roles = null;
50
51 /**
52 * The value of the attribute.
53 */
54 protected Object value = null;
55
56 /**
57 * The expression to evaluate. Ignored if {@link #value} is not
58 * <code>null</code>.
59 *
60 * @since 2.2.0
61 */
62 protected Expression expressionObject = null;
63
64 /**
65 * The renderer name of the attribute. Default names are <code>string</code>,
66 * <code>template</code>, <code>definition</code>, <code>object</code>.
67 */
68 private String renderer = null;
69
70 /**
71 * Constructor.
72 *
73 */
74 public Attribute() {
75 }
76
77 /**
78 * Constructor.
79 *
80 * @param value Object to store.
81 */
82 public Attribute(Object value) {
83 this.value = value;
84 }
85
86 /**
87 * Copy constructor.
88 *
89 * @param attribute The attribute to copy from.
90 */
91 public Attribute(Attribute attribute) {
92 this.roles = attribute.roles;
93 this.value = attribute.getValue();
94 if (attribute.expressionObject != null) {
95 this.expressionObject = new Expression(attribute.expressionObject);
96 } else {
97 this.expressionObject = null;
98 }
99 this.renderer = attribute.renderer;
100 }
101
102 /**
103 * Constructor.
104 *
105 * @param value Object to store.
106 * @param role Asociated role.
107 */
108 public Attribute(Object value, String role) {
109 this.value = value;
110 setRole(role);
111 }
112
113 /**
114 * Constructor.
115 *
116 * @param value Object to store. If specified, the <code>expression</code>
117 * parameter will be ignored.
118 * @param expression The expression to be evaluated. Ignored if the
119 * <code>value</code> is not null.
120 * @param role Associated role.
121 * @param rendererName The renderer name.
122 * @since 2.2.0
123 */
124 public Attribute(Object value, Expression expression, String role, String rendererName) {
125 this.value = value;
126 this.expressionObject = expression;
127 this.renderer = rendererName;
128 setRole(role);
129 }
130
131 /**
132 * Creates a template attribute, starting from the name of the template.
133 *
134 * @param template The template that will be rendered.
135 * @return The template attribute.
136 * @since 2.1.2
137 */
138 public static Attribute createTemplateAttribute(String template) {
139 Attribute attribute = new Attribute();
140 attribute.setValue(template);
141 attribute.setRenderer(TEMPLATE_RENDERER);
142 return attribute;
143 }
144
145 /**
146 * Creates a template attribute, starting from the name of the template.
147 *
148 * @param template The template that will be rendered.
149 * @param templateExpression The template expression that will be evaluated
150 * to a template.
151 * @param templateType The type, or renderer, of the template. If null, the
152 * default <code>template</code> will be used.
153 * @param role The comma-separated roles for which the template is
154 * authorized to be rendered.
155 * @return The template attribute.
156 * @since 2.2.2
157 */
158 public static Attribute createTemplateAttribute(String template,
159 String templateExpression, String templateType, String role) {
160 Attribute templateAttribute = createTemplateAttribute(template);
161 templateAttribute.setRole(role);
162 if (templateType != null) {
163 templateAttribute.setRenderer(templateType);
164 }
165 templateAttribute
166 .setExpressionObject(Expression
167 .createExpressionFromDescribedExpression(templateExpression));
168 return templateAttribute;
169 }
170
171 /**
172 * Creates a template attribute, starting from the expression to evaluate to
173 * obtain the template.
174 *
175 * @param templateExpression The expression to evaluate.
176 * @return The template attribute.
177 * @since 2.1.2
178 */
179 public static Attribute createTemplateAttributeWithExpression(
180 String templateExpression) {
181 Attribute attribute = new Attribute();
182 attribute.setExpressionObject(new Expression(templateExpression));
183 attribute.setRenderer(TEMPLATE_RENDERER);
184 return attribute;
185 }
186
187 /**
188 * Get role.
189 * @return the name of the required role(s)
190 */
191 public String getRole() {
192 String retValue = null;
193
194 if (roles != null && !roles.isEmpty()) {
195 StringBuilder builder = new StringBuilder();
196 Iterator<String> roleIt = roles.iterator();
197 if (roleIt.hasNext()) {
198 builder.append(roleIt.next());
199 while (roleIt.hasNext()) {
200 builder.append(",");
201 builder.append(roleIt.next());
202 }
203 retValue = builder.toString();
204 }
205 }
206
207 return retValue;
208 }
209
210 /**
211 * Returns the roles that can render this attribute.
212 *
213 * @return The enabled roles.
214 * @since 2.0.6
215 */
216 public Set<String> getRoles() {
217 return roles;
218 }
219
220 /**
221 * Set role.
222 *
223 * @param role Associated role.
224 */
225 public void setRole(String role) {
226 if (role != null && role.trim().length() > 0) {
227 String[] rolesStrings = role.split("\\s*,\\s*");
228 roles = new HashSet<String>();
229 for (int i = 0; i < rolesStrings.length; i++) {
230 roles.add(rolesStrings[i]);
231 }
232 } else {
233 roles = null;
234 }
235 }
236
237 /**
238 * Sets the roles that can render this attribute.
239 *
240 * @param roles The enabled roles.
241 * @since 2.0.6
242 */
243 public void setRoles(Set<String> roles) {
244 this.roles = roles;
245 }
246
247 /**
248 * Get value.
249 * @return the value
250 */
251 public Object getValue() {
252 return value;
253 }
254
255 /**
256 * Set value.
257 *
258 * @param value New value.
259 */
260 public void setValue(Object value) {
261 this.value = value;
262 }
263
264 /**
265 * Returns The expression to evaluate. Ignored if {@link #value} is not
266 * <code>null</code>.
267 *
268 * @return The expression to be evaluated.
269 * @since 2.2.0
270 */
271 public Expression getExpressionObject() {
272 return expressionObject;
273 }
274
275 /**
276 * Sets The expression to evaluate. Ignored if {@link #value} is not
277 * <code>null</code>.
278 *
279 * @param expressionObject The expression to be evaluated.
280 * @since 2.2.0
281 */
282 public void setExpressionObject(Expression expressionObject) {
283 this.expressionObject = expressionObject;
284 }
285
286 /** {@inheritDoc} */
287 @Override
288 public String toString() {
289 if (value != null) {
290 return value.toString();
291 }
292 return null;
293 }
294
295 /**
296 * Returns the renderer name to use.
297 *
298 * @return The renderer name.
299 * @since 2.1.0
300 */
301 public String getRenderer() {
302 return renderer;
303 }
304
305 /**
306 * Sets the renderer name to use.
307 *
308 * @param rendererName The renderer.
309 * @since 2.1.0
310 */
311 public void setRenderer(String rendererName) {
312 this.renderer = rendererName;
313 }
314
315 /**
316 * Inherits an attribute, i.e. overwrites null properties with the ones
317 * provided by the attribute.
318 *
319 * @param attribute The attribute to inherit.
320 * @since 2.1.2
321 */
322 public void inherit(Attribute attribute) {
323 if (value == null) {
324 value = attribute.getValue();
325 }
326 Expression targetExpressionObject = attribute.getExpressionObject();
327 if (targetExpressionObject != null
328 && (expressionObject == null || expressionObject
329 .getExpression() == null)) {
330 expressionObject = new Expression(targetExpressionObject);
331 }
332 if (roles == null || roles.isEmpty()) {
333 roles = attribute.getRoles();
334 }
335 if (renderer == null) {
336 renderer = attribute.getRenderer();
337 }
338 }
339
340 /** {@inheritDoc} */
341 @Override
342 public boolean equals(Object obj) {
343 Attribute attribute = (Attribute) obj;
344 return nullSafeEquals(value, attribute.value)
345 && nullSafeEquals(renderer, attribute.renderer)
346 && nullSafeEquals(roles, attribute.roles)
347 && nullSafeEquals(expressionObject, attribute.expressionObject);
348 }
349
350 /**
351 * Checks if the current user can use this attribute.
352 *
353 * @param request The request context.
354 * @return <code>true</code> if the current user can see this attribute.
355 * @since 3.0.0
356 */
357 public boolean isPermitted(Request request) {
358 if (roles == null || roles.isEmpty()) {
359 return true;
360 }
361
362 boolean retValue = false;
363
364 for (Iterator<String> roleIt = roles.iterator(); roleIt.hasNext()
365 && !retValue;) {
366 retValue = request.isUserInRole(roleIt.next());
367 }
368
369 return retValue;
370 }
371
372 /** {@inheritDoc} */
373 @Override
374 public int hashCode() {
375 return nullSafeHashCode(value) + nullSafeHashCode(renderer)
376 + nullSafeHashCode(roles) + nullSafeHashCode(expressionObject);
377 }
378
379 /** {@inheritDoc} */
380 @Override
381 public Attribute clone() {
382 return new Attribute(this);
383 }
384 }