You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by ta...@apache.org on 2006/12/06 22:29:48 UTC

svn commit: r483240 - in /portals/jetspeed-2/trunk: commons/src/java/org/apache/jetspeed/container/ components/portal/src/java/org/apache/jetspeed/aggregator/impl/ components/portal/src/java/org/apache/jetspeed/container/invoker/ components/portal/src/...

Author: taylor
Date: Wed Dec  6 13:29:46 2006
New Revision: 483240

URL: http://svn.apache.org/viewvc?view=rev&rev=483240
Log:
https://issues.apache.org/jira/browse/JS2-226
continuing work on AsyncPageAggregator with contributions from Woonsan Ko
this work is still ongoing

Modified:
    portals/jetspeed-2/trunk/commons/src/java/org/apache/jetspeed/container/JetspeedContainerServlet.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/AsyncPageAggregatorImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/invoker/ServletPortletInvoker.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/servlet/ServletRequestImpl.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/request/JetspeedRequestContextComponent.java
    portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/aggregator/MockRenderJob.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/PortalReservedParameters.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletRenderer.java

Modified: portals/jetspeed-2/trunk/commons/src/java/org/apache/jetspeed/container/JetspeedContainerServlet.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/commons/src/java/org/apache/jetspeed/container/JetspeedContainerServlet.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/commons/src/java/org/apache/jetspeed/container/JetspeedContainerServlet.java (original)
+++ portals/jetspeed-2/trunk/commons/src/java/org/apache/jetspeed/container/JetspeedContainerServlet.java Wed Dec  6 13:29:46 2006
@@ -20,6 +20,7 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -203,18 +204,40 @@
         Integer method = ContainerConstants.METHOD_NOOP;
         Portlet portlet = null;
         boolean destroyPortlet = false;
+        Map workerAsMap = null;
         
         try
         {
-            method = (Integer) request.getAttribute(ContainerConstants.METHOD_ID);
+            Thread ct = Thread.currentThread();
+            if (ct instanceof Map)
+            {
+                workerAsMap = (Map) ct;
+            }
+            if (workerAsMap != null)
+            {
+                method = (Integer) workerAsMap.get(ContainerConstants.METHOD_ID);
+            }
+            else
+            {
+                method = (Integer) request.getAttribute(ContainerConstants.METHOD_ID);
+            }
             if (method == ContainerConstants.METHOD_NOOP)
             {
                 return;
             }
             
-            portlet = (Portlet)request.getAttribute(ContainerConstants.PORTLET);
-            portletName = (String)request.getAttribute(ContainerConstants.PORTLET_NAME);
             request.removeAttribute(ContainerConstants.PORTLET);
+            if (workerAsMap != null)
+            {
+                portlet = (Portlet) workerAsMap.get(ContainerConstants.PORTLET);
+                portletName = (String) workerAsMap.get(ContainerConstants.PORTLET_NAME);
+            }
+            else
+            {
+                portlet = (Portlet)request.getAttribute(ContainerConstants.PORTLET);
+                portletName = (String)request.getAttribute(ContainerConstants.PORTLET_NAME);
+                request.removeAttribute(ContainerConstants.PORTLET);
+            }
 
             if (method == ContainerConstants.METHOD_ACTION)
             {
@@ -227,11 +250,21 @@
             }
             else if (method == ContainerConstants.METHOD_RENDER)
             {
-                RenderRequest renderRequest = (RenderRequest) request.getAttribute(ContainerConstants.PORTLET_REQUEST);
-                RenderResponse renderResponse = (RenderResponse) request.getAttribute(ContainerConstants.PORTLET_RESPONSE);
+                RenderRequest renderRequest = null;
+                RenderResponse renderResponse =  null;
+
+                if (workerAsMap != null)
+                {
+                    renderRequest = (RenderRequest) workerAsMap.get(ContainerConstants.PORTLET_REQUEST);
+                    renderResponse = (RenderResponse) workerAsMap.get(ContainerConstants.PORTLET_RESPONSE);
+                }
+                else
+                {
+                    renderRequest = (RenderRequest) request.getAttribute(ContainerConstants.PORTLET_REQUEST);
+                    renderResponse = (RenderResponse) request.getAttribute(ContainerConstants.PORTLET_RESPONSE);
+                }                
                 // inject the current request into the renderRequest handler (o.a.j.engine.servlet.ServletRequestImpl)
                 ((HttpServletRequestWrapper)((HttpServletRequestWrapper)renderRequest).getRequest()).setRequest(request);
-
                 portlet.render(renderRequest, renderResponse);
             }
 

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/AsyncPageAggregatorImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/AsyncPageAggregatorImpl.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/AsyncPageAggregatorImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/AsyncPageAggregatorImpl.java Wed Dec  6 13:29:46 2006
@@ -18,6 +18,7 @@
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ArrayList;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -27,6 +28,8 @@
 import org.apache.jetspeed.aggregator.FailedToRenderFragmentException;
 import org.apache.jetspeed.aggregator.PageAggregator;
 import org.apache.jetspeed.aggregator.PortletRenderer;
+import org.apache.jetspeed.aggregator.RenderingJob;
+import org.apache.jetspeed.aggregator.PortletContent;
 import org.apache.jetspeed.container.state.NavigationalState;
 import org.apache.jetspeed.exception.JetspeedException;
 import org.apache.jetspeed.om.page.ContentFragment;
@@ -93,7 +96,7 @@
         }
         else
         {
-            aggregateAndRender(root, context, page, true);
+            aggregateAndRender(root, context, page, true, null, null);
         }
         
         //dispatcher.include(root);
