This project has retired. For details please refer to its
Attic page.
BasicAttributeContext xref
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;
23
24 import java.io.Serializable;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.Set;
31
32
33 /***
34 * Basic implementation for <code>AttributeContext</code>.
35 *
36 * @version $Rev: 788344 $ $Date: 2009-06-25 14:47:40 +0200 (gio, 25 giu 2009) $
37 * @since 2.1.0
38 */
39 public class BasicAttributeContext implements AttributeContext, Serializable {
40
41 /***
42 * The template attribute, to render a template.
43 *
44 * @since 2.1.2
45 */
46 protected Attribute templateAttribute;
47
48 /***
49 * Associated ViewPreparer URL or classname, if defined.
50 *
51 * @since 2.1.0
52 */
53 protected String preparer = null;
54
55 /***
56 * Template attributes.
57 * @since 2.1.0
58 */
59 protected Map<String, Attribute> attributes = null;
60
61 /***
62 * Cascaded template attributes.
63 * @since 2.1.0
64 */
65 protected Map<String, Attribute> cascadedAttributes = null;
66
67 /***
68 * Constructor.
69 *
70 * @since 2.1.0
71 */
72 public BasicAttributeContext() {
73 super();
74 }
75
76 /***
77 * Constructor.
78 * Create a context and set specified attributes.
79 *
80 * @param attributes Attributes to initialize context.
81 * @since 2.1.0
82 */
83 public BasicAttributeContext(Map<String, Attribute> attributes) {
84 if (attributes != null) {
85 this.attributes = deepCopyAttributeMap(attributes);
86 }
87 }
88
89 /***
90 * Copy constructor.
91 *
92 * @param context The constructor to copy.
93 * @since 2.1.0
94 */
95 public BasicAttributeContext(AttributeContext context) {
96 if (context instanceof BasicAttributeContext) {
97 copyBasicAttributeContext((BasicAttributeContext) context);
98 } else {
99 Attribute parentTemplateAttribute = context.getTemplateAttribute();
100 if (parentTemplateAttribute != null) {
101 this.templateAttribute = new Attribute(parentTemplateAttribute);
102 }
103 this.preparer = context.getPreparer();
104 this.attributes = new HashMap<String, Attribute>();
105 for (String name : context.getLocalAttributeNames()) {
106 attributes.put(name, new Attribute(context.getLocalAttribute(name)));
107 }
108 inheritCascadedAttributes(context);
109 }
110 }
111
112 /***
113 * Copy constructor.
114 *
115 * @param context The constructor to copy.
116 * @since 2.1.0
117 */
118 public BasicAttributeContext(BasicAttributeContext context) {
119 copyBasicAttributeContext(context);
120 }
121
122 /*** {@inheritDoc} */
123 public Attribute getTemplateAttribute() {
124 return templateAttribute;
125 }
126
127 /*** {@inheritDoc} */
128 public void setTemplateAttribute(Attribute templateAttribute) {
129 this.templateAttribute = templateAttribute;
130 }
131
132 /*** {@inheritDoc} */
133 public String getPreparer() {
134 return preparer;
135 }
136
137 /*** {@inheritDoc} */
138 public void setPreparer(String url) {
139 this.preparer = url;
140 }
141
142 /*** {@inheritDoc} */
143 public void inheritCascadedAttributes(AttributeContext context) {
144 if (context instanceof BasicAttributeContext) {
145 copyCascadedAttributes((BasicAttributeContext) context);
146 } else {
147 this.cascadedAttributes = new HashMap<String, Attribute>();
148 for (String name : context.getCascadedAttributeNames()) {
149 cascadedAttributes.put(name, new Attribute(context
150 .getCascadedAttribute(name)));
151 }
152 }
153 }
154
155 /*** {@inheritDoc} */
156 public void inherit(AttributeContext parent) {
157 if (parent instanceof BasicAttributeContext) {
158 inherit((BasicAttributeContext) parent);
159 } else {
160
161 Attribute parentTemplateAttribute = parent.getTemplateAttribute();
162 inheritParentTemplateAttribute(parentTemplateAttribute);
163 if (preparer == null) {
164 preparer = parent.getPreparer();
165 }
166
167
168 Set<String> names = parent.getCascadedAttributeNames();
169 if (names != null && !names.isEmpty()) {
170 for (String name : names) {
171 Attribute attribute = parent.getCascadedAttribute(name);
172 Attribute destAttribute = getCascadedAttribute(name);
173 if (destAttribute == null) {
174 putAttribute(name, attribute, true);
175 } else if (attribute instanceof ListAttribute
176 && destAttribute instanceof ListAttribute
177 && ((ListAttribute) destAttribute).isInherit()) {
178 ((ListAttribute) destAttribute).inherit((ListAttribute) attribute);
179 }
180 }
181 }
182 names = parent.getLocalAttributeNames();
183 if (names != null && !names.isEmpty()) {
184 for (String name : names) {
185 Attribute attribute = parent.getLocalAttribute(name);
186 Attribute destAttribute = getLocalAttribute(name);
187 if (destAttribute == null) {
188 putAttribute(name, attribute, false);
189 } else if (attribute instanceof ListAttribute
190 && destAttribute instanceof ListAttribute
191 && ((ListAttribute) destAttribute).isInherit()) {
192 ((ListAttribute) destAttribute).inherit((ListAttribute) attribute);
193 }
194 }
195 }
196 }
197 }
198
199 /***
200 * Inherits the attribute context, inheriting, i.e. copying if not present,
201 * the attributes.
202 *
203 * @param parent The attribute context to inherit.
204 * @since 2.1.0
205 */
206 public void inherit(BasicAttributeContext parent) {
207
208 inheritParentTemplateAttribute(parent.getTemplateAttribute());
209 if (preparer == null) {
210 preparer = parent.preparer;
211 }
212
213
214 cascadedAttributes = addMissingAttributes(
215 ((BasicAttributeContext) parent).cascadedAttributes,
216 cascadedAttributes);
217 attributes = addMissingAttributes(
218 ((BasicAttributeContext) parent).attributes, attributes);
219 }
220
221 /***
222 * Add all attributes to this context.
223 * Copies all of the mappings from the specified attribute map to this context.
224 * New attribute mappings will replace any mappings that this context had for any of the keys
225 * currently in the specified attribute map.
226 *
227 * @param newAttributes Attributes to add.
228 * @since 2.1.0
229 */
230 public void addAll(Map<String, Attribute> newAttributes) {
231 if (newAttributes == null) {
232 return;
233 }
234
235 if (attributes == null) {
236 attributes = new HashMap<String, Attribute>(newAttributes);
237 return;
238 }
239
240 attributes.putAll(newAttributes);
241 }
242
243 /***
244 * Add all missing attributes to this context.
245 * Copies all of the mappings from the specified attributes map to this context.
246 * New attribute mappings will be added only if they don't already exist in
247 * this context.
248 *
249 * @param defaultAttributes Attributes to add.
250 * @since 2.1.0
251 */
252 public void addMissing(Map<String, Attribute> defaultAttributes) {
253 if (defaultAttributes == null) {
254 return;
255 }
256
257 if (attributes == null) {
258 attributes = new HashMap<String, Attribute>(defaultAttributes);
259 if (cascadedAttributes == null || cascadedAttributes.isEmpty()) {
260 return;
261 }
262 }
263
264 Set<Map.Entry<String, Attribute>> entries = defaultAttributes.entrySet();
265 for (Map.Entry<String, Attribute> entry : entries) {
266 String key = entry.getKey();
267 if (!attributes.containsKey(key)
268 && (cascadedAttributes == null || cascadedAttributes
269 .containsKey(key))) {
270 attributes.put(entry.getKey(), entry.getValue());
271 }
272 }
273 }
274
275 /*** {@inheritDoc} */
276 public Attribute getAttribute(String name) {
277 Attribute retValue = null;
278 if (attributes != null) {
279 retValue = attributes.get(name);
280 }
281
282 if (retValue == null && cascadedAttributes != null) {
283 retValue = cascadedAttributes.get(name);
284 }
285
286 return retValue;
287 }
288
289 /*** {@inheritDoc} */
290 public Attribute getLocalAttribute(String name) {
291 if (attributes == null) {
292 return null;
293 }
294
295 return attributes.get(name);
296 }
297
298 /*** {@inheritDoc} */
299 public Attribute getCascadedAttribute(String name) {
300 if (cascadedAttributes == null) {
301 return null;
302 }
303
304 return cascadedAttributes.get(name);
305 }
306
307 /*** {@inheritDoc} */
308 public Iterator<String> getAttributeNames() {
309 Set<String> attributeSet = null;
310
311 if (attributes != null && !attributes.isEmpty()) {
312 attributeSet = new HashSet<String>(attributes
313 .keySet());
314 if (cascadedAttributes != null && !cascadedAttributes.isEmpty()) {
315 attributeSet.addAll(cascadedAttributes.keySet());
316 }
317 } else if (cascadedAttributes != null && !cascadedAttributes.isEmpty()) {
318 attributeSet = new HashSet<String>(cascadedAttributes.keySet());
319 }
320
321 if (attributeSet != null) {
322 return attributeSet.iterator();
323 } else {
324 return new ArrayList<String>().iterator();
325 }
326 }
327
328 /*** {@inheritDoc} */
329 public Set<String> getLocalAttributeNames() {
330 if (attributes != null && !attributes.isEmpty()) {
331 return attributes.keySet();
332 } else {
333 return null;
334 }
335 }
336
337 /*** {@inheritDoc} */
338 public Set<String> getCascadedAttributeNames() {
339 if (cascadedAttributes != null && !cascadedAttributes.isEmpty()) {
340 return cascadedAttributes.keySet();
341 } else {
342 return null;
343 }
344 }
345
346 /*** {@inheritDoc} */
347 public void putAttribute(String name, Attribute value) {
348 if (attributes == null) {
349 attributes = new HashMap<String, Attribute>();
350 }
351
352 attributes.put(name, value);
353 }
354
355 /*** {@inheritDoc} */
356 public void putAttribute(String name, Attribute value, boolean cascade) {
357 Map<String, Attribute> mapToUse;
358 if (cascade) {
359 if (cascadedAttributes == null) {
360 cascadedAttributes = new HashMap<String, Attribute>();
361 }
362 mapToUse = cascadedAttributes;
363 } else {
364 if (attributes == null) {
365 attributes = new HashMap<String, Attribute>();
366 }
367 mapToUse = attributes;
368 }
369 mapToUse.put(name, value);
370 }
371
372 /*** {@inheritDoc} */
373 public void clear() {
374 templateAttribute = null;
375 preparer = null;
376 attributes.clear();
377 cascadedAttributes.clear();
378 }
379
380 /***
381 * Inherits the parent template attribute.
382 *
383 * @param parentTemplateAttribute The parent template attribute.
384 */
385 private void inheritParentTemplateAttribute(
386 Attribute parentTemplateAttribute) {
387 if (parentTemplateAttribute != null) {
388 if (templateAttribute == null) {
389 templateAttribute = new Attribute(parentTemplateAttribute);
390 } else {
391 templateAttribute.inherit(parentTemplateAttribute);
392 }
393 }
394 }
395
396 /***
397 * Copies a BasicAttributeContext in an easier way.
398 *
399 * @param context The context to copy.
400 */
401 private void copyBasicAttributeContext(BasicAttributeContext context) {
402 Attribute parentTemplateAttribute = context.getTemplateAttribute();
403 if (parentTemplateAttribute != null) {
404 this.templateAttribute = new Attribute(parentTemplateAttribute);
405 }
406 preparer = context.preparer;
407 if (context.attributes != null && !context.attributes.isEmpty()) {
408 attributes = deepCopyAttributeMap(context.attributes);
409 }
410 copyCascadedAttributes(context);
411 }
412
413 /***
414 * Copies the cascaded attributes to the current context.
415 *
416 * @param context The context to copy from.
417 */
418 private void copyCascadedAttributes(BasicAttributeContext context) {
419 if (context.cascadedAttributes != null
420 && !context.cascadedAttributes.isEmpty()) {
421 cascadedAttributes = deepCopyAttributeMap(context.cascadedAttributes);
422 }
423 }
424
425 /***
426 * Adds missing attributes to the destination map.
427 *
428 * @param source The source attribute map.
429 * @param destination The destination attribute map.
430 * @return The destination attribute map if not null, a new one otherwise.
431 */
432 private Map<String, Attribute> addMissingAttributes(Map<String, Attribute> source,
433 Map<String, Attribute> destination) {
434 if (source != null && !source.isEmpty()) {
435 if (destination == null) {
436 destination = new HashMap<String, Attribute>();
437 }
438 for (Map.Entry<String, Attribute> entry : source.entrySet()) {
439 String key = entry.getKey();
440 Attribute destAttribute = destination.get(key);
441 if (destAttribute == null) {
442 destination.put(key, entry.getValue());
443 } else if (destAttribute instanceof ListAttribute
444 && entry.getValue() instanceof ListAttribute
445 && ((ListAttribute) destAttribute).isInherit()) {
446 ((ListAttribute) destAttribute)
447 .inherit((ListAttribute) entry.getValue());
448 }
449 }
450 }
451
452 return destination;
453 }
454
455 /***
456 * Deep copies the attribute map, by creating clones (using copy
457 * constructors) of the attributes.
458 *
459 * @param attributes The attribute map to copy.
460 * @return The copied map.
461 */
462 private Map<String, Attribute> deepCopyAttributeMap(
463 Map<String, Attribute> attributes) {
464 Map<String, Attribute> retValue = new HashMap<String, Attribute>(attributes.size());
465 for (Map.Entry<String, Attribute> entry : attributes.entrySet()) {
466 Attribute toCopy = entry.getValue();
467 if (toCopy != null) {
468 retValue.put(entry.getKey(), toCopy.clone());
469 }
470 }
471 return retValue;
472 }
473 }