| CODENOTIFIER | HelpYou are not signed inSign in |
Project: Stripes
Revision: 945
Author: javelotinfo
Date: 25 Jun 2008 13:06:31
Changes:Made the DefaultViewActionBean attempted views easier to customize
Files:| ... | ...@@ -1,5 +1,6 @@ | |
| 1 | 1 | package net.sourceforge.stripes.controller; |
| 2 | 2 | |
| 3 | import java.util.List; | |
| 3 | 4 | import org.testng.Assert; |
| 4 | 5 | import org.testng.annotations.Test; |
| 5 | 6 | import net.sourceforge.stripes.action.UrlBinding; |
| ... | ...@@ -74,4 +75,13 @@ | |
| 74 | 75 | getAnnotation(UrlBinding.class).value()); |
| 75 | 76 | } |
| 76 | 77 | |
| 78 | @Test(groups="fast") | |
| 79 | public void testGetFindViewAttempts() { | |
| 80 | String urlBinding = "/account/ViewAccount.action"; | |
| 81 | List<String> viewAttempts = this.resolver.getFindViewAttempts(urlBinding); | |
| 82 | Assert.assertEquals(viewAttempts.size(), 3); | |
| 83 | Assert.assertEquals(viewAttempts.get(0), "/account/ViewAccount.jsp"); | |
| 84 | Assert.assertEquals(viewAttempts.get(1), "/account/viewAccount.jsp"); | |
| 85 | Assert.assertEquals(viewAttempts.get(2), "/account/view_account.jsp"); | |
| 86 | } | |
| 77 | 87 | } |
| ... | ...@@ -27,6 +27,7 @@ | |
| 27 | 27 | import java.lang.reflect.Method; |
| 28 | 28 | import java.lang.reflect.Modifier; |
| 29 | 29 | import java.net.MalformedURLException; |
| 30 | import java.util.ArrayList; | |
| 30 | 31 | import java.util.Collections; |
| 31 | 32 | import java.util.List; |
| 32 | 33 | import java.util.Set; |
| ... | ...@@ -70,12 +71,12 @@ | |
| 70 | 71 | * URL that is not bound to an ActionBean the resolver will attempt to map the request to a view |
| 71 | 72 | * and return a 'dummy' ActionBean that will take the user to the view. The exact behaviour is |
| 72 | 73 | * modifiable by overriding one or more of |
| 73 | * {@link #handleActionBeanNotFound(ActionBeanContext, String)} or {@link #findView(String)}. The | |
| 74 | * default behaviour is to map the URL being requested to three potential JSP names/paths, check | |
| 75 | * for the existence of a JSP at those locations and if one exists then to return an ActionBean | |
| 76 | * that will render the view. For example if a user requested '/account/ViewAccount.action' but | |
| 77 | * an ActionBean does not yet exist bound to that URL, the resolver will check for JSPs in the | |
| 78 | * following order:</p> | |
| 74 | * {@link #handleActionBeanNotFound(ActionBeanContext, String)}, {@link #findView(String)} or | |
| 75 | * {@link #getFindViewAttempts(String)}. The default behaviour is to map the URL being requested | |
| 76 | * to three potential JSP names/paths, check for the existence of a JSP at those locations and if | |
| 77 | * one exists then to return an ActionBean that will render the view. For example if a user | |
| 78 | * requested '/account/ViewAccount.action' but an ActionBean does not yet exist bound to that URL, | |
| 79 | * the resolver will check for JSPs in the following order:</p> | |
| 79 | 80 | * |
| 80 | 81 | * <ul> |
| 81 | 82 | * <li>/account/ViewAccount.jsp</li> |
| ... | ...@@ -212,6 +213,8 @@ | |
| 212 | 213 | /** |
| 213 | 214 | * Returns a list of suffixes to be removed from the end of the Action Bean class name, if present. |
| 214 | 215 | * The defaults are ["Bean", "Action"]. |
| 216 | * | |
| 217 | * @since Stripes 1.5 | |
| 215 | 218 | */ |
| 216 | 219 | protected List<String> getActionBeanSuffixes() { |
| 217 | 220 | return DEFAULT_ACTION_BEAN_SUFFIXES; |
| ... | ...@@ -299,76 +302,87 @@ | |
| 299 | 302 | |
| 300 | 303 | /** |
| 301 | 304 | * <p>Attempts to locate a default view for the urlBinding provided and return a |
| 302 | * ForwardResolution that will take the user to the view. Looks for views by | |
| 303 | * converting the incoming urlBinding with the following rules. For example if the | |
| 304 | * urlBinding is '/account/ViewAccount.action' the following views will be looked for | |
| 305 | * in order:</p> | |
| 306 | * | |
| 307 | * <ul> | |
| 308 | * <li>/account/ViewAccount.jsp</li> | |
| 309 | * <li>/account/viewAccount.jsp</li> | |
| 310 | * <li>/account/view_account.jsp</li> | |
| 311 | * </ul> | |
| 305 | * ForwardResolution that will take the user to the view. Looks for views by using the | |
| 306 | * list of attempts returned by {@link #getFindViewAttempts(String)}. | |
| 312 | 307 | * |
| 313 | 308 | * <p>For each view name derived a check is performed using |
| 314 | 309 | * {@link ServletContext#getResource(String)} to see if there is a file located at that URL. |
| 315 | 310 | * Only if a file actually exists will a Resolution be returned.</p> |
| 316 | 311 | * |
| 317 | * <p>Can be overridden to look for views with a different pattern, or to provide a different | |
| 318 | * kind of resolution. It is strongly recommended when overriding this method to check for | |
| 319 | * the actual existence of views prior to manufacturing a resolution in order not to cause | |
| 320 | * confusion when URLs are mistyped.</p> | |
| 312 | * <p>Can be overridden to provide a different kind of resolution. It is strongly recommended | |
| 313 | * when overriding this method to check for the actual existence of views prior to manufacturing | |
| 314 | * a resolution in order not to cause confusion when URLs are mistyped.</p> | |
| 321 | 315 | * |
| 322 | 316 | * @param urlBinding the url being accessed by the client in the current request |
| 323 | 317 | * @return a Resolution if a default view can be found, or null otherwise |
| 324 | 318 | * @since Stripes 1.3 |
| 325 | 319 | */ |
| 326 | 320 | protected Resolution findView(String urlBinding) { |
| 327 | int lastPeriod = urlBinding.lastIndexOf('.'); | |
| 328 | String path = urlBinding.substring(0, urlBinding.lastIndexOf("/") + 1); | |
| 329 | String name = (lastPeriod >= path.length()) ? urlBinding.substring(path.length(), lastPeriod) | |
| 330 | : urlBinding.substring(path.length()); | |
| 321 | List<String> attempts = getFindViewAttempts(urlBinding); | |
| 331 | 322 | |
| 332 | 323 | ServletContext ctx = StripesFilter.getConfiguration() |
| 333 | 324 | .getBootstrapPropertyResolver().getFilterConfig().getServletContext(); |
| 334 | 325 | |
| 335 | try { | |
| 336 | // This will try /account/ViewAccount.jsp | |
| 337 | String jsp = path + name + ".jsp"; | |
| 338 | if (ctx.getResource(jsp) != null) { | |
| 339 | return new ForwardResolution(jsp); | |
| 326 | for (String jsp : attempts) { | |
| 327 | try { | |
| 328 | // This will try /account/ViewAccount.jsp | |
| 329 | if (ctx.getResource(jsp) != null) { | |
| 330 | return new ForwardResolution(jsp); | |
| 331 | } | |
| 340 | 332 | } |
| 341 | ||
| 342 | // This will try /account/viewAccount.jsp | |
| 343 | name = Character.toLowerCase(name.charAt(0)) + name.substring(1); | |
| 344 | jsp = path + name + ".jsp"; | |
| 345 | if (ctx.getResource(jsp) != null) { | |
| 346 | return new ForwardResolution(jsp); | |
| 333 | catch (MalformedURLException mue) { | |
| 347 | 334 | } |
| 335 | } | |
| 336 | return null; | |
| 337 | } | |
| 348 | 338 | |
| 349 | // And finally this will try /account/view_account.jsp | |
| 350 | StringBuilder builder = new StringBuilder(); | |
| 351 | for (int i=0; i<name.length(); ++i) { | |
| 352 | char ch = name.charAt(i); | |
| 353 | if (Character.isUpperCase(ch)) { | |
| 354 | builder.append("_"); | |
| 355 | builder.append(Character.toLowerCase(ch)); | |
| 356 | } | |
| 357 | else { | |
| 358 | builder.append(ch); | |
| 359 | } | |
| 360 | } | |
| 339 | /** | |
| 340 | * <p>Returns the list of attempts to locate a default view for the urlBinding provided. | |
| 341 | * Generates attempts for views by converting the incoming urlBinding with the following rules. | |
| 342 | * For example if the urlBinding is '/account/ViewAccount.action' the following views will be | |
| 343 | * returned in order:</p> | |
| 344 | * | |
| 345 | * <ul> | |
| 346 | * <li>/account/ViewAccount.jsp</li> | |
| 347 | * <li>/account/viewAccount.jsp</li> | |
| 348 | * <li>/account/view_account.jsp</li> | |
| 349 | * </ul> | |
| 350 | * | |
| 351 | * <p>Can be overridden to look for views with a different pattern.</p> | |
| 352 | * | |
| 353 | * @param urlBinding the url being accessed by the client in the current request | |
| 354 | * @since Stripes 1.5 | |
| 355 | */ | |
| 356 | protected List<String> getFindViewAttempts(String urlBinding) { | |
| 357 | List<String> attempts = new ArrayList<String>(3); | |
| 361 | 358 | |
| 362 | jsp = path + builder.toString() + ".jsp"; | |
| 363 | if (ctx.getResource(jsp) != null) { | |
| 364 | return new ForwardResolution(jsp); | |
| 365 | } | |
| 359 | int lastPeriod = urlBinding.lastIndexOf('.'); | |
| 360 | String path = urlBinding.substring(0, urlBinding.lastIndexOf("/") + 1); | |
| 361 | String name = (lastPeriod >= path.length()) ? urlBinding.substring(path.length(), lastPeriod) | |
| 362 | : urlBinding.substring(path.length()); | |
| 366 | 363 | |
| 367 | return null; | |
| 368 | } | |
| 369 | catch (MalformedURLException mue) { | |
| 370 | return null; | |
| 364 | // This will try /account/ViewAccount.jsp | |
| 365 | attempts.add(path + name + ".jsp"); | |
| 366 | ||
| 367 | // This will try /account/viewAccount.jsp | |
| 368 | name = Character.toLowerCase(name.charAt(0)) + name.substring(1); | |
| 369 | attempts.add(path + name + ".jsp"); | |
| 370 | ||
| 371 | // And finally this will try /account/view_account.jsp | |
| 372 | StringBuilder builder = new StringBuilder(); | |
| 373 | for (int i=0; i<name.length(); ++i) { | |
| 374 | char ch = name.charAt(i); | |
| 375 | if (Character.isUpperCase(ch)) { | |
| 376 | builder.append("_"); | |
| 377 | builder.append(Character.toLowerCase(ch)); | |
| 378 | } | |
| 379 | else { | |
| 380 | builder.append(ch); | |
| 381 | } | |
| 371 | 382 | } |
| 383 | attempts.add(path + builder.toString() + ".jsp"); | |
| 384 | ||
| 385 | return attempts; | |
| 372 | 386 | } |
| 373 | 387 | } |
| 374 | 388 |