1 7 package org.exoplatform.services.wsrp.producer.impl; 8 9 import java.rmi.RemoteException ; 10 import java.util.ArrayList ; 11 import java.util.Collections ; 12 import java.util.HashMap ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Map ; 16 17 import javax.portlet.PortletMode; 18 import javax.portlet.WindowState; 19 20 import org.apache.commons.lang.StringUtils; 21 import org.apache.commons.logging.Log; 22 import org.exoplatform.Constants; 23 import org.exoplatform.commons.utils.IdentifierUtil; 24 import org.exoplatform.container.SessionContainer; 25 import org.exoplatform.services.log.LogService; 26 import org.exoplatform.services.organization.OrganizationService; 27 import org.exoplatform.services.portletcontainer.pci.*; 28 import org.exoplatform.services.portletcontainer.pci.model.Supports; 29 import org.exoplatform.services.wsrp.WSRPConstants; 30 import org.exoplatform.services.wsrp.exceptions.Exception2Fault; 31 import org.exoplatform.services.wsrp.exceptions.Faults; 32 import org.exoplatform.services.wsrp.exceptions.WSRPException; 33 import org.exoplatform.services.wsrp.producer.MarkupOperationsInterface; 34 import org.exoplatform.services.wsrp.producer.PersistentStateManager; 35 import org.exoplatform.services.wsrp.producer.PortletContainerProxy; 36 import org.exoplatform.services.wsrp.producer.PortletManagementOperationsInterface; 37 import org.exoplatform.services.wsrp.producer.TransientStateManager; 38 import org.exoplatform.services.wsrp.producer.impl.helpers.WSRPConsumerRewriterPortletURLFactory; 39 import org.exoplatform.services.wsrp.producer.impl.helpers.WSRPHttpServletRequest; 40 import org.exoplatform.services.wsrp.producer.impl.helpers.WSRPHttpServletResponse; 41 import org.exoplatform.services.wsrp.producer.impl.helpers.WSRPHttpSession; 42 import org.exoplatform.services.wsrp.producer.impl.helpers.WSRPProducerRewriterPortletURLFactory; 43 import org.exoplatform.services.wsrp.type.*; 44 45 46 50 public class MarkupOperationsInterfaceImpl implements MarkupOperationsInterface { 51 52 private static final String DEFAULT_WINDOW_ID = "windowID"; 53 private Log log; 54 private WSRPConfiguration conf; 55 private PersistentStateManager persitentStateManager; 56 private PortletContainerProxy container; 57 private TransientStateManager transientStateManager; 58 private PortletManagementOperationsInterface portletManagementOperationsInterface; 59 private OrganizationService orgService; 60 private WSRPPortletPreferencesPersister persister; 61 62 public MarkupOperationsInterfaceImpl(PortletManagementOperationsInterface portletManagementOperationsInterface, 63 PersistentStateManager persitentStateManager, 64 TransientStateManager transientStateManager, 65 PortletContainerProxy container, 66 WSRPConfiguration conf, 67 OrganizationService orgService, 68 LogService logService) { 69 this.portletManagementOperationsInterface = portletManagementOperationsInterface; 70 this.container = container; 71 this.log = logService.getLog("org.exoplatform.services.wsrp"); 72 this.conf = conf; 73 this.persitentStateManager = persitentStateManager; 74 this.transientStateManager = transientStateManager; 75 this.orgService = orgService; 76 this.persister = WSRPPortletPreferencesPersister.getInstance(); 77 } 78 79 public MarkupResponse getMarkup(RegistrationContext registrationContext, 80 PortletContext portletContext, 81 RuntimeContext runtimeContext, 82 UserContext userContext, 83 MarkupParams markupParams) 84 throws RemoteException { 85 String portletHandle = portletContext.getPortletHandle(); 87 portletHandle = manageRegistration(portletHandle, registrationContext); 88 log.debug("Portlet handle : " + portletHandle); 89 String [] k = StringUtils.split(portletHandle, Constants.PORTLET_HANDLE_ENCODER); 90 String portletApplicationName = k[0]; 91 String portletName = k[1]; 92 String uniqueID = k[2]; 93 94 String sessionID = runtimeContext.getSessionID(); 96 WSRPHttpSession session = resolveSession(sessionID, userContext.getUserContextKey()); 97 sessionID = session.getId(); 98 SessionContext sessionContext = new SessionContext(); 99 sessionContext.setSessionID(session.getId()); 100 sessionContext.setExpires(TransientStateManager.SESSION_TIME_PERIOD); 101 102 userContext = transientStateManager.reolveUserContext(userContext, session); 104 String owner = userContext.getUserContextKey(); 105 log.debug("Owner Context : " + owner); 106 107 if (markupParams.getValidateTag() != null) { 109 try { 110 if (transientStateManager.validateCache(markupParams.getValidateTag())) { 111 MarkupContext markupContext = new MarkupContext(); 112 markupContext.setUseCachedMarkup(new Boolean (true)); 113 MarkupResponse markup = new MarkupResponse(); 114 markup.setMarkupContext(markupContext); 115 markup.setSessionContext(sessionContext); 116 return markup; 117 } 118 } catch (WSRPException e) { 119 log.debug("Can not validate Cache for validateTag : " + markupParams.getValidateTag()); 120 Exception2Fault.handleException(e); 121 } 122 } 123 124 Map portletMetaDatas = container.getAllPortletMetaData(); 125 PortletData portletDatas = (PortletData) portletMetaDatas. 126 get(portletApplicationName + Constants.PORTLET_META_DATA_ENCODER + portletName); 127 128 Map renderParameters = null; 130 try { 131 renderParameters = processNavigationalState(markupParams.getNavigationalState()); 132 } catch (WSRPException e) { 133 Exception2Fault.handleException(e); 134 } 135 if (renderParameters == null) { 136 renderParameters = new HashMap (); 137 log.debug("No navigational state exists"); 138 } 139 140 byte[] portletState = managePortletState(portletContext); 142 143 String mimeType = null; 145 try { 146 mimeType = getMimeType(markupParams.getMimeTypes(), portletDatas); 147 } catch (WSRPException e) { 148 Exception2Fault.handleException(e); 149 } 150 151 String baseURL = null; 152 PortletURLFactory portletURLFactory = null; 153 154 if (conf.isDoesUrlTemplateProcessing()) { 155 log.debug("Producer URL rewriting"); 156 Templates templates = manageTemplates(runtimeContext, session); 157 baseURL = templates.getRenderTemplate(); 158 portletURLFactory = new WSRPProducerRewriterPortletURLFactory(mimeType, portletDatas.getSupports(), 159 markupParams.isSecureClientCommunication(), new ArrayList (container.getWindowStates(portletApplicationName)), 160 Collections.enumeration(container.getSupportedWindowStates()), 161 templates.getRenderTemplate(), 162 portletHandle, persitentStateManager, sessionID); 163 } else { 164 log.debug("Consumer URL rewriting"); 165 baseURL = WSRPConstants.WSRP_REWITE_PREFIX; 166 portletURLFactory = new WSRPConsumerRewriterPortletURLFactory(mimeType, portletDatas.getSupports(), 167 markupParams.isSecureClientCommunication(), new ArrayList (container.getWindowStates(portletApplicationName)), 168 Collections.enumeration(container.getSupportedWindowStates()), 169 baseURL, portletHandle, persitentStateManager, sessionID); 170 } 171 172 PortletMode mode = processMode(markupParams.getMode()); 174 WindowState windowState = processWindowState(markupParams.getWindowState()); 175 176 WSRPHttpServletRequest request = new WSRPHttpServletRequest(session); 178 WSRPHttpServletResponse response = new WSRPHttpServletResponse(); 179 180 RenderInput input = new RenderInput(); 182 ExoWindowID windowID = new ExoWindowID(); 183 windowID.setOwner(owner); 184 windowID.setPortletApplicationName(portletApplicationName); 185 windowID.setPortletName(portletName); 186 windowID.setUniqueID(uniqueID); 187 input.setWindowID(windowID); 188 input.setBaseURL(baseURL); 189 input.setUserAttributes(new HashMap ()); 190 input.setPortletMode(mode); 191 input.setWindowState(windowState); 192 input.setMarkup(mimeType); 193 input.setRenderParameters(renderParameters); 194 input.setPortletURLFactory(portletURLFactory); 195 input.setPortletState(portletState); 196 input.setPortletPreferencesPersister(persister); 197 199 RenderOutput output = null; 200 try { 201 output = container.render(request, response, input); 202 } catch (WSRPException e) { 203 log.debug("The call to render method was a failure ", e); 204 Exception2Fault.handleException(e); 205 } 206 207 CacheControl cacheControl = null; 209 try { 210 cacheControl = transientStateManager.getCacheControl(portletDatas); 211 } catch (WSRPException e) { 212 Exception2Fault.handleException(e); 213 } 214 215 MarkupContext markupContext = new MarkupContext(); 217 markupContext.setMimeType(mimeType); 218 markupContext.setCacheControl(cacheControl); 219 markupContext.setMarkupString(new String (output.getContent())); 220 markupContext.setPreferredTitle(output.getTitle()); 221 markupContext.setRequiresUrlRewriting(new Boolean (!conf.isDoesUrlTemplateProcessing())); 222 markupContext.setUseCachedMarkup(new Boolean (false)); 223 226 MarkupResponse markup = new MarkupResponse(); 227 markup.setSessionContext(sessionContext); 228 markup.setMarkupContext(markupContext); 229 return markup; 230 } 231 232 233 public BlockingInteractionResponse performBlockingInteraction(RegistrationContext registrationContext, 234 PortletContext portletContext, 235 RuntimeContext runtimeContext, 236 UserContext userContext, 237 MarkupParams markupParams, 238 InteractionParams interactionParams) 239 throws RemoteException { 240 String portletHandle = portletContext.getPortletHandle(); 242 portletHandle = manageRegistration(portletHandle, registrationContext); 243 String [] k = StringUtils.split(portletHandle, Constants.PORTLET_HANDLE_ENCODER); 244 String portletApplicationName = k[0]; 245 String portletName = k[1]; 246 String uniqueID = k[2]; 247 248 String sessionID = runtimeContext.getSessionID(); 250 WSRPHttpSession session = resolveSession(sessionID, userContext.getUserContextKey()); 251 252 SessionContext sessionContext = new SessionContext(); 254 sessionContext.setSessionID(session.getId()); 255 sessionContext.setExpires(TransientStateManager.SESSION_TIME_PERIOD); 256 257 userContext = transientStateManager.reolveUserContext(userContext, session); 259 String owner = userContext.getUserContextKey(); 260 log.debug("Owner Context : " + owner); 261 262 String baseURL = null; 264 if (conf.isDoesUrlTemplateProcessing()) { 265 log.debug("Producer URL rewriting"); 266 Templates templates = manageTemplates(runtimeContext, session); 267 baseURL = templates.getRenderTemplate(); 268 } else { 269 log.debug("Consumer URL rewriting"); 270 baseURL = WSRPConstants.WSRP_REWITE_PREFIX; 271 } 272 273 byte[] portletState = managePortletState(portletContext); 275 276 PortletMode mode = processMode(markupParams.getMode()); 278 WindowState windowState = processWindowState(markupParams.getWindowState()); 279 280 boolean isStateChangeAuthorized = false; 282 String stateChange = interactionParams.getPortletStateChange().getValue(); 283 if (StateChange.readWrite.getValue().equalsIgnoreCase(stateChange)) { 284 log.debug("readWrite state change"); 285 isStateChangeAuthorized = true; 287 } else if (StateChange.cloneBeforeWrite.getValue().equalsIgnoreCase(stateChange)) { 288 log.debug("cloneBeforWrite state change"); 289 portletContext = portletManagementOperationsInterface.clonePortlet(registrationContext, 290 portletContext, userContext); 291 isStateChangeAuthorized = true; 293 } else if (StateChange.readOnly.getValue().equalsIgnoreCase(stateChange)) { 294 log.debug("readOnly state change"); 295 } else { 298 log.debug("The submited portlet state change value : " + stateChange + " is not supported"); 299 Exception2Fault.handleException(new WSRPException(Faults.PORTLET_STATE_CHANGE_REQUIRED_FAULT)); 300 } 301 302 String mimeType = markupParams.getMimeTypes(0); 304 WSRPHttpServletRequest request = new WSRPHttpServletRequest(session); 305 WSRPHttpServletResponse response = new WSRPHttpServletResponse(); 306 putInteractionParameterInRequest(request, interactionParams); 307 308 ActionInput input = new ActionInput(); 310 ExoWindowID windowID = new ExoWindowID(); 311 windowID.setOwner(owner); 312 windowID.setPortletApplicationName(portletApplicationName); 313 windowID.setPortletName(portletName); 314 windowID.setUniqueID(uniqueID); 315 input.setWindowID(windowID); 316 input.setBaseURL(baseURL); 317 input.setUserAttributes(new HashMap ()); 318 input.setPortletMode(mode); 319 input.setWindowState(windowState); 320 input.setMarkup(mimeType); 321 input.setStateChangeAuthorized(isStateChangeAuthorized); 322 input.setStateSaveOnClient(conf.isSavePortletStateOnConsumer()); 323 input.setPortletState(portletState); 324 input.setPortletPreferencesPersister(persister); 325 ActionOutput output = null; 327 try { 328 output = container.processAction(request, response, input); 329 } catch (WSRPException e) { 330 log.debug("The call to processAction method was a failure ", e); 331 Exception2Fault.handleException(e); 332 } 333 334 String ns = IdentifierUtil.generateUUID(output); 336 try { 337 log.debug("set new navigational state : " + ns); 338 persitentStateManager.putNavigationalState(ns, output.getRenderParameters()); 339 } catch (WSRPException e) { 340 Exception2Fault.handleException(e); 341 } 342 343 BlockingInteractionResponse blockingInteractionResponse = new BlockingInteractionResponse(); 344 345 if (output.getProperties().get(ActionOutput.SEND_REDIRECT) != null) { 346 log.debug("Redirect the response to : " + (String ) output.getProperties().get(ActionOutput.SEND_REDIRECT)); 347 blockingInteractionResponse.setRedirectURL((String ) output.getProperties().get(ActionOutput.SEND_REDIRECT)); 348 blockingInteractionResponse.setUpdateResponse(null); 349 } else { 350 MarkupContext markupContext = null; 351 if (conf.isBlockingInteractionOptimized()) { 352 markupParams.setNavigationalState(ns); 353 MarkupResponse markupResponse = getMarkup(registrationContext, portletContext, 354 runtimeContext, userContext, markupParams); 355 markupContext = markupResponse.getMarkupContext(); 356 } 357 358 UpdateResponse updateResponse = new UpdateResponse(); 359 updateResponse.setNavigationalState(ns); 360 if (output.getNextMode() != null) { 361 updateResponse.setNewMode(WSRPConstants.WSRP_PREFIX + output.getNextMode().toString()); 362 } 363 if (output.getNextState() != null) { 364 updateResponse.setNewWindowState(WSRPConstants.WSRP_PREFIX + output.getNextState().toString()); 365 } 366 updateResponse.setSessionContext(sessionContext); 367 updateResponse.setMarkupContext(markupContext); 368 if (conf.isSavePortletStateOnConsumer()) 370 portletContext.setPortletState(output.getPortletState()); 371 updateResponse.setPortletContext(portletContext); 372 blockingInteractionResponse.setUpdateResponse(updateResponse); 373 } 374 375 return blockingInteractionResponse; 376 } 377 378 private void putInteractionParameterInRequest(WSRPHttpServletRequest request, InteractionParams interactionParams) { 379 NamedString[] array = interactionParams.getFormParameters(); 380 if (array == null) { 381 log.debug("no form parameters"); 382 return; 383 } 384 for (int i = 0; i < array.length; i++) { 385 log.debug("form parameters; name : " + array[i].getName() + "; value : " + array[i].getValue()); 386 request.setParameter(array[i].getName(), array[i].getValue()); 387 } 388 } 389 390 public ReturnAny initCookie(RegistrationContext registrationContext) 391 throws RemoteException { 392 if (conf.isRegistrationRequired()) { 393 log.debug("Registration required"); 394 if (registrationContext == null) { 395 Exception2Fault.handleException(new WSRPException(Faults.INVALID_REGISTRATION_FAULT)); 396 } 397 } 398 return new ReturnAny(); 399 } 400 401 public ReturnAny releaseSessions(RegistrationContext registrationContext, 402 String [] sessionIDs) 403 throws RemoteException { 404 if (conf.isRegistrationRequired()) { 405 log.debug("Registration required"); 406 if (registrationContext == null) { 407 Exception2Fault.handleException(new WSRPException(Faults.INVALID_REGISTRATION_FAULT)); 408 } 409 } 410 for (int i = 0; i < sessionIDs.length; i++) { 411 transientStateManager.releaseSession(sessionIDs[i]); 412 } 413 return new ReturnAny(); 414 } 415 416 private WSRPHttpSession resolveSession(String sessionID, String user) throws RemoteException { 417 WSRPHttpSession session = null; 418 try { 419 session = transientStateManager.resolveSession(sessionID, user); 420 } catch (WSRPException e) { 421 log.debug("Can not lookup or create new session, sessionID parameter : " + sessionID); 422 Exception2Fault.handleException(e); 423 } 424 log.debug("Use session with ID : " + session.getId()); 425 return session; 426 } 427 428 private String manageRegistration(String portletHandle, RegistrationContext registrationContext) throws RemoteException { 429 log.debug("manageRegistration called for portlet handle : " + portletHandle); 430 if (!container.isPortletOffered(portletHandle)) { 431 log.debug("The latter handle is not offered by the Producer"); 432 Exception2Fault.handleException(new WSRPException(Faults.INVALID_HANDLE_FAULT)); 433 } else { 434 String [] keys = StringUtils.split(portletHandle, Constants.PORTLET_HANDLE_ENCODER); 435 if (keys.length == 2) { 436 portletHandle += Constants.PORTLET_HANDLE_ENCODER + DEFAULT_WINDOW_ID; 437 } 438 } 439 440 if (conf.isRegistrationRequired()) { 441 log.debug("Registration required"); 442 if (registrationContext == null) { 443 Exception2Fault.handleException(new WSRPException(Faults.INVALID_REGISTRATION_FAULT)); 444 } 445 } else { 446 log.debug("Registration non required"); 447 } 448 return portletHandle; 449 } 450 451 private PortletMode processMode(String mode) { 452 log.debug("Call with portlet mode : " + mode); 453 if ((WSRPConstants.WSRP_PREFIX + PortletMode.VIEW.toString()).equalsIgnoreCase(mode)) { 454 return PortletMode.VIEW; 455 } else if ((WSRPConstants.WSRP_PREFIX + PortletMode.EDIT.toString()).equalsIgnoreCase(mode)) { 456 return PortletMode.EDIT; 457 } else if ((WSRPConstants.WSRP_PREFIX + PortletMode.HELP.toString()).equalsIgnoreCase(mode)) { 458 return PortletMode.HELP; 459 } 460 return new PortletMode(mode.substring(WSRPConstants.WSRP_PREFIX.length())); 461 } 462 463 private WindowState processWindowState(String state) { 464 log.debug("Call with window state : " + state); 465 if ((WSRPConstants.WSRP_PREFIX + WindowState.NORMAL.toString()).equalsIgnoreCase(state)) { 466 return WindowState.NORMAL; 467 } else if ((WSRPConstants.WSRP_PREFIX + WindowState.MINIMIZED.toString()).equalsIgnoreCase(state)) { 468 return WindowState.MINIMIZED; 469 } else if ((WSRPConstants.WSRP_PREFIX + WindowState.MAXIMIZED.toString()).equalsIgnoreCase(state)) { 470 return WindowState.MAXIMIZED; 471 } 472 return new WindowState(state.substring(WSRPConstants.WSRP_PREFIX.length())); 473 } 474 475 private Map processNavigationalState(String navigationalState) throws WSRPException { 476 log.debug("Lookup navigational state : " + navigationalState); 477 Map map = persitentStateManager.getNavigationalSate(navigationalState); 478 if(map != null){ 480 for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) { 481 String s = (String ) iterator.next(); 482 log.debug("attribute in map referenced by ns : " + s); 483 } 484 } 485 return map; 487 } 488 489 private String getMimeType(String [] mimeTypes, PortletData portletData) throws WSRPException { 490 if (mimeTypes == null || mimeTypes.length == 0) { 491 log.debug("the given array of MimeTypes is empty or null"); 492 throw new WSRPException(Faults.MISSING_PARAMETERS_FAULT); 493 } 494 List l = portletData.getSupports(); 495 for (int i = 0; i < mimeTypes.length; i++) { 496 String mimeType = mimeTypes[i]; 497 for (Iterator iterator = l.iterator(); iterator.hasNext();) { 498 String supports = ((Supports) iterator.next()).getMimeType(); 499 if (supports.equalsIgnoreCase(mimeType)) 500 return mimeType; 501 } 502 } 503 log.debug("No mime type is supported"); 504 throw new WSRPException(Faults.UNSUPPORTED_MIME_TYPE_FAULT); 505 } 506 507 private byte[] managePortletState(PortletContext portletContext) { 508 if (conf.isSavePortletStateOnConsumer()) { 509 log.debug("Save state on consumer"); 510 return portletContext.getPortletState(); 511 } 512 log.debug("Save state on producer"); 513 return null; 514 } 515 516 private Templates manageTemplates(RuntimeContext runtimeContext, WSRPHttpSession session) { 517 Templates templates = runtimeContext.getTemplates(); 518 if (conf.isTemplatesStoredInSession()) { 519 log.debug("Optimized mode : templates store in session"); 520 if (templates == null) { 521 log.debug("Optimized mode : retrieves the template from session"); 522 templates = transientStateManager.getTemplates(session); 523 } else { 524 log.debug("Optimized mode : store the templates in session"); 525 transientStateManager.storeTemplates(templates, session); 526 } 527 } 528 return templates; 529 } 530 531 } 532 | Popular Tags |