Coverage report

  %line %branch
org.apache.jetspeed.aggregator.impl.RenderingJobImpl
0% 
0% 

 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.jetspeed.aggregator.impl;
 19  
 
 20  
 import java.util.Iterator;
 21  
 import java.util.Map;
 22  
 import java.util.HashMap;
 23  
 import java.util.Collection;
 24  
 import java.util.Collections;
 25  
 import java.util.Arrays;
 26  
 
 27  
 import javax.portlet.UnavailableException;
 28  
 import javax.servlet.ServletRequest;
 29  
 import javax.servlet.http.HttpServletRequest;
 30  
 import javax.servlet.http.HttpServletResponse;
 31  
 import javax.servlet.http.HttpServletRequestWrapper;
 32  
 
 33  
 import org.apache.commons.logging.Log;
 34  
 import org.apache.commons.logging.LogFactory;
 35  
 import org.apache.jetspeed.PortalReservedParameters;
 36  
 import org.apache.jetspeed.aggregator.ContentDispatcherCtrl;
 37  
 import org.apache.jetspeed.aggregator.CurrentWorkerContext;
 38  
 import org.apache.jetspeed.aggregator.PortletContent;
 39  
 import org.apache.jetspeed.aggregator.PortletRenderer;
 40  
 import org.apache.jetspeed.aggregator.PortletTrackingManager;
 41  
 import org.apache.jetspeed.aggregator.RenderingJob;
 42  
 import org.apache.jetspeed.components.portletentity.PortletEntityImpl;
 43  
 import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
 44  
 import org.apache.jetspeed.om.page.ContentFragment;
 45  
 import org.apache.jetspeed.request.RequestContext;
 46  
 import org.apache.jetspeed.statistics.PortalStatistics;
 47  
 import org.apache.pluto.PortletContainer;
 48  
 import org.apache.pluto.om.portlet.PortletDefinition;
 49  
 import org.apache.pluto.om.window.PortletWindow;
 50  
 
 51  
 /**
 52  
  * The RenderingJob is responsible for storing all necessary objets for
 53  
  * asynchronous portlet rendering as well as implementing the rendering logic
 54  
  * in its Runnable method.
 55  
  *
 56  
  * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
 57  
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
 58  
  * @author <a>Woonsan Ko</a>
 59  
  * @version $Id: RenderingJobImpl.java 592263 2007-11-06 04:19:20Z woonsan $
 60  
  */
 61  
 public class RenderingJobImpl implements RenderingJob
 62  
 {
 63  
     /** Commons logging */
 64  0
     protected final static Log log = LogFactory.getLog(RenderingJobImpl.class);
 65  
 
 66  
     /** WorkerMonitor used to flush the queue */
 67  0
     protected PortletWindow window = null;
 68  0
     protected HttpServletRequest request = null;
 69  0
     protected HttpServletResponse response = null;
 70  
     
 71  0
     protected PortletContainer container = null;
 72  0
     protected PortletRenderer renderer = null;
 73  0
     protected ContentFragment fragment = null;
 74  0
     protected RequestContext requestContext = null;
 75  0
     protected PortletTrackingManager portletTracking = null;
 76  
 
 77  
     protected PortletDefinition portletDefinition;
 78  
     protected PortletContent portletContent;
 79  
     protected PortalStatistics statistics;
 80  
     protected ContentDispatcherCtrl dispatcher;
 81  
     protected boolean contentIsCached;
 82  
     
 83  0
     protected int expirationCache = 0;
 84  
 
 85  
     protected Map workerAttributes;
 86  
 
 87  0
     protected long startTimeMillis = 0;
 88  
     protected long timeout;
 89  
     
 90  
     public RenderingJobImpl(PortletContainer container,
 91  
                             PortletRenderer renderer,
 92  
                             PortletDefinition portletDefinition,
 93  
                             PortletContent portletContent, 
 94  
                             ContentFragment fragment, 
 95  
                             ContentDispatcherCtrl dispatcher,
 96  
                             HttpServletRequest request, 
 97  
                             HttpServletResponse response, 
 98  
                             RequestContext requestContext, 
 99  
                             PortletWindow window,
 100  
                             PortalStatistics statistics,
 101  
                             int expirationCache,
 102  
                             boolean contentIsCached)
 103  0
     {
 104  0
         this.container = container;
 105  0
         this.renderer = renderer;
 106  0
         this.portletTracking = renderer.getPortletTrackingManager();        
 107  0
         this.statistics = statistics;
 108  0
         this.portletDefinition = portletDefinition;
 109  0
         this.fragment = fragment;
 110  0
         this.dispatcher = dispatcher;
 111  0
         this.request = request;
 112  0
         this.response = response;
 113  0
         this.requestContext = requestContext; 
 114  0
         this.window = window;
 115  0
         this.portletContent = portletContent; 
 116  0
         ((MutablePortletEntity)window.getPortletEntity()).setFragment(fragment);
 117  0
         this.expirationCache = expirationCache;
 118  0
         this.contentIsCached = contentIsCached;
 119  0
     }
 120  
 
 121  
     public RenderingJobImpl(PortletContainer container, 
 122  
                             PortletRenderer renderer,
 123  
                             PortletDefinition portletDefinition,
 124  
                             PortletContent portletContent, 
 125  
                             ContentFragment fragment,
 126  
                             ContentDispatcherCtrl dispatcher,
 127  
                             HttpServletRequest request, 
 128  
                             HttpServletResponse response, 
 129  
                             RequestContext requestContext, 
 130  
                             PortletWindow window,
 131  
                             PortalStatistics statistics,
 132  
                             int expirationCache,
 133  
                             boolean contentIsCached,
 134  
                             Map workerAttrs)
 135  
     {
 136  0
         this(container, renderer, portletDefinition, portletContent, fragment, dispatcher,
 137  
                         request, response, requestContext, window, statistics, expirationCache, contentIsCached);
 138  
         
 139  0
         if (workerAttrs != null)
 140  
         {
 141  0
             this.workerAttributes = Collections.synchronizedMap(workerAttrs);
 142  
         }
 143  0
     }
 144  
 
 145  
     /**
 146  
      * Sets portlet timout in milliseconds.
 147  
      */
 148  
     public void setTimeout(long timeout) {
 149  0
         this.timeout = timeout;
 150  0
     }
 151  
 
 152  
     /**
 153  
      * Gets portlet timout in milliseconds.
 154  
      */
 155  
     public long getTimeout() {
 156  0
         return this.timeout;
 157  
     }
 158  
 
 159  
     /**
 160  
      * Checks if the portlet rendering is timeout
 161  
      */
 162  
     public boolean isTimeout() {
 163  0
         if ((this.timeout > 0) && (class="keyword">this.startTimeMillis > 0)) {
 164  0
             return (System.currentTimeMillis() - this.startTimeMillis > class="keyword">this.timeout);
 165  
         }
 166  
 
 167  0
         return false;
 168  
     }
 169  
 
 170  
     /**
 171  
      * Checks if queue is empty, if not try to empty it by calling
 172  
      * the WorkerMonitor. When done, pause until next scheduled scan.
 173  
      */
 174  
     public void run()
 175  
     {       
 176  
         try
 177  
         {
 178  0
             if (this.timeout > 0) 
 179  
             {
 180  0
                 CurrentWorkerContext.setParallelRenderingMode(true);
 181  0
                 this.startTimeMillis = System.currentTimeMillis();
 182  
             }
 183  
 
 184  
             // A little baby hack to make sure the worker thread has PortletContent to write too.
 185  0
             fragment.setPortletContent(portletContent);
 186  0
             execute();                     
 187  
         }
 188  
         finally
 189  
         {
 190  0
             synchronized (portletContent)
 191  
             {
 192  0
                if (log.isDebugEnabled()) log.debug("Notifying completion of rendering job for fragment " + fragment.getId());                
 193  0
                portletContent.notifyAll();
 194  0
             }
 195  0
         }
 196  0
     }
 197  
     
 198  
     /**
 199  
      * <p>
 200  
      * execute
 201  
      * </p>
 202  
      *
 203  
      * 
 204  
      */
 205  
     public void execute()
 206  
     {
 207  0
         long start = System.currentTimeMillis();
 208  0
         boolean isParallelMode = false;
 209  0
         PortletWindow curWindow = this.window;
 210  
         try
 211  
         {
 212  0
             if (log.isDebugEnabled()) log.debug("Rendering OID "+this.window.getId()+" "+ this.request +" "+this.response);
 213  
 
 214  
             // if the current thread is worker, then store attribues in that.
 215  0
             if (this.workerAttributes != null)
 216  
             {
 217  0
                 isParallelMode = CurrentWorkerContext.getParallelRenderingMode();
 218  0
                 if (isParallelMode)
 219  
                 {
 220  0
                     Collection attrNames = Arrays.asList(this.workerAttributes.keySet().toArray());
 221  
                     
 222  0
                     Iterator itAttrNames = attrNames.iterator();
 223  0
                     while (itAttrNames.hasNext()) 
 224  
                     {
 225  0
                         String name = (String) itAttrNames.next();
 226  0
                         CurrentWorkerContext.setAttribute(name, this.workerAttributes.get(name));
 227  0
                     }
 228  
                     
 229  
                     // The portletEntity stores its portletDefinition into the ThreadLocal member,
 230  
                     // before the worker starts doing a rendering job.
 231  
                     // So the thread contexts are different from each other.
 232  
                     // Therefore, in parallel mode, we have to clear threadlocal fragmentPortletDefinition cache
 233  
                     // of portletEntity and to replace the portletDefinition with one of current worker context.
 234  
                     // Refer to org.apache.jetspeed.components.portletentity.PortletEntityImpl class
 235  
                     
 236  0
                     curWindow = (PortletWindow) 
 237  
                         CurrentWorkerContext.getAttribute(PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE); 
 238  0
                     PortletEntityImpl curEntity = (PortletEntityImpl) curWindow.getPortletEntity();
 239  0
                     PortletDefinition oldPortletDefinition = curEntity.getPortletDefinition();
 240  0
                     PortletDefinition curPortletDefinition = (PortletDefinition)
 241  
                         CurrentWorkerContext.getAttribute(PortalReservedParameters.PORTLET_DEFINITION_ATTRIBUTE);
 242  
                     
 243  0
                     if (!oldPortletDefinition.getId().equals(curPortletDefinition.getId())) {
 244  0
                         curEntity.setPortletDefinition(curPortletDefinition);
 245  
                     }
 246  
                 }
 247  
             }
 248  
             
 249  0
             if (isParallelMode)
 250  
             {
 251  0
                 ServletRequest servletRequest = ((HttpServletRequestWrapper)((HttpServletRequestWrapper) this.request).getRequest()).getRequest();
 252  
                 
 253  0
                 synchronized (servletRequest)
 254  
                 {
 255  0
                     this.request.setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
 256  0
                     this.request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE, requestContext.getPage());
 257  0
                     this.request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);
 258  0
                     this.request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_OBJECTS, requestContext.getObjects());            
 259  
                   //  this.request.setAttribute(PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE,dispatcher);
 260  0
                 }
 261  0
             }
 262  
             else
 263  
             {
 264  0
                 this.request.setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
 265  0
                 this.request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE, requestContext.getPage());
 266  0
                 this.request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, requestContext);
 267  0
                 this.request.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_OBJECTS, requestContext.getObjects());            
 268  
               //  this.request.setAttribute(PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE,dispatcher);
 269  
             }
 270  
             
 271  0
             container.renderPortlet(this.window, class="keyword">this.request, class="keyword">this.response);               
 272  0
             this.response.flushBuffer();                           
 273  0
         }
 274  0
         catch (Throwable t)
 275  
         {
 276  0
             if (t instanceof UnavailableException)
 277  
             {
 278  
                 // no need to dump a full stack trace to the log
 279  0
                 log.error("Error rendering portlet OID " + curWindow.getId() + ": " + t.toString());
 280  
             }
 281  
             else
 282  
             {
 283  0
                 log.error("Error rendering portlet OID " + curWindow.getId(), t);
 284  
             }
 285  0
             fragment.overrideRenderedContent(t.getMessage());
 286  0
         }
 287  
         finally
 288  
         {
 289  0
             try
 290  
             {
 291  0
                 if (isParallelMode)
 292  
                 {
 293  0
                     this.renderer.addTitleToHeader(curWindow, fragment,
 294  
                                                    this.request, class="keyword">this.response,
 295  
                                                    this.dispatcher, class="keyword">this.contentIsCached);
 296  
                 
 297  0
                     CurrentWorkerContext.removeAllAttributes();
 298  
                 }
 299  
                 
 300  0
                 if (fragment.getType().equals(ContentFragment.PORTLET))
 301  
                 {
 302  0
                     long end = System.currentTimeMillis();
 303  0
                     boolean exceededTimeout = portletTracking.exceededTimeout(end - start, window);
 304  
                     
 305  0
                     if (statistics != null)
 306  
                     {
 307  0
                         statistics.logPortletAccess(requestContext, fragment.getName(), PortalStatistics.HTTP_OK, end - start);
 308  
                     }
 309  0
                     if (exceededTimeout)
 310  
                     {
 311  
                         // took too long to render
 312  0
                         log.info("Portlet Exceeded timeout: " + curWindow.getPortletEntity().getPortletDefinition().getName() + " for window " + curWindow.getId());
 313  0
                         portletTracking.incrementRenderTimeoutCount(curWindow);
 314  
                     }
 315  
                     else
 316  
                     {
 317  0
                         portletTracking.success(curWindow);
 318  
                     }
 319  
                 }
 320  
             }
 321  
             finally
 322  
             {
 323  0
                 synchronized (portletContent)
 324  
                 {
 325  0
                     if (fragment.getOverriddenContent() != null)
 326  
                     {
 327  0
                         portletContent.completeWithError();
 328  
                     }
 329  
                     else
 330  
                     {
 331  0
                         portletContent.complete();
 332  
                     }
 333  0
                 }
 334  0
             }
 335  0
         }
 336  0
     }
 337  
  
 338  
     /**
 339  
      * 
 340  
      * <p>
 341  
      * getWindow
 342  
      * </p>
 343  
      *
 344  
      * @return The window this job is in charge of rendering
 345  
      */
 346  
     public PortletWindow getWindow()
 347  
     {
 348  0
         return window;
 349  
     }
 350  
 
 351  
     /**
 352  
      * 
 353  
      * <p>
 354  
      * getPortletContent
 355  
      * </p>
 356  
      *
 357  
      * @return The portlet content this job is in charge of rendering
 358  
      */
 359  
     public PortletContent getPortletContent()
 360  
     {
 361  0
         return portletContent;
 362  
     }
 363  
 
 364  
     public PortletDefinition getPortletDefinition()
 365  
     {
 366  0
         return this.portletDefinition;
 367  
     }
 368  
 
 369  
     public HttpServletRequest getRequest()
 370  
     {
 371  0
         return this.request;
 372  
     }
 373  
 
 374  
     public HttpServletResponse getResponse()
 375  
     {
 376  0
         return this.response;
 377  
     }
 378  
 
 379  
     public ContentFragment getFragment()
 380  
     {
 381  0
         return this.fragment;
 382  
     }
 383  
 
 384  
     public RequestContext getRequestContext()
 385  
     {
 386  0
         return this.requestContext;
 387  
     }
 388  
 
 389  
     public int getExpirationCache()
 390  
     {
 391  0
         return this.expirationCache;
 392  
     }
 393  
 
 394  
     public ContentDispatcherCtrl getDispatcher()
 395  
     {
 396  0
         return this.dispatcher;
 397  
     }
 398  
 
 399  
     public boolean isContentCached() 
 400  
     {
 401  0
         return this.contentIsCached;
 402  
     }
 403  
     
 404  
     public void setWorkerAttribute(String name, Object value)
 405  
     {
 406  0
         if (this.workerAttributes == null)
 407  
         {
 408  0
             this.workerAttributes = Collections.synchronizedMap(new HashMap());
 409  
         }
 410  
         
 411  0
         if (value != null)
 412  
         {
 413  0
             this.workerAttributes.put(name, value);
 414  
         }
 415  
         else
 416  
         {
 417  0
             this.workerAttributes.remove(name);
 418  
         }
 419  0
     }
 420  
     
 421  
     public Object getWorkerAttribute(String name)
 422  
     {
 423  0
         Object value = null;
 424  
         
 425  0
         if (this.workerAttributes != null)
 426  
         {
 427  0
             value = this.workerAttributes.get(name);
 428  
         }
 429  
         
 430  0
         return value;
 431  
     }
 432  
     
 433  
     public void removeWorkerAttribute(String name)
 434  
     {
 435  0
         if (this.workerAttributes != null)
 436  
         {
 437  0
             this.workerAttributes.remove(name);
 438  
         }
 439  0
     }
 440  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.