/** * This method is called after an attribute is added to the ServletRequest. Note that this should * only get called for remote WSRP portlets. For more info, see: * http://issues.liferay.com/browse/FACES-146 */ public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) { // NOTE: We only care about phases prior to the RENDER_PHASE because we're concerned here about // managed beans // that get added to the request scope when the BridgeRequestScope begins. We're trying to // provide those managed // beans with an opportunity to prepare for an unexpected invocation of their methods annotated // with // @PreDestroy. ServletRequest servletRequest = servletRequestAttributeEvent.getServletRequest(); PortletPhase phase = (PortletPhase) servletRequest.getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE); // If this is taking place within a PortletRequest handled by the bridge in any phase prior to // the // RENDER_PHASE, then if ((phase != null) && (phase != PortletPhase.RENDER_PHASE)) { // If the attribute being added is not excluded, then invoke all methods on the attribute // value (class // instance) that are annotated with the BridgeRequestScopeAttributeAdded annotation. String attributeName = servletRequestAttributeEvent.getName(); BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); BridgeConfig bridgeConfig = bridgeContext.getBridgeConfig(); Set<String> excludedRequestScopeAttributes = bridgeConfig.getExcludedRequestAttributes(); if (!excludedRequestScopeAttributes.contains(attributeName)) { Object attributeValue = servletRequestAttributeEvent.getValue(); logger.trace("Attribute added name=[{0}] value=[{1}]", attributeName, attributeValue); if (attributeValue != null) { Method[] methods = attributeValue.getClass().getMethods(); if (methods != null) { for (Method method : methods) { if (method != null) { if (method.isAnnotationPresent(BridgeRequestScopeAttributeAdded.class)) { try { method.invoke(attributeValue, new Object[] {}); } catch (Exception e) { logger.error(e); } } } } } } } } }
/** * This method is called prior to the {@link PhaseId#RENDER_RESPONSE} phase of the JSF lifecycle. */ @Override public void beforePhase(PhaseEvent phaseEvent) { // Determine if there are any resources in the LIFERAY_SHARED_PAGE_TOP request attribute, so // that execution of // the {@link #afterPhase(PhaseEvent)} can be optimized. liferaySharedPageTopLength = 0; BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); PortletRequest portletRequest = bridgeContext.getPortletRequest(); StringBundler pageTop = getPageTop(portletRequest); if (pageTop != null) { liferaySharedPageTopLength = pageTop.length(); } }
/** * This method overrides the {@link #decode(FacesContext, UIComponent)} method so that it can * avoid a Servlet-API dependency in the RichFaces FileUploadRenderer. Note that rich:fileUpload * will do an Ajax postback and invoke the JSF lifecycle for each individual file. */ @Override public void decode(FacesContext facesContext, UIComponent uiComponent) { try { // Get the UploadedFile from the request attribute map. ContextMapFactory contextMapFactory = (ContextMapFactory) FactoryExtensionFinder.getFactory(ContextMapFactory.class); BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); Map<String, Collection<UploadedFile>> uploadedFileMap = contextMapFactory.getUploadedFileMap(bridgeContext); if (uploadedFileMap != null) { // Use reflection to create a dynamic proxy class that implements the RichFaces UploadedFile // interface. Class<?> uploadedFileInterface = Class.forName(RICHFACES_UPLOADED_FILE_FQCN); Class<?> fileUploadEventClass = Class.forName(RICHFACES_FILE_UPLOAD_EVENT_FQCN); ClassLoader classLoader = uploadedFileInterface.getClassLoader(); String clientId = uiComponent.getClientId(facesContext); Collection<UploadedFile> uploadedFiles = uploadedFileMap.get(clientId); if (uploadedFiles != null) { for (UploadedFile uploadedFile : uploadedFiles) { RichFacesUploadedFileHandler richFacesUploadedFileHandler = new RichFacesUploadedFileHandler(uploadedFile); Object richFacesUploadedFile = Proxy.newProxyInstance( classLoader, new Class[] {uploadedFileInterface}, richFacesUploadedFileHandler); FacesEvent fileUploadEvent = (FacesEvent) fileUploadEventClass .getConstructor(UIComponent.class, uploadedFileInterface) .newInstance(uiComponent, richFacesUploadedFile); // Queue the RichFaces FileUploadEvent instance so that it can be handled with an // ActionListener. uiComponent.queueEvent(fileUploadEvent); } } } } catch (Exception e) { logger.error(e); } }
public ExternalContextCompat_1_2_Impl( PortletContext portletContext, PortletRequest portletRequest, PortletResponse portletResponse) { this.portletContext = portletContext; this.portletRequest = portletRequest; this.portletResponse = portletResponse; // Get the BridgeContext. this.bridgeContext = BridgeContext.getCurrentInstance(); this.incongruityContext = bridgeContext.getIncongruityContext(); // Determine whether or not lifecycle incongruities should be managed. PortletConfig portletConfig = bridgeContext.getPortletConfig(); this.manageIncongruities = PortletConfigParam.ManageIncongruities.getBooleanValue(portletConfig); }
/** This method is called after the {@link PhaseId#RENDER_RESPONSE} phase of the JSF lifecycle. */ @Override public void afterPhase(PhaseEvent phaseEvent) { BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); // Remove duplicate resources from the LIFERAY_SHARED_PAGE_TOP request attribute. For more // information, see: // http://issues.liferay.com/browse/FACES-1216 if (liferaySharedPageTopLength > 0) { PortletRequest portletRequest = bridgeContext.getPortletRequest(); StringBundler pageTop = getPageTop(portletRequest); if (pageTop != null) { LiferaySharedPageTop liferaySharedPageTop = new LiferaySharedPageTop(pageTop); liferaySharedPageTop.removeDuplicates(); pageTop = liferaySharedPageTop.toStringBundler(); setPageTop(portletRequest, pageTop); } } }
/** * Saves the state of the FacesContext as required by section 5.1.2 of the JSR 329 spec. This * method is designed to be called during the ACTION_PHASE of the portlet lifecycle. * * @param facesContext The current faces context. */ public void saveState(FacesContext facesContext) { logger.debug("saveState(facesContext)"); // Get the ExternalContext and PortletResponse. BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); ExternalContext externalContext = facesContext.getExternalContext(); PortletResponse portletResponse = (PortletResponse) facesContext.getExternalContext().getResponse(); if ((beganInPhase == Bridge.PortletPhase.ACTION_PHASE) || (beganInPhase == Bridge.PortletPhase.EVENT_PHASE) || (beganInPhase == Bridge.PortletPhase.RESOURCE_PHASE)) { // Save the view root. setAttribute(BRIDGE_REQ_SCOPE_ATTR_FACES_VIEW_ROOT, facesContext.getViewRoot()); // If the PortletMode hasn't changed, then preserve the "javax.faces.ViewState" request // parameter value. if (!isPortletModeChanged()) { if (portletResponse instanceof ActionResponse) { String viewState = facesContext .getExternalContext() .getRequestParameterMap() .get(ResponseStateManager.VIEW_STATE_PARAM); if (viewState != null) { // NOTE: Although it is possible to save this as a render parameter, can't use that // approach // because portlet containers like Pluto will add the "javax.faces.ViewState" parameter // to any // ResourceURLs that are created during the RENDER_PHASE of the portlet lifecycle. setAttribute(ResponseStateManager.VIEW_STATE_PARAM, viewState); } } } // If specified in the WEB-INF/portlet.xml descriptor, then preserve the action parameters. if (bridgeContext.isPreserveActionParams()) { Map<String, String> actionRequestParameterMap = new HashMap<String, String>(externalContext.getRequestParameterMap()); actionRequestParameterMap.remove(ResponseStateManager.VIEW_STATE_PARAM); actionRequestParameterMap.remove(JAVAX_FACES_ENCODED_URL_PARAM); setAttribute(BRIDGE_REQ_SCOPE_ATTR_ACTION_PARAMS, actionRequestParameterMap); } // Save the list of faces messages. List<FacesMessageWrapper> facesMessageWrappers = new ArrayList<FacesMessageWrapper>(); Iterator<String> clientIds = facesContext.getClientIdsWithMessages(); while (clientIds.hasNext()) { String clientId = clientIds.next(); Iterator<FacesMessage> facesMessages = facesContext.getMessages(clientId); while (facesMessages.hasNext()) { FacesMessage facesMessage = facesMessages.next(); FacesMessageWrapper facesMessageWrapper = new FacesMessageWrapper(clientId, facesMessage); facesMessageWrappers.add(facesMessageWrapper); } } if (facesMessageWrappers.size() > 0) { setAttribute(BRIDGE_REQ_SCOPE_ATTR_FACES_MESSAGES, facesMessageWrappers); } else { logger.trace("Not saving any faces messages"); } // NOTE: PROPOSED-FOR-BRIDGE3-API: https://issues.apache.org/jira/browse/PORTLETBRIDGE-203 // Build up a list // of attributes found in the FacesContext attribute map and save them. It has to be copied in // this manner // because the Faces implementation likely calls the clear() method during the call to its // FacesContextImpl.release() method. saveJSF2FacesContextAttributes(facesContext); } if ((beganInPhase == Bridge.PortletPhase.ACTION_PHASE) || (beganInPhase == Bridge.PortletPhase.EVENT_PHASE) || (beganInPhase == Bridge.PortletPhase.RESOURCE_PHASE)) { boolean saveNonExcludedAttributes = true; // If a redirect occurred, then indicate that the non-excluded request attributes are not to // be preserved. if (isRedirectOccurred()) { // TCK TestPage062: eventScopeNotRestoredRedirectTest logger.trace("Due to redirect, not saving any non-excluded request attributes"); saveNonExcludedAttributes = false; } // Otherwise, if the portlet mode has changed, then indicate that the non-exluded request // attributes are // not to be preserved. else if (isPortletModeChanged()) { logger.trace("Due to PortletMode change, not saving any non-excluded request attributes"); saveNonExcludedAttributes = false; } // If appropriate, save the non-excluded request attributes. This would include, for example, // managed-bean // instances that may have been created during the ACTION_PHASE that need to survive to the // RENDER_PHASE. Map<String, Object> currentRequestAttributes = externalContext.getRequestMap(); if (currentRequestAttributes != null) { List<RequestAttribute> savedRequestAttributes = new ArrayList<RequestAttribute>(); List<String> nonExcludedAttributeNames = new ArrayList<String>(); Iterator<Map.Entry<String, Object>> itr = currentRequestAttributes.entrySet().iterator(); if (itr != null) { while (itr.hasNext()) { Map.Entry<String, Object> mapEntry = itr.next(); String attributeName = mapEntry.getKey(); Object attributeValue = mapEntry.getValue(); if (isExcludedRequestAttributeByConfig(attributeName, attributeValue) || isExcludedRequestAttributeByAnnotation(attributeValue) || isExcludedRequestAttributeByNamespace(attributeName) || isExcludedRequestAttributeByInstance(attributeName, attributeValue) || isExcludedRequestAttributeByPreExisting(attributeName)) { logger.trace("NOT saving EXCLUDED attribute name=[{0}]", attributeName); } else { if (saveNonExcludedAttributes) { logger.trace( "SAVING non-excluded request attribute name=[{0}] value=[{1}]", attributeName, attributeValue); savedRequestAttributes.add(new RequestAttribute(attributeName, attributeValue)); } nonExcludedAttributeNames.add(attributeName); } } if (savedRequestAttributes.size() > 0) { setAttribute(BRIDGE_REQ_SCOPE_ATTR_REQUEST_ATTRIBUTES, savedRequestAttributes); } else { logger.trace("Not saving any non-excluded request attributes"); } setAttribute(BRIDGE_REQ_SCOPE_NON_EXCLUDED_ATTR_NAMES, nonExcludedAttributeNames); } } else { logger.trace( "Not saving any non-excluded request attributes because there are no request attributes!"); } } // If running in the ACTION_PHASE or EVENT_PHASE, then the Flash scope must be saved as well so // that it can be // restored. Bridge.PortletPhase portletRequestPhase = bridgeContext.getPortletRequestPhase(); if ((portletRequestPhase == Bridge.PortletPhase.ACTION_PHASE) || (portletRequestPhase == Bridge.PortletPhase.EVENT_PHASE)) { // PROPOSED-FOR-JSR344-API: http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1070 // PROPOSED-FOR-BRIDGE3-API: https://issues.apache.org/jira/browse/PORTLETBRIDGE-201 saveFlashState(facesContext); } // If running in the ACTION_PHASE or EVENT_PHASE, then the incongruity context must be saved as // well so that it // can be restored. if ((portletRequestPhase == Bridge.PortletPhase.ACTION_PHASE) || (portletRequestPhase == Bridge.PortletPhase.EVENT_PHASE)) { IncongruityContext incongruityContext = bridgeContext.getIncongruityContext(); Map<String, Object> incongruityAttributeMap = incongruityContext.getAttributes(); int mapSize = incongruityAttributeMap.size(); List<IncongruityAttribute> savedIncongruityAttributes = new ArrayList<IncongruityAttribute>(mapSize); Iterator<Map.Entry<String, Object>> itr = incongruityAttributeMap.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<String, Object> mapEntry = itr.next(); String name = mapEntry.getKey(); Object value = mapEntry.getValue(); logger.trace("Saving IncongruityContext attribute name=[{0}] value=[{1}]", name, value); savedIncongruityAttributes.add(new IncongruityAttribute(name, value)); } setAttribute( BRIDGE_REQ_SCOPE_ATTR_INCONGRUITY_CONTEXT_ATTRIBUTES, savedIncongruityAttributes); } }
@SuppressWarnings("unchecked") public void restoreState(FacesContext facesContext) { logger.debug("restoreState(facesContext)"); boolean restoreNonExcludedRequestAttributes = ((beganInPhase == Bridge.PortletPhase.ACTION_PHASE) || (beganInPhase == Bridge.PortletPhase.EVENT_PHASE) || (beganInPhase == Bridge.PortletPhase.RESOURCE_PHASE)); BridgeContext bridgeContext = BridgeContext.getCurrentInstance(); PortletPhase portletRequestPhase = bridgeContext.getPortletRequestPhase(); if (portletRequestPhase == Bridge.PortletPhase.RENDER_PHASE) { if (!portletMode.equals(bridgeContext.getPortletRequest().getPortletMode())) { setPortletModeChanged(true); restoreNonExcludedRequestAttributes = false; } } if ((beganInPhase == Bridge.PortletPhase.ACTION_PHASE) || (beganInPhase == Bridge.PortletPhase.EVENT_PHASE) || (beganInPhase == Bridge.PortletPhase.RESOURCE_PHASE)) { // Restore the view root that may have been saved during the ACTION_PHASE of the portlet // lifecycle. UIViewRoot uiViewRoot = (UIViewRoot) getAttribute(BRIDGE_REQ_SCOPE_ATTR_FACES_VIEW_ROOT); if (uiViewRoot != null) { facesContext.setViewRoot(uiViewRoot); logger.debug("Restored viewId=[{0}] uiViewRoot=[{1}]", uiViewRoot.getViewId(), uiViewRoot); } else { logger.debug("Did not restore uiViewRoot"); } // Restore the faces messages that may have been saved during the ACTION_PHASE of the portlet // lifecycle. List<FacesMessageWrapper> facesMessages = (List<FacesMessageWrapper>) getAttribute(BRIDGE_REQ_SCOPE_ATTR_FACES_MESSAGES); boolean restoredFacesMessages = false; if (facesMessages != null) { for (FacesMessageWrapper facesMessageWrapper : facesMessages) { String clientId = facesMessageWrapper.getClientId(); FacesMessage facesMessage = facesMessageWrapper.getFacesMessage(); facesContext.addMessage(clientId, facesMessage); logger.trace("Restored facesMessage=[{0}]", facesMessage.getSummary()); restoredFacesMessages = true; } } if (restoredFacesMessages) { logger.debug("Restored facesMessages"); } else { logger.debug("Did not restore any facesMessages"); } // NOTE: PROPOSE-FOR-BRIDGE3-API: https://issues.apache.org/jira/browse/PORTLETBRIDGE-203 // Restore the // FacesContext attributes that may have been saved during the ACTION_PHASE of the portlet // lifecycle. restoreJSF2FacesContextAttributes(facesContext); } if (restoreNonExcludedRequestAttributes) { // Restore the non-excluded request attributes. List<RequestAttribute> savedRequestAttributes = (List<RequestAttribute>) getAttribute(BRIDGE_REQ_SCOPE_ATTR_REQUEST_ATTRIBUTES); boolean restoredNonExcludedRequestAttributes = false; if (savedRequestAttributes != null) { Map<String, Object> currentRequestAttributes = facesContext.getExternalContext().getRequestMap(); // If a redirect did not occur, then restore the non-excluded request attributes. if (!isRedirectOccurred()) { for (RequestAttribute requestAttribute : savedRequestAttributes) { String name = requestAttribute.getName(); Object value = requestAttribute.getValue(); logger.trace( "Restoring non-excluded request attribute name=[{0}] value=[{1}]", name, value); currentRequestAttributes.put(name, value); restoredNonExcludedRequestAttributes = true; } } } if (restoredNonExcludedRequestAttributes) { logger.debug("Restored non-excluded request attributes"); } else { logger.debug("Did not restore any non-excluded request attributes"); } } // If running in the RENDER_PHASE, then the Flash scope must be restored. if (portletRequestPhase == Bridge.PortletPhase.RENDER_PHASE) { // NOTE: PROPOSED-FOR-BRIDGE3-API: https://issues.apache.org/jira/browse/PORTLETBRIDGE-201 // Restore the flash scope. restoreFlashState(facesContext); } // If running in the RENDER_PHASE, then the incongruity context must be restored. if (((beganInPhase == Bridge.PortletPhase.ACTION_PHASE) || (beganInPhase == Bridge.PortletPhase.EVENT_PHASE)) && (portletRequestPhase == Bridge.PortletPhase.RENDER_PHASE)) { List<IncongruityAttribute> savedIncongruityAttributes = (List<IncongruityAttribute>) getAttribute(BRIDGE_REQ_SCOPE_ATTR_INCONGRUITY_CONTEXT_ATTRIBUTES); if (savedIncongruityAttributes != null) { IncongruityContext incongruityContext = bridgeContext.getIncongruityContext(); Map<String, Object> incongruityContextAttributes = incongruityContext.getAttributes(); for (IncongruityAttribute incongruityAttribute : savedIncongruityAttributes) { String key = incongruityAttribute.getName(); Object value = incongruityAttribute.getValue(); incongruityContextAttributes.put(key, value); } } } }