1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.tiles.impl.mgmt;
22
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.apache.tiles.Definition;
27 import org.apache.tiles.TilesContainer;
28 import org.apache.tiles.TilesContainerWrapper;
29 import org.apache.tiles.definition.NoSuchDefinitionException;
30 import org.apache.tiles.mgmt.MutableTilesContainer;
31 import org.apache.tiles.request.Request;
32
33
34
35
36
37
38
39 public class CachingTilesContainer extends TilesContainerWrapper implements MutableTilesContainer {
40
41
42
43
44 private static final String DEFAULT_DEFINITIONS_ATTRIBUTE_NAME =
45 "org.apache.tiles.impl.mgmt.DefinitionManager.DEFINITIONS";
46
47
48
49
50 private String definitionsAttributeName;
51
52
53
54
55
56 public CachingTilesContainer(TilesContainer originalContainer) {
57 super(originalContainer);
58 definitionsAttributeName = DEFAULT_DEFINITIONS_ATTRIBUTE_NAME;
59 }
60
61
62
63
64
65
66
67 public CachingTilesContainer(TilesContainer originalContainer, String definitionsAttributeName) {
68 super(originalContainer);
69 this.definitionsAttributeName = definitionsAttributeName;
70 if (this.definitionsAttributeName == null) {
71 this.definitionsAttributeName = DEFAULT_DEFINITIONS_ATTRIBUTE_NAME;
72 }
73 }
74
75
76
77
78
79
80
81
82
83
84 public Definition getDefinition(String definition,
85 Request request) {
86 Definition retValue = null;
87 retValue = getCustomDefinition(definition, request);
88 if (retValue == null) {
89 retValue = super.getDefinition(definition, request);
90 }
91 return retValue;
92 }
93
94
95 @Override
96 public boolean isValidDefinition(String definition, Request request) {
97 if (getCustomDefinition(definition, request) != null) {
98 return true;
99 }
100 return super.isValidDefinition(definition, request);
101 }
102
103
104 @Override
105 public void register(Definition definition, Request request) {
106 Map<String, Definition> definitions = getOrCreateDefinitions(request);
107 if (definition.getName() == null) {
108 definition.setName(getNextUniqueDefinitionName(definitions));
109 }
110
111 if (definition.isExtending()) {
112 this.resolveInheritance(definition, request);
113 }
114
115 definitions.put(definition.getName(), definition);
116 }
117
118
119 @Override
120 public void render(String definition, Request request) {
121 Definition toRender = getDefinition(definition, request);
122 if (toRender == null) {
123 throw new NoSuchDefinitionException(
124 "Cannot find definition named '" + definition + "'");
125 }
126 super.render(toRender, request);
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 private void resolveInheritance(Definition definition,
143 Request request) {
144
145 if (!definition.isExtending()) {
146 return;
147 }
148
149 String parentDefinitionName = definition.getExtends();
150
151 boolean recurse = true;
152 Definition parent = getCustomDefinition(parentDefinitionName, request);
153 if (parent == null) {
154 parent = container.getDefinition(parentDefinitionName, request);
155 recurse = false;
156 }
157
158 if (parent == null) {
159 throw new NoSuchDefinitionException(
160 "Error while resolving definition inheritance: child '"
161 + definition.getName()
162 + "' can't find its ancestor '"
163 + parentDefinitionName
164 + "'. Please check your description file.");
165 }
166
167
168 if (recurse) {
169 resolveInheritance(parent, request);
170 }
171 definition.inherit(parent);
172 }
173
174
175
176
177
178
179
180 @SuppressWarnings("unchecked")
181 private Map<String, Definition> getDefinitions(
182 Request request) {
183 return (Map<String, Definition>) request.getContext("request")
184 .get(definitionsAttributeName);
185 }
186
187
188
189
190
191
192
193
194 @SuppressWarnings("unchecked")
195 private Map<String, Definition> getOrCreateDefinitions(
196 Request request) {
197 Map<String, Definition> definitions =
198 (Map<String, Definition>) request.getContext("request").get(definitionsAttributeName);
199 if (definitions == null) {
200 definitions = new HashMap<String, Definition>();
201 request.getContext("request")
202 .put(definitionsAttributeName, definitions);
203 }
204
205 return definitions;
206 }
207
208
209
210
211
212
213
214
215 private String getNextUniqueDefinitionName(
216 Map<String, Definition> definitions) {
217 String candidate;
218 int anonymousDefinitionIndex = 1;
219
220 do {
221 candidate = "$anonymousMutableDefinition" + anonymousDefinitionIndex;
222 anonymousDefinitionIndex++;
223 } while (definitions.containsKey(candidate));
224
225 return candidate;
226 }
227
228
229
230
231
232
233
234
235 private Definition getCustomDefinition(String definition, Request request) {
236 Map<String, Definition> definitions = getDefinitions(request);
237 if (definitions != null) {
238 return definitions.get(definition);
239 }
240 return null;
241 }
242 }