@@ -157,11 +160,22 @@
         }
     }
 
-    protected void aggregateAndRender(ContentFragment f, RequestContext context, ContentPage page, boolean isRoot)
+    protected void aggregateAndRender(ContentFragment f, RequestContext context, ContentPage page, boolean isRoot,
+                                      List portletJobs, List layoutFragments)
             throws FailedToRenderFragmentException
     {
         // First Pass, kick off async render threads for all portlets on page 
-                
+        // Store portlet rendering jobs in the list to wait later.
+        // Store layout fragment in the list to render later.
+        if (portletJobs == null) 
+        {
+            portletJobs = new ArrayList(16);
+        }
+        if (layoutFragments == null)
+        {
+            layoutFragments = new ArrayList(4);
+        }
+
         if (f.getContentFragments() != null && f.getContentFragments().size() > 0)
         {
             Iterator children = f.getContentFragments().iterator();
@@ -173,29 +187,57 @@
                     if (child.getType().equals(ContentFragment.PORTLET))
                     {
                         // kick off render thread
-                        renderer.render(child, context); 
+                        // and store the portlet rendering job into the portlet jobs list.
+                        RenderingJob job = renderer.render(child, context); 
+                        portletJobs.add(job);
                     }
                     else
                     {
                         // walk thru layout 
-                        aggregateAndRender(child, context, page, false);
+                        // and store the layout rendering job into the layout jobs list.
+                        aggregateAndRender(child, context, page, false, portletJobs, layoutFragments);
+                        layoutFragments.add(child);
                     }
                 }
             }
         }
 
+        // If the fragment is not root, skip the following.
+        if (!isRoot)
+            return;
 
-        // sync
-        // TODO: synchronize on completion of all jobs
-        // not sure where that code went, used to be in here, very odd
-        try
-        {
-            // TODO: remove this when I get the monitor/sync in place (again)
-            // need to dig thru old code in cvs if its still there
-            Thread.sleep(4000);
+
+        // synchronize on completion of all jobs
+        Iterator it = portletJobs.iterator();
+        
+        try 
+        {
+            while (it.hasNext()) 
+            {
+                RenderingJob job = (RenderingJob) it.next();
+                PortletContent portletContent = job.getPortletContent();
+                
+                if (!portletContent.isComplete()) 
+                {
+                    synchronized (portletContent) 
+                    {
+                        portletContent.wait();
+                    }
+                }
+            }
         }
         catch (Exception e)
-        {}
+        {
+            log.error("Exception during synchronizing all portlet rendering jobs.", e);
+        }
+        
+        // render layout fragments.
+        it = layoutFragments.iterator();
+        while (it.hasNext()) 
+        {
+            ContentFragment child = (ContentFragment) it.next();
+            renderer.renderNow(child, context);
+        }
         
         // Start the actual rendering process
         String defaultPortletDecorator = page.getEffectiveDefaultDecorator(ContentFragment.PORTLET);
@@ -207,15 +249,6 @@
         renderer.renderNow(f, context);
         
         
-//        if (strategy == STRATEGY_SEQUENTIAL)
-//        {
-//            renderer.renderNow(f, context);
-//        }
-//        else
-//        {
-//            renderer.render(f, context);
-//        }
-
         if (f.getDecorator() != null && f.getType().equals(ContentFragment.PORTLET))
         {
             log.debug("decorator=" + f.getDecorator());
@@ -224,8 +257,10 @@
         else if (f.getDecorator() == null && f.getType().equals(ContentFragment.PORTLET))
         {
             log.debug("no decorator for defined for portlet fragement," + f.getId() + ".  So using page default, "
-                    + defaultPortletDecorator);
+                      + defaultPortletDecorator);
             contentServer.addStyle(context, defaultPortletDecorator, ContentFragment.PORTLET);
         }
     }
