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 java.io.IOException;
22 import java.util.List;
23 import java.util.Locale;
24
25 import javax.faces.FacesException;
26 import javax.faces.application.ViewHandler;
27 import javax.faces.component.UIViewRoot;
28 import javax.faces.context.ExternalContext;
29 import javax.faces.context.FacesContext;
30 import javax.servlet.ServletContext;
31 import javax.servlet.ServletRequest;
32 import javax.servlet.ServletResponse;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35 import javax.servlet.http.HttpSession;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.myfaces.shared_tomahawk.webapp.webxml.ServletMapping;
40 import org.apache.myfaces.shared_tomahawk.webapp.webxml.WebXml;
41 import org.apache.struts.tiles.ComponentContext;
42 import org.apache.struts.tiles.ComponentDefinition;
43 import org.apache.struts.tiles.Controller;
44 import org.apache.struts.tiles.DefinitionsFactory;
45 import org.apache.struts.tiles.DefinitionsFactoryConfig;
46 import org.apache.struts.tiles.DefinitionsFactoryException;
47 import org.apache.struts.tiles.TilesUtil;
48
49
50
51
52
53 public class JspTilesViewHandlerImpl
54 extends ViewHandler
55 {
56 private ViewHandler _viewHandler;
57
58 private static final Log log = LogFactory.getLog(JspTilesViewHandlerImpl.class);
59 private static final String TILES_DEF_EXT = ".tiles";
60 private static final String TILES_DEF_ATTR = "tiles-definitions";
61 private static final String TILES_EXT_ATTR = "tiles-extension";
62
63 private String tilesExtension = TILES_DEF_EXT;
64 private DefinitionsFactory _definitionsFactory;
65
66 public JspTilesViewHandlerImpl(ViewHandler viewHandler)
67 {
68 _viewHandler = viewHandler;
69 }
70
71 private DefinitionsFactory getDefinitionsFactory()
72 {
73 if (_definitionsFactory == null)
74 {
75 if (log.isDebugEnabled()) log.debug("JspTilesViewHandlerImpl init");
76 ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
77 String tilesDefinitions = context.getInitParameter(TILES_DEF_ATTR);
78 if (tilesDefinitions == null)
79 {
80 log.fatal("No Tiles definition found. Specify Definition files by adding "
81 + TILES_DEF_ATTR + " param in your web.xml");
82 return null;
83 }
84
85 String tilezExtension = context.getInitParameter(TILES_EXT_ATTR);
86 if (tilezExtension != null)
87 {
88 tilesExtension = tilezExtension;
89 if (log.isDebugEnabled())
90 {
91 log.debug("Using non-default tiles extension of: " + tilesExtension);
92 }
93 }
94
95 DefinitionsFactoryConfig factoryConfig = new DefinitionsFactoryConfig();
96 factoryConfig.setDefinitionConfigFiles(tilesDefinitions);
97 try
98 {
99 if (log.isDebugEnabled()) log.debug("Reading tiles definitions");
100 _definitionsFactory = TilesUtil.createDefinitionsFactory((ServletContext)context.getContext(),
101 factoryConfig);
102 }
103 catch (DefinitionsFactoryException e)
104 {
105 log.fatal("Error reading tiles definitions", e);
106 return null;
107 }
108 }
109 return _definitionsFactory;
110 }
111
112 public void renderView(FacesContext facesContext, UIViewRoot viewToRender) throws IOException, FacesException
113 {
114 if (viewToRender == null)
115 {
116 log.fatal("viewToRender must not be null");
117 throw new NullPointerException("viewToRender must not be null");
118 }
119
120 ExternalContext externalContext = facesContext.getExternalContext();
121
122 String viewId = facesContext.getViewRoot().getViewId();
123 ServletMapping servletMapping = getServletMapping(externalContext);
124
125 String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
126 String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
127 if (servletMapping.isExtensionMapping())
128 {
129 if (!viewId.endsWith(suffix))
130 {
131 int dot = viewId.lastIndexOf('.');
132 if (dot == -1)
133 {
134 if (log.isTraceEnabled()) log.trace("Current viewId has no extension, appending default suffix " + suffix);
135 viewId = viewId + suffix;
136 }
137 else
138 {
139 if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
140 viewId = viewId.substring(0, dot) + suffix;
141 }
142 facesContext.getViewRoot().setViewId(viewId);
143 }
144 }
145 else if (!viewId.endsWith(suffix))
146 {
147
148 dispatch(externalContext, viewToRender, viewId);
149 return;
150 }
151
152 String tilesId = viewId;
153 int idx = tilesId.lastIndexOf('.');
154 if (idx > 0)
155 {
156 tilesId = tilesId.substring(0, idx) + tilesExtension;
157 }
158 else
159 {
160 tilesId = tilesId + tilesExtension;
161 }
162 ServletRequest request = (ServletRequest)externalContext.getRequest();
163 ServletContext servletContext = (ServletContext)externalContext.getContext();
164
165 ComponentDefinition definition = null;
166 try
167 {
168 definition = getDefinitionsFactory().getDefinition(tilesId, request, servletContext);
169
170 if (definition == null)
171 {
172
173
174
175
176 int slashIndex = tilesId.indexOf("/");
177 if (slashIndex == 0)
178 {
179 tilesId = tilesId.substring(1);
180 definition = getDefinitionsFactory().getDefinition(tilesId, request, servletContext);
181 }
182 }
183
184 if (definition != null)
185 {
186
187 ComponentContext tileContext = ComponentContext.getContext(request);
188 if (tileContext == null)
189 {
190 tileContext = new ComponentContext(definition.getAttributes());
191 ComponentContext.setContext(tileContext, request);
192 }
193 else
194 {
195 tileContext.addMissing(definition.getAttributes());
196 }
197 viewId = definition.getPage();
198
199 Controller tilesController = definition.getOrCreateController();
200 if (tilesController != null) {
201 ServletResponse response = (ServletResponse) externalContext.getResponse();
202 if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
203 try {
204 tilesController.execute(tileContext, (HttpServletRequest) request,
205 (HttpServletResponse) response, servletContext);
206 } catch (Exception e) {
207 throw new FacesException(e);
208 }
209 }
210 }
211 }
212 }
213 catch (DefinitionsFactoryException e)
214 {
215 throw new FacesException(e);
216 }
217 catch (InstantiationException e)
218 {
219 throw new FacesException(e);
220 }
221
222 dispatch(externalContext, viewToRender, viewId);
223 }
224
225 private void dispatch(ExternalContext externalContext, UIViewRoot viewToRender, String viewId)
226 throws IOException
227 {
228 if (log.isTraceEnabled()) log.trace("Dispatching to " + viewId);
229
230
231 if (externalContext.getResponse() instanceof ServletResponse) {
232 ServletResponse response = (ServletResponse) externalContext.getResponse();
233 response.setLocale(viewToRender.getLocale());
234 }
235
236 externalContext.dispatch(viewId);
237
238
239 if (externalContext.getRequest() instanceof HttpServletRequest) {
240 HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
241 HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
242 HttpSession session = request.getSession(false);
243
244 if (session != null) {
245 session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, response.getCharacterEncoding());
246 }
247 }
248
249
250 }
251
252 private static ServletMapping getServletMapping(ExternalContext externalContext)
253 {
254 String servletPath = externalContext.getRequestServletPath();
255 String requestPathInfo = externalContext.getRequestPathInfo();
256
257 WebXml webxml = WebXml.getWebXml(externalContext);
258 List mappings = webxml.getFacesServletMappings();
259
260 boolean isExtensionMapping = requestPathInfo == null;
261
262 for (int i = 0, size = mappings.size(); i < size; i++)
263 {
264 ServletMapping servletMapping = (ServletMapping) mappings.get(i);
265 if (servletMapping.isExtensionMapping() == isExtensionMapping)
266 {
267 String urlpattern = servletMapping.getUrlPattern();
268 if (isExtensionMapping)
269 {
270 String extension = urlpattern.substring(1, urlpattern.length());
271 if (servletPath.endsWith(extension))
272 {
273 return servletMapping;
274 }
275 }
276 else
277 {
278 urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
279
280
281
282 if (servletPath.equals(urlpattern))
283 {
284 return servletMapping;
285 }
286 }
287 }
288 }
289 log.error("could not find pathMapping for servletPath = " + servletPath +
290 " requestPathInfo = " + requestPathInfo);
291 throw new IllegalArgumentException("could not find pathMapping for servletPath = " + servletPath +
292 " requestPathInfo = " + requestPathInfo);
293 }
294
295
296 public Locale calculateLocale(FacesContext context)
297 {
298 return _viewHandler.calculateLocale(context);
299 }
300
301 public String calculateRenderKitId(FacesContext context)
302 {
303 return _viewHandler.calculateRenderKitId(context);
304 }
305
306 public UIViewRoot createView(FacesContext context, String viewId)
307 {
308 return _viewHandler.createView(context, viewId);
309 }
310
311 public String getActionURL(FacesContext context, String viewId)
312 {
313 return _viewHandler.getActionURL(context, viewId);
314 }
315
316 public String getResourceURL(FacesContext context, String path)
317 {
318 return _viewHandler.getResourceURL(context, path);
319 }
320
321 public UIViewRoot restoreView(FacesContext context, String viewId)
322 {
323 return _viewHandler.restoreView(context, viewId);
324 }
325
326 public void writeState(FacesContext context) throws IOException
327 {
328 _viewHandler.writeState(context);
329 }
330
331 }