@Override protected void doDecode(FacesContext context, UIComponent component) { Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap(); AbstractPanelMenuItem menuItem = (AbstractPanelMenuItem) component; String compClientId = component.getClientId(context); if (requestMap.get(compClientId) != null) { AbstractPanelMenu pm = getParentPanelMenu(menuItem); if (pm.isImmediate()) { menuItem.setImmediate(true); } new ActionEvent(menuItem).queue(); if (context.getPartialViewContext().isPartialRequest()) { // TODO nick - why render item by default? context.getPartialViewContext().getRenderIds().add(component.getClientId(context)); // TODO nick - this should be done on encode, not on decode addOnCompleteParam(context, component.getClientId(context)); } } }
/** * Downloads a blob and sends it to the requesting user, in the JSF current context. * * @param doc the document, if available * @param xpath the blob's xpath or blobholder index, if available * @param blob the blob, if already fetched * @param filename the filename to use * @param reason the download reason * @param extendedInfos an optional map of extended informations to log * @since 7.3 */ public static void download( DocumentModel doc, String xpath, Blob blob, String filename, String reason, Map<String, Serializable> extendedInfos) { FacesContext facesContext = FacesContext.getCurrentInstance(); if (facesContext.getResponseComplete()) { // nothing can be written, an error was probably already sent. don't bother log.debug("Cannot send " + filename + ", response already complete"); return; } if (facesContext.getPartialViewContext().isAjaxRequest()) { // do not perform download in an ajax request return; } ExternalContext externalContext = facesContext.getExternalContext(); HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); try { DownloadService downloadService = Framework.getService(DownloadService.class); downloadService.downloadBlob( request, response, doc, xpath, blob, filename, reason, extendedInfos); } catch (IOException e) { log.error("Error while downloading the file: " + filename, e); } finally { facesContext.responseComplete(); } }
@Override public void doDecode(FacesContext context, UIComponent component) { final Map<String, String> map = context.getExternalContext().getRequestParameterMap(); String newToggleState = map.get(component.getClientId(context) + NEW_NODE_TOGGLE_STATE); if (newToggleState != null) { AbstractTreeNode treeNode = (AbstractTreeNode) component; boolean initialState = treeNode.isExpanded(); boolean newState = Boolean.valueOf(newToggleState); if (initialState ^ newState) { new TreeToggleEvent(treeNode, newState).queue(); } PartialViewContext pvc = context.getPartialViewContext(); if (pvc.isAjaxRequest() && map.get(component.getClientId(context) + TRIGGER_NODE_AJAX_UPDATE) != null) { pvc.getRenderIds() .add( component.getClientId(context) + MetaComponentResolver.META_COMPONENT_SEPARATOR_CHAR + AbstractTreeNode.SUBTREE_META_COMPONENT_ID); context.getAttributes().put(AJAX_TOGGLED_NODE_ATTRIBUTE, component.getClientId(context)); context .getAttributes() .put( AJAX_TOGGLED_NODE_STATE_ATTRIBUTE, initialState ? TreeNodeState.expanded : TreeNodeState.collapsed); } } }
public void execute(FacesContext facesContext) throws FacesException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Entering RenderResponsePhase"); } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("About to render view " + facesContext.getViewRoot().getViewId()); } // For requests intended to produce a partial response, we need prohibit // writing any content outside of the view itself (f:view). PartialViewContext partialViewContext = facesContext.getPartialViewContext(); if (partialViewContext.isAjaxRequest()) { OnOffResponseWrapper onOffResponse = new OnOffResponseWrapper(facesContext); onOffResponse.setEnabled(false); } try { ViewHandler vh = facesContext.getApplication().getViewHandler(); ViewDeclarationLanguage vdl = vh.getViewDeclarationLanguage(facesContext, facesContext.getViewRoot().getViewId()); if (vdl != null) { vdl.buildView(facesContext, facesContext.getViewRoot()); } boolean viewIdsUnchanged; do { String beforePublishViewId = facesContext.getViewRoot().getViewId(); // the before render event on the view root is a special case to keep door open for // navigation // this must be called *after* PDL.buildView() and before VH.renderView() facesContext .getApplication() .publishEvent(facesContext, PreRenderViewEvent.class, facesContext.getViewRoot()); String afterPublishViewId = facesContext.getViewRoot().getViewId(); viewIdsUnchanged = beforePublishViewId == null && afterPublishViewId == null || (beforePublishViewId != null && afterPublishViewId != null) && beforePublishViewId.equals(afterPublishViewId); } while (!viewIdsUnchanged); // render the view vh.renderView(facesContext, facesContext.getViewRoot()); } catch (IOException e) { throw new FacesException(e.getMessage(), e); } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log( Level.FINEST, "+=+=+=+=+=+= View structure printout for " + facesContext.getViewRoot().getViewId()); DebugUtil.printTree(facesContext.getViewRoot(), LOGGER, Level.FINEST); } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Exiting RenderResponsePhase"); } }
@Override public void handle() throws FacesException { final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); while (i.hasNext()) { ExceptionQueuedEvent event = i.next(); ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); Throwable t = context.getException(); final FacesContext fc = FacesContext.getCurrentInstance(); final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap(); try { System.out.printf(">>> Exception caught: %s", t.getMessage()); t.printStackTrace(); requestMap.put("exceptionMessage", t.getMessage()); ExternalContext extContext = fc.getExternalContext(); String url = extContext.encodeActionURL(extContext.getRequestContextPath() + "/500.xhtml"); extContext.redirect(url); } catch (Exception e) { String errorPageLocation = "/WEB-INF/500.xhtml"; fc.setViewRoot(fc.getApplication().getViewHandler().createView(fc, errorPageLocation)); fc.getPartialViewContext().setRenderAll(false); fc.renderResponse(); } finally { i.remove(); } } getWrapped().handle(); }
/** * Return the {@link PartialViewContext} for this request. The {@link PartialViewContext} is used * to control the processing of specified components during the execute portion of the request * processing lifecycle (known as partial processing) and the rendering of specified components * (known as partial rendering). This method must return a new {@link PartialViewContext} if one * does not already exist. * * @throws IllegalStateException if this method is called after this instance has been released * @since 2.0 */ public PartialViewContext getPartialViewContext() { if (defaultFacesContext != null) { return defaultFacesContext.getPartialViewContext(); } throw new UnsupportedOperationException(); }
public void broadcast(FacesEvent event) throws AbortProcessingException { if (event instanceof DataScrollEvent) { DataScrollEvent dataScrollerEvent = (DataScrollEvent) event; updateModel(dataScrollerEvent.getPage()); FacesContext facesContext = getFacesContext(); UIComponent dataTable = getDataTable(); List<AbstractDataScroller> dataScrollers = DataScrollerUtils.findDataScrollers(dataTable); for (AbstractDataScroller dataScroller : dataScrollers) { facesContext .getPartialViewContext() .getRenderIds() .add(dataScroller.getClientId(facesContext)); } String dataTableId = null; if (dataTable instanceof MetaComponentResolver && !(dataTable instanceof UIDataTableBase && ((UIDataTableBase) dataTable).hasRowChildren())) { dataTableId = ((MetaComponentResolver) dataTable).resolveClientId(facesContext, dataTable, "body"); } if (dataTableId == null) { dataTableId = dataTable.getClientId(facesContext); } facesContext.getPartialViewContext().getRenderIds().add(dataTableId); // add datascroller to render String dataScrollerId = getClientId(facesContext); if (!facesContext.getPartialViewContext().getRenderIds().contains(dataScrollerId)) { facesContext.getPartialViewContext().getRenderIds().add(dataScrollerId); } } super.broadcast(event); }
public void end( ResponseWriter writer, FacesContext context, UIComponent component, Object[] params) throws IOException { writer.endElement(HtmlConstants.TH_ELEM); writer.endElement(HtmlConstants.TR_ELEMENT); writer.endElement(HtmlConstants.THEAD_ELEMENT); boolean partial = (Boolean) (Boolean) params[0]; if (partial) { context.getPartialViewContext().getPartialResponseWriter().endUpdate(); } }
@Override protected void doDecode(FacesContext context, UIComponent component) { Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap(); AbstractTab tab = (AbstractTab) component; String compClientId = component.getClientId(context); if (requestMap.get(compClientId) != null) { AbstractTabPanel parentTabPanel = getParentTabPanel(tab); if (parentTabPanel.isImmediate()) { tab.setImmediate(true); } new ActionEvent(tab).queue(); if (context.getPartialViewContext().isPartialRequest()) { context.getPartialViewContext().getRenderIds().add(component.getClientId(context)); addOnCompleteParam(context, tab.getName(), tab.getTabPanel().getClientId(context)); } } }
public void encodeTBody( ResponseWriter writer, FacesContext facesContext, AbstractDataGrid dataGrid, boolean partial) throws IOException { String clientId = dataGrid.getClientId(facesContext) + ":dgb"; if (partial) { facesContext.getPartialViewContext().getPartialResponseWriter().startUpdate(clientId); } writer.startElement(HtmlConstants.TBODY_ELEMENT, dataGrid); writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, clientId, null); writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "rf-dg-body", null); if (dataGrid.getRowCount() > 0) { processRows(writer, facesContext, dataGrid, null); } else { encodeNoData(writer, facesContext, dataGrid); } writer.endElement(HtmlConstants.TBODY_ELEMENT); if (partial) { facesContext.getPartialViewContext().getPartialResponseWriter().endUpdate(); } }
public String getThrowExceptionOnAjax() { FacesContext context = FacesContext.getCurrentInstance(); PartialViewContext partialContext = context.getPartialViewContext(); if (null != partialContext) { if (partialContext.isAjaxRequest()) { throw new RuntimeException("Intentionally throwing exception on ajax request"); } } String result = "not an ajax request"; return result; }
/** * This method delegates to the RequestContext.isPartialRequest() with the exception that JSF Ajax * render="@all" requests are reported as non-partial * * @param context * @return */ public static boolean isPartialRequest(FacesContext context) { RequestContext rc = RequestContext.getCurrentInstance(); if (rc == null) return false; boolean isPartial = rc.isPartialRequest(context); if (isPartial && context.getPartialViewContext().isRenderAll()) { // We do not want to create PartialPageContext and use the tree visit (if enabled) // for the 'render all' <f:ajax> case isPartial = false; } return isPartial; }
@Override public void encodeMetaComponent( FacesContext context, UIComponent component, String metaComponentId) throws IOException { if (AbstractTabPanel.HEADER_META_COMPONENT.equals(metaComponentId)) { AbstractTabPanel panel = (AbstractTabPanel) component; PartialResponseWriter w = context.getPartialViewContext().getPartialResponseWriter(); String id = component.getClientId() + AbstractTabPanel.HEADER_META_COMPONENT; w.startUpdate(id); writeTabsLine(w, context, panel); w.endUpdate(); } else { super.encodeMetaComponent(context, component, metaComponentId); } }
public VisitResult visit(VisitContext context, UIComponent comp) { try { if (curPhase == PhaseId.APPLY_REQUEST_VALUES) { // RELEASE_PENDING handle immediate request(s) // If the user requested an immediate request // Make sure to set the immediate flag here. comp.processDecodes(ctx); } else if (curPhase == PhaseId.PROCESS_VALIDATIONS) { comp.processValidators(ctx); } else if (curPhase == PhaseId.UPDATE_MODEL_VALUES) { comp.processUpdates(ctx); } else if (curPhase == PhaseId.RENDER_RESPONSE) { PartialResponseWriter writer = ctx.getPartialViewContext().getPartialResponseWriter(); writer.startUpdate(comp.getClientId(ctx)); try { // do the default behavior... comp.encodeAll(ctx); } catch (Exception ce) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.severe(ce.toString()); } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, ce.toString(), ce); } } writer.endUpdate(); } else { throw new IllegalStateException( "I18N: Unexpected " + "PhaseId passed to " + " PhaseAwareContextCallback: " + curPhase.toString()); } } catch (IOException ex) { ex.printStackTrace(); } // Once we visit a component, there is no need to visit // its children, since processDecodes/Validators/Updates and // encodeAll() already traverse the subtree. We return // VisitResult.REJECT to supress the subtree visit. return VisitResult.REJECT; }
@Override protected void doDecode(FacesContext context, UIComponent component) { AbstractTooltip tooltip = (AbstractTooltip) component; Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap(); String compClientId = component.getClientId(context); String clientId = requestMap.get(compClientId); if (clientId != null && clientId.equals(compClientId)) { context.getPartialViewContext().getRenderIds().add(tooltip.getContentClientId(context)); // TODO nick - this should be done on encode, not on decode addOnCompleteParam(context, tooltip.getClientId(context)); context.renderResponse(); } }
public void encodeMetaComponent( FacesContext context, UIComponent component, String metaComponentId) throws IOException { if (AbstractTooltip.CONTENT_META_COMPONENT_ID.equals(metaComponentId)) { AbstractTooltip tooltip = (AbstractTooltip) component; PartialResponseWriter writer = context.getPartialViewContext().getPartialResponseWriter(); writer.startUpdate( tooltip.getClientId(context) + ":" + AbstractTooltip.CONTENT_META_COMPONENT_ID); encodeContentBegin(writer, context, tooltip); for (UIComponent child : tooltip.getChildren()) { child.encodeAll(context); } encodeContentEnd(writer, context, tooltip); writer.endUpdate(); } }
/** * This code is currently common to all {@link ViewHandlingStrategy} instances. * * @see ViewHandler#writeState(javax.faces.context.FacesContext) */ public void writeState(FacesContext context) throws IOException { Util.notNull("context", context); if (!context.getPartialViewContext().isAjaxRequest()) { if (logger.isLoggable(Level.FINE)) { logger.fine("Begin writing marker for viewId " + context.getViewRoot().getViewId()); } WriteBehindStateWriter writer = WriteBehindStateWriter.getCurrentInstance(); if (writer != null) { writer.writingState(); } context.getResponseWriter().write(RIConstants.SAVESTATE_FIELD_MARKER); if (logger.isLoggable(Level.FINE)) { logger.fine("End writing marker for viewId " + context.getViewRoot().getViewId()); } } }
private void renderAll(FacesContext context, UIViewRoot viewRoot) throws IOException { // If this is a "render all via ajax" request, // make sure to wrap the entire page in a <render> elemnt // with the special viewStateId of VIEW_ROOT_ID. This is how the client // JavaScript knows how to replace the entire document with // this response. PartialViewContext pvc = context.getPartialViewContext(); PartialResponseWriter writer = pvc.getPartialResponseWriter(); writer.startUpdate(PartialResponseWriter.RENDER_ALL_MARKER); if (viewRoot.getChildCount() > 0) { for (UIComponent uiComponent : viewRoot.getChildren()) { uiComponent.encodeAll(context); } } writer.endUpdate(); }
public void beforePhase(PhaseEvent phaseEvent) { Bridge.PortletPhase portletRequestPhase = BridgeUtil.getPortletRequestPhase(phaseEvent.getFacesContext()); if ((portletRequestPhase == Bridge.PortletPhase.RESOURCE_PHASE) || (portletRequestPhase == Bridge.PortletPhase.RENDER_PHASE)) { if (phaseEvent.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES) { beforeApplyRequestValuesPhase(phaseEvent); } else if (phaseEvent.getPhaseId() == PhaseId.RENDER_RESPONSE) { FacesContext facesContext = phaseEvent.getFacesContext(); if (facesContext.getPartialViewContext().isAjaxRequest()) { beforeAjaxifiedRenderResponsePhase(phaseEvent); } } } }
public void processEvent(SystemEvent cse) throws AbortProcessingException { AutoUpdatable component = (AutoUpdatable) cse.getSource(); FacesContext context = FacesContext.getCurrentInstance(); if (component.isAutoUpdate() && context.getRenderKit().getResponseStateManager().isPostback(context)) { Object ignoreAutoUpdateObject = context .getExternalContext() .getRequestParameterMap() .get(Constants.RequestParams.IGNORE_AUTO_UPDATE_PARAM); boolean ignoreAutoUpdate = (null != ignoreAutoUpdateObject && "true".equals(ignoreAutoUpdateObject)) ? true : false; if (!ignoreAutoUpdate) { context.getPartialViewContext().getRenderIds().add(component.getClientId(context)); } } }
private void handlePartialResponseError(FacesContext context, Throwable t) { if (context.getResponseComplete()) { return; // don't write anything if the response is complete } try { ExternalContext extContext = context.getExternalContext(); extContext.setResponseContentType("text/xml"); extContext.addResponseHeader("Cache-Control", "no-cache"); PartialResponseWriter writer = context.getPartialViewContext().getPartialResponseWriter(); writer.startDocument(); writer.startError(t.getClass().toString()); String msg; if (context.isProjectStage(ProjectStage.Production)) { msg = "See your server log for more information"; } else { if (t.getCause() != null) { msg = t.getCause().getMessage(); } else { msg = t.getMessage(); } } writer.write(((msg != null) ? msg : "")); writer.endError(); writer.endDocument(); if (LOGGER.isLoggable(Level.SEVERE)) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); LOGGER.log(Level.SEVERE, sw.toString()); } context.responseComplete(); } catch (IOException ioe) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, ioe.toString(), ioe); } } }
public void encodeMetaComponent( FacesContext context, UIComponent component, String metaComponentId) throws IOException { if (AbstractAutocomplete.ITEMS_META_COMPONENT_ID.equals(metaComponentId)) { List<Object> fetchValues = new ArrayList<Object>(); PartialResponseWriter partialWriter = context.getPartialViewContext().getPartialResponseWriter(); partialWriter.startUpdate(getStrategy(component).getContainerElementId(context, component)); encodeItems(context, component, fetchValues); partialWriter.endUpdate(); if (!fetchValues.isEmpty()) { Map<String, Object> dataMap = ExtendedPartialViewContext.getInstance(context).getResponseComponentDataMap(); dataMap.put(component.getClientId(context), fetchValues); } } else { throw new IllegalArgumentException(metaComponentId); } }
private void renderState(FacesContext context) throws IOException { if (!context.getViewRoot().isTransient()) { // Get the view state and write it to the response.. PartialViewContext pvc = context.getPartialViewContext(); PartialResponseWriter writer = pvc.getPartialResponseWriter(); String viewStateId = Util.getViewStateId(context); writer.startUpdate(viewStateId); String state = context.getApplication().getStateManager().getViewState(context); writer.write(state); writer.endUpdate(); ClientWindow window = context.getExternalContext().getClientWindow(); if (null != window) { String windowIdId = Util.getWindowIdId(context); writer.startUpdate(windowIdId); writer.write(window.getId()); writer.endUpdate(); } } }
@Override protected void doDecode(FacesContext context, UIComponent component) { AbstractAutocomplete autocomplete = (AbstractAutocomplete) component; if (InputUtils.isDisabled(autocomplete)) { return; } Map<String, String> requestParameters = context.getExternalContext().getRequestParameterMap(); String value = requestParameters.get(component.getClientId(context) + "Input"); if (value != null) { autocomplete.setSubmittedValue(value); } if (requestParameters.get(component.getClientId(context) + ".ajax") != null) { PartialViewContext pvc = context.getPartialViewContext(); pvc.getRenderIds() .add( component.getClientId(context) + MetaComponentResolver.META_COMPONENT_SEPARATOR_CHAR + AbstractAutocomplete.ITEMS_META_COMPONENT_ID); context.renderResponse(); } }
public void begin( ResponseWriter writer, FacesContext context, UIComponent component, Object[] params) throws IOException { String clientId = component.getClientId(context) + ":h"; boolean partial = (Boolean) (Boolean) params[0]; if (partial) { context.getPartialViewContext().getPartialResponseWriter().startUpdate(clientId); } writer.startElement(HtmlConstants.THEAD_ELEMENT, component); writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, clientId, null); writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "rf-dg-thead", null); writer.startElement(HtmlConstants.TR_ELEMENT, component); writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "rf-dg-h", null); writer.startElement(HtmlConstants.TH_ELEM, component); writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "rf-dg-h-c", null); int columns = (Integer) component.getAttributes().get("columns"); if (columns > 0) { writer.writeAttribute(HtmlConstants.COLSPAN_ATTRIBUTE, columns, null); } }
/** @see javax.faces.context.PartialViewContext#processPartial(javax.faces.event.PhaseId)) */ @Override public void processPartial(PhaseId phaseId) { updateFacesContext(); PartialViewContext pvc = ctx.getPartialViewContext(); Collection<String> executeIds = pvc.getExecuteIds(); Collection<String> renderIds = pvc.getRenderIds(); UIViewRoot viewRoot = ctx.getViewRoot(); if (phaseId == PhaseId.APPLY_REQUEST_VALUES || phaseId == PhaseId.PROCESS_VALIDATIONS || phaseId == PhaseId.UPDATE_MODEL_VALUES) { // Skip this processing if "none" is specified in the render list, // or there were no execute phase client ids. if (executeIds == null || executeIds.isEmpty()) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log( Level.FINE, "No execute and render identifiers specified. Skipping component processing."); } return; } try { processComponents(viewRoot, phaseId, executeIds, ctx); } catch (Exception e) { if (LOGGER.isLoggable(Level.INFO)) { LOGGER.log(Level.INFO, e.toString(), e); } } // If we have just finished APPLY_REQUEST_VALUES phase, install the // partial response writer. We want to make sure that any content // or errors generated in the other phases are written using the // partial response writer. // if (phaseId == PhaseId.APPLY_REQUEST_VALUES) { PartialResponseWriter writer = pvc.getPartialResponseWriter(); ctx.setResponseWriter(writer); } } else if (phaseId == PhaseId.RENDER_RESPONSE) { try { // // We re-enable response writing. // PartialResponseWriter writer = pvc.getPartialResponseWriter(); ResponseWriter orig = ctx.getResponseWriter(); ctx.getAttributes().put(ORIGINAL_WRITER, orig); ctx.setResponseWriter(writer); ExternalContext exContext = ctx.getExternalContext(); exContext.setResponseContentType("text/xml"); exContext.addResponseHeader("Cache-Control", "no-cache"); writer.startDocument(); if (isRenderAll()) { renderAll(ctx, viewRoot); renderState(ctx); writer.endDocument(); return; } // Skip this processing if "none" is specified in the render list, // or there were no render phase client ids. if (renderIds == null || renderIds.isEmpty()) { } else { processComponents(viewRoot, phaseId, renderIds, ctx); } renderState(ctx); writer.endDocument(); } catch (IOException ex) { this.cleanupAfterView(); } catch (RuntimeException ex) { this.cleanupAfterView(); // Throw the exception throw ex; } } }
public boolean isAjaxRequest(FacesContext context) { return context.getPartialViewContext().isAjaxRequest(); }
/** * <p> * Stores the provided state within the session obtained from the provided * <code>FacesContext</code> * </p> * * <p>If <code>stateCapture</code> is <code>null</code>, the composite * key used to look up the actual and logical views will be written to * the client as a hidden field using the <code>ResponseWriter</code> * from the provided <code>FacesContext</code>.</p> * * <p>If <code>stateCapture</code> is not <code>null</code>, the composite * key will be appended to the <code>StringBuilder<code> without any markup * included or any content written to the client. */ public void writeState(FacesContext ctx, Object state, StringBuilder stateCapture) throws IOException { Util.notNull("context", ctx); String id; UIViewRoot viewRoot = ctx.getViewRoot(); if (!viewRoot.isTransient()) { if (!ctx.getAttributes().containsKey("com.sun.faces.ViewStateValue")) { Util.notNull("state", state); Object[] stateToWrite = (Object[]) state; ExternalContext externalContext = ctx.getExternalContext(); Object sessionObj = externalContext.getSession(true); Map<String, Object> sessionMap = externalContext.getSessionMap(); //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (sessionObj) { Map<String, Map> logicalMap = TypedCollections.dynamicallyCastMap( (Map) sessionMap.get(LOGICAL_VIEW_MAP), String.class, Map.class); if (logicalMap == null) { logicalMap = Collections.synchronizedMap(new LRUMap<String, Map>(numberOfLogicalViews)); sessionMap.put(LOGICAL_VIEW_MAP, logicalMap); } Object structure = stateToWrite[0]; Object savedState = handleSaveState(stateToWrite[1]); String idInLogicalMap = (String) RequestStateManager.get(ctx, RequestStateManager.LOGICAL_VIEW_MAP); if (idInLogicalMap == null) { idInLogicalMap = ((generateUniqueStateIds) ? createRandomId() : createIncrementalRequestId(ctx)); } String idInActualMap = null; if (ctx.getPartialViewContext().isPartialRequest()) { // If partial request, do not change actual view Id, because page not actually changed. // Otherwise partial requests will soon overflow cache with values that would be never // used. idInActualMap = (String) RequestStateManager.get(ctx, RequestStateManager.ACTUAL_VIEW_MAP); } if (null == idInActualMap) { idInActualMap = ((generateUniqueStateIds) ? createRandomId() : createIncrementalRequestId(ctx)); } Map<String, Object[]> actualMap = TypedCollections.dynamicallyCastMap( logicalMap.get(idInLogicalMap), String.class, Object[].class); if (actualMap == null) { actualMap = new LRUMap<String, Object[]>(numberOfViews); logicalMap.put(idInLogicalMap, actualMap); } id = idInLogicalMap + ':' + idInActualMap; Object[] stateArray = actualMap.get(idInActualMap); // reuse the array if possible if (stateArray != null) { stateArray[0] = structure; stateArray[1] = savedState; } else { actualMap.put(idInActualMap, new Object[] {structure, savedState}); } // always call put/setAttribute as we may be in a clustered environment. sessionMap.put(LOGICAL_VIEW_MAP, logicalMap); ctx.getAttributes().put("com.sun.faces.ViewStateValue", id); } } else { id = (String) ctx.getAttributes().get("com.sun.faces.ViewStateValue"); } } else { id = "stateless"; } if (stateCapture != null) { stateCapture.append(id); } else { ResponseWriter writer = ctx.getResponseWriter(); writer.startElement("input", null); writer.writeAttribute("type", "hidden", null); String viewStateParam = ResponseStateManager.VIEW_STATE_PARAM; if ((namespaceParameters) && (viewRoot instanceof NamingContainer)) { String namingContainerId = viewRoot.getContainerClientId(ctx); if (namingContainerId != null) { viewStateParam = namingContainerId + viewStateParam; } } writer.writeAttribute("name", viewStateParam, null); if (webConfig.isOptionEnabled(EnableViewStateIdRendering)) { String viewStateId = Util.getViewStateId(ctx); writer.writeAttribute("id", viewStateId, null); } writer.writeAttribute("value", id, null); if (webConfig.isOptionEnabled(AutoCompleteOffOnViewState)) { writer.writeAttribute("autocomplete", "off", null); } writer.endElement("input"); writeClientWindowField(ctx, writer); writeRenderKitIdField(ctx, writer); } }
/** * @see javax.faces.view.ViewDeclarationLanguage#renderView(javax.faces.context.FacesContext, * javax.faces.component.UIViewRoot) */ public void renderView(FacesContext context, UIViewRoot view) throws IOException { // suppress rendering if "rendered" property on the component is // false if (!view.isRendered() || context.getResponseComplete()) { return; } ExternalContext extContext = context.getExternalContext(); if (!Util.isViewPopulated(context, view)) { buildView(context, view); } // set up the ResponseWriter RenderKitFactory renderFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); RenderKit renderKit = renderFactory.getRenderKit(context, view.getRenderKitId()); ResponseWriter oldWriter = context.getResponseWriter(); WriteBehindStateWriter stateWriter = new WriteBehindStateWriter( extContext.getResponseOutputWriter(), context, responseBufferSize); ResponseWriter newWriter; if (null != oldWriter) { newWriter = oldWriter.cloneWithWriter(stateWriter); } else { newWriter = renderKit.createResponseWriter( stateWriter, null, extContext.getRequestCharacterEncoding()); } context.setResponseWriter(newWriter); // Don't call startDoc and endDoc on a partial response if (context.getPartialViewContext().isPartialRequest()) { doRenderView(context, view); try { extContext.getFlash().doPostPhaseActions(context); } catch (UnsupportedOperationException uoe) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine( "ExternalContext.getFlash() throw UnsupportedOperationException -> Flash unavailable"); } } } else { // render the view to the response newWriter.startDocument(); doRenderView(context, view); try { extContext.getFlash().doPostPhaseActions(context); } catch (UnsupportedOperationException uoe) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine( "ExternalContext.getFlash() throw UnsupportedOperationException -> Flash unavailable"); } } newWriter.endDocument(); } // replace markers in the body content and write it to response. // flush directly to the response if (stateWriter.stateWritten()) { stateWriter.flushToWriter(); } // clear the ThreadLocal reference. stateWriter.release(); if (null != oldWriter) { context.setResponseWriter(oldWriter); } // write any AFTER_VIEW_CONTENT to the response // side effect: AFTER_VIEW_CONTENT removed ViewHandlerResponseWrapper wrapper = (ViewHandlerResponseWrapper) RequestStateManager.remove(context, RequestStateManager.AFTER_VIEW_CONTENT); if (null != wrapper) { wrapper.flushToWriter( extContext.getResponseOutputWriter(), extContext.getResponseCharacterEncoding()); } extContext.responseFlushBuffer(); }