+    
+
 }

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/PortletRendererImpl.java Wed Dec  6 13:29:46 2006
@@ -15,6 +15,9 @@
  */
 package org.apache.jetspeed.aggregator.impl;
 
+import java.util.Map;
+import java.util.HashMap;
+
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -126,7 +129,7 @@
             servletRequest = requestContext.getRequestForWindow(portletWindow);
             servletResponse = dispatcherCtrl.getResponseForWindow(portletWindow, requestContext);
 
-            RenderingJob rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext);
+            RenderingJob rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext, false);
             rJob.execute();
             addTitleToHeader( portletWindow, fragment, servletRequest, servletResponse );
         }
@@ -160,7 +163,7 @@
             HttpServletRequest servletRequest = requestContext.getRequestForWindow(portletWindow);
             HttpServletResponse servletResponse = dispatcherCtrl.getResponseForWindow(portletWindow, requestContext);
 
-            RenderingJob rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext);
+            RenderingJob rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext, false);
             rJob.execute();
             addTitleToHeader( portletWindow, fragment, servletRequest, servletResponse );
         }
@@ -180,8 +183,9 @@
      * @throws UnknownPortletDefinitionException
      * @throws FailedToRetrievePortletWindow
      */
-    public void render( ContentFragment fragment, RequestContext requestContext )
+    public RenderingJob render( ContentFragment fragment, RequestContext requestContext )
     {
+        RenderingJob rJob = null;
         PortletWindow portletWindow;
         
         ContentDispatcherCtrl dispatcherCtrl = getDispatcherCtrl(requestContext, true);
@@ -195,7 +199,7 @@
             portletWindow = getPortletWindow(fragment);
             servletRequest = requestContext.getRequestForWindow(portletWindow);
             servletResponse = dispatcherCtrl.getResponseForWindow(portletWindow, requestContext);
-            RenderingJob rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext);
+            rJob = buildRenderingJob(fragment, servletRequest, servletResponse, requestContext, true);                
             workMonitor.process(rJob);
             addTitleToHeader( portletWindow, fragment, servletRequest, servletResponse );
         }
@@ -208,7 +212,7 @@
 //            ObjectID oid = JetspeedObjectID.createFromString(fragment.getId());
         //    ((ContentDispatcherImpl) dispatcherCtrl).notify(oid);
         }
