1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.tomahawk.application.jsp;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.tiles.access.TilesAccess;
24 import org.apache.tiles.factory.TilesContainerFactory;
25 import org.apache.tiles.TilesContainer;
26 import org.apache.tiles.TilesException;
27 import org.apache.myfaces.shared_tomahawk.webapp.webxml.ServletMapping;
28 import org.apache.myfaces.shared_tomahawk.webapp.webxml.WebXml;
29
30 import javax.faces.application.ViewHandler;
31 import javax.faces.context.ExternalContext;
32 import javax.faces.context.FacesContext;
33 import javax.faces.FacesException;
34 import javax.faces.component.UIViewRoot;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpServletResponse;
37 import javax.servlet.http.HttpSession;
38 import javax.servlet.ServletResponse;
39 import java.io.IOException;
40 import java.util.List;
41 import java.util.Locale;
42
43
44
45
46
47
48 public class JspTilesTwoViewHandlerImpl
49 extends ViewHandler {
50 private ViewHandler _viewHandler;
51
52 private static final Log log = LogFactory.getLog(JspTilesTwoViewHandlerImpl.class);
53 private static final String TILES_DEF_EXT = ".tiles";
54
55 private String tilesExtension = TILES_DEF_EXT;
56
57 public JspTilesTwoViewHandlerImpl(ViewHandler viewHandler)
58 {
59 _viewHandler = viewHandler;
60 }
61
62 private void initContainer(ExternalContext context) {
63
64 if(TilesAccess.getContainer(context.getContext())==null) {
65 try
66 {
67 TilesContainerFactory factory = TilesContainerFactory.getFactory(context.getContext());
68 TilesContainer container = factory.createTilesContainer(context.getContext());
69 TilesAccess.setContainer(context.getContext(),container);
70 }
71 catch (Exception e)
72 {
73 throw new FacesException("Error reading tiles definitions : " + e.getMessage(), e);
74 }
75 }
76 }
77
78 public void renderView(FacesContext facesContext, UIViewRoot viewToRender) throws IOException, FacesException
79 {
80 if (viewToRender == null)
81 {
82 log.fatal("viewToRender must not be null");
83 throw new NullPointerException("viewToRender must not be null");
84 }
85
86 ExternalContext externalContext = facesContext.getExternalContext();
87
88 String viewId = deriveViewId(externalContext, viewToRender.getViewId());
89
90 if(viewId==null) {
91
92 _viewHandler.renderView(facesContext, viewToRender);
93 return;
94 }
95
96
97 initContainer(externalContext);
98
99 String tilesId = deriveTileFromViewId(viewId);
100
101 TilesContainer container = TilesAccess.getContainer(externalContext.getContext());
102
103 Object[] requestObjects = {externalContext.getRequest(), externalContext.getResponse()};
104
105 if(container.isValidDefinition(tilesId, requestObjects)) {
106
107
108 setViewId(viewToRender, viewId, facesContext);
109
110 renderTilesView(externalContext, requestObjects, container, viewToRender, viewId, tilesId);
111 }
112 else {
113
114
115 _viewHandler.renderView(facesContext, viewToRender);
116 }
117 }
118
119 private void renderTilesView(ExternalContext externalContext, Object[] requestObjects, TilesContainer container, UIViewRoot viewToRender, String viewId, String tilesId) {
120 handleCharacterEncoding(viewId, externalContext, viewToRender);
121
122 container.startContext(requestObjects);
123 try {
124 container.render(tilesId,requestObjects);
125 } catch (TilesException e) {
126 throw new FacesException(e);
127 }
128 finally {
129 container.endContext(requestObjects);
130 }
131
132 handleCharacterEncodingPostDispatch(externalContext);
133 }
134
135 private void setViewId(UIViewRoot viewToRender, String viewId, FacesContext facesContext) {
136 viewToRender.setViewId(viewId);
137 if(facesContext.getViewRoot()!=null) {
138 facesContext.getViewRoot().setViewId(viewId);
139 }
140 }
141
142 private String deriveTileFromViewId(String viewId) {
143 String tilesId = viewId;
144 int idx = tilesId.lastIndexOf('.');
145 if (idx > 0)
146 {
147 tilesId = tilesId.substring(0, idx) + tilesExtension;
148 }
149 else
150 {
151 tilesId = tilesId + tilesExtension;
152 }
153 return tilesId;
154 }
155
156 private String deriveViewId(ExternalContext externalContext, String viewId) {
157 ServletMapping servletMapping = getServletMapping(externalContext);
158
159 String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
160 String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
161 if (servletMapping.isExtensionMapping())
162 {
163 if (!viewId.endsWith(suffix))
164 {
165 int dot = viewId.lastIndexOf('.');
166 if (dot == -1)
167 {
168 if (log.isTraceEnabled()) log.trace("Current viewId has no extension, appending default suffix " + suffix);
169 return viewId + suffix;
170 }
171 else
172 {
173 if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
174 return viewId.substring(0, dot) + suffix;
175 }
176 }
177
178
179 return viewId;
180 }
181 else if (!viewId.endsWith(suffix))
182 {
183
184 return null;
185 }
186 else {
187
188 return viewId;
189 }
190 }
191
192 private void handleCharacterEncodingPostDispatch(ExternalContext externalContext) {
193
194 if (externalContext.getRequest() instanceof HttpServletRequest) {
195 HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
196 HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
197 HttpSession session = request.getSession(false);
198
199 if (session != null) {
200 session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, response.getCharacterEncoding());
201 }
202 }
203 }
204
205 private void handleCharacterEncoding(String viewId, ExternalContext externalContext, UIViewRoot viewToRender) {
206 if (log.isTraceEnabled()) log.trace("Dispatching to " + viewId);
207
208
209 if (externalContext.getResponse() instanceof ServletResponse) {
210 ServletResponse response = (ServletResponse) externalContext.getResponse();
211 response.setLocale(viewToRender.getLocale());
212 }
213 }
214
215 private static ServletMapping getServletMapping(ExternalContext externalContext)
216 {
217 String servletPath = externalContext.getRequestServletPath();
218 String requestPathInfo = externalContext.getRequestPathInfo();
219
220 WebXml webxml = WebXml.getWebXml(externalContext);
221 List mappings = webxml.getFacesServletMappings();
222
223 boolean isExtensionMapping = requestPathInfo == null;
224
225 for (int i = 0, size = mappings.size(); i < size; i++)
226 {
227 ServletMapping servletMapping = (ServletMapping) mappings.get(i);
228 if (servletMapping.isExtensionMapping() == isExtensionMapping)
229 {
230 String urlpattern = servletMapping.getUrlPattern();
231 if (isExtensionMapping)
232 {
233 String extension = urlpattern.substring(1, urlpattern.length());
234 if (servletPath.endsWith(extension))
235 {
236 return servletMapping;
237 }
238 }
239 else
240 {
241 urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
242
243
244
245 if (servletPath.equals(urlpattern))
246 {
247 return servletMapping;
248 }
249 }
250 }
251 }
252 log.error("could not find pathMapping for servletPath = " + servletPath +
253 " requestPathInfo = " + requestPathInfo);
254 throw new IllegalArgumentException("could not find pathMapping for servletPath = " + servletPath +
255 " requestPathInfo = " + requestPathInfo);
256 }
257
258
259 public Locale calculateLocale(FacesContext context)
260 {
261 return _viewHandler.calculateLocale(context);
262 }
263
264 public String calculateRenderKitId(FacesContext context)
265 {
266 return _viewHandler.calculateRenderKitId(context);
267 }
268
269 public UIViewRoot createView(FacesContext context, String viewId)
270 {
271 return _viewHandler.createView(context, viewId);
272 }
273
274 public String getActionURL(FacesContext context, String viewId)
275 {
276 return _viewHandler.getActionURL(context, viewId);
277 }
278
279 public String getResourceURL(FacesContext context, String path)
280 {
281 return _viewHandler.getResourceURL(context, path);
282 }
283
284 public UIViewRoot restoreView(FacesContext context, String viewId)
285 {
286 return _viewHandler.restoreView(context, viewId);
287 }
288
289 public void writeState(FacesContext context) throws IOException
290 {
291 _viewHandler.writeState(context);
292 }
293
294 }