/** * Obtain and return the {@link ResponseStateManager} for the specified #renderKitId. * * @param context the {@link FacesContext} of the current request * @param renderKitId {@link RenderKit} ID * @return the {@link ResponseStateManager} for the specified #renderKitId * @throws FacesException if an exception occurs while trying to obtain the <code> * ResponseStateManager</code> */ public static ResponseStateManager getResponseStateManager( FacesContext context, String renderKitId) throws FacesException { assert (null != renderKitId); assert (null != context); RenderKit renderKit = context.getRenderKit(); if (renderKit == null) { // check request scope for a RenderKitFactory implementation RenderKitFactory factory = (RenderKitFactory) RequestStateManager.get(context, RequestStateManager.RENDER_KIT_IMPL_REQ); if (factory != null) { renderKit = factory.getRenderKit(context, renderKitId); } else { factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); if (factory == null) { throw new IllegalStateException(); } else { RequestStateManager.set(context, RequestStateManager.RENDER_KIT_IMPL_REQ, factory); } renderKit = factory.getRenderKit(context, renderKitId); } } return renderKit.getResponseStateManager(); }
private void applyCompositeComponent(FaceletContext ctx, UIComponent c) throws IOException { FacesContext facesContext = ctx.getFacesContext(); FaceletFactory factory = (FaceletFactory) RequestStateManager.get(facesContext, RequestStateManager.FACELET_FACTORY); VariableMapper orig = ctx.getVariableMapper(); UIPanel facetComponent; if (ComponentHandler.isNew(c)) { facetComponent = (UIPanel) facesContext.getApplication().createComponent("javax.faces.Panel"); facetComponent.setRendererType("javax.faces.Group"); c.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent); } else { facetComponent = (UIPanel) c.getFacets().get(UIComponent.COMPOSITE_FACET_NAME); } assert (null != facetComponent); try { Facelet f = factory.getFacelet(ccResource.getURL()); VariableMapper wrapper = new VariableMapperWrapper(orig) { @Override public ValueExpression resolveVariable(String variable) { return super.resolveVariable(variable); } }; ctx.setVariableMapper(wrapper); f.apply(facesContext, facetComponent); } finally { ctx.setVariableMapper(orig); } }
/** * @return Stack of UIComponentClassicTagBase instances, each of which is a "view" tag. The bottom * most element on the stack is the ViewTag itself. Subsequent instances are SubviewTag * instances. */ static Stack<UIComponentClassicTagBase> getViewTagStack() { FacesContext ctx = FacesContext.getCurrentInstance(); //noinspection unchecked Stack<UIComponentClassicTagBase> result = (Stack<UIComponentClassicTagBase>) RequestStateManager.get(ctx, RequestStateManager.VIEWTAG_STACK_ATTR_NAME); if (result == null) { result = new Stack<UIComponentClassicTagBase>(); RequestStateManager.set(ctx, RequestStateManager.VIEWTAG_STACK_ATTR_NAME, result); } return result; }
@Override public BeanInfo getComponentMetadata(FacesContext context, Resource ccResource) { // PENDING this implementation is terribly wasteful. // Must find a better way. CompositeComponentBeanInfo result; FaceletContext ctx = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); FaceletFactory factory = (FaceletFactory) RequestStateManager.get(context, RequestStateManager.FACELET_FACTORY); VariableMapper orig = ctx.getVariableMapper(); UIComponent tmp = context.getApplication().createComponent("javax.faces.NamingContainer"); UIPanel facetComponent = (UIPanel) context.getApplication().createComponent("javax.faces.Panel"); facetComponent.setRendererType("javax.faces.Group"); tmp.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent); // We have to put the resource in here just so the classes that eventually // get called by facelets have access to it. tmp.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, ccResource); Facelet f; try { f = factory.getFacelet(ccResource.getURL()); VariableMapper wrapper = new VariableMapperWrapper(orig) { @Override public ValueExpression resolveVariable(String variable) { return super.resolveVariable(variable); } }; ctx.setVariableMapper(wrapper); context.getAttributes().put(IS_BUILDING_METADATA, Boolean.TRUE); f.apply(context, facetComponent); } catch (Exception e) { if (e instanceof FacesException) { throw (FacesException) e; } else { throw new FacesException(e); } } finally { context.getAttributes().remove(IS_BUILDING_METADATA); ctx.setVariableMapper(orig); } result = (CompositeComponentBeanInfo) tmp.getAttributes().get(UIComponent.BEANINFO_KEY); return result; }
/** * @see {@link javax.faces.render.ResponseStateManager#getState(javax.faces.context.FacesContext, * String)} */ @Override public Object getState(FacesContext context, String viewId) { Object state = RequestStateManager.get(context, RequestStateManager.FACES_VIEW_STATE); if (state == null) { try { state = helper.getState(context, viewId); if (state != null) { RequestStateManager.set(context, RequestStateManager.FACES_VIEW_STATE, state); } } catch (IOException e) { throw new FacesException(e); } } return state; }
/** See the class javadocs. */ public Object resolveVariable(FacesContext context, String name) throws EvaluationException { Object result = null; ELResolverChainType type = null; Object valueObject = RequestStateManager.get(context, RequestStateManager.EL_RESOLVER_CHAIN_TYPE_NAME); if (null != valueObject && valueObject instanceof ELResolverChainType) { type = (ELResolverChainType) valueObject; } if (ELResolverChainType.JSP == type) { ValueExpression ve = context .getApplication() .getExpressionFactory() .createValueExpression(context.getELContext(), "#{" + name + "}", Object.class); result = ve.getValue(context.getELContext()); } else if (ELResolverChainType.Faces == type) { ELResolver elr = context.getApplication().getELResolver(); result = elr.getValue(context.getELContext(), null, name); } return result; }
/** * <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); } }
/** * Execute the target view. If the HTTP status code range is not 2xx, then return true to indicate * the response should be immediately flushed by the caller so that conditions such as 404 are * properly handled. * * @param context the <code>FacesContext</code> for the current request * @param viewToExecute the view to build * @return <code>true</code> if the response should be immediately flushed to the client, * otherwise <code>false</code> * @throws java.io.IOException if an error occurs executing the page */ private boolean executePageToBuildView(FacesContext context, UIViewRoot viewToExecute) throws IOException { if (null == context) { String message = MessageUtils.getExceptionMessageString( MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context"); throw new NullPointerException(message); } if (null == viewToExecute) { String message = MessageUtils.getExceptionMessageString( MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "viewToExecute"); throw new NullPointerException(message); } ExternalContext extContext = context.getExternalContext(); if ("/*".equals(RequestStateManager.get(context, RequestStateManager.INVOCATION_PATH))) { throw new FacesException( MessageUtils.getExceptionMessageString(MessageUtils.FACES_SERVLET_MAPPING_INCORRECT_ID)); } String requestURI = viewToExecute.getViewId(); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("About to execute view " + requestURI); } // update the JSTL locale attribute in request scope so that JSTL // picks up the locale from viewRoot. This attribute must be updated // before the JSTL setBundle tag is called because that is when the // new LocalizationContext object is created based on the locale. if (extContext.getRequest() instanceof ServletRequest) { Config.set( (ServletRequest) extContext.getRequest(), Config.FMT_LOCALE, context.getViewRoot().getLocale()); } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Before dispacthMessage to viewId " + requestURI); } // save the original response Object originalResponse = extContext.getResponse(); // replace the response with our wrapper ViewHandlerResponseWrapper wrapped = getWrapper(extContext); extContext.setResponse(wrapped); try { // build the view by executing the page extContext.dispatch(requestURI); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("After dispacthMessage to viewId " + requestURI); } } finally { // replace the original response extContext.setResponse(originalResponse); } // Follow the JSTL 1.2 spec, section 7.4, // on handling status codes on a forward if (wrapped.getStatus() < 200 || wrapped.getStatus() > 299) { // flush the contents of the wrapper to the response // this is necessary as the user may be using a custom // error page - this content should be propagated wrapped.flushContentToWrappedResponse(); return true; } // Put the AFTER_VIEW_CONTENT into request scope // temporarily RequestStateManager.set(context, RequestStateManager.AFTER_VIEW_CONTENT, wrapped); return false; }