-
+        return rJob;
     }
 
     /**
@@ -250,9 +254,10 @@
     }
 
     protected RenderingJob buildRenderingJob( ContentFragment fragment, HttpServletRequest request,
-            HttpServletResponse response, RequestContext requestContext ) throws FailedToRetrievePortletWindow,
-            FailedToRenderFragmentException, PortletEntityNotStoredException
+        HttpServletResponse response, RequestContext requestContext, boolean isParallel ) 
+    throws FailedToRetrievePortletWindow, FailedToRenderFragmentException, PortletEntityNotStoredException
     {
+        RenderingJob rJob = null;
         ContentDispatcher dispatcher = null;
         
         PortletWindow portletWindow = getPortletWindow(fragment);
@@ -265,14 +270,38 @@
         request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE, requestContext.getPage());
         request.setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
         request.setAttribute(PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE, dispatcher);
-        request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);        
-        request.setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
+        request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);                
         request.setAttribute(PortalReservedParameters.PATH_ATTRIBUTE, requestContext.getAttribute(PortalReservedParameters.PATH_ATTRIBUTE));
         request.setAttribute(PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE, portletWindow);
         PortletContent portletContent = dispatcher.getPortletContent(fragment);
         fragment.setPortletContent(portletContent);
         
-        return new RenderingJobImpl(container, portletContent, fragment, request, response, requestContext, portletWindow, statistics);
+        // In case of parallel mode, store attributes in a map to be refered by worker.
+        if (isParallel)
+        {
+            Map workerAttrs = new HashMap();
+            workerAttrs.put(PortalReservedParameters.PAGE_ATTRIBUTE, requestContext.getPage());
+            workerAttrs.put(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
+            workerAttrs.put(PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE, dispatcher);
+            workerAttrs.put(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);        
+            workerAttrs.put(PortalReservedParameters.PATH_ATTRIBUTE, requestContext.getAttribute(PortalReservedParameters.PATH_ATTRIBUTE));
+            workerAttrs.put(PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE, portletWindow);
+
+            // the portlet invoker is not thread safe; it stores current portlet definition as a member variable.
+            // so, store portlet definition as an attribute of worker
+            workerAttrs.put(PortalReservedParameters.PORTLET_DEFINITION_ATTRIBUTE, 
+                            portletWindow.getPortletEntity().getPortletDefinition());
+
+            rJob = new RenderingJobImpl(container, portletContent, fragment, request, response, requestContext, portletWindow, statistics, workerAttrs);
+        }
+        else
+        {
+            rJob = new RenderingJobImpl(container, portletContent, fragment, request, response, requestContext, portletWindow, statistics);
+        }
+
+
+        return rJob;
+        
     }
     
     protected void addTitleToHeader( PortletWindow portletWindow, ContentFragment fragment, HttpServletRequest request, HttpServletResponse response )

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java Wed Dec  6 13:29:46 2006
@@ -16,6 +16,8 @@
 
 package org.apache.jetspeed.aggregator.impl;
 
+import java.util.Map;
+
 import javax.portlet.UnavailableException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -31,6 +33,9 @@
 import org.apache.jetspeed.statistics.PortalStatistics;
 import org.apache.pluto.PortletContainer;
 import org.apache.pluto.om.window.PortletWindow;
+import org.apache.pluto.om.portlet.PortletDefinition;
+import org.apache.pluto.om.entity.PortletEntity;
+import org.apache.jetspeed.components.portletentity.PortletEntityImpl;
 
 /**
  * The RenderingJob is responsible for storing all necessary objets for
@@ -56,6 +61,8 @@
 
     protected PortletContent portletContent;
     protected PortalStatistics statistics;
+
+    protected Map workerAttributes;
     
     public RenderingJobImpl(PortletContainer container, 
                             PortletContent portletContent, 
@@ -78,6 +85,20 @@
         
     }
 
+    public RenderingJobImpl(PortletContainer container, 
+                            PortletContent portletContent, 
+                            ContentFragment fragment, 
+                            HttpServletRequest request, 
+                            HttpServletResponse response, 
+                            RequestContext requestContext, 
+                            PortletWindow window,
+                            PortalStatistics statistics,
+                            Map workerAttributes)
+    {
+        this(container, portletContent, fragment, request, response, requestContext, window, statistics);
+        this.workerAttributes = workerAttributes;
+    }
+
     /**
      * Checks if queue is empty, if not try to empty it by calling
      * the WorkerMonitor. When done, pause until next scheduled scan.
@@ -110,10 +131,41 @@
      */
     public void execute()
     {
-        long start = System.currentTimeMillis();       
+        long start = System.currentTimeMillis();
+
+        Map workerAsMap = null;
+
         try
         {
-            log.debug("Rendering OID "+this.window.getId()+" "+ this.request +" "+this.response);            
+            log.debug("Rendering OID "+this.window.getId()+" "+ this.request +" "+this.response);
+
+            // if the current thread is worker, then store attribues in that.
+            if (this.workerAttributes != null)
+            {
+                Thread ct = Thread.currentThread();
+                if (ct instanceof Map)
+                {
+                    workerAsMap = (Map) ct;
+                    workerAsMap.putAll(this.workerAttributes);
+
+                    // Sometimes, the portlet definition of some portlet entities are replaced.
+                    // I could not find why it happens.
+                    // If the portlet definition of portlet entity is not same as an attribute of worker's, then
+                    // reset the portlet definition of portlet entity. (by Woonsan Ko)
+                    // TODO: Investigate more and find why it happens.
+                    PortletDefinition portletDefinition = 
+                        (PortletDefinition) workerAsMap.get(PortalReservedParameters.PORTLET_DEFINITION_ATTRIBUTE);
+                    PortletWindow window = 
+                        (PortletWindow) workerAsMap.get(PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE);
+                    PortletEntityImpl portletEntityImpl = (PortletEntityImpl) window.getPortletEntity();
+                    PortletDefinition oldPortletDefinition = portletEntityImpl.getPortletDefinition();
+
+                    if (!oldPortletDefinition.getId().equals(portletDefinition.getId())) {
+                        portletEntityImpl.setPortletDefinition(portletDefinition);
+                    }
+                }
+            }
+            
             this.request.setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
             this.request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE, requestContext.getPage());
             this.request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);
