You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2004/07/08 06:17:47 UTC

cvs commit: jakarta-struts/contrib/struts-faces/src/java/org/apache/struts/faces/renderer BaseRenderer.java

craigmcc    2004/07/07 21:17:47

  Modified:    contrib/struts-faces/src/java/org/apache/struts/faces/renderer
                        BaseRenderer.java
  Log:
  Fix several flaws in the href URL being returned by <s:base>:
  
  - A servler-relative URI (starting with "/") was being returned,
    but the HTML spec says it must be absolute.
  
  - The calculated URI was being mapped to FacesServlet, but we
    really want the URI of a JSP page itself (if that's your
    view technology).  This happens now, and the generated href
    is identical in form to what the Struts <html:base> tag does.
  
  While I was at it, I implemented a portlet-specific version of this
  calculation as well, using reflection so that nothing bad happens if
  the portlet API classes are not visible.  I don't have an environment
  available to test this at the moment, but it *should* work.
  
  Revision  Changes    Path
  1.10      +115 -20   jakarta-struts/contrib/struts-faces/src/java/org/apache/struts/faces/renderer/BaseRenderer.java
  
  Index: BaseRenderer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/contrib/struts-faces/src/java/org/apache/struts/faces/renderer/BaseRenderer.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- BaseRenderer.java	8 Mar 2004 02:49:54 -0000	1.9
  +++ BaseRenderer.java	8 Jul 2004 04:17:47 -0000	1.10
  @@ -18,12 +18,15 @@
   
   
   import java.io.IOException;
  +import java.lang.reflect.InvocationTargetException;
   
  +import javax.faces.FacesException;
   import javax.faces.component.UIComponent;
   import javax.faces.context.FacesContext;
   import javax.faces.context.ResponseWriter;
  -// import javax.servlet.http.HttpServletRequest;
  +import javax.servlet.http.HttpServletRequest;
   
  +import org.apache.commons.beanutils.MethodUtils;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -67,6 +70,11 @@
               throw new NullPointerException();
           }
   
  +        if (log.isTraceEnabled()) {
  +            log.trace("viewId='" + context.getViewRoot().getViewId() +
  +                      "' --> uri='" + uri(context) + "'");
  +        }
  +
           ResponseWriter writer = context.getResponseWriter();
           writer.startElement("base", component);
           writer.writeURIAttribute("href", uri(context), null);
  @@ -85,17 +93,95 @@
   
   
       /**
  -     * <p>Return the absolute URI to be rendered as the value of the
  -     * <code>href</code> attribute.</p>
  +     * <p>Return <code>true</code> if this is a portlet request instance.
  +     * NOTE:  Implementation must not require portlet API classes to be
  +     * present.</p>
        *
        * @param context <code>FacesContext</code> for the current request
        */
  -    protected String uri(FacesContext context) {
  +    protected boolean isPortletRequest(FacesContext context) {
  +
  +        Object request = context.getExternalContext().getRequest();
  +        Class clazz = request.getClass();
  +        while (clazz != null) {
  +            // Does this class implement PortletRequest?
  +            Class interfaces[] = clazz.getInterfaces();
  +            if (interfaces == null) {
  +                interfaces = new Class[0];
  +            }
  +            for (int i = 0; i < interfaces.length; i++) {
  +                if ("javax.portlet.PortletRequest".equals
  +                    (interfaces[i].getName())) {
  +                    return (true);
  +                }
  +            }
  +            // Try our superclass (if any)
  +            clazz = clazz.getSuperclass();
  +        }
  +        return (false);
  +
  +    }
  +
  +
  +    /**
  +     * <p>Return <code>true</code> if this is a servlet request instance.</p>
  +     *
  +     * @param context <code>FacesContext</code> for the current request
  +     */
  +    protected boolean isServletRequest(FacesContext context) {
  +
  +        Object request = context.getExternalContext().getRequest();
  +        return (request instanceof HttpServletRequest);
  +
  +    }
  +
   
  -        return (context.getApplication().getViewHandler().
  -                getActionURL(context, context.getViewRoot().getViewId()));
  +    /**
  +     * <p>Return an absolute URI for the current page suitable for use
  +     * in a portlet environment.  NOTE:  Implementation must not require
  +     * portlet API classes to be present, so use reflection as needed.</p>
  +     *
  +     * @param context <code>FacesContext</code> for the current request
  +     */
  +    protected String portletUri(FacesContext context) {
  +
  +        Object request = context.getExternalContext().getRequest();
  +        try {
  +            String scheme = (String)
  +                MethodUtils.invokeMethod(request, "getScheme", null);
  +            StringBuffer sb = new StringBuffer(scheme);
  +            sb.append("://");
  +            sb.append(MethodUtils.invokeMethod(request, "getServerName", null));
  +            Integer port = (Integer)
  +                MethodUtils.invokeMethod(request, "getServerPort", null);
  +            if ("http".equals(scheme) && (port.intValue() == 80)) {
  +                ;
  +            } else if ("https".equals(scheme) && (port.intValue() == 443)) {
  +                ;
  +            } else {
  +                sb.append(":" + port);
  +            }
  +            sb.append
  +                (MethodUtils.invokeMethod(request, "getContextPath", null));
  +            sb.append(context.getViewRoot().getViewId());
  +            return (sb.toString());
  +        } catch (InvocationTargetException e) {
  +            throw new FacesException(e.getTargetException());
  +        } catch (Exception e) {
  +            throw new FacesException(e);
  +        }
  +
  +    }
  +
  +
  +    /**
  +     * <p>Return an absolute URI for the current page suitable for use
  +     * in a servlet environment.</p>
  +     *
  +     * @param context <code>FacesContext</code> for the current request
  +     */
  +    protected String servletUri(FacesContext context) {
   
  -        /*
           HttpServletRequest request = (HttpServletRequest)
               context.getExternalContext().getRequest();
           StringBuffer sb = new StringBuffer(request.getScheme());
  @@ -111,19 +197,28 @@
               sb.append(":" + request.getServerPort());
           }
           sb.append(request.getContextPath());
  -        String servletPath = request.getServletPath();
  -        if (servletPath != null) {
  -            if (servletPath.startsWith("/faces")) {
  -                sb.append(servletPath.substring(6));
  -            } else {
  -                sb.append(servletPath);
  -            }
  -        }
  -        if (request.getPathInfo() != null) {
  -            sb.append(request.getPathInfo());
  -        }
  +        sb.append(context.getViewRoot().getViewId());
           return (sb.toString());
  -        */
  +
  +    }
  +
  +
  +    /**
  +     * <p>Return the absolute URI to be rendered as the value of the
  +     * <code>href</code> attribute.</p>
  +     *
  +     * @param context <code>FacesContext</code> for the current request
  +     */
  +    protected String uri(FacesContext context) {
  +
  +        if (isServletRequest(context)) {
  +            return (servletUri(context));
  +        } else if (isPortletRequest(context)) {
  +            return (portletUri(context));
  +        } else {
  +            throw new IllegalArgumentException
  +                ("Request is neither HttpServletRequest nor PortletRequest");
  +        }
   
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org