You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2007/12/06 11:11:26 UTC

svn commit: r601678 - in /myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav: UrlParameterNavigationHandler.java UrlParameterViewHandler.java

Author: skitching
Date: Thu Dec  6 02:11:22 2007
New Revision: 601678

URL: http://svn.apache.org/viewvc?rev=601678&view=rev
Log:
ORCHESTRA-13 Ensure EL expressions are expanded before RequestParameterProviderManager runs.

Modified:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterNavigationHandler.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterViewHandler.java

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterNavigationHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterNavigationHandler.java?rev=601678&r1=601677&r2=601678&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterNavigationHandler.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterNavigationHandler.java Thu Dec  6 02:11:22 2007
@@ -19,26 +19,15 @@
 package org.apache.myfaces.orchestra.urlParamNav;
 
 import javax.faces.application.NavigationHandler;
-import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
-import javax.faces.el.ValueBinding;
-import java.io.IOException;
 
 /**
- * This navigation handler replaces EL expressions (value bindings) within the to-view-id
- * property of a navigation rule.
+ * A navigation handler that exists only for backwards compatibility.
  * <p>
- * Since we do not know quite how this feature may interact with other JSF frameworks that
- * also provide navigation handlers, this feature is not enabled by default.
- * <p>
- * To enable this feature:
- * <ul>
- * <li>add this navigation handler to your faces-config.xml</li>
- * <li>add the {@link UrlParameterViewHandler} to your faces-config.xml</li>
- * <li>configure the navigation case to use &lt;redirect/&gt; flag.<li/>
- * </ul>
- * Note that redirect is required for the rule; this is only natural as without redirect
- * there is no bookmarkable URL for the user. 
+ * In orchestra-core 1.0 this class was necessary when using the UrlParameterViewHandler.
+ * In release 1.1, all the functionality implemented here has been moved to the
+ * UrlParameterViewHandler class and there is no longer anything here. However this class
+ * has been left to avoid breaking faces-config.xml configurations that reference it.
  */
 public class UrlParameterNavigationHandler extends NavigationHandler
 {
@@ -51,53 +40,6 @@
 
 	public void handleNavigation(final FacesContext context, String fromAction, String outcome)
 	{
-		original.handleNavigation(new FacesContextWrapper(context)
-		{
-			public ExternalContext getExternalContext()
-			{
-				return new ExternalContextWrapper(super.getExternalContext())
-				{
-					public void redirect(String url) throws IOException
-					{
-						super.redirect(interceptRedirect(context, url));
-					}
-				};
-			}
-		}, fromAction, outcome);
-	}
-
-	/**
-	 * Expand any EL expressions in the URL string.
-	 * <p>
-	 * If the url string contains one or more EL expressions (ie contains "#{" anywhere)
-	 * then expand all embedded EL expressions in the url.
-	 * <p>
-	 * The result of evaluating an EL expression is inserted directly into the url without
-	 * any further encoding. Therefore an EL expression must ONLY return data that is valid
-	 * within a url (and in particular, no space characters).
-	 * <p>
-	 * TODO: Consider evaluating each EL expression separately, and encoding each
-	 * result, so the EL expression can safely return any data without worrying about
-	 * generating invalid urls. However encoding things like questionmarks, slashes,
-	 * spaces, etc. would limit the usefulness of the EL expressions.
-	 * <p>
-	 * TODO: Consider supporting the "${" EL expression marker too, just for consistency.
-	 * <p>
-	 * Returns the original string if it contains no EL expressions, otherwise a new
-	 * string with the EL expressions expanded.
-	 */
-	protected String interceptRedirect(FacesContext context, String url)
-	{
-		int pos = url.indexOf("#{");
-		if (pos > -1 && url.indexOf("}", pos) > -1)
-		{
-			// There is at least one EL expression, so evaluate the whole url string.
-			// Note that something like "aaa#{foo}bbb#{bar}ccc" is fine; both the
-			// el expressions will get replaced.
-			ValueBinding vb = context.getApplication().createValueBinding(url);
-			return (String) vb.getValue(context);
-		}
-
-		return url;
+		original.handleNavigation(context, fromAction, outcome);
 	}
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterViewHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterViewHandler.java?rev=601678&r1=601677&r2=601678&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterViewHandler.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/urlParamNav/UrlParameterViewHandler.java Thu Dec  6 02:11:22 2007
@@ -26,13 +26,17 @@
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+
 import java.io.IOException;
 import java.util.Locale;
 
 /**
- * This view handler helps to preserve any url parameter you configured in your navigation.
- *
- * @see org.apache.myfaces.orchestra.urlParamNav.UrlParameterNavigationHandler
+ * Allow the to-view-id URL in a faces-config navigation case to include
+ * query parameters and EL expressions.
+ * <p>
+ * This class plays a few tricks to hide from the real NavigationHandler
+ * and ViewHandler classes the fact that a URL contains non-standard data.
  */
 public class UrlParameterViewHandler extends ViewHandler
 {
@@ -62,6 +66,35 @@
 	{
 		if (viewId != null)
 		{
+			// Expand any EL expression in the URL.
+			//
+			// This handles a call from a NavigationHandler which is processing a redirect
+			// navigation case. A NavigationHandler must call the following in order:
+			//  * ViewHandler.getActionURL,
+			//  * ExternalContext.encodeActionURL
+			//  * ExternalContext.redirect
+			//
+			// Orchestra hooks into ExternalContext.encodeActionURL to trigger the
+			// RequestParameterProviderManager whch then inserts various query params
+			// into the URL.
+			//
+			// So here, ensure that any EL expressions are expanded before the
+			// RequestParameterProviderManager is invoked. An alternative would be for
+			// the RequestParameterProviderManager to do the encoding, but at the current
+			// time that class is not JSF-dependent in any way, so calling JSF expression
+			// expansion from there is not possible.
+			//
+			// Note that this method is also called from a Form component when rendering
+			// its 'action' attribute. This code therefore has the side-effect of
+			// permitting EL expressions in a form's action. This is not particularly
+			// useful, however, as they are expected to have been expanded before this
+			// method is invoked.. 
+			viewId = expandExpressions(context, viewId);
+
+			// Hide query parameters from the standard ViewHandlerImpl. The standard
+			// implementation of ViewHandlerImpl.getActionUrl method does not handle
+			// query params well. So strip them off, invoke the processing, then reattach
+			// them afterwards.
 			int pos = viewId.indexOf('?');
 			if (pos > -1)
 			{
@@ -94,5 +127,20 @@
 		throws IOException
 	{
 		original.writeState(context);
+	}
+
+	private static String expandExpressions(FacesContext context, String url)
+	{
+		int pos = url.indexOf("#{");
+		if (pos > -1 && url.indexOf("}", pos) > -1)
+		{
+			// There is at least one EL expression, so evaluate the whole url string.
+			// Note that something like "aaa#{foo}bbb#{bar}ccc" is fine; both the
+			// el expressions will get replaced.
+			ValueBinding vb = context.getApplication().createValueBinding(url);
+			return (String) vb.getValue(context);
+		}
+
+		return url;
 	}
 }