@@ -137,6 +189,11 @@
         }
         finally
         {
+            if (workerAsMap != null)
+            {
+                workerAsMap.clear();
+            }
+
             portletContent.complete();
             if (fragment.getType().equals(ContentFragment.PORTLET))
             {
@@ -160,4 +217,17 @@
     {
         return window;
     }
-}
\ No newline at end of file
+
+    /**
+     * 
+     * <p>
+     * getPortletContent
+     * </p>
+     *
+     * @return The portlet content this job is in charge of rendering
+     */
+    public PortletContent getPortletContent()
+    {
+        return portletContent;
+    }
+}

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java Wed Dec  6 13:29:46 2006
@@ -18,6 +18,10 @@
 
 import java.security.AccessControlContext;
 import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 import javax.security.auth.Subject;
 
@@ -35,7 +39,7 @@
  * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
  * @version $Id$
  */
-public class WorkerImpl extends Thread implements Worker
+public class WorkerImpl extends Thread implements Worker, Map
 {
     /** Commons logging */
     protected final static Log log = LogFactory.getLog(WorkerImpl.class);
@@ -56,6 +60,9 @@
     /** Monitor for this Worker */
     private WorkerMonitor monitor = null;
 
+    /** Attributes for this Worker **/
+    private Map attributes = null;    
+    
     public WorkerImpl(WorkerMonitor monitor)
     {
         super();
@@ -200,4 +207,82 @@
             monitor.release(this);
         }
     }
+
+    // map implementations
+
+    public int size() 
+    {
+        return (null == this.attributes ? 0 : this.attributes.size());
+    }
+
+    public boolean isEmpty() 
+    {
+        return (null == this.attributes ? true : this.attributes.isEmpty());
+    }
+
+    public boolean containsKey(Object key) 
+    {
+        return (null == this.attributes ? false : this.attributes.containsKey(key));
+    }
+
+    public boolean containsValue(Object value) 
+    {
+        return (null == this.attributes ? false : this.attributes.containsValue(value));
+    }
+
+    public Object get(Object key) 
+    {
+        return (null == this.attributes ? null : this.attributes.get(key));
+    }
+
+    public Object put(Object key, Object value) 
+    {
+        if (null == this.attributes) {
+            this.attributes = new HashMap();
+        }
+
+        return this.attributes.put(key, value);
+    }
+
+    public Object remove(Object key) 
+    {
+        if (null != this.attributes) {
+            return this.attributes.remove(key);
+        } else {
+            return null;
+        }
+    }
+
+    public void putAll(Map t) 
+    {
+        if (null == this.attributes) {
+            this.attributes = new HashMap();
+        }
+
+        this.attributes.putAll(t);
+    }
+
+    public void clear() 
+    {
+        if (null != this.attributes) {
+            this.attributes.clear();
+        }
+    }
+
+    public Set keySet() 
+    {
+        return (null == this.attributes ? null : this.attributes.keySet());
+    }
+
+    public Collection values() 
+    {
+        return (null == this.attributes ? null : this.attributes.values());
+    }
+
+    public Set entrySet() 
+    {
+        return (null == this.attributes ? null : this.attributes.entrySet());
+    }
+
+    
 }

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/invoker/ServletPortletInvoker.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/invoker/ServletPortletInvoker.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/invoker/ServletPortletInvoker.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/invoker/ServletPortletInvoker.java Wed Dec  6 13:29:46 2006
@@ -16,6 +16,7 @@
 package org.apache.jetspeed.container.invoker;
 
 import java.io.IOException;
