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.context;
23
24 import java.io.Serializable;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.Stack;
31
32 import org.apache.tiles.Attribute;
33 import org.apache.tiles.AttributeContext;
34
35 /***
36 * Basic implementation for <code>AttributeContext</code>.
37 *
38 * @version $Rev: 616498 $ $Date: 2008-01-29 20:40:35 +0100 (Tue, 29 Jan 2008) $
39 */
40 public class BasicAttributeContext implements AttributeContext, Serializable {
41
42 /***
43 * Name used to store attribute context stack.
44 */
45 private static final String ATTRIBUTE_CONTEXT_STACK =
46 "org.apache.tiles.AttributeContext.STACK";
47
48 /***
49 * Template attributes.
50 */
51 private Map<String, Attribute> attributes = null;
52
53 /***
54 * Constructor.
55 */
56 public BasicAttributeContext() {
57 super();
58 }
59
60 /***
61 * Constructor.
62 * Create a context and set specified attributes.
63 *
64 * @param attributes Attributes to initialize context.
65 */
66 public BasicAttributeContext(Map<String, Attribute> attributes) {
67 if (attributes != null) {
68 this.attributes = new HashMap<String, Attribute>(attributes);
69 }
70 }
71
72
73 /***
74 * Copy constructor.
75 *
76 * @param context The constructor to copy.
77 */
78 public BasicAttributeContext(AttributeContext context) {
79 this.attributes = new HashMap<String, Attribute>();
80 Iterator<String> names = context.getAttributeNames();
81 while (names.hasNext()) {
82 String name = names.next();
83 attributes.put(name, context.getAttribute(name));
84 }
85 }
86
87 /***
88 * Add all attributes to this context.
89 * Copies all of the mappings from the specified attribute map to this context.
90 * New attribute mappings will replace any mappings that this context had for any of the keys
91 * currently in the specified attribute map.
92 *
93 * @param newAttributes Attributes to add.
94 */
95 public void addAll(Map<String, Attribute> newAttributes) {
96 if (newAttributes == null) {
97 return;
98 }
99
100 if (attributes == null) {
101 attributes = new HashMap<String, Attribute>(newAttributes);
102 return;
103 }
104
105 attributes.putAll(newAttributes);
106 }
107
108 /***
109 * Add all missing attributes to this context.
110 * Copies all of the mappings from the specified attributes map to this context.
111 * New attribute mappings will be added only if they don't already exist in
112 * this context.
113 *
114 * @param defaultAttributes Attributes to add.
115 */
116 public void addMissing(Map<String, Attribute> defaultAttributes) {
117 if (defaultAttributes == null) {
118 return;
119 }
120
121 if (attributes == null) {
122 attributes = new HashMap<String, Attribute>(defaultAttributes);
123 return;
124 }
125
126 Set<Map.Entry<String, Attribute>> entries = defaultAttributes.entrySet();
127 for (Map.Entry<String, Attribute> entry : entries) {
128 if (!attributes.containsKey(entry.getKey())) {
129 attributes.put(entry.getKey(), entry.getValue());
130 }
131 }
132 }
133
134 /***
135 * Get an attribute from context.
136 *
137 * @param name Name of the attribute.
138 * @return <{Attribute}>
139 */
140 public Attribute getAttribute(String name) {
141 if (attributes == null) {
142 return null;
143 }
144
145 return attributes.get(name);
146 }
147
148 /***
149 * Get names of all attributes.
150 *
151 * @return <{Attribute}>
152 */
153 public Iterator<String> getAttributeNames() {
154 if (attributes == null) {
155 return new ArrayList<String>().iterator();
156 }
157
158 return attributes.keySet().iterator();
159 }
160
161 /***
162 * Put a new attribute to context.
163 *
164 * @param name Name of the attribute.
165 * @param value Value of the attribute.
166 */
167 public void putAttribute(String name, Attribute value) {
168 if (attributes == null) {
169 attributes = new HashMap<String, Attribute>();
170 }
171
172 attributes.put(name, value);
173 }
174
175 /***
176 * Get attribute context from request.
177 *
178 * @param tilesContext current Tiles application context.
179 * @return BasicAttributeContext or null if context is not found or an
180 * jspException is present in the request.
181 * @deprecated Use {@link TilesContainer#getAttributeContext(Object...)}.
182 */
183 @Deprecated
184 public static AttributeContext getContext(TilesRequestContext tilesContext) {
185 Stack<AttributeContext> contextStack = getContextStack(tilesContext);
186 if (!contextStack.isEmpty()) {
187 return contextStack.peek();
188 } else {
189 return null;
190 }
191 }
192
193 /***
194 * Returns the context stack.
195 *
196 * @param tilesContext The Tiles context object to use.
197 * @return The needed stack of contexts.
198 * @deprecated Use {@link TilesContainer#getAttributeContext(Object...)},
199 * {@link TilesContainer#startContext(Object...)} or
200 * {@link TilesContainer#endContext(Object...)}.
201 */
202 @Deprecated
203 @SuppressWarnings("unchecked")
204 public static Stack<AttributeContext> getContextStack(TilesRequestContext tilesContext) {
205 Stack<AttributeContext> contextStack =
206 (Stack<AttributeContext>) tilesContext.getRequestScope().get(
207 BasicAttributeContext.ATTRIBUTE_CONTEXT_STACK);
208 if (contextStack == null) {
209 contextStack = new Stack<AttributeContext>();
210 tilesContext.getRequestScope().put(BasicAttributeContext.ATTRIBUTE_CONTEXT_STACK,
211 contextStack);
212 }
213
214 return contextStack;
215 }
216
217 /***
218 * Pushes a context object in the stack.
219 *
220 * @param context The context to push.
221 * @param tilesContext The Tiles context object to use.
222 * @deprecated Use {@link TilesContainer#startContext(Object...)}.
223 */
224 @Deprecated
225 public static void pushContext(AttributeContext context,
226 TilesRequestContext tilesContext) {
227 Stack<AttributeContext> contextStack = getContextStack(tilesContext);
228 contextStack.push(context);
229 }
230
231 /***
232 * Pops a context object out of the stack.
233 *
234 * @param tilesContext The Tiles context object to use.
235 * @return The popped context object.
236 * @deprecated Use {@link TilesContainer#endContext(Object...)}.
237 */
238 public static AttributeContext popContext(TilesRequestContext tilesContext) {
239 Stack<AttributeContext> contextStack = getContextStack(tilesContext);
240 return contextStack.pop();
241 }
242
243 /*** {@inheritDoc} */
244 public void clear() {
245 attributes.clear();
246 }
247 }