Ken,
My response inline...
Ken Paulsen wrote:
>
> Hi Senthil,
>
> I think there may be a couple issues with this.
>
> First I'm not sure this does what you expect. If you want to
> urlencode QUERY_STRING parameters, this does not do that. If you want
> to add the "jsessionid" to the url when cookies are disabled... then
> it does do what you expected. In either case, can you please document
> the handler explaining more specifically what it does?
I meant jsessionid when cookies are enabled. I'll change the document
clearly explaining about this.
>
> Second, I would like all JSFTemplating handlers to be compatible with
> a Portlet environment. This means you should use the
> ExternalContext's methods, or be very careful to write Portlet
> compatible code. Casting to ServletResponse will not work in a
> Portlet environment. You can use the encodeActionURL to do the same
> thing you are doing. While this does not technically call the same
> method (encodeURL vs. encodeRedirectURL) the container's
> implementation is the same (at least for GlassFish).
I didn't think about it portlet compatible, Thanks for letting me know
about this. I'll make this change as well.
>
> If you meant to urlencode the QUERY_STRING parameters, you will have a
> lot more work to do b/c you'll have to do each parameter
> individually. I'm not sure a method that takes a String version of a
> URL should attempt this because you will not be able to easily
> distinguish between an '&' that is part of a value, and an '&' that
> seperates a value. Same with '='. Instead the developer constructing
> the URL should take the responsibility of calling the existing
> "urlencode" handler on each "value" of a QUERY_STRING parameter they
> add (or call the URLEncoder.encode() method directly from Java code).
I think we can use urlencode for now for this. If there is a strong need
for this then I'll add this as RFE.
>
> I hope this makes sense... let me know if you need more clarification.
I'll send you the changes soon as per your comments/review.
thx
Senthil
>
> Thanks!!
>
> Ken
>
> Senthil Chidambaram wrote:
>
>> Ken,
>> Could you please review this, and let me know. I've added
>> encoderedirect() in NavigationHandlers. The diffs are attached with
>> the src as well.
>>
>> thx
>> Senthil
>>
>>------------------------------------------------------------------------
>>
>>/*
>> * The contents of this file are subject to the terms
>> * of the Common Development and Distribution License
>> * (the License). You may not use this file except in
>> * compliance with the License.
>> *
>> * You can obtain a copy of the license at
>> * https://jsftemplating.dev.java.net/cddl1.html or
>> * jsftemplating/cddl1.txt.
>> * See the License for the specific language governing
>> * permissions and limitations under the License.
>> *
>> * When distributing Covered Code, include this CDDL
>> * Header Notice in each file and include the License file
>> * at jsftemplating/cddl1.txt.
>> * If applicable, add the following below the CDDL Header,
>> * with the fields enclosed by brackets [] replaced by
>> * you own identifying information:
>> * "Portions Copyrighted [year] [name of copyright owner]"
>> *
>> * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
>> */
>>/*
>> * NavigationHandlers.java
>> *
>> * Created on December 6, 2004, 11:06 PM
>> */
>>package com.sun.jsftemplating.handlers;
>>
>>import com.sun.jsftemplating.annotation.Handler;
>>import com.sun.jsftemplating.annotation.HandlerInput;
>>import com.sun.jsftemplating.annotation.HandlerOutput;
>>import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext;
>>
>>import java.io.IOException;
>>
>>import javax.faces.component.UIViewRoot;
>>import javax.faces.context.FacesContext;
>>import javax.faces.context.ExternalContext;
>>
>>import javax.servlet.http.HttpServletResponse;
>>
>>
>>/**
>> * <p> This class contains
>> * {_at_link com.sun.jsftemplating.layout.descriptors.handler.Handler}
>> * methods that perform navigation oriented actions.</p>
>> *
>> * @author Ken Paulsen (ken.paulsen_at_sun.com)
>> */
>>public class NavigationHandlers {
>>
>> /**
>> * <p> Default Constructor.</p>
>> */
>> public NavigationHandlers() {
>> }
>>
>> /**
>> * <p> This handler returns a <code>UIViewRoot</code>. If the
>> * <code>id</code> parameter is supplied it will return the requested
>> * <code>UIViewRoot</code> (this may fail and cause an exception). If
>> * the <code>id</code> is <em>not</em> supplied, it will return the
>> * current <code>UIViewRoot</code>. The result will be returned in
>> * an output parameter named <code>viewRoot</code>.</p>
>> */
>> @Handler(id="getUIViewRoot",
>> input={
>> @HandlerInput(name="id", type=String.class)
>> },
>> output={
>> @HandlerOutput(name="viewRoot", type=UIViewRoot.class)
>> })
>> public void getUIViewRoot(HandlerContext context) {
>> String pageName = (String) context.getInputValue("id");
>> FacesContext ctx = context.getFacesContext();
>> UIViewRoot root = null;
>> if (pageName == null) {
>> root = ctx.getViewRoot();
>> } else {
>> if (pageName.charAt(0) != '/') {
>> // Ensure we start w/ a '/'
>> pageName = "/" + pageName;
>> }
>> root = ctx.getApplication().getViewHandler().
>> createView(ctx, pageName);
>> }
>> context.setOutputValue("viewRoot", root);
>> }
>>
>> /**
>> * <p> This method gives you a "resource URL" as defined by the
>> * <code>ViewHandler</code>'s <code>getActionURL(String
>> * url)</code> method.</p>
>> *
>> * @param handlerCtx The {_at_link HandlerContext}.
>> */
>> @Handler(id="getActionURL",
>> input={
>> @HandlerInput(name="url", type=String.class, required=true)
>> },
>> output={
>> @HandlerOutput(name="url", type=String.class)
>> })
>> public static void getActionURL(HandlerContext handlerCtx) {
>> String url = (String) handlerCtx.getInputValue("url");
>> FacesContext ctx = handlerCtx.getFacesContext();
>> handlerCtx.setOutputValue("url", ctx.getApplication().getViewHandler().
>> getActionURL(ctx, url));
>> }
>>
>> /**
>> * <p> This method gives you a "resource URL" as defined by the
>> * <code>ViewHandler</code>'s <code>getResourceURL(String
>> * url)</code> method.</p>
>> *
>> * @param handlerCtx The {_at_link HandlerContext}.
>> */
>> @Handler(id="getResourceURL",
>> input={
>> @HandlerInput(name="url", type=String.class, required=true)
>> },
>> output={
>> @HandlerOutput(name="url", type=String.class)
>> })
>> public static void getResourceURL(HandlerContext handlerCtx) {
>> String url = (String) handlerCtx.getInputValue("url");
>> FacesContext ctx = handlerCtx.getFacesContext();
>> handlerCtx.setOutputValue("url", ctx.getApplication().getViewHandler().
>> getResourceURL(ctx, url));
>> }
>>
>> /**
>> * <p> This handler navigates to the given page. <code>page</code> may
>> * either be a <code>UIViewRoot</code> or a <code>String</code>
>> * representing a <code>UIViewRoot</code>. Passing in a
>> * <code>String</code> name of a <code>UIViewRoot</code> will always
>> * create a new <code>UIViewRoot</code>. Passing in the
>> * <code>UIViewRoot</code> provides an opportunity to customize the
>> * <code>UIComponent</code> tree that will be displayed.</p>
>> *
>> * <p> The {_at_link #getUIViewRoot(HandlerContext)} handler provides a way
>> * to obtain a <code>UIViewRoot</code>.</p>
>> *
>> * <p> Input value: "page" -- Type: <code>Object</code> (should be a
>> * <code>String</code> or a <code>UIViewRoot</code>).</p>
>> *
>> * @param context The {_at_link HandlerContext}.
>> */
>> @Handler(id="navigate",
>> input={
>> @HandlerInput(name="page", type=Object.class, required=true)
>> })
>> public static void navigate(HandlerContext context) {
>> Object page = context.getInputValue("page");
>> UIViewRoot root = null;
>> FacesContext ctx = context.getFacesContext();
>> if (page instanceof String) {
>> // Create a new UIViewRoot with the given id
>> String strPage = (String) page;
>> if (strPage.charAt(0) != '/') {
>> // Ensure we start w/ a '/'
>> strPage = "/" + strPage;
>> }
>> root = ctx.getApplication().getViewHandler().
>> createView(ctx, strPage);
>> } else if (page instanceof UIViewRoot) {
>> // We recieved a UIViewRoot, use it...
>> root = (UIViewRoot) page;
>> } else {
>> throw new IllegalArgumentException("Type '"
>> + page.getClass().getName()
>> + "' is not valid. It must be a String or UIViewRoot.");
>> }
>>
>> // Set the UIViewRoot so that it will be displayed
>> ctx.setViewRoot(root);
>> }
>>
>> /**
>> * <p> This handler redirects to the given page.</p>
>> *
>> * <p> Input value: "page" -- Type: <code>String</code></p>
>> *
>> * @param context The {_at_link HandlerContext}.
>> */
>> @Handler(id="redirect",
>> input={
>> @HandlerInput(name="page", type=String.class, required=true)
>> })
>> public static void redirect(HandlerContext context) {
>> String page = (String) context.getInputValue("page");
>> FacesContext ctx = context.getFacesContext();
>> try {
>> ctx.getExternalContext().redirect(page);
>> ctx.responseComplete();
>> } catch (IOException ex) {
>> throw new RuntimeException(
>> "Unable to navigate to page '" + page + "'!", ex);
>> }
>> }
>>
>> /**
>> * <p> This handler encodes URL, and redirects to the given page.</p>
>> *
>> * <p> Input value: "page" -- Type: <code>String</code></p>
>> *
>> * @param context The {_at_link HandlerContext}.
>> */
>> @Handler(id="encoderedirect",
>> input={
>> @HandlerInput(name="page", type=String.class, required=true)
>> })
>> public static void encoderedirect(HandlerContext context) {
>> String page = (String) context.getInputValue("page");
>> ExternalContext ctx = context.getFacesContext().getExternalContext();
>> HttpServletResponse response = (HttpServletResponse)ctx.getResponse();
>> page = response.encodeRedirectURL(page);
>> try {
>> ctx.redirect(page);
>> context.getFacesContext().responseComplete();
>> } catch (IOException ex) {
>> throw new RuntimeException(
>> "Unable to navigate to page '" + page + "'!", ex);
>> }
>> }
>>
>> /**
>> * <p> This handler forwards to the given page. Normally you will want
>> * to do {_at_link #navigate} as that follows JSF patterns. This uses
>> * the raw dispatcher forward mechanism (via the ExternalContext).</p>
>> *
>> * <p> Input value: "url" -- Type: <code>String</code></p>
>> *
>> * @param context The {_at_link HandlerContext}.
>> */
>> @Handler(id="dispatch",
>> input={
>> @HandlerInput(name="path", type=String.class, required=true)
>> })
>> public static void dispatch(HandlerContext context) {
>> String path = (String) context.getInputValue("path");
>> FacesContext ctx = context.getFacesContext();
>> try {
>> ctx.getExternalContext().dispatch(path);
>> ctx.responseComplete();
>> } catch (IOException ex) {
>> throw new RuntimeException(
>> "Unable to navigate to path '" + path + "'!", ex);
>> }
>> }
>>}
>>
>>
>>------------------------------------------------------------------------
>>
>>Index: NavigationHandlers.java
>>===================================================================
>>RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/handlers/NavigationHandlers.java,v
>>retrieving revision 1.5
>>diff -c -r1.5 NavigationHandlers.java
>>*** NavigationHandlers.java 16 Feb 2007 10:31:10 -0000 1.5
>>--- NavigationHandlers.java 24 Feb 2007 15:46:09 -0000
>>***************
>>*** 36,41 ****
>>--- 36,44 ----
>>
>> import javax.faces.component.UIViewRoot;
>> import javax.faces.context.FacesContext;
>>+ import javax.faces.context.ExternalContext;
>>+
>>+ import javax.servlet.http.HttpServletResponse;
>>
>>
>> /**
>>***************
>>*** 191,196 ****
>>--- 194,225 ----
>> try {
>> ctx.getExternalContext().redirect(page);
>> ctx.responseComplete();
>>+ } catch (IOException ex) {
>>+ throw new RuntimeException(
>>+ "Unable to navigate to page '" + page + "'!", ex);
>>+ }
>>+ }
>>+
>>+ /**
>>+ * <p> This handler encodes URL, and redirects to the given page.</p>
>>+ *
>>+ * <p> Input value: "page" -- Type: <code>String</code></p>
>>+ *
>>+ * @param context The {_at_link HandlerContext}.
>>+ */
>>+ @Handler(id="encoderedirect",
>>+ input={
>>+ @HandlerInput(name="page", type=String.class, required=true)
>>+ })
>>+ public static void encoderedirect(HandlerContext context) {
>>+ String page = (String) context.getInputValue("page");
>>+ ExternalContext ctx = context.getFacesContext().getExternalContext();
>>+ HttpServletResponse response = (HttpServletResponse)ctx.getResponse();
>>+ page = response.encodeRedirectURL(page);
>>+ context.setOutputValue("page", page);
>>+ try {
>>+ ctx.redirect(page);
>>+ context.getFacesContext().responseComplete();
>> } catch (IOException ex) {
>> throw new RuntimeException(
>> "Unable to navigate to page '" + page + "'!", ex);
>>
>>