+import java.util.Map;
 
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
@@ -164,6 +165,24 @@
     protected void invoke(PortletRequest portletRequest, PortletResponse portletResponse, Integer methodID)
         throws PortletException, IOException
     {
+        // In case of parallel mode, the portletDefinition member is not thread-safe.
+        // So, hide the member variable by the following local variable.
+        PortletDefinition portletDefinition = null;
+
+        // In case of parallel mode, get portlet definition object from the worker thread.
+        // Otherwise, refer the member variable.
+        Map workerAsMap = null;
+        Thread ct = Thread.currentThread();
+        if (ct instanceof Map)
+        {
+            workerAsMap = (Map) ct;
+            portletDefinition = (PortletDefinition) workerAsMap.get(PortalReservedParameters.PORTLET_DEFINITION_ATTRIBUTE);
+        }
+        else
+        {
+            portletDefinition = this.portletDefinition;
+        }
+        
         ClassLoader paClassLoader = portletFactory.getPortletApplicationClassLoader((PortletApplication)portletDefinition.getPortletApplicationDefinition());
 
         MutablePortletApplication app = (MutablePortletApplication)portletDefinition.getPortletApplicationDefinition();
@@ -211,6 +230,18 @@
             RequestContext requestContext = (RequestContext)servletRequest.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
             servletRequest.setAttribute(ContainerConstants.PORTAL_CONTEXT, requestContext.getRequest().getContextPath());
 
+            // Store same request attributes into the worker in parallel mode.
+            if (workerAsMap != null)
+            {
+                workerAsMap.put(ContainerConstants.PORTLET, portletInstance);
+                workerAsMap.put(ContainerConstants.PORTLET_CONFIG, portletInstance.getConfig());
+                workerAsMap.put(ContainerConstants.PORTLET_REQUEST, portletRequest);
+                workerAsMap.put(ContainerConstants.PORTLET_RESPONSE, portletResponse);
+                workerAsMap.put(ContainerConstants.METHOD_ID, methodID);
+                workerAsMap.put(ContainerConstants.PORTLET_NAME, app.getName()+"::"+portletDefinition.getName());
+                workerAsMap.put(ContainerConstants.PORTAL_CONTEXT, requestContext.getRequest().getContextPath());                
+            }
+
             PortletRequestContext.createContext(portletDefinition, portletInstance, portletRequest, portletResponse);
             dispatcher.include(servletRequest, servletResponse);
             
@@ -225,6 +256,19 @@
         finally
         {
             PortletRequestContext.clearContext();
+
+            // In parallel mode, remove attributes of worker.
+            if (workerAsMap != null)
+            {
+                workerAsMap.remove(ContainerConstants.PORTLET);
+                workerAsMap.remove(ContainerConstants.PORTLET_CONFIG);
+                workerAsMap.remove(ContainerConstants.PORTLET_REQUEST);
+                workerAsMap.remove(ContainerConstants.PORTLET_RESPONSE);
+                workerAsMap.remove(ContainerConstants.METHOD_ID);
+                workerAsMap.remove(ContainerConstants.PORTLET_NAME);
+                workerAsMap.remove(ContainerConstants.PORTAL_CONTEXT);
+            }
+
             servletRequest.removeAttribute(ContainerConstants.PORTLET);
             servletRequest.removeAttribute(ContainerConstants.PORTLET_CONFIG);
             servletRequest.removeAttribute(ContainerConstants.PORTLET_REQUEST);

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/servlet/ServletRequestImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/servlet/ServletRequestImpl.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/servlet/ServletRequestImpl.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/engine/servlet/ServletRequestImpl.java Wed Dec  6 13:29:46 2006
@@ -207,6 +207,29 @@
      */
     public Object getAttribute( String name )
     {
+        Object value = null;
+
+        // In parallel mode, first look up from the worker.
+
+        Thread ct = Thread.currentThread();
+
+        if (ct instanceof Map) 
+        {
+            Map workerAsMap = (Map) ct;
+            value = workerAsMap.get(name);
+        }
+
+        // If no attribute found, then look up from the request
+        if (null == value) 
+        {
+            value = getAttributeInternal(name);
+        }
+
+        return value;
+    }
+
+    private Object getAttributeInternal( String name )
+    {
         Object value = super.getAttribute(name);
         if (name.equals(PortletRequest.USER_INFO))
         {
@@ -346,6 +369,31 @@
      * @param arg1
      */
     public void setAttribute( String name, Object value )
+    {
+        // In parallel mode, put attribute into worker.
+
+        Thread ct = Thread.currentThread();
+
+        if (ct instanceof Map) 
+        {
+            Map workerAsMap = (Map) ct;
+
+            if (null == value) 
+            {
+                workerAsMap.remove(name);
+            } 
+            else 
+            {
+                workerAsMap.put(name, value);
+            }
+        }
+
+        // put attribute into request also.
+
+        setAttributeInternal(name, value);
+    }
+
+    private void setAttributeInternal( String name, Object value )
     {
         if (name == null)
         {

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/request/JetspeedRequestContextComponent.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/request/JetspeedRequestContextComponent.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/request/JetspeedRequestContextComponent.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/request/JetspeedRequestContextComponent.java Wed Dec  6 13:29:46 2006
@@ -16,6 +16,7 @@
 package org.apache.jetspeed.request;
 
 import java.lang.reflect.Constructor;
+import java.util.Map;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.http.HttpServletRequest;
@@ -114,8 +115,19 @@
     
     public RequestContext getRequestContext()
     {
-        RequestContext rc =  (RequestContext) tlRequestContext.get();        
-        
+        RequestContext rc = null;
+
+        Thread ct = Thread.currentThread();
+        if (ct instanceof Map)
+        {
+            Map workerAsMap = (Map) ct;
+            rc = (RequestContext) workerAsMap.get(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
+        }
+        else
+        {
+            rc = (RequestContext) tlRequestContext.get();        
+        }
+
         if(rc != null)
         {
             return rc;

Modified: portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/aggregator/MockRenderJob.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/aggregator/MockRenderJob.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/aggregator/MockRenderJob.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/aggregator/MockRenderJob.java Wed Dec  6 13:29:46 2006
@@ -69,4 +69,13 @@
         return window;
     }
 
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.aggregator.RenderingJob#getPortletContent()
+     */
+    public PortletContent getPortletContent()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/PortalReservedParameters.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/PortalReservedParameters.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/PortalReservedParameters.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/PortalReservedParameters.java Wed Dec  6 13:29:46 2006
@@ -55,6 +55,7 @@
     public static final String PATH_ATTRIBUTE = "org.apache.jetspeed.Path";
     public static final String PARAMETER_ALREADY_DECODED_ATTRIBUTE = "org.apache.jetspeed.parameterAlreadyDecoded";
     public static final String RESOVLER_CACHE_ATTR = "org.apache.jetspeed.resovler.cache";
+    public static final String PORTLET_DEFINITION_ATTRIBUTE = "org.apache.jetspeed.portlet.definition";
     public static final String PORTLET_WINDOW_ATTRIBUTE = "org.apache.jetspeed.portlet.window";
     public static final String PAGE_THEME_ATTRIBUTE = "org.apache.jetspeed.theme";
     /**

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletRenderer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletRenderer.java?view=diff&rev=483240&r1=483239&r2=483240
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletRenderer.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/aggregator/PortletRenderer.java Wed Dec  6 13:29:46 2006
@@ -54,12 +54,13 @@
      * Render the specified Page fragment.
      * The method returns before rendering is complete, rendered content can be
      * accessed through the ContentDispatcher
+     * @return the asynchronous portlet rendering job to synchronize
      */
-    public void render(ContentFragment fragment, RequestContext request);
+    public RenderingJob render(ContentFragment fragment, RequestContext request);
 
     /**
      * Retrieve the ContentDispatcher for the specified request
      */
     public ContentDispatcher getDispatcher(RequestContext request, boolean isParallel);
 
-}
\ No newline at end of file
+}



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