1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springbyexample.web.servlet.view.tiles2;
18
19 import javax.servlet.ServletContext;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.apache.tiles.Attribute;
24 import org.apache.tiles.AttributeContext;
25 import org.apache.tiles.TilesContainer;
26 import org.apache.tiles.TilesException;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.util.StringUtils;
30 import org.springframework.web.servlet.support.JstlUtils;
31 import org.springframework.web.servlet.support.RequestContext;
32 import org.springframework.web.util.WebUtils;
33
34
35
36
37
38
39 public class DynamicTilesViewProcessor {
40
41 final Logger logger = LoggerFactory.getLogger(DynamicTilesViewProcessor.class);
42
43
44
45
46 private String derivedDefinitionName = null;
47
48 private String tilesDefinitionName = "mainTemplate";
49 private String tilesBodyAttributeName = "content";
50 private String tilesDefinitionDelimiter = ".";
51
52
53
54
55
56
57 public void setTilesDefinitionName(String tilesDefinitionName) {
58 this.tilesDefinitionName = tilesDefinitionName;
59 }
60
61
62
63
64
65
66 public void setTilesBodyAttributeName(String tilesBodyAttributeName) {
67 this.tilesBodyAttributeName = tilesBodyAttributeName;
68 }
69
70
71
72
73
74
75
76
77
78 public void setTilesDefinitionDelimiter(String tilesDefinitionDelimiter) {
79 this.tilesDefinitionDelimiter = tilesDefinitionDelimiter;
80 }
81
82
83
84
85 protected void renderMergedOutputModel(String beanName, String url,
86 ServletContext servletContext,
87 HttpServletRequest request, HttpServletResponse response,
88 TilesContainer container)
89 throws Exception {
90 JstlUtils.exposeLocalizationContext(new RequestContext(request, servletContext));
91
92 if (!response.isCommitted()) {
93
94
95
96
97
98
99 if (servletContext.getMajorVersion() == 2 && servletContext.getMinorVersion() < 5) {
100 WebUtils.exposeForwardRequestAttributes(request);
101 }
102 }
103
104 String definitionName = startDynamicDefinition(beanName, url, request, response, container);
105
106 container.render(definitionName, request, response);
107
108 endDynamicDefinition(definitionName, beanName, request, response, container);
109 }
110
111
112
113
114 protected String startDynamicDefinition(String beanName, String url,
115 HttpServletRequest request, HttpServletResponse response,
116 TilesContainer container)
117 throws TilesException {
118 String definitionName = processTilesDefinitionName(beanName, container,
119 request, response);
120
121
122
123 if (!definitionName.equals(beanName)) {
124 Attribute attr = new Attribute();
125 attr.setName(tilesBodyAttributeName);
126 attr.setValue(url);
127
128 AttributeContext attributeContext = container.startContext(request, response);
129 attributeContext.putAttribute(tilesBodyAttributeName, attr);
130
131 logger.debug("URL used for Tiles body. url='" + url + "'.");
132 }
133
134 return definitionName;
135 }
136
137
138
139
140 protected void endDynamicDefinition(String definitionName, String beanName,
141 HttpServletRequest request, HttpServletResponse response,
142 TilesContainer container) {
143 if (!definitionName.equals(beanName)) {
144 container.endContext(request, response);
145 }
146 }
147
148
149
150
151
152
153
154
155
156 protected String processTilesDefinitionName(String beanName,
157 TilesContainer container,
158 HttpServletRequest request,
159 HttpServletResponse response)
160 throws TilesException {
161
162
163
164 if (derivedDefinitionName != null) {
165 return derivedDefinitionName;
166 } else if (container.isValidDefinition(beanName, request, response)) {
167 derivedDefinitionName = beanName;
168
169 return beanName;
170 } else {
171 String result = null;
172
173 StringBuilder sb = new StringBuilder();
174 int lastIndex = beanName.lastIndexOf("/");
175 boolean rootDefinition = false;
176
177
178 if (StringUtils.hasLength(tilesDefinitionDelimiter)) {
179 sb.append(tilesDefinitionDelimiter);
180 }
181
182
183 if (lastIndex == -1) {
184 rootDefinition = true;
185 } else {
186 String path = (beanName != null ? beanName.substring(0, lastIndex) : "");
187
188 if (StringUtils.hasLength(tilesDefinitionDelimiter)) {
189 path = StringUtils.replace(path, "/", tilesDefinitionDelimiter);
190
191 }
192
193 sb.append(path);
194
195 if (StringUtils.hasLength(tilesDefinitionDelimiter)) {
196 sb.append(tilesDefinitionDelimiter);
197 }
198 }
199
200 sb.append(tilesDefinitionName);
201
202 if (container.isValidDefinition(sb.toString(), request, response)) {
203 result = sb.toString();
204 } else if (!rootDefinition) {
205 String root = null;
206
207 if (StringUtils.hasLength(tilesDefinitionDelimiter)) {
208 root = tilesDefinitionDelimiter;
209 }
210
211 root += tilesDefinitionName;
212
213 if (container.isValidDefinition(root, request, response)) {
214 result = root;
215 } else {
216 throw new TilesException("No defintion of found for " +
217 "'" + root +"'" +
218 " or '" + sb.toString() +"'");
219 }
220 }
221
222 derivedDefinitionName = result;
223
224 return result;
225 }
226 }
227
228 }