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