1 5 package org.exoplatform.services.portletcontainer.impl; 6 7 import java.util.Collections ; 8 import java.util.Locale ; 9 import java.util.ResourceBundle ; 10 import javax.portlet.*; 11 import javax.servlet.ServletContext ; 12 import javax.servlet.http.HttpServletRequest ; 13 import javax.servlet.http.HttpServletResponse ; 14 import org.apache.commons.logging.Log; 15 import org.apache.commons.pool.ObjectPool; 16 import org.apache.commons.pool.impl.StackObjectPool; 17 import org.exoplatform.container.PortalContainer; 18 import org.exoplatform.services.log.LogService; 19 import org.exoplatform.services.portletcontainer.PortletContainerConstants; 20 import org.exoplatform.services.portletcontainer.PortletContainerException; 21 import org.exoplatform.services.portletcontainer.helper.PortletWindowInternal; 22 import org.exoplatform.services.portletcontainer.impl.monitor.PortletMonitor; 23 import org.exoplatform.services.portletcontainer.impl.monitor.PortletRuntimeDatasImpl; 24 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.*; 25 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.bundle.ResourceBundleManager; 26 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.helpers.CustomRequestWrapper; 27 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.helpers.CustomResponseWrapper; 28 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.helpers.SharedSessionWrapper; 29 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.pool.PortletObjectsWrapper; 30 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.pool.PortletObjectsWrapperFactory; 31 import org.exoplatform.services.portletcontainer.pci.Input; 32 import org.exoplatform.services.portletcontainer.pci.Output; 33 import org.exoplatform.services.portletcontainer.pci.RenderInput; 34 import org.exoplatform.services.portletcontainer.pci.RenderOutput; 35 42 public class PortletApplicationHandler { 43 44 private PortalContext portalContext; 45 private int nbInstances = 0; 46 private ObjectPool portletObjectsWrapperPool; 47 48 private PortletApplicationsHolder holder; 49 private PortletContainerConf conf; 50 private Log log_; 51 private PortletMonitor monitor; 52 private ResourceBundleManager resourceBundleManager; 53 54 public PortletApplicationHandler(PortalContext portalContext, 55 PortletApplicationsHolder holder, 56 PortletContainerConf conf, 57 LogService logService, 58 PortletMonitor portletMonitor, 59 ResourceBundleManager manager) { 60 this.portalContext = portalContext; 61 this.holder = holder; 62 this.conf = conf; 63 this.monitor = portletMonitor; 64 this.resourceBundleManager= manager; 65 log_ = logService.getLog("org.exoplatform.services.portletcontainer"); 66 initPools(); 67 } 68 69 private void initPools() { 70 nbInstances = conf.getNbOfInstancesInPool(); 71 if (nbInstances > 0) { 72 log_.info("Pooling enabled"); 73 portletObjectsWrapperPool = new StackObjectPool(new PortletObjectsWrapperFactory(), nbInstances); 74 } else { 75 log_.info("Pooling disabled"); 76 } 77 } 78 79 public void process(ServletContext servletContext, HttpServletRequest request, 80 HttpServletResponse response, Input input, Output output, 81 PortletWindowInternal windowInfos, boolean isAction) 82 throws PortletContainerException { 83 84 long startTime = System.currentTimeMillis() ; 85 log_.debug("process() method in PortletApplicationHandler entered"); 86 PortletObjectsWrapper portletObjectsWrapper = null; 88 PortletSessionImp session = null; 89 SharedSessionWrapper sharedSession = null; 90 CustomRequestWrapper requestWrapper = null; 91 CustomResponseWrapper responseWrapper = null; 92 PortletRequestImp portletRequest = null; 93 PortletResponseImp portletResponse = null; 94 String portletAppName = windowInfos.getWindowID().getPortletApplicationName(); 95 String portletName = windowInfos.getWindowID().getPortletName(); 96 try { 97 PortalContainer manager = PortalContainer.getInstance(); 98 PortletApplicationProxy proxy = 99 (PortletApplicationProxy) manager.getComponentInstance(portletAppName); 100 101 if (!holder.isModeSuported(portletAppName, portletName, input.getMarkup(), input.getPortletMode())) { 102 throw new PortletContainerException("The portlet mode " + input.getPortletMode().toString() + 103 " is not supported for the " + input.getMarkup() + " markup language."); 104 } 105 106 if (!holder.isStateSupported(input.getWindowState(), portletAppName)) { 107 log_.debug("Window state : " + input.getWindowState() + 108 " not supported, set the window state to normal"); 109 input.setWindowState(WindowState.NORMAL); 110 } 111 112 String exception_key = PortletContainerConstants.EXCEPTION + portletAppName + portletName; 113 114 PortletContext portletContext = 116 PortletAPIObjectFactory.getInstance().createPortletContext(servletContext); 117 118 if (nbInstances > 0) { 119 log_.debug("Extract objects from pool"); 120 try { 121 portletObjectsWrapper = (PortletObjectsWrapper) portletObjectsWrapperPool.borrowObject(); 122 } catch (Exception e) { 123 log_.error("Can not borrow object from pool", e); 124 throw new PortletContainerException("Can not borrow object from pool", e); 125 } 126 } else { 127 log_.debug("Create new object (no use of pool)"); 128 portletObjectsWrapper = PortletObjectsWrapperFactory.getInstance().createObject(); 129 } 130 131 if (conf.isSharedSessionEnable()) { 132 log_.debug("shared session enable"); 133 sharedSession = portletObjectsWrapper.getSharedSessionWrapper(); 134 } 135 session = (PortletSessionImp) portletObjectsWrapper.getPortletSession(); 136 requestWrapper = portletObjectsWrapper.getCustomRequestWrapper(); 137 responseWrapper = portletObjectsWrapper.getCustomResponseWrapper(); 138 if (isAction) { 139 portletRequest = (ActionRequestImp) portletObjectsWrapper.getActionRequest(); 140 portletResponse = (ActionResponseImp) portletObjectsWrapper.getActionResponse(); 141 } else { 142 portletRequest = (RenderRequestImp) portletObjectsWrapper.getRenderRequest(); 143 portletResponse = (RenderResponseImp) portletObjectsWrapper.getRenderResponse(); 144 } 145 146 long portletAppVersionNumber = 1; 147 portletAppVersionNumber = monitor.getPortletVersionNumber(portletAppName); 148 log_.debug("Get portlet version number : " + portletAppVersionNumber); 149 150 if (conf.isSharedSessionEnable()) { 152 sharedSession.fillSharedSessionWrapper(request.getSession(), portletAppName); 153 sharedSession.init(); 154 session.fillPortletSession(sharedSession, 155 portletContext, windowInfos.getWindowID().getUniqueID()); 156 } else { 157 session.fillPortletSession(request.getSession(), portletContext, windowInfos.getWindowID(). 158 getUniqueID()); 159 } 160 161 requestWrapper.fillCustomRequestWrapper(request, windowInfos.getWindowID(). 163 getUniqueID()); 164 165 responseWrapper.fillResponseWrapper(response); 167 168 portletRequest.fillPortletRequest(requestWrapper, portalContext, portletContext, session, 170 holder.getPortletMetaData(portletAppName, portletName), 171 input, windowInfos, 172 holder.getPortletApplication(portletAppName).getSecurityConstraint(), 173 holder.getPortletApplication(portletAppName).getUserAttribute(), 174 holder.getPortletApplication(portletAppName).getCustomPortletMode(), 175 holder.getPortletApplication(portletAppName).getCustomWindowState(), 176 holder.getRoles(portletAppName), 177 conf.getSupportedContent()); 178 portletRequest.setAttribute(PortletRequest.USER_INFO, input.getUserAttributes()); 180 181 portletResponse.fillPortletResponse(responseWrapper, output, 182 holder.getPortletApplication(portletAppName).getCustomWindowState()); 183 184 if (isAction) { 185 ((ActionResponseImp) portletResponse).fillActionResponse(input, holder.getPortletMetaData(portletAppName, portletName)); 186 } else { 187 ((RenderRequestImp) portletRequest).fillRenderRequest(((RenderInput) input).getRenderParameters(), 188 ((RenderInput) input).isUpdateCache()); 189 ((RenderResponseImp) portletResponse).fillRenderResponse(windowInfos.getWindowID().getUniqueID(), input, 190 holder.getPortletMetaData(portletAppName, portletName), request.isSecure(), 191 conf.getSupportedContent(), Collections.enumeration(holder.getWindowStates(portletAppName))); 192 } 193 194 monitor.setLastAccessTime(portletAppName, portletName, startTime); 195 boolean isBroken = monitor.isBroken(portletAppName, portletName); 196 boolean isAvailable = monitor.isAvailable(portletAppName, portletName, startTime); 197 boolean isDestroyed = monitor.isDestroyed(portletAppName, portletName); 198 199 if (isDestroyed) { 200 log_.debug("Portlet is destroyed"); 201 generateOutputForException(portletRequest, isAction, null, output); 202 return; 203 } else if (isBroken || !isAvailable || portletRequest.getAttribute(exception_key) != null) { 204 log_.debug("Portlet is borken, not available or the request contains an associated error"); 205 generateOutputForException(portletRequest, isAction, exception_key, output); 206 return; 207 } else { 208 Portlet portlet = null; 209 try { 210 portlet = proxy.getPortlet(portletContext, portletName); 211 } catch (PortletException e) { 212 log_.error("unable to get portlet : " + portletName, e); 213 portletRequest.setAttribute(exception_key, e); 214 generateOutputForException(portletRequest, isAction, exception_key, output); 215 return; 216 } 217 try { 218 if (isAction) { 219 portlet.processAction((ActionRequest) portletRequest, (ActionResponse) portletResponse); 220 if (((ActionResponseImp) portletResponse).isSendRedirectAlreadyOccured()) { 221 String location = ((ActionResponseImp) portletResponse).getLocation(); 222 log_.debug("need to redirect to " + location); 223 output.addProperty(Output.SEND_REDIRECT, location); 224 } 225 } else { 226 portlet.render((RenderRequest) portletRequest, (RenderResponse) portletResponse); 227 if (((RenderInput) input).getTitle() != null) { 228 log_.debug("overide default title"); 229 ((RenderOutput) output).setTitle(((RenderInput) input).getTitle()); 230 } 231 } 232 } catch (Throwable t) { 233 log_.error("exception returned by processAction() or render() methods", t); 234 monitor.setLastFailureAccessTime(portletAppName, portletName, startTime); 235 if (t instanceof PortletException) { 236 log_.debug("It is a portlet exception"); 237 PortletException e = (PortletException) t; 238 if (t instanceof UnavailableException) { 239 log_.debug("It is an unavailable exception"); 240 UnavailableException ex = (UnavailableException) e; 241 if (!ex.isPermanent()) { 242 log_.debug("but a non permanent one"); 243 monitor.setUnavailabilityPeriod(portletAppName, portletName, ex.getUnavailableSeconds()); 244 } else { 245 log_.debug("a permanent one, so destroy the portlet and borke it"); 246 proxy.destroy(portletName); 247 monitor.brokePortlet(portletAppName, portletName); 248 } 249 } 250 portletRequest.setAttribute(exception_key, e); 251 generateOutputForException(portletRequest, isAction, exception_key, output); 252 return; 253 } 254 log_.debug("It is not a portlet exception, borke the portlet"); 255 monitor.brokePortlet(portletAppName, portletName); 256 proxy.destroy(portletName); 257 portletRequest.setAttribute(exception_key, t); 258 generateOutputForException(portletRequest, isAction, exception_key, output); 259 return; 260 } 261 } 262 } finally { 263 if (nbInstances > 0) { 264 try { 265 portletObjectsWrapperPool.returnObject(portletObjectsWrapper); 266 } catch (Exception e) { 267 log_.error("Can not return object to pool", e); 268 throw new PortletContainerException("Can not return object to pool", e); 269 } 270 } 271 long endTime = System.currentTimeMillis() ; 272 PortletRuntimeDatasImpl rtd = monitor.getPortletRuntimeData(portletAppName, portletName) ; 273 if(rtd != null) { if(isAction) { 275 rtd.logProcessActionRequest(startTime, endTime) ; 276 } else { 277 boolean cacheHit = ((RenderOutput) output).isCacheHit() ; 278 rtd.logRenderRequest(startTime, endTime, cacheHit) ; 279 } 280 } 281 } 282 } 283 284 private void generateOutputForException(PortletRequestImp request, 285 boolean isAction, 286 String key, 287 Output output) { 288 String prop_key = ""; 289 String prop_output = ""; 290 String title = ""; 291 String content = ""; 292 log_.debug("generate the exception message"); 293 if (key == null) { 294 prop_key = PortletContainerConstants.DESTROYED; 295 prop_output = "output generated because of a destroyed portlet access"; 296 title = "Portlet destroyed"; 297 content = "Portlet unvailable"; 298 } else { 299 Throwable e = (Throwable ) request.getAttribute(key); 300 prop_key = PortletContainerConstants.EXCEPTION; 301 prop_output = "output generated because of an exception"; 302 title = "Exception occured"; 303 if (e != null) { 304 log_.debug("Exception associated : " + e.toString()); 305 content = e.toString(); 306 if (content == null) { 307 content = prop_output; 308 } 309 } else { 310 log_.debug("No exception associated"); 311 content = "There is a problem"; 312 } 313 } 314 if (isAction) { 315 output.addProperty(prop_key, prop_output); 317 } else { 318 ((RenderOutput) output).setTitle(title); 320 ((RenderOutput) output).setContent(content.toCharArray()); 321 } 322 } 323 324 public ResourceBundle getBundle(String portletAppName, String portletName, Locale locale) { 325 org.exoplatform.services.portletcontainer.pci.model.Portlet type = 326 holder.getPortletMetaData(portletAppName, portletName); 327 try { 328 return resourceBundleManager.lookupBundle(type, locale); 329 } catch (Exception e) { 330 return null; 331 } 332 } 333 } | Popular Tags |