1 5 package org.exoplatform.services.portletcontainer.impl; 6 7 import java.io.IOException ; 8 import java.net.MalformedURLException ; 9 import java.net.URL ; 10 import java.net.URLClassLoader ; 11 import java.util.ArrayList ; 12 import java.util.Collection ; 13 import java.util.Collections ; 14 import java.util.Enumeration ; 15 import java.util.Iterator ; 16 import java.util.Locale ; 17 import java.util.Map ; 18 import java.util.Set ; 19 20 import javax.portlet.PortletMode; 21 import javax.portlet.ReadOnlyException; 22 import javax.portlet.WindowState; 23 import javax.servlet.RequestDispatcher ; 24 import javax.servlet.ServletContext ; 25 import javax.servlet.ServletException ; 26 import javax.servlet.http.HttpServletRequest ; 27 import javax.servlet.http.HttpServletResponse ; 28 29 import org.apache.commons.logging.Log; 30 import org.exoplatform.commons.Environment; 31 import org.exoplatform.commons.utils.IOUtil; 32 import org.exoplatform.container.PortalContainer; 33 import org.exoplatform.container.SessionContainer; 34 import org.exoplatform.services.log.LogService; 35 import org.exoplatform.services.portletcontainer.PortletContainerException; 36 import org.exoplatform.services.portletcontainer.helper.PortletWindowInternal; 37 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.PortletPreferencesImp; 38 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.persistenceImp.PersistenceManager; 39 import org.exoplatform.services.portletcontainer.pci.*; 40 import org.exoplatform.services.portletcontainer.pci.model.ExoPortletPreferences; 41 import org.exoplatform.services.portletcontainer.pci.model.Portlet; 42 43 50 public class PortletContainerDispatcher { 51 52 public static final String INPUT = "org.exoplatform.services.portletcontainer.pci.Input"; 53 public static final String OUTPUT = "org.exoplatform.services.portletcontainer.pci.Output"; 54 public static final String WINDOW_INFO = "org.exoplatform.services.portletcontainer.impl.portletAPIImp.helpers.PortletWindowInternal"; 55 public static final String IS_ACTION = "org.exoplatform.services.portletcontainer.impl.isAction"; 56 public static final String IS_TO_GET_BUNDLE = "org.exoplatform.services.portletcontainer.impl.isToGetBundle"; 57 public static final String LOCALE_FOR_BUNDLE = "org.exoplatform.services.portletcontainer.impl.LocaleForBundle"; 58 public static final String BUNDLE = "org.exoplatform.services.portletcontainer.impl.Bundle"; 59 public static String PORTLET_APPLICATION_NAME = "org.exoplatform.services.portletcontainer.impl.PortletAppName"; 60 public static String PORTLET_NAME = "org.exoplatform.services.portletcontainer.impl.PortletName"; 61 public static final String SERVLET_MAPPING = "/PortletWrapper"; 62 63 protected static final String PORTLET_APP_PATH = "file:./war_template/"; 65 66 private PortletContainerConf containerConf; 67 private PersistenceManager manager; 68 private PortletApplicationsHolder portletApplications; 69 private PortletApplicationHandler standAloneHandler; 70 private Log log; 71 72 public PortletContainerDispatcher(PortletContainerConf containerConf, 73 PersistenceManager manager, PortletApplicationsHolder holder, 74 PortletApplicationHandler standAloneHandler, 75 LogService logService) { 76 portletApplications = holder; 77 this.containerConf = containerConf; 78 this.manager = manager; 79 this.standAloneHandler = standAloneHandler; 80 this.log = logService.getLog("org.exoplatform.services.portletcontainer"); 81 } 82 83 public void setPortletContainerName(String containerName) { 84 containerConf.setPortletContainerName(containerName); 85 } 86 87 public void setMajorVersion(int majorVersion) { 88 containerConf.setMajorVersion(majorVersion); 89 } 90 91 public void setMinorVersion(int minorVersion) { 92 containerConf.setMinorVersion(minorVersion); 93 } 94 95 public void setProperties(Map properties) { 96 containerConf.setProperties(properties); 97 } 98 99 public void setSupportedPortletModesWithDescriptions(Collection portletModes) { 100 containerConf.setCustomModesWithDescriptions(portletModes); 101 } 102 103 public void setSupportedWindowStatesWithDescriptions(Collection customStates) { 104 containerConf.setCustomStatesWithDescriptions(customStates); 105 } 106 107 public Collection getSupportedPortletModesWithDescriptions() { 108 return containerConf.getSupportedPortletModesWithDescriptions(); 109 } 110 111 public Collection getSupportedWindowStatesWithDescriptions() { 112 return containerConf.getSupportedWindowStatesWithDescriptions(); 113 } 114 115 public Collection getSupportedPortletModes() { 116 return Collections.list(containerConf.getSupportedPortletModes()); 117 } 118 119 public Collection getSupportedWindowStates() { 120 return Collections.list(containerConf.getSupportedWindowStates()); 121 } 122 123 public Collection getPortletModes(String portletAppName, String portletName, String markup) { 124 Collection filteredModes = new ArrayList (); 125 Collection nonFilteredModes = portletApplications.getPortletModes(portletAppName, portletName, markup); 126 for (Iterator iter = nonFilteredModes.iterator(); iter.hasNext();) { 127 PortletMode mode = (PortletMode) iter.next(); 128 Enumeration portalModes = containerConf.getSupportedPortletModes(); 129 while (portalModes.hasMoreElements()) { 130 PortletMode portalMode = (PortletMode) portalModes.nextElement(); 131 if(mode.equals(portalMode)) 132 filteredModes.add(mode); 133 } 134 } 135 return filteredModes; 136 } 137 138 public boolean isModeSuported(String portletAppName, String portletName, 139 String markup, PortletMode mode) { 140 boolean isPortalMode = false; 141 Enumeration portalModes = containerConf.getSupportedPortletModes(); 142 while (portalModes.hasMoreElements()) { 143 PortletMode portalMode = (PortletMode) portalModes.nextElement(); 144 if(portalMode.equals(mode)){ 145 isPortalMode = true; 146 break; 147 } 148 } 149 return portletApplications.isModeSuported(portletAppName, portletName, markup, mode) && isPortalMode; 150 } 151 152 public Collection getWindowStates(String portletAppName) { 153 Collection filteredStates = new ArrayList (); 154 Collection nonFilteredStates = portletApplications.getWindowStates(portletAppName); 155 for (Iterator iter = nonFilteredStates.iterator(); iter.hasNext();) { 156 WindowState state = (WindowState) iter.next(); 157 Enumeration portalStates = containerConf.getSupportedWindowStates(); 158 while (portalStates.hasMoreElements()) { 159 WindowState portalState = (WindowState) portalStates.nextElement(); 160 if(state.equals(portalState)) 161 filteredStates.add(state); 162 } 163 } 164 return filteredStates; 165 } 166 167 public boolean isStateSupported(WindowState state, String portletApplication) { 168 boolean isPortalState = false; 169 Enumeration portalStates = containerConf.getSupportedWindowStates(); 170 while (portalStates.hasMoreElements()) { 171 WindowState portalState = (WindowState) portalStates.nextElement(); 172 if(portalState.equals(state)){ 173 isPortalState = true; 174 break; 175 } 176 } 177 return portletApplications.isStateSupported(state, portletApplication) && isPortalState; 178 } 179 180 public Map getAllPortletMetaData() { 181 return portletApplications.getAllPortletMetaData(); 182 } 183 184 public void setPortletPreference(Input input, Map preferencesMap) throws PortletContainerException { 185 log.debug("try to set a portlet preference directly from the setPortletPreference() method"); 186 WindowID windowID = input.getWindowID(); 187 Portlet pDatas = 188 portletApplications.getPortletMetaData(windowID.getPortletApplicationName(), windowID.getPortletName()); 189 ExoPortletPreferences defaultPrefs = pDatas.getPortletPreferences(); 190 PortletWindowInternal windowInfos = manager.getWindow(input, defaultPrefs); 191 PortletPreferencesImp preferences = (PortletPreferencesImp) windowInfos.getPreferences(); 192 preferences.setMethodCalledIsAction(true); Set keys = preferencesMap.keySet(); 194 try { 195 for (Iterator iter = keys.iterator(); iter.hasNext();) { 196 String key = (String ) iter.next(); 197 try { 198 preferences.setValue(key, (String ) preferencesMap.get(key)); 199 } catch (ReadOnlyException e) { 200 log.error("Can not set a property that has a ReadOnly tag set to true", e); 201 } 202 } 203 preferences.store(); 204 } catch (Exception e) { 205 log.error("Can not store a portlet preference", e); 206 throw new PortletContainerException(e); 207 } 208 } 209 210 public Map getPortletPreference(Input input) { 211 log.debug("Try to get a portlet preference directly from the getPortletPreference() method "); 212 WindowID windowID = input.getWindowID(); 213 Portlet pDatas = 214 portletApplications.getPortletMetaData(windowID.getPortletApplicationName(), windowID.getPortletName()); 215 ExoPortletPreferences defaultPrefs = pDatas.getPortletPreferences(); 216 PortletWindowInternal windowInfos = manager.getWindow(input, defaultPrefs); 217 PortletPreferencesImp preferences = (PortletPreferencesImp) windowInfos.getPreferences(); 218 return preferences.getMap(); 219 } 220 221 public java.util.ResourceBundle getBundle(HttpServletRequest request, 222 HttpServletResponse response, 223 String portletAppName, 224 String portletName, 225 Locale locale) throws PortletContainerException { 226 log.debug("Try to get a bundle object for locale : " + locale); 227 if (Environment.getInstance().getPlatform() == Environment.STAND_ALONE) { 228 URLClassLoader oldCL = (URLClassLoader ) Thread.currentThread().getContextClassLoader(); 229 initTests(); 230 try { 231 return standAloneHandler.getBundle(portletAppName, portletName, locale); 232 } finally { 233 Thread.currentThread().setContextClassLoader(oldCL); 234 } 235 } 236 237 request.setAttribute(IS_TO_GET_BUNDLE, new Boolean (true)); 238 request.setAttribute(LOCALE_FOR_BUNDLE, locale); 239 request.setAttribute(PORTLET_APPLICATION_NAME, portletAppName); 240 request.setAttribute(PORTLET_NAME, portletName); 241 dispatch(request, response, portletAppName); 242 java.util.ResourceBundle bundle = (java.util.ResourceBundle ) request.getAttribute(BUNDLE); 243 request.removeAttribute(IS_TO_GET_BUNDLE); 244 request.removeAttribute(LOCALE_FOR_BUNDLE); 245 request.removeAttribute(PORTLET_APPLICATION_NAME); 246 request.removeAttribute(PORTLET_NAME); 247 request.removeAttribute(BUNDLE); 248 return bundle; 249 } 250 251 public ActionOutput processAction(HttpServletRequest httpServletRequest, 252 HttpServletResponse httpServletResponse, 253 ActionInput actionInput) 254 throws PortletContainerException { 255 log.debug("ProcessAction method in PortletContainerDispatcher entered"); 256 return (ActionOutput) process(httpServletRequest, httpServletResponse, actionInput, true); 257 } 258 259 public RenderOutput render(HttpServletRequest httpServletRequest, 260 HttpServletResponse httpServletResponse, 261 RenderInput renderInput) 262 throws PortletContainerException { 263 log.debug("Render method in PortletContainerDispatcher entered"); 264 try { 266 httpServletResponse.flushBuffer(); 267 } catch (IOException e) { 268 log.error("Can not flush servlet response buffer", e); 269 throw new PortletContainerException("Can not flush servlet response buffer", e); 270 } 271 return (RenderOutput) process(httpServletRequest, httpServletResponse, renderInput, false); 272 } 273 274 private Output process(HttpServletRequest request, HttpServletResponse response, 275 Input input, boolean isAction) 276 throws PortletContainerException { 277 log.debug("Process method in PortletContainerDispatcher entered"); 278 log.debug("Encoding used : " + request.getCharacterEncoding()); 279 Output output = null; 281 if (isAction) { 282 output = new ActionOutput(); 283 } else { 284 output = new RenderOutput(); 285 } 286 287 PortletWindowInternal windowInfos = getWindowInfos(request, input, isAction); 289 String portletApplicationName = windowInfos.getWindowID().getPortletApplicationName(); 290 291 request.setAttribute(INPUT, input); 292 request.setAttribute(OUTPUT, output); 293 request.setAttribute(WINDOW_INFO, windowInfos); 294 request.setAttribute(IS_ACTION, new Boolean (isAction)); 295 296 if (Environment.getInstance().getPlatform() == Environment.STAND_ALONE) { 297 log.debug("Stand alone environement : direct call to handler"); 298 URLClassLoader oldCL = (URLClassLoader ) Thread.currentThread().getContextClassLoader(); 299 initTests(); 300 try { 301 ServletContext portalContext = PortalContainer.getInstance().getPortalServletContext(); 302 standAloneHandler.process(portalContext, request, response, input, output, windowInfos, isAction); 303 } finally { 305 Thread.currentThread().setContextClassLoader(oldCL); 306 } 307 } else { 308 log.debug("Embded environement : use servlet dispatcher to access handler"); 309 try { 310 dispatch(request, response, portletApplicationName); 311 } finally { 312 ((PortletPreferencesImp) windowInfos.getPreferences()).discard(); 313 } 314 } 315 if (input.isStateSaveOnClient() && isAction) { 316 try { 317 log.debug("Serialize Portlet Preferences object to store it on the client"); 318 ((ActionOutput) output).setPortletState(IOUtil.serialize(windowInfos.getPreferences())); 319 } catch (Exception e) { 320 log.error("Can not serialize Portlet Preferences", e); 321 throw new PortletContainerException("Can not serialize Portlet Preferences", e); 322 } 323 } 324 return output; 325 } 326 327 private PortletWindowInternal getWindowInfos(HttpServletRequest request, Input input, 328 boolean isAction) { 329 boolean stateChangeAuthorized = true; 330 if (isAction) { 331 stateChangeAuthorized = ((ActionInput) input).isStateChangeAuthorized(); 332 } 333 334 PortletWindowInternal windowInfos = null; 335 if (!input.isStateSaveOnClient()) { log.debug("Extract or create windows info (store in the server)"); 337 SessionContainer sessionContainer = SessionContainer.getInstance(); 338 String key = "SESSION_CONTAINER_KEY_ENCODER" + input.getWindowID().generateKey(); 339 if (sessionContainer.getComponentInstance(key) != null) { 340 windowInfos = (PortletWindowInternal) sessionContainer.getComponentInstance(key); 341 } else { 342 WindowID windowID = input.getWindowID(); 343 Portlet pDatas = 344 portletApplications.getPortletMetaData(windowID.getPortletApplicationName(), windowID.getPortletName()); 345 ExoPortletPreferences defaultPrefs = pDatas.getPortletPreferences(); 346 windowInfos = manager.getWindow(input, defaultPrefs); 347 sessionContainer.registerComponentInstance(key, windowInfos); 348 } 349 } else { log.debug("Extract or create windows info (sent by the client)"); 351 WindowID windowID = input.getWindowID(); 352 Portlet pDatas = 353 portletApplications.getPortletMetaData(windowID.getPortletApplicationName(), windowID.getPortletName()); 354 ExoPortletPreferences defaultPrefs = pDatas.getPortletPreferences(); 355 windowInfos = manager.getWindow(input, defaultPrefs); 356 } 357 ((PortletPreferencesImp) windowInfos.getPreferences()).setMethodCalledIsAction(isAction); 358 ((PortletPreferencesImp) windowInfos.getPreferences()).setStateChangeAuthorized(stateChangeAuthorized); 359 ((PortletPreferencesImp) windowInfos.getPreferences()).setStateSaveOnClient(input.isStateSaveOnClient()); 360 return windowInfos; 361 } 362 363 private void dispatch(HttpServletRequest request, HttpServletResponse response, 364 String portletApplicationName) throws PortletContainerException { 365 ServletContext portalContext = PortalContainer.getInstance().getPortalServletContext(); 366 ServletContext portletContext = portalContext.getContext("/" + portletApplicationName); 367 RequestDispatcher dispatcher = portletContext.getRequestDispatcher(SERVLET_MAPPING); 368 try { 369 log.debug("Dispatch resuest to the portlet application : " + portletApplicationName); 370 dispatcher.include(request, response); 371 } catch (ServletException e) { 372 log.error("Servlet exception while dispatching to portlet", e); 373 throw new PortletContainerException(e); 374 } catch (IOException e) { 375 log.error("In and out exception while dispatching to portlet", e); 376 throw new PortletContainerException(e); 377 } 378 } 379 380 private void initTests() { 381 try { 382 URL [] URLs = {new URL (PORTLET_APP_PATH + "WEB-INF/classes/"), 383 new URL ("file:./lib/portlet-api.jar"), 384 new URL (PORTLET_APP_PATH + "WEB-INF/lib/")}; 385 Thread.currentThread().setContextClassLoader(new URLClassLoader (URLs)); 386 } catch (MalformedURLException e) { 387 log.error("Can not init tests", e); 388 } 389 } 390 } 391 | Popular Tags |