ICEfaces
  1. ICEfaces
  2. ICE-2247

"javax.portlet.response" request attribute is not passed to externalContext in portlet environment

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7DR#1
    • Fix Version/s: 1.7DR#3, 1.7
    • Component/s: None
    • Labels:
      None
    • Environment:
      JBoss 4.2.1, Liferay 4.3.2, Sun RI 1.2 (Embedded in JBoss), Facelets (ICE Faces Implementation)

      Description

      Portlet specification (sec. 16.3.2) determines that PortletRequestDispatcher must add "javax.portlet.response" including another Servlet or JSP.

      Such an include is done in com.icesoft.faces.webapp.http.portlet.MainPortlet and PortletRequestDispatcher adds corresponding attribut to a request - this attribut is presented in the request passed to the service method of com.icesoft.faces.webapp.http.servlet.MainServlet.

      But than this attribute is lost somewhere. I can't get it in my portlet code using facesContext.getExternalContext().getRequestMap().getAttribute("javax.portlet.response").

      It is rather important to have such an attribute since it allows to construct direct URL to the portlet and some page inside a portlet (using renderResponse.createRenderURL).

        Activity

        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Assignee Deryk Sinotte [ deryk.sinotte ]
        Ken Fyten made changes -
        Fix Version/s 1.7 [ 10080 ]
        Hide
        Aaron Lucas added a comment -

        I have a problem with the documentation and the comment above.

        The values for the hiddenPortletAttributes are shown to be separated by commas, yet if you look at the source they are split on spaces:

        Collection hiddenCustomAttributeNames = Arrays.asList(customPortletAttributes.split(" "));

        I am taking that it should be spaces to work now but I would suggest using another delimiter instead, just as you suggest a comma and then update the source to reflect this change.

        Collection hiddenCustomAttributeNames = Arrays.asList(customPortletAttributes.split(","));

        Show
        Aaron Lucas added a comment - I have a problem with the documentation and the comment above. The values for the hiddenPortletAttributes are shown to be separated by commas, yet if you look at the source they are split on spaces: Collection hiddenCustomAttributeNames = Arrays.asList(customPortletAttributes.split(" ")); I am taking that it should be spaces to work now but I would suggest using another delimiter instead, just as you suggest a comma and then update the source to reflect this change. Collection hiddenCustomAttributeNames = Arrays.asList(customPortletAttributes.split(","));
        Deryk Sinotte made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Deryk Sinotte added a comment -

        Resolving as fixed.

        My tests now indicate that this works as advertised in our upcoming documentation. Standard attributes from the specification (e.g. javax.portlet.request) are now properly maintained and exposed via the request Map:

        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext exContext = facesContext.getExternalContext();
        Map reqMap = exContext.getRequestMap();

        Custom attributes (e.g. Liferay's THEME_DISPLAY) can now be added into the web.xml via a customer context-parameter so that they can be maintained as well:

        <context-param>
        <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name>
        <param-value>THEME_DISPLAY</param-value>
        </context-param>

        Show
        Deryk Sinotte added a comment - Resolving as fixed. My tests now indicate that this works as advertised in our upcoming documentation. Standard attributes from the specification (e.g. javax.portlet.request) are now properly maintained and exposed via the request Map: FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext exContext = facesContext.getExternalContext(); Map reqMap = exContext.getRequestMap(); Custom attributes (e.g. Liferay's THEME_DISPLAY) can now be added into the web.xml via a customer context-parameter so that they can be maintained as well: <context-param> <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name> <param-value>THEME_DISPLAY</param-value> </context-param>
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #15287 Mon Dec 03 14:55:16 MST 2007 deryk.sinotte ICE-2247: Removing Liferay specific constants as we are now using a more dynamic approach.
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/jasper/Constants.java
        Ken Fyten made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Hide
        Neil Griffin added a comment -

        After committing the fix, the JSR-168 TCK tests broke. So I asked bchan to backout all the fixes in Liferay.

        As documented in LEP-3845, moving forward the best solution is to use Mircea's new web.xml feature:

        <context-param>
        <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name>
        <param-value>javax.portlet.config,javax.portlet.userinfo,THEME_DISPLAY</param-value>
        </context-param>

        This of course means that you have to use ICEfaces 1.7 DR#3 or newer.

        Show
        Neil Griffin added a comment - After committing the fix, the JSR-168 TCK tests broke. So I asked bchan to backout all the fixes in Liferay. As documented in LEP-3845, moving forward the best solution is to use Mircea's new web.xml feature: <context-param> <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name> <param-value>javax.portlet.config,javax.portlet.userinfo,THEME_DISPLAY</param-value> </context-param> This of course means that you have to use ICEfaces 1.7 DR#3 or newer.
        Hide
        Neil Griffin added a comment -

        Fixed in Liferay trunk on 12/1/2007:
        http://support.liferay.com/browse/LEP-3845

        This will be fixed in Liferay 4.4 and possibly backported to Liferay 4.3.5

        Show
        Neil Griffin added a comment - Fixed in Liferay trunk on 12/1/2007: http://support.liferay.com/browse/LEP-3845 This will be fixed in Liferay 4.4 and possibly backported to Liferay 4.3.5
        Hide
        Neil Griffin added a comment -

        Correction – the only one Mircea took out was Constants.LIFERAY_THEME_DISPLAY

        When I put the following in web.xml:

        <context-param>
        <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name>
        <param-value>THEME_DISPLAY</param-value>
        </context-param>

        it worked great.

        Thanks,

        Neil

        Show
        Neil Griffin added a comment - Correction – the only one Mircea took out was Constants.LIFERAY_THEME_DISPLAY When I put the following in web.xml: <context-param> <param-name>com.icesoft.faces.hiddenPortletAttributes</param-name> <param-value>THEME_DISPLAY</param-value> </context-param> it worked great. Thanks, Neil
        Hide
        Neil Griffin added a comment -

        I request that this issue be reopened.

        When Mircea committed revision 15246 to the trunk, he refactored things a little and dropped the following constants from PortletEnvironmentRenderRequest.java:

        PORTLET_CONFIG,
        PORTLET_USERINFO,
        LIFERAY_THEME_DISPLAY

        I was able to fix this by inserting them into Mircea's new RequestConstants list at the top of PortletEnvironmentRenderRequest.java:

        private static final Collection RequestConstants = Arrays.asList(new String[]

        { Constants.PORTLET_CONFIG, Constants.PORTLET_REQUEST, Constants.PORTLET_RESPONSE, Constants.PORTLET_USERINFO, Constants.LIFERAY_THEME_DISPLAY}

        );

        Neil

        Show
        Neil Griffin added a comment - I request that this issue be reopened. When Mircea committed revision 15246 to the trunk, he refactored things a little and dropped the following constants from PortletEnvironmentRenderRequest.java: PORTLET_CONFIG, PORTLET_USERINFO, LIFERAY_THEME_DISPLAY I was able to fix this by inserting them into Mircea's new RequestConstants list at the top of PortletEnvironmentRenderRequest.java: private static final Collection RequestConstants = Arrays.asList(new String[] { Constants.PORTLET_CONFIG, Constants.PORTLET_REQUEST, Constants.PORTLET_RESPONSE, Constants.PORTLET_USERINFO, Constants.LIFERAY_THEME_DISPLAY} ); Neil
        Deryk Sinotte made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 1.7DR#3 [ 10112 ]
        Resolution Fixed [ 1 ]
        Hide
        Deryk Sinotte added a comment -

        I've added in the requested constants from the case as well as a couple of others suggested by Liferay. They are all defined in the Constants class:

        public static final String PORTLET_CONFIG =
        "javax.portlet.config";
        public static final String PORTLET_REQUEST =
        "javax.portlet.request";
        public static final String PORTLET_RESPONSE =
        "javax.portlet.response";
        public static final String PORTLET_USERINFO =
        "javax.portlet.userinfo";

        public static final String LIFERAY_THEME_DISPLAY =
        "THEME_DISPLAY";

        The copying logic is all done in the PortletEnvironmentRenderRequest class. This is not a good long term solution as there are a number of other javax.portlet.* attributes available that would need to be added whenever a developer found that they needed one that we're not copying. We should probably look at reading in the keys from some properties list that can be changed without recompiling.

        Resolving as fixed.

        Show
        Deryk Sinotte added a comment - I've added in the requested constants from the case as well as a couple of others suggested by Liferay. They are all defined in the Constants class: public static final String PORTLET_CONFIG = "javax.portlet.config"; public static final String PORTLET_REQUEST = "javax.portlet.request"; public static final String PORTLET_RESPONSE = "javax.portlet.response"; public static final String PORTLET_USERINFO = "javax.portlet.userinfo"; public static final String LIFERAY_THEME_DISPLAY = "THEME_DISPLAY"; The copying logic is all done in the PortletEnvironmentRenderRequest class. This is not a good long term solution as there are a number of other javax.portlet.* attributes available that would need to be added whenever a developer found that they needed one that we're not copying. We should probably look at reading in the keys from some properties list that can be changed without recompiling. Resolving as fixed.
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #15084 Fri Nov 02 11:25:15 MDT 2007 deryk.sinotte ICE-2247: Added some javax.portlet.* and Liferay attributes to be copied.
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/env/PortletEnvironmentRenderRequest.java
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/jasper/Constants.java
        Hide
        Vadim Lotarev added a comment -

        Well, this works for me, it is not so important how the response object is gotten.

        P.S. I've created separate issue for splitting MainPortlet.render: http://jira.icefaces.org/browse/ICE-2295

        Show
        Vadim Lotarev added a comment - Well, this works for me, it is not so important how the response object is gotten. P.S. I've created separate issue for splitting MainPortlet.render: http://jira.icefaces.org/browse/ICE-2295
        Hide
        Deryk Sinotte added a comment -

        First, let's open a separate JIRA for the latest issue as it's not directly related to the original case subject. I agree that splitting out the logic makes sense but for this case, we'll concentrate on the response object attribute and value.

        I've got some code to check in to fix the attribute issue originally reported. In the meantime, the response should be available via:

        (PortletResponse)facesContext.getExternalContext().getResponse()

        Does accessing it via the getAttribute behave differently than simply using the ExternalContext API?

        Deryk

        Show
        Deryk Sinotte added a comment - First, let's open a separate JIRA for the latest issue as it's not directly related to the original case subject. I agree that splitting out the logic makes sense but for this case, we'll concentrate on the response object attribute and value. I've got some code to check in to fix the attribute issue originally reported. In the meantime, the response should be available via: (PortletResponse)facesContext.getExternalContext().getResponse() Does accessing it via the getAttribute behave differently than simply using the ExternalContext API? Deryk
        Hide
        Vadim Lotarev added a comment -

        Wouldn't it be possible to extract the getting viewId logic from MainPortlet.render method to separate protected method as a part of this fix? TO be more precisely, this code:

        // Get the inital view that is configured in the portlet.xml file
        PortletMode portletMode = renderRequest.getPortletMode();
        String viewId = null;
        if (portletMode == PortletMode.VIEW) {
        viewId = portletConfig.getInitParameter(Constants.VIEW_KEY);
        if (viewId == null) {
        if (log.isErrorEnabled())

        { log.error(Constants.VIEW_KEY + " is not properly configured"); }

        throw new PortletException(Constants.VIEW_KEY + " is not properly configured");
        }
        } else if (portletMode == PortletMode.EDIT) {
        viewId = portletConfig.getInitParameter(Constants.EDIT_KEY);
        if (viewId == null) {
        if (log.isErrorEnabled())

        { log.error(Constants.EDIT_KEY + " is not properly configured"); }

        throw new PortletException(Constants.EDIT_KEY + " is not properly configured");
        }
        } else if (portletMode == PortletMode.HELP) {
        viewId = portletConfig.getInitParameter(Constants.HELP_KEY);
        if (viewId == null) {
        if (log.isErrorEnabled())

        { log.error(Constants.HELP_KEY + " is not properly configured"); }

        throw new PortletException(Constants.HELP_KEY + " is not properly configured");
        }
        }

        It would be useful to have an ability to override this logic in the subclasses. Personally, I'd like to add an ability to show some view based on request parameters.

        Show
        Vadim Lotarev added a comment - Wouldn't it be possible to extract the getting viewId logic from MainPortlet.render method to separate protected method as a part of this fix? TO be more precisely, this code: // Get the inital view that is configured in the portlet.xml file PortletMode portletMode = renderRequest.getPortletMode(); String viewId = null; if (portletMode == PortletMode.VIEW) { viewId = portletConfig.getInitParameter(Constants.VIEW_KEY); if (viewId == null) { if (log.isErrorEnabled()) { log.error(Constants.VIEW_KEY + " is not properly configured"); } throw new PortletException(Constants.VIEW_KEY + " is not properly configured"); } } else if (portletMode == PortletMode.EDIT) { viewId = portletConfig.getInitParameter(Constants.EDIT_KEY); if (viewId == null) { if (log.isErrorEnabled()) { log.error(Constants.EDIT_KEY + " is not properly configured"); } throw new PortletException(Constants.EDIT_KEY + " is not properly configured"); } } else if (portletMode == PortletMode.HELP) { viewId = portletConfig.getInitParameter(Constants.HELP_KEY); if (viewId == null) { if (log.isErrorEnabled()) { log.error(Constants.HELP_KEY + " is not properly configured"); } throw new PortletException(Constants.HELP_KEY + " is not properly configured"); } } It would be useful to have an ability to override this logic in the subclasses. Personally, I'd like to add an ability to show some view based on request parameters.
        Hide
        Deryk Sinotte added a comment -

        After a bit more examination, there are some other areas where we might expose/use these attributes to make our code more in line with the spec. I'll look into it as part of this fix as well.

        Show
        Deryk Sinotte added a comment - After a bit more examination, there are some other areas where we might expose/use these attributes to make our code more in line with the spec. I'll look into it as part of this fix as well.
        Hide
        Deryk Sinotte added a comment -

        You're right. The specification does say that and it looks like Liferay is adhering strictly. I can't imagine that the original intent of the specification was for the attribute names to be omitted from the collection returned by getAttributeNames but that's the way it is. It turns out that we already had a fix for the javax.servlet.include.* attributes to do the same thing so I'll apply the same logic to the javax.portlet.* attributes. Should make it into 1.7 DR3.

        Show
        Deryk Sinotte added a comment - You're right. The specification does say that and it looks like Liferay is adhering strictly. I can't imagine that the original intent of the specification was for the attribute names to be omitted from the collection returned by getAttributeNames but that's the way it is. It turns out that we already had a fix for the javax.servlet.include.* attributes to do the same thing so I'll apply the same logic to the javax.portlet.* attributes. Should make it into 1.7 DR3.
        Deryk Sinotte made changes -
        Assignee Deryk Sinotte [ deryk.sinotte ]
        Vadim Lotarev made changes -
        Field Original Value New Value
        Attachment MainServletDebugging.jpg [ 10710 ]
        Hide
        Vadim Lotarev added a comment -

        This attribute name is not presented around the names returned by request.GetAttributeNames() but it's value returned by request.getAttribute("javax.protlet.response") (see attachment).

        I don't know whether this is a Liferay bug or feature but strictly speaking they do exactly what specification says:

        "These attributes must be the same Portlet API objects accessible to the portlet doing the
        include call. They are accessible from the included servlet or JSP via the
        getAttribute method on the HttpServletRequest object."

        No any word about request.GetAttributeNames() ...

        Show
        Vadim Lotarev added a comment - This attribute name is not presented around the names returned by request.GetAttributeNames() but it's value returned by request.getAttribute("javax.protlet.response") (see attachment). I don't know whether this is a Liferay bug or feature but strictly speaking they do exactly what specification says: "These attributes must be the same Portlet API objects accessible to the portlet doing the include call. They are accessible from the included servlet or JSP via the getAttribute method on the HttpServletRequest object." No any word about request.GetAttributeNames() ...
        Vadim Lotarev created issue -

          People

          • Assignee:
            Unassigned
            Reporter:
            Vadim Lotarev
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: