You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by ms...@apache.org on 2015/11/27 13:38:13 UTC

[32/38] portals-pluto git commit: First step in implementation of header phase support. Initial, incomplete implementation of HeaderRequestImpl, HeaderResponseImpl and th associated contexts. Completed invocation path.

First step in implementation of header phase support. Initial, incomplete
implementation of HeaderRequestImpl, HeaderResponseImpl and th associated
contexts. Completed invocation path.


Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/65c0050b
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/65c0050b
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/65c0050b

Branch: refs/heads/V3Prototype
Commit: 65c0050bb2abb44ad2ee51441a59c9b28c46b3bb
Parents: 29448a1
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Nov 20 14:52:29 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Nov 20 14:52:29 2015 +0100

----------------------------------------------------------------------
 .../apache/pluto/container/FilterManager.java   |  98 +--
 .../pluto/container/PortletContainer.java       |  16 +
 .../container/PortletEnvironmentService.java    | 111 +--
 .../container/PortletHeaderResponseContext.java |  30 +
 .../pluto/container/PortletInvokerService.java  |  15 +-
 .../container/PortletRequestContextService.java |   7 +
 .../pluto/container/driver/PortletServlet3.java | 799 +++++++++----------
 .../pluto/container/impl/HeaderRequestImpl.java |  40 +
 .../container/impl/HeaderResponseImpl.java      | 127 +++
 .../pluto/container/impl/MimeResponseImpl.java  |   2 +-
 .../container/impl/PortletContainerImpl.java    |  53 ++
 .../impl/PortletEnvironmentServiceImpl.java     | 189 +++--
 .../pluto/container/impl/RenderRequestImpl.java | 115 +--
 .../container/impl/RenderResponseImpl.java      |   7 +-
 .../services/container/FilterChainImpl.java     | 422 +++++-----
 .../services/container/FilterManagerImpl.java   | 302 +++----
 .../PortletHeaderResponseContextImpl.java       |  55 ++
 .../PortletRequestContextServiceImpl.java       |  15 +
 .../pluto/driver/PortalDriverServlet.java       |  28 +-
 .../container/DefaultPortletInvokerService.java |  26 +-
 .../main/java/javax/portlet/PortletRequest.java |  11 +
 21 files changed, 1462 insertions(+), 1006 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/FilterManager.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/FilterManager.java b/pluto-container-api/src/main/java/org/apache/pluto/container/FilterManager.java
index 6ef1f8a..bc95ad7 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/FilterManager.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/FilterManager.java
@@ -1,47 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container;
-
-import java.io.IOException;
-
-import javax.portlet.ActionRequest;
-import javax.portlet.ActionResponse;
-import javax.portlet.EventPortlet;
-import javax.portlet.EventRequest;
-import javax.portlet.EventResponse;
-import javax.portlet.Portlet;
-import javax.portlet.PortletContext;
-import javax.portlet.PortletException;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceRequest;
-import javax.portlet.ResourceResponse;
-import javax.portlet.ResourceServingPortlet;
-
-/**
- * Manage the initialization and doFilter for the filter which are
- * declareted in the deployment descriptor.
- * @since 05/29/2007
- * @version 2.0
- */
-public interface FilterManager {
-
-    void processFilter(ActionRequest req, ActionResponse res, Portlet portlet, PortletContext portletContext) throws PortletException, IOException;
-    void processFilter(RenderRequest req, RenderResponse res, Portlet portlet, PortletContext portletContext) throws PortletException, IOException;
-    void processFilter(ResourceRequest req, ResourceResponse res, ResourceServingPortlet resourceServingPortlet, PortletContext portletContext)throws PortletException, IOException;
-    void processFilter(EventRequest req, EventResponse res, EventPortlet eventPortlet, PortletContext portletContext)throws PortletException, IOException;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container;
+
+import java.io.IOException;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventPortlet;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.HeaderPortlet;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.Portlet;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.ResourceServingPortlet;
+
+/**
+ * Manage the initialization and doFilter for the filter which are
+ * declareted in the deployment descriptor.
+ * @since 05/29/2007
+ * @version 2.0
+ */
+public interface FilterManager {
+
+    void processFilter(ActionRequest req, ActionResponse res, Portlet portlet, PortletContext portletContext) throws PortletException, IOException;
+    void processFilter(HeaderRequest req, HeaderResponse res, HeaderPortlet portlet, PortletContext portletContext) throws PortletException, IOException;
+    void processFilter(RenderRequest req, RenderResponse res, Portlet portlet, PortletContext portletContext) throws PortletException, IOException;
+    void processFilter(ResourceRequest req, ResourceResponse res, ResourceServingPortlet resourceServingPortlet, PortletContext portletContext)throws PortletException, IOException;
+    void processFilter(EventRequest req, EventResponse res, EventPortlet eventPortlet, PortletContext portletContext)throws PortletException, IOException;
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
index d96c066..8529654 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
@@ -63,6 +63,22 @@ public interface PortletContainer {
     void destroy() throws PortletContainerException;
 
     /**
+     * Calls the render headers method of the given portlet window.
+     * @param portletWindow the portlet Window
+     * @param request               the servlet request
+     * @param response              the servlet response
+     * @throws PortletException          if one portlet has trouble fulfilling
+     *                                   the request
+     * @throws IOException               if the streaming causes an I/O problem
+     * @throws PortletContainerException if the portlet container implementation
+     *                                   has trouble fulfilling the request
+     */
+    void doHeader(PortletWindow portletWindow,
+            HttpServletRequest request,
+            HttpServletResponse response)
+    throws PortletException, IOException, PortletContainerException;
+
+    /**
      * Calls the render method of the given portlet window.
      * @param portletWindow the portlet Window
      * @param request               the servlet request

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletEnvironmentService.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletEnvironmentService.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletEnvironmentService.java
index be7c5c3..874bd5f 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletEnvironmentService.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletEnvironmentService.java
@@ -1,53 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container;
-
-import javax.portlet.ActionRequest;
-import javax.portlet.ActionResponse;
-import javax.portlet.Event;
-import javax.portlet.EventRequest;
-import javax.portlet.EventResponse;
-import javax.portlet.PortletContext;
-import javax.portlet.PortletSession;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceRequest;
-import javax.portlet.ResourceResponse;
-import javax.servlet.http.HttpSession;
-
-
-/**
- * Factory Service for creating Portlet request, responses and session.
- *
- * @since 1.1.0
- */
-public interface PortletEnvironmentService
-{    
-    ActionRequest createActionRequest(PortletRequestContext requestContext, PortletActionResponseContext responseContext);
-    ActionResponse createActionResponse(PortletActionResponseContext responseContext);
-
-    EventRequest createEventRequest(PortletRequestContext requestContext, PortletEventResponseContext responseContext, Event event);
-    EventResponse createEventResponse(PortletEventResponseContext responseContext);
-    
-    RenderRequest createRenderRequest(PortletRequestContext requestContext, PortletRenderResponseContext responseContext);
-    RenderResponse createRenderResponse(PortletRenderResponseContext responseContext);
-    
-    ResourceRequest createResourceRequest(PortletResourceRequestContext requestContext, PortletResourceResponseContext responseContext);
-    ResourceResponse createResourceResponse(PortletResourceResponseContext responseContext, String requestCacheLevel);
-
-    PortletSession createPortletSession(PortletContext portletContext, PortletWindow portletWindow, HttpSession session);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.Event;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.servlet.http.HttpSession;
+
+
+/**
+ * Factory Service for creating Portlet request, responses and session.
+ *
+ * @since 1.1.0
+ */
+public interface PortletEnvironmentService
+{    
+    ActionRequest createActionRequest(PortletRequestContext requestContext, PortletActionResponseContext responseContext);
+    ActionResponse createActionResponse(PortletActionResponseContext responseContext);
+
+    EventRequest createEventRequest(PortletRequestContext requestContext, PortletEventResponseContext responseContext, Event event);
+    EventResponse createEventResponse(PortletEventResponseContext responseContext);
+    
+    HeaderRequest createHeaderRequest(PortletRequestContext requestContext, PortletHeaderResponseContext responseContext);
+    HeaderResponse createHeaderResponse(PortletHeaderResponseContext responseContext);
+    
+    RenderRequest createRenderRequest(PortletRequestContext requestContext, PortletRenderResponseContext responseContext);
+    RenderResponse createRenderResponse(PortletRenderResponseContext responseContext);
+    
+    ResourceRequest createResourceRequest(PortletResourceRequestContext requestContext, PortletResourceResponseContext responseContext);
+    ResourceResponse createResourceResponse(PortletResourceResponseContext responseContext, String requestCacheLevel);
+
+    PortletSession createPortletSession(PortletContext portletContext, PortletWindow portletWindow, HttpSession session);
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletHeaderResponseContext.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletHeaderResponseContext.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletHeaderResponseContext.java
new file mode 100644
index 0000000..397dd33
--- /dev/null
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletHeaderResponseContext.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container;
+
+import java.util.Collection;
+
+import javax.portlet.PortletMode;
+
+/**
+ * @author Scott Nicklous
+ */
+public interface PortletHeaderResponseContext extends PortletMimeResponseContext
+{
+    void setTitle(String title);
+    void setNextPossiblePortletModes(Collection<PortletMode> portletModes);
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletInvokerService.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletInvokerService.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletInvokerService.java
index 8b35a56..2dddf78 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletInvokerService.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletInvokerService.java
@@ -22,6 +22,8 @@ import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
 import javax.portlet.EventRequest;
 import javax.portlet.EventResponse;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
 import javax.portlet.PortletException;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletResponse;
@@ -77,6 +79,14 @@ public interface PortletInvokerService {
     String METHOD_ID = "org.apache.pluto.core.method";
 
     /**
+     * The unique method identifier for header requests.  Header requests are
+     * requested through a call to the {@link PortletContainer#doHeader(org.apache.pluto.container.PortletWindow,
+     * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+     * method.
+     */
+    Integer METHOD_HEADER = new Integer(101);
+
+    /**
      * The unique method identifier for render requests.  Render requests are
      * requested through a call to the {@link PortletContainer#doRender(org.apache.pluto.container.PortletWindow,
      * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
@@ -85,7 +95,7 @@ public interface PortletInvokerService {
     Integer METHOD_RENDER = new Integer(1);
 
     /**
-     * The unique method identifier for render requests.  Render requests are
+     * The unique method identifier for action requests.  Action requests are
      * requested through a call to the {@link PortletContainer#doAction(org.apache.pluto.container.PortletWindow,
      * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
      * method.
@@ -137,6 +147,9 @@ public interface PortletInvokerService {
     void render(PortletRequestContext ctx, RenderRequest req, RenderResponse res, FilterManager filterManager)
     throws IOException, PortletException, PortletContainerException;
 
+    void header(PortletRequestContext ctx, HeaderRequest req, HeaderResponse res, FilterManager filterManager)
+    throws IOException, PortletException, PortletContainerException;
+
     void serveResource(PortletRequestContext ctx, ResourceRequest req, ResourceResponse res, FilterManager filterManager)
     throws IOException, PortletException, PortletContainerException;
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
index 51bf95a..15643e6 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
@@ -38,6 +38,9 @@ public interface PortletRequestContextService
                                                                    PortletWindow window,
                                                                    String pageState);
 
+    PortletRequestContext getPortletHeaderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                         HttpServletResponse containerResponse, PortletWindow window);
+
     PortletRequestContext getPortletRenderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
                                                          HttpServletResponse containerResponse, PortletWindow window);
 
@@ -55,4 +58,8 @@ public interface PortletRequestContextService
     PortletRenderResponseContext getPortletRenderResponseContext(PortletContainer container,
                                                                  HttpServletRequest containerRequest,
                                                                  HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletHeaderResponseContext getPortletHeaderResponseContext(PortletContainer container,
+                                                                 HttpServletRequest containerRequest,
+                                                                 HttpServletResponse containerResponse, PortletWindow window);
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
index 804f316..e8aaf53 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
@@ -25,6 +25,9 @@ import javax.portlet.ActionResponse;
 import javax.portlet.EventPortlet;
 import javax.portlet.EventRequest;
 import javax.portlet.EventResponse;
+import javax.portlet.HeaderPortlet;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
 import javax.portlet.Portlet;
 import javax.portlet.PortletConfig;
 import javax.portlet.PortletException;
@@ -51,435 +54,393 @@ import org.apache.pluto.container.PortletResourceRequestContext;
 import org.apache.pluto.container.PortletResponseContext;
 import org.apache.pluto.container.PortletWindow;
 import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * Portlet Invocation Servlet. This servlet recieves cross context requests from
- * the the container and services the portlet request for the specified method.
- *
+ * Portlet Invocation Servlet. This servlet recieves cross context requests from the the container and services the
+ * portlet request for the specified method.
+ * 
  * @version 1.1
  * @since 09/22/2004
  */
-public class PortletServlet3 extends HttpServlet
-{
-    private static final long serialVersionUID = -5096339022539360365L;
-    
-    /**
-     * Portlet name constant, needed by portlet container initializer
-     */
-    public static final String PORTLET_NAME = "portlet-name"; 
-
-
-    static class NullPortlet implements EventPortlet, ResourceServingPortlet, Portlet
-    {
-        public void processEvent(EventRequest arg0, EventResponse arg1)
-        throws PortletException, IOException
-        {
-        }
-
-        public void serveResource(ResourceRequest arg0, ResourceResponse arg1)
-        throws PortletException, IOException
-        {
-        }
-
-        public void destroy()
-        {
-        }
-
-        public void init(PortletConfig arg0) throws PortletException
-        {
-        }
-
-        public void processAction(ActionRequest arg0, ActionResponse arg1)
-        throws PortletException, IOException
-        {
-        }
-
-        public void render(RenderRequest arg0, RenderResponse arg1)
-        throws PortletException, IOException
-        {
-        }
-    }
-
-    // Private Member Variables ------------------------------------------------
-    /**
-     * The portlet name as defined in the portlet app descriptor.
-     */
-    private String portletName;
-
-    /**
-     * The portlet instance wrapped by this servlet.
-     */
-    private Portlet portlet;
-
-    /**
-     * The internal portlet context instance.
-     */
-    private DriverPortletContext portletContext;
-
-    /**
-     * The internal portlet config instance.
-     */
-    private DriverPortletConfig portletConfig;
-
-    /**
-     * The Event Portlet instance (the same object as portlet) wrapped by this
-     * servlet.
-     */
-    private EventPortlet eventPortlet;
-
-    /** The resource serving portlet instance wrapped by this servlet. */
-    private ResourceServingPortlet resourceServingPortlet;
-
-    private PortletContextService contextService;
-
-    private boolean started = false;
-    Timer   startTimer;
-
-    // HttpServlet Impl --------------------------------------------------------
-
-    public String getServletInfo()
-    {
-        return "Pluto PortletServlet3 [" + portletName + "]";
-    }
-
-    /**
-     * Initialize the portlet invocation servlet.
-     *
-     * @throws ServletException
-     *             if an error occurs while loading portlet.
-     */
-    public void init(ServletConfig config) throws ServletException
-    {
-
-        // Call the super initialization method.
-        super.init(config);
-
-        // Retrieve portlet name as defined as an initialization parameter.
-        portletName = getInitParameter(PORTLET_NAME);
-
-        started = false;
-
-        startTimer = new Timer(true);
-        final ServletContext servletContext = getServletContext();
-        final ClassLoader paClassLoader = Thread.currentThread().getContextClassLoader();
-        startTimer.schedule(new TimerTask()
-        {
-            public void run()
-            {
-                synchronized(servletContext)
-                {
-                    if (startTimer != null)
-                    {
-                        if (attemptRegistration(servletContext, paClassLoader ))
-                        {
-                            startTimer.cancel();
-                            startTimer = null;
-                        }
-                    }
-                }
-            }
-        }, 1, 10000);
-    }
-
-    protected boolean attemptRegistration(ServletContext context, ClassLoader paClassLoader)
-    {
-        if (PlutoServices.getServices() != null)
-        {
-            contextService = PlutoServices.getServices().getPortletContextService();
-            try
-            {
-                ServletConfig sConfig = getServletConfig();
-                if (sConfig == null)
-                {
-                    String msg = "Problem obtaining servlet configuration(getServletConfig() returns null).";
-                    context.log(msg);
-                    return true;
-                }
-
-                String applicationName = contextService.register(sConfig);
-                started = true;
-                portletContext = contextService.getPortletContext(applicationName);
-                portletConfig = contextService.getPortletConfig(applicationName, portletName);
-
-            }
-            catch (PortletContainerException ex)
-            {
-                context.log(ex.getMessage(),ex);
-                return true;
-            }
-
-            PortletDefinition portletDD = portletConfig.getPortletDefinition();
-
-            //          Create and initialize the portlet wrapped in the servlet.
-            try
-            {
-                Class<?> clazz = paClassLoader.loadClass((portletDD.getPortletClass()));
-                portlet = (Portlet) clazz.newInstance();
-                portlet.init(portletConfig);
-                initializeEventPortlet();
-                initializeResourceServingPortlet();
-                return true;
-            }
-            catch (Exception ex)
-            {
-                context.log(ex.getMessage(),ex);
-                // take out of service
-                portlet = null;
-                portletConfig = null;
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void destroy()
-    {
-        synchronized(getServletContext())
-        {
-            if ( startTimer != null )
-            {
-                startTimer.cancel();
-                startTimer = null;
-            }
-            else if ( started && portletContext != null)
-            {
-                started = false;
-                contextService.unregister(portletContext);
-                if (portlet != null)
-                {
-                    try
-                    {
-                        portlet.destroy();
-                    }
-                    catch (Exception e)
-                    {
-                        // ignore
-                    }
-                    portlet = null;
-                }
+public class PortletServlet3 extends HttpServlet {
+   private static final long  serialVersionUID = -5096339022539360365L;
+   
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletServlet3.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
+   
+
+   /**
+    * Portlet name constant, needed by portlet container initializer
+    */
+   public static final String PORTLET_NAME     = "portlet-name";
+
+   private class NullPortlet implements EventPortlet, ResourceServingPortlet, Portlet, HeaderPortlet {
+      public void processEvent(EventRequest arg0, EventResponse arg1) throws PortletException, IOException {
+      }
+
+      public void serveResource(ResourceRequest arg0, ResourceResponse arg1) throws PortletException, IOException {
+      }
+
+      public void destroy() {
+      }
+
+      public void init(PortletConfig arg0) throws PortletException {
+      }
+
+      public void processAction(ActionRequest arg0, ActionResponse arg1) throws PortletException, IOException {
+      }
+
+      public void render(RenderRequest arg0, RenderResponse arg1) throws PortletException, IOException {
+      }
+
+      @Override
+      public void renderHeaders(HeaderRequest request, HeaderResponse response) throws PortletException, IOException {
+         if (isDebug) {
+            LOG.debug("NullPortlet renderHeaders! Portlet name: " + portletName);
+         }
+      }
+   }
+
+   // Private Member Variables ------------------------------------------------
+
+   /**
+    * The portlet name as defined in the portlet app descriptor.
+    */
+   private String                 portletName;
+
+   /**
+    * The portlet instance wrapped by this servlet.
+    */
+   private Portlet                portlet;
+
+   /**
+    * The internal portlet context instance.
+    */
+   private DriverPortletContext   portletContext;
+
+   /**
+    * The internal portlet config instance.
+    */
+   private DriverPortletConfig    portletConfig;
+
+   /**
+    * The Event Portlet instance (the same object as portlet) wrapped by this servlet.
+    */
+   private EventPortlet           eventPortlet;
+   
+   /**
+    * Header portlet instance
+    */
+   private HeaderPortlet          headerPortlet;
+
+   /** The resource serving portlet instance wrapped by this servlet. */
+   private ResourceServingPortlet resourceServingPortlet;
+
+   private PortletContextService  contextService;
+
+   private boolean                started = false;
+   Timer                          startTimer;
+
+   // HttpServlet Impl --------------------------------------------------------
+
+   public String getServletInfo() {
+      return "Pluto PortletServlet3 [" + portletName + "]";
+   }
+
+   /**
+    * Initialize the portlet invocation servlet.
+    * 
+    * @throws ServletException
+    *            if an error occurs while loading portlet.
+    */
+   public void init(ServletConfig config) throws ServletException {
+
+      // Call the super initialization method.
+      super.init(config);
+
+      // Retrieve portlet name as defined as an initialization parameter.
+      portletName = getInitParameter(PORTLET_NAME);
+
+      started = false;
+
+      startTimer = new Timer(true);
+      final ServletContext servletContext = getServletContext();
+      final ClassLoader paClassLoader = Thread.currentThread().getContextClassLoader();
+      startTimer.schedule(new TimerTask() {
+         public void run() {
+            synchronized (servletContext) {
+               if (startTimer != null) {
+                  if (attemptRegistration(servletContext, paClassLoader)) {
+                     startTimer.cancel();
+                     startTimer = null;
+                  }
+               }
             }
-            super.destroy();
-        }
-    }
-
-    protected void doGet(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException
-            {
-        dispatch(request, response);
-            }
-
-    protected void doPost(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException
-            {
-        dispatch(request, response);
-            }
-
-    protected void doPut(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException
-            {
-        dispatch(request, response);
-            }
-
-    // Private Methods ---------------------------------------------------------
-
-    /**
-     * Dispatch the request to the appropriate portlet methods. This method
-     * assumes that the following attributes are set in the servlet request
-     * scope:
-     * <ul>
-     * <li>METHOD_ID: indicating which method to dispatch.</li>
-     * <li>PORTLET_REQUEST: the internal portlet request.</li>
-     * <li>PORTLET_RESPONSE: the internal portlet response.</li>
-     * </ul>
-     *
-     * @param request
-     *            the servlet request.
-     * @param response
-     *            the servlet response.
-     * @throws ServletException
-     * @throws IOException
-     */
-    private void dispatch(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException
-            {
-        if (portlet == null)
-        {
-            throw new javax.servlet.UnavailableException("Portlet "+portletName+" unavailable");
-        }
-
-        // Retrieve attributes from the servlet request.
-        Integer methodId = (Integer) request.getAttribute(PortletInvokerService.METHOD_ID);
-
-        final PortletRequest portletRequest = (PortletRequest)request.getAttribute(PortletInvokerService.PORTLET_REQUEST);
-
-        final PortletResponse portletResponse = (PortletResponse)request.getAttribute(PortletInvokerService.PORTLET_RESPONSE);
-
-        final PortletRequestContext requestContext = (PortletRequestContext)portletRequest.getAttribute(PortletInvokerService.REQUEST_CONTEXT);
-        final PortletResponseContext responseContext = (PortletResponseContext)portletRequest.getAttribute(PortletInvokerService.RESPONSE_CONTEXT);
-
-        final FilterManager filterManager = (FilterManager)request.getAttribute(PortletInvokerService.FILTER_MANAGER);
-
-        request.removeAttribute(PortletInvokerService.METHOD_ID);
-        request.removeAttribute(PortletInvokerService.PORTLET_REQUEST);
-        request.removeAttribute(PortletInvokerService.PORTLET_RESPONSE);
-        request.removeAttribute(PortletInvokerService.FILTER_MANAGER);
-
-        requestContext.init(portletConfig, getServletContext(), request, response);
-        responseContext.init(request, response);
-
-        PortletWindow window = requestContext.getPortletWindow();
-
-        PortletInvocationEvent event = new PortletInvocationEvent(portletRequest, window, methodId.intValue());
-
-        notify(event, true, null);
-
-        // FilterManager filtermanager = (FilterManager) request.getAttribute(
-        // "filter-manager");
-
-        try
-        {
-
-            // The requested method is RENDER: call Portlet.render(..)
-            if (methodId == PortletInvokerService.METHOD_RENDER)
-            {
-                RenderRequest renderRequest = (RenderRequest) portletRequest;
-                RenderResponse renderResponse = (RenderResponse) portletResponse;
-                filterManager.processFilter(renderRequest, renderResponse,
-                        portlet, portletContext);
-            }
-
-            // The requested method is RESOURCE: call
-            // ResourceServingPortlet.serveResource(..)
-            else if (methodId == PortletInvokerService.METHOD_RESOURCE)
-            {
-                ResourceRequest resourceRequest = (ResourceRequest) portletRequest;
-
-                // if pageState != null, we're dealing with a Partial Action request, so
-                // store the page state string as a request attribute
-                PortletResourceRequestContext rc = (PortletResourceRequestContext) requestContext;
-                String ps = rc.getPageState();
-                if (ps != null) {
-                   resourceRequest.setAttribute(ResourceRequest.PAGE_STATE, ps);
-                }
-
-                ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
-                filterManager.processFilter(resourceRequest, resourceResponse,
-                        resourceServingPortlet, portletContext);
+         }
+      }, 1, 10000);
+   }
+
+   protected boolean attemptRegistration(ServletContext context, ClassLoader paClassLoader) {
+      if (PlutoServices.getServices() != null) {
+         contextService = PlutoServices.getServices().getPortletContextService();
+         try {
+            ServletConfig sConfig = getServletConfig();
+            if (sConfig == null) {
+               String msg = "Problem obtaining servlet configuration(getServletConfig() returns null).";
+               context.log(msg);
+               return true;
             }
 
-            // The requested method is ACTION: call Portlet.processAction(..)
-            else if (methodId == PortletInvokerService.METHOD_ACTION)
-            {
-                ActionRequest actionRequest = (ActionRequest) portletRequest;
-                ActionResponse actionResponse = (ActionResponse) portletResponse;
-                filterManager.processFilter(actionRequest, actionResponse,
-                        portlet, portletContext);
-            }
-
-            // The request methode is Event: call Portlet.processEvent(..)
-            else if (methodId == PortletInvokerService.METHOD_EVENT)
-            {
-                EventRequest eventRequest = (EventRequest) portletRequest;
-                EventResponse eventResponse = (EventResponse) portletResponse;
-                filterManager.processFilter(eventRequest, eventResponse,
-                        eventPortlet, portletContext);
-            }
-            // The requested method is ADMIN: call handlers.
-            else if (methodId == PortletInvokerService.METHOD_ADMIN)
-            {
-                PortalAdministrationService pas = PlutoServices.getServices().getPortalAdministrationService();
-
-                for (AdministrativeRequestListener l : pas.getAdministrativeRequestListeners())
-                {
-                    l.administer(portletRequest, portletResponse);
-                }
-            }
-
-            // The requested method is LOAD: do nothing.
-            else if (methodId == PortletInvokerService.METHOD_LOAD)
-            {
-                // Do nothing.
-            }
-
-            notify(event, false, null);
-
-        }
-        catch (UnavailableException ex)
-        {
-            //
-            // if (e.isPermanent()) { throw new
-            // UnavailableException(e.getMessage()); } else { throw new
-            // UnavailableException(e.getMessage(), e.getUnavailableSeconds());
-            // }
-            //
-
-            // Portlet.destroy() isn't called by Tomcat, so we have to fix it.
-            try
-            {
-                portlet.destroy();
-            }
-            catch (Throwable th)
-            {
-                // Don't care for Exception
-                this.getServletContext().log("Error during portlet destroy.", th);
-            }
-            // take portlet out of service
+            String applicationName = contextService.register(sConfig);
+            started = true;
+            portletContext = contextService.getPortletContext(applicationName);
+            portletConfig = contextService.getPortletConfig(applicationName, portletName);
+
+         } catch (PortletContainerException ex) {
+            context.log(ex.getMessage(), ex);
+            return true;
+         }
+
+         PortletDefinition portletDD = portletConfig.getPortletDefinition();
+
+         // Create and initialize the portlet wrapped in the servlet.
+         try {
+            Class<?> clazz = paClassLoader.loadClass((portletDD.getPortletClass()));
+            portlet = (Portlet) clazz.newInstance();
+            portlet.init(portletConfig);
+            initializeEventPortlet();
+            initializeResourceServingPortlet();
+            initializeHeaderPortlet();
+            return true;
+         } catch (Exception ex) {
+            context.log(ex.getMessage(), ex);
+            // take out of service
             portlet = null;
-
-            // TODO: Handle everything as permanently for now.
-            throw new javax.servlet.UnavailableException(ex.getMessage());
-
-        }
-        catch (PortletException ex)
-        {
-            notify(event, false, ex);
-            throw new ServletException(ex);
-
-        }
+            portletConfig = null;
+            return true;
+         }
+      }
+      return false;
+   }
+
+   public void destroy() {
+      synchronized (getServletContext()) {
+         if (startTimer != null) {
+            startTimer.cancel();
+            startTimer = null;
+         } else if (started && portletContext != null) {
+            started = false;
+            contextService.unregister(portletContext);
+            if (portlet != null) {
+               try {
+                  portlet.destroy();
+               } catch (Exception e) {
+                  // ignore
+               }
+               portlet = null;
             }
-
-    protected void notify(PortletInvocationEvent event, boolean pre, Throwable e)
-    {
-        PortalAdministrationService pas = PlutoServices.getServices().getPortalAdministrationService();
-
-        for (PortletInvocationListener listener : pas.getPortletInvocationListeners())
-        {
-            if (pre)
-            {
-                listener.onBegin(event);
+         }
+         super.destroy();
+      }
+   }
+
+   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+      dispatch(request, response);
+   }
+
+   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+      dispatch(request, response);
+   }
+
+   protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+      dispatch(request, response);
+   }
+
+   // Private Methods ---------------------------------------------------------
+
+   /**
+    * Dispatch the request to the appropriate portlet methods. This method assumes that the following attributes are set
+    * in the servlet request scope:
+    * <ul>
+    * <li>METHOD_ID: indicating which method to dispatch.</li>
+    * <li>PORTLET_REQUEST: the internal portlet request.</li>
+    * <li>PORTLET_RESPONSE: the internal portlet response.</li>
+    * </ul>
+    * 
+    * @param request
+    *           the servlet request.
+    * @param response
+    *           the servlet response.
+    * @throws ServletException
+    * @throws IOException
+    */
+   private void dispatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+      if (portlet == null) {
+         throw new javax.servlet.UnavailableException("Portlet " + portletName + " unavailable");
+      }
+
+      // Retrieve attributes from the servlet request.
+      Integer methodId = (Integer) request.getAttribute(PortletInvokerService.METHOD_ID);
+
+      final PortletRequest portletRequest = (PortletRequest) request
+            .getAttribute(PortletInvokerService.PORTLET_REQUEST);
+
+      final PortletResponse portletResponse = (PortletResponse) request
+            .getAttribute(PortletInvokerService.PORTLET_RESPONSE);
+
+      final PortletRequestContext requestContext = (PortletRequestContext) portletRequest
+            .getAttribute(PortletInvokerService.REQUEST_CONTEXT);
+      final PortletResponseContext responseContext = (PortletResponseContext) portletRequest
+            .getAttribute(PortletInvokerService.RESPONSE_CONTEXT);
+
+      final FilterManager filterManager = (FilterManager) request.getAttribute(PortletInvokerService.FILTER_MANAGER);
+
+      request.removeAttribute(PortletInvokerService.METHOD_ID);
+      request.removeAttribute(PortletInvokerService.PORTLET_REQUEST);
+      request.removeAttribute(PortletInvokerService.PORTLET_RESPONSE);
+      request.removeAttribute(PortletInvokerService.FILTER_MANAGER);
+
+      requestContext.init(portletConfig, getServletContext(), request, response);
+      responseContext.init(request, response);
+
+      PortletWindow window = requestContext.getPortletWindow();
+
+      PortletInvocationEvent event = new PortletInvocationEvent(portletRequest, window, methodId.intValue());
+
+      notify(event, true, null);
+
+      // FilterManager filtermanager = (FilterManager) request.getAttribute(
+      // "filter-manager");
+
+      try {
+
+         // The requested method is RENDER: call Portlet.render(..)
+         if (methodId == PortletInvokerService.METHOD_RENDER) {
+            RenderRequest renderRequest = (RenderRequest) portletRequest;
+            RenderResponse renderResponse = (RenderResponse) portletResponse;
+            filterManager.processFilter(renderRequest, renderResponse, portlet, portletContext);
+         }
+
+         // The requested method is HEADER: call
+         // HeaderPortlet.renderHeaders(..)
+         else if (methodId == PortletInvokerService.METHOD_HEADER) {
+            HeaderRequest headerRequest = (HeaderRequest) portletRequest;
+            HeaderResponse headerResponse = (HeaderResponse) portletResponse;
+            filterManager.processFilter(headerRequest, headerResponse, headerPortlet, portletContext);
+         }
+
+         // The requested method is RESOURCE: call
+         // ResourceServingPortlet.serveResource(..)
+         else if (methodId == PortletInvokerService.METHOD_RESOURCE) {
+            ResourceRequest resourceRequest = (ResourceRequest) portletRequest;
+
+            // if pageState != null, we're dealing with a Partial Action request, so
+            // store the page state string as a request attribute
+            PortletResourceRequestContext rc = (PortletResourceRequestContext) requestContext;
+            String ps = rc.getPageState();
+            if (ps != null) {
+               resourceRequest.setAttribute(ResourceRequest.PAGE_STATE, ps);
             }
-            else if (e == null)
-            {
-                listener.onEnd(event);
-            }
-            else
-            {
-                listener.onError(event, e);
+
+            ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
+            filterManager.processFilter(resourceRequest, resourceResponse, resourceServingPortlet, portletContext);
+         }
+
+         // The requested method is ACTION: call Portlet.processAction(..)
+         else if (methodId == PortletInvokerService.METHOD_ACTION) {
+            ActionRequest actionRequest = (ActionRequest) portletRequest;
+            ActionResponse actionResponse = (ActionResponse) portletResponse;
+            filterManager.processFilter(actionRequest, actionResponse, portlet, portletContext);
+         }
+
+         // The request methode is Event: call Portlet.processEvent(..)
+         else if (methodId == PortletInvokerService.METHOD_EVENT) {
+            EventRequest eventRequest = (EventRequest) portletRequest;
+            EventResponse eventResponse = (EventResponse) portletResponse;
+            filterManager.processFilter(eventRequest, eventResponse, eventPortlet, portletContext);
+         }
+         // The requested method is ADMIN: call handlers.
+         else if (methodId == PortletInvokerService.METHOD_ADMIN) {
+            PortalAdministrationService pas = PlutoServices.getServices().getPortalAdministrationService();
+
+            for (AdministrativeRequestListener l : pas.getAdministrativeRequestListeners()) {
+               l.administer(portletRequest, portletResponse);
             }
-        }
-    }
-
-    private void initializeEventPortlet()
-    {
-        if (portlet instanceof EventPortlet)
-        {
-            eventPortlet = (EventPortlet) portlet;
-        }
-        else
-        {
-            eventPortlet = new NullPortlet();
-        }
-    }
-
-    private void initializeResourceServingPortlet()
-    {
-        if (portlet instanceof ResourceServingPortlet)
-        {
-            resourceServingPortlet = (ResourceServingPortlet) portlet;
-        }
-        else
-        {
-            resourceServingPortlet = new NullPortlet();
-        }
-    }
+         }
+
+         // The requested method is LOAD: do nothing.
+         else if (methodId == PortletInvokerService.METHOD_LOAD) {
+            // Do nothing.
+         }
+
+         notify(event, false, null);
+
+      } catch (UnavailableException ex) {
+         //
+         // if (e.isPermanent()) { throw new
+         // UnavailableException(e.getMessage()); } else { throw new
+         // UnavailableException(e.getMessage(), e.getUnavailableSeconds());
+         // }
+         //
+
+         // Portlet.destroy() isn't called by Tomcat, so we have to fix it.
+         try {
+            portlet.destroy();
+         } catch (Throwable th) {
+            // Don't care for Exception
+            this.getServletContext().log("Error during portlet destroy.", th);
+         }
+         // take portlet out of service
+         portlet = null;
+
+         // TODO: Handle everything as permanently for now.
+         throw new javax.servlet.UnavailableException(ex.getMessage());
+
+      } catch (PortletException ex) {
+         notify(event, false, ex);
+         throw new ServletException(ex);
+
+      }
+   }
+
+   protected void notify(PortletInvocationEvent event, boolean pre, Throwable e) {
+      PortalAdministrationService pas = PlutoServices.getServices().getPortalAdministrationService();
+
+      for (PortletInvocationListener listener : pas.getPortletInvocationListeners()) {
+         if (pre) {
+            listener.onBegin(event);
+         } else if (e == null) {
+            listener.onEnd(event);
+         } else {
+            listener.onError(event, e);
+         }
+      }
+   }
+
+   private void initializeEventPortlet() {
+      if (portlet instanceof EventPortlet) {
+         eventPortlet = (EventPortlet) portlet;
+      } else {
+         eventPortlet = new NullPortlet();
+      }
+   }
+
+   private void initializeResourceServingPortlet() {
+      if (portlet instanceof ResourceServingPortlet) {
+         resourceServingPortlet = (ResourceServingPortlet) portlet;
+      } else {
+         resourceServingPortlet = new NullPortlet();
+      }
+   }
+
+   private void initializeHeaderPortlet() {
+      if (portlet instanceof HeaderPortlet) {
+         headerPortlet = (HeaderPortlet) portlet;
+      } else {
+         headerPortlet = new NullPortlet();
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
new file mode 100644
index 0000000..81863c4
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
@@ -0,0 +1,40 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.impl;
+
+import javax.portlet.HeaderRequest;
+import javax.portlet.PortletRequest;
+
+import org.apache.pluto.container.PortletHeaderResponseContext;
+import org.apache.pluto.container.PortletRenderResponseContext;
+import org.apache.pluto.container.PortletRequestContext;
+
+/**
+ * The header request.
+ * 
+ * @author Scott Nicklous
+ */
+public class HeaderRequestImpl extends RenderRequestImpl implements HeaderRequest {
+   
+   HeaderRequestImpl(PortletRequestContext requestContext, PortletHeaderResponseContext responseContext) {
+      super(requestContext, responseContext, PortletRequest.HEADER_PHASE);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
new file mode 100644
index 0000000..37845ed
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletMode;
+import javax.portlet.RenderResponse;
+
+import org.apache.pluto.container.PortletHeaderResponseContext;
+import org.apache.pluto.container.PortletRenderResponseContext;
+import org.apache.pluto.container.util.ArgumentUtility;
+
+
+/**
+ * Implementation of the <code>javax.portlet.RenderResponse</code> interface.
+ * 
+ */
+@SuppressWarnings("unchecked")
+public class HeaderResponseImpl extends MimeResponseImpl implements HeaderResponse
+{	
+    
+    public HeaderResponseImpl(PortletHeaderResponseContext responseContext)
+    {
+        super(responseContext);
+    }
+    
+    /**
+     * Checks if the specified content type is valid (supported by the portlet).
+     * The specified content type should be a tripped mime type without any
+     * character encoding suffix.
+     * @param contentType  the content type to check.
+     * @return true if the content type is valid, false otherwise.
+     */
+    protected boolean isValidContentType(String contentType)
+    {
+        boolean valid = false;
+        for (String supportedType : getResponseContentTypes())
+        {
+            // Content type is supported by an exact match.
+            if (supportedType.equals(contentType))
+            {
+                valid = true;
+            }
+            // The supported type contains a wildcard.
+            else if (supportedType.indexOf("*") >= 0)
+            {
+                int index = supportedType.indexOf("/");
+                String supportedPrefix = supportedType.substring(0, index);
+                String supportedSuffix = supportedType.substring(index + 1);
+                index = contentType.indexOf("/");
+                String typePrefix = contentType.substring(0, index);
+                String typeSuffix = contentType.substring(index + 1);
+                // Check if the prefixes match AND the suffixes match.
+                if (supportedPrefix.equals("*") || supportedPrefix.equals(typePrefix))
+                {
+                    if (supportedSuffix.equals("*") || supportedSuffix.equals(typeSuffix))
+                    {
+                        valid = true;
+                    }
+                }
+            }
+        }
+        // Return the check result.
+        return valid;
+    }
+    
+    @Override
+    public void setContentType(String contentType)
+    {
+        ArgumentUtility.validateNotNull("contentType", contentType);
+        int index =contentType.indexOf(';');
+        if (index != -1)
+        {
+            contentType = contentType.substring(0, index);
+        }
+        contentType = contentType.trim();
+        if (!isValidContentType(contentType))
+        {
+            throw new IllegalArgumentException("Specified content type '" + contentType + "' is not supported.");
+        }
+        super.setContentType(contentType);
+    }
+    
+    public void setNextPossiblePortletModes(Collection<? extends PortletMode> portletModes)
+    {
+        ArgumentUtility.validateNotNull("portletModes", portletModes);
+        if (portletModes.isEmpty())
+        {
+            throw new IllegalArgumentException("At least one possible PortletMode should be specified.");            
+        }
+        ArrayList<PortletMode> modes = new ArrayList<PortletMode>();
+        for (PortletMode mode : portletModes)
+        {
+            if (isPortletModeAllowed(mode))
+            {
+                modes.add(mode);
+            }
+        }
+        if (modes.isEmpty())
+        {
+            modes.add(getPortletWindow().getPortletMode());
+        }
+        ((PortletHeaderResponseContext) responseContext).setNextPossiblePortletModes(modes);
+    }
+    
+    public void setTitle(String title)
+    {
+       ((PortletHeaderResponseContext) responseContext).setTitle(title);
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/MimeResponseImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/MimeResponseImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/MimeResponseImpl.java
index 8958cf9..ac0efe2 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/MimeResponseImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/MimeResponseImpl.java
@@ -46,7 +46,7 @@ public class MimeResponseImpl extends PortletResponseImpl implements
    private boolean                    committed;
    private String                     contentType;
 
-   private PortletMimeResponseContext responseContext;
+   protected PortletMimeResponseContext responseContext;
 
    public MimeResponseImpl(PortletMimeResponseContext responseContext) {
       super(responseContext);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
index 69b7c3f..84b5146 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
@@ -24,6 +24,8 @@ import javax.portlet.ActionResponse;
 import javax.portlet.Event;
 import javax.portlet.EventRequest;
 import javax.portlet.EventResponse;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
 import javax.portlet.PortletException;
 import javax.portlet.PortletRequest;
 import javax.portlet.RenderRequest;
@@ -40,6 +42,7 @@ import org.apache.pluto.container.PortletContainer;
 import org.apache.pluto.container.PortletContainerException;
 import org.apache.pluto.container.PortletEnvironmentService;
 import org.apache.pluto.container.PortletEventResponseContext;
+import org.apache.pluto.container.PortletHeaderResponseContext;
 import org.apache.pluto.container.PortletInvokerService;
 import org.apache.pluto.container.PortletRenderResponseContext;
 import org.apache.pluto.container.PortletRequestContext;
@@ -120,6 +123,55 @@ public class PortletContainerImpl implements PortletContainer
 
 
     /**
+     * Performs Header request for the portlet associated with the specified portlet window.
+     * @param portletWindow  the portlet window.
+     * @param request  the servlet request.
+     * @param response  the servlet response.
+     * @throws IllegalStateException  if the container is not initialized.
+     * @throws PortletException
+     * @throws IOException
+     * @throws PortletContainerException
+     * 
+     * @see javax.portlet.Portlet#header(HeaderRequest, HeaderResponse)
+     */
+    @Override
+    public void doHeader(PortletWindow portletWindow,
+            HttpServletRequest request,
+            HttpServletResponse response)
+    throws PortletException, IOException, PortletContainerException
+    {
+        ensureInitialized();
+
+        debugWithName("Header request received for portlet: "
+                + portletWindow.getPortletDefinition().getPortletName());
+
+        PortletRequestContextService rcService = getContainerServices().getPortletRequestContextService();
+        PortletEnvironmentService envService = getContainerServices().getPortletEnvironmentService();
+        PortletInvokerService invoker = getContainerServices().getPortletInvokerService();
+
+        PortletRequestContext requestContext = rcService.getPortletHeaderRequestContext(this, request, response, portletWindow);
+        PortletHeaderResponseContext responseContext = rcService.getPortletHeaderResponseContext(this, request, response, portletWindow);
+        HeaderRequest portletRequest = envService.createHeaderRequest(requestContext, responseContext);
+        HeaderResponse portletResponse = envService.createHeaderResponse(responseContext);
+
+        FilterManager filterManager = filterInitialisation(portletWindow,PortletRequest.HEADER_PHASE);
+
+        try
+        {
+            invoker.header(requestContext, portletRequest, portletResponse, filterManager);
+            // Mark portlet interaction is completed: backend implementation can flush response state now
+            responseContext.close();
+        }
+        finally
+        {
+            responseContext.release();
+        }
+
+        debugWithName("Portlet header done for: " + portletWindow.getPortletDefinition().getPortletName());
+    }
+
+
+    /**
      * Renders the portlet associated with the specified portlet window.
      * @param portletWindow  the portlet window.
      * @param request  the servlet request.
@@ -131,6 +183,7 @@ public class PortletContainerImpl implements PortletContainer
      * 
      * @see javax.portlet.Portlet#render(RenderRequest, RenderResponse)
      */
+    @Override
     public void doRender(PortletWindow portletWindow,
             HttpServletRequest request,
             HttpServletResponse response)

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletEnvironmentServiceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletEnvironmentServiceImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletEnvironmentServiceImpl.java
index 8849fb2..f7e41a0 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletEnvironmentServiceImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletEnvironmentServiceImpl.java
@@ -1,89 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import javax.portlet.ActionRequest;
-import javax.portlet.ActionResponse;
-import javax.portlet.Event;
-import javax.portlet.EventRequest;
-import javax.portlet.EventResponse;
-import javax.portlet.PortletContext;
-import javax.portlet.PortletSession;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceRequest;
-import javax.portlet.ResourceResponse;
-import javax.servlet.http.HttpSession;
-
-import org.apache.pluto.container.PortletActionResponseContext;
-import org.apache.pluto.container.PortletEnvironmentService;
-import org.apache.pluto.container.PortletEventResponseContext;
-import org.apache.pluto.container.PortletRenderResponseContext;
-import org.apache.pluto.container.PortletRequestContext;
-import org.apache.pluto.container.PortletResourceRequestContext;
-import org.apache.pluto.container.PortletResourceResponseContext;
-import org.apache.pluto.container.PortletWindow;
-
-public class PortletEnvironmentServiceImpl implements PortletEnvironmentService
-{
-    public ActionRequest createActionRequest(PortletRequestContext requestContext, PortletActionResponseContext responseContext)
-    {
-        return new ActionRequestImpl(requestContext, responseContext);
-    }
-
-    public ActionResponse createActionResponse(PortletActionResponseContext responseContext)
-    {
-        return new ActionResponseImpl(responseContext);
-    }
-
-    public EventRequest createEventRequest(PortletRequestContext requestContext, PortletEventResponseContext responseContext, Event event)
-    {
-        return new EventRequestImpl(requestContext, responseContext, event);
-    }
-
-    public EventResponse createEventResponse(PortletEventResponseContext responseContext)
-    {
-        return new EventResponseImpl(responseContext);
-    }
-
-    public PortletSession createPortletSession(PortletContext portletContext, PortletWindow portletWindow,
-                                               HttpSession session)
-    {
-        return new PortletSessionImpl(portletContext, portletWindow, session);
-    }
-
-    public RenderRequest createRenderRequest(PortletRequestContext requestContext, PortletRenderResponseContext responseContext)
-    {
-        return new RenderRequestImpl(requestContext, responseContext);
-    }
-
-    public RenderResponse createRenderResponse(PortletRenderResponseContext responseContext)
-    {
-        return new RenderResponseImpl(responseContext);
-    }
-
-    public ResourceRequest createResourceRequest(PortletResourceRequestContext requestContext, PortletResourceResponseContext responseContext)
-    {
-        return new ResourceRequestImpl(requestContext, responseContext);
-    }
-
-    public ResourceResponse createResourceResponse(PortletResourceResponseContext responseContext,
-                                                   String requestCacheLevel)
-    {
-        return new ResourceResponseImpl(responseContext, requestCacheLevel);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.Event;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.pluto.container.PortletActionResponseContext;
+import org.apache.pluto.container.PortletEnvironmentService;
+import org.apache.pluto.container.PortletEventResponseContext;
+import org.apache.pluto.container.PortletHeaderResponseContext;
+import org.apache.pluto.container.PortletRenderResponseContext;
+import org.apache.pluto.container.PortletRequestContext;
+import org.apache.pluto.container.PortletResourceRequestContext;
+import org.apache.pluto.container.PortletResourceResponseContext;
+import org.apache.pluto.container.PortletWindow;
+
+public class PortletEnvironmentServiceImpl implements PortletEnvironmentService
+{
+    public ActionRequest createActionRequest(PortletRequestContext requestContext, PortletActionResponseContext responseContext)
+    {
+        return new ActionRequestImpl(requestContext, responseContext);
+    }
+
+    public ActionResponse createActionResponse(PortletActionResponseContext responseContext)
+    {
+        return new ActionResponseImpl(responseContext);
+    }
+
+    public EventRequest createEventRequest(PortletRequestContext requestContext, PortletEventResponseContext responseContext, Event event)
+    {
+        return new EventRequestImpl(requestContext, responseContext, event);
+    }
+
+    public EventResponse createEventResponse(PortletEventResponseContext responseContext)
+    {
+        return new EventResponseImpl(responseContext);
+    }
+
+    public PortletSession createPortletSession(PortletContext portletContext, PortletWindow portletWindow,
+                                               HttpSession session)
+    {
+        return new PortletSessionImpl(portletContext, portletWindow, session);
+    }
+
+    public HeaderRequest createHeaderRequest(PortletRequestContext requestContext, PortletHeaderResponseContext responseContext)
+    {
+        return new HeaderRequestImpl(requestContext, responseContext);
+    }
+
+    public HeaderResponse createHeaderResponse(PortletHeaderResponseContext responseContext)
+    {
+        return new HeaderResponseImpl(responseContext);
+    }
+
+    public RenderRequest createRenderRequest(PortletRequestContext requestContext, PortletRenderResponseContext responseContext)
+    {
+        return new RenderRequestImpl(requestContext, responseContext);
+    }
+
+    public RenderResponse createRenderResponse(PortletRenderResponseContext responseContext)
+    {
+        return new RenderResponseImpl(responseContext);
+    }
+
+    public ResourceRequest createResourceRequest(PortletResourceRequestContext requestContext, PortletResourceResponseContext responseContext)
+    {
+        return new ResourceRequestImpl(requestContext, responseContext);
+    }
+
+    public ResourceResponse createResourceResponse(PortletResourceResponseContext responseContext,
+                                                   String requestCacheLevel)
+    {
+        return new ResourceResponseImpl(responseContext, requestCacheLevel);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderRequestImpl.java
index 821f85e..38e2fd6 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderRequestImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderRequestImpl.java
@@ -1,51 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import javax.portlet.CacheControl;
-import javax.portlet.PortletRequest;
-import javax.portlet.RenderRequest;
-
-import org.apache.pluto.container.PortletRenderResponseContext;
-import org.apache.pluto.container.PortletRequestContext;
-
-/**
- * Implementation of the <code>javax.portlet.RenderRequest</code> interface.
- * 
- */
-public class RenderRequestImpl extends PortletRequestImpl implements RenderRequest 
-{
-    private CacheControl cacheControl;
-    
-    public RenderRequestImpl(PortletRequestContext requestContext, PortletRenderResponseContext responseContext) 
-    {
-        super(requestContext, responseContext, PortletRequest.RENDER_PHASE);
-        this.cacheControl = responseContext.getCacheControl();
-    }
-
-    @Override
-    public String getProperty(String name)
-    {
-        String result = getMimeRequestProperty(name, cacheControl);
-        return result != null ? result : super.getProperty(name);
-   }
-
-    public String getETag()
-    {
-        return cacheControl.getETag();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import javax.portlet.CacheControl;
+import javax.portlet.PortletRequest;
+import javax.portlet.RenderRequest;
+
+import org.apache.pluto.container.PortletMimeResponseContext;
+import org.apache.pluto.container.PortletRenderResponseContext;
+import org.apache.pluto.container.PortletRequestContext;
+
+/**
+ * Implementation of the <code>javax.portlet.RenderRequest</code> interface.
+ * 
+ */
+public class RenderRequestImpl extends PortletRequestImpl implements RenderRequest 
+{
+    private CacheControl cacheControl;
+    
+    public RenderRequestImpl(PortletRequestContext requestContext, PortletRenderResponseContext responseContext) 
+    {
+        super(requestContext, responseContext, PortletRequest.RENDER_PHASE);
+        this.cacheControl = responseContext.getCacheControl();
+    }
+    
+    /**
+     * For use in HeaderRequestImpl constructor.
+     * @param requestContext
+     * @param responseContext
+     * @param lifecyclePhase
+     */
+    public RenderRequestImpl(PortletRequestContext requestContext, PortletMimeResponseContext responseContext, String lifecyclePhase) 
+    {
+        super(requestContext, responseContext, lifecyclePhase);
+        this.cacheControl = responseContext.getCacheControl();
+    }
+
+    @Override
+    public String getProperty(String name)
+    {
+        String result = getMimeRequestProperty(name, cacheControl);
+        return result != null ? result : super.getProperty(name);
+   }
+
+    public String getETag()
+    {
+        return cacheControl.getETag();
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/65c0050b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderResponseImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderResponseImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderResponseImpl.java
index 04b41ea..7ed3d24 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderResponseImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/RenderResponseImpl.java
@@ -30,14 +30,13 @@ import org.apache.pluto.container.util.ArgumentUtility;
  * Implementation of the <code>javax.portlet.RenderResponse</code> interface.
  * 
  */
+@SuppressWarnings("unchecked")
 public class RenderResponseImpl extends MimeResponseImpl implements RenderResponse
 {	
-    private PortletRenderResponseContext responseContext;
     
     public RenderResponseImpl(PortletRenderResponseContext responseContext)
     {
         super(responseContext);
-        this.responseContext = responseContext;
     }
     
     /**
@@ -116,11 +115,11 @@ public class RenderResponseImpl extends MimeResponseImpl implements RenderRespon
         {
             modes.add(getPortletWindow().getPortletMode());
         }
-        responseContext.setNextPossiblePortletModes(modes);
+        ((PortletRenderResponseContext) responseContext).setNextPossiblePortletModes(modes);
     }
     
     public void setTitle(String title)
     {
-        responseContext.setTitle(title);
+       ((PortletRenderResponseContext) responseContext).setTitle(title);
     }
 }