/* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.myfaces.taglib.core; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.myfaces.application.MyfacesStateManager; import org.apache.myfaces.application.jsp.JspViewHandlerImpl; import org.apache.myfaces.shared_impl.renderkit.html.HtmlLinkRendererBase; import org.apache.myfaces.shared_impl.util.LocaleUtils; import javax.faces.application.StateManager; import javax.faces.component.UIComponent; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.el.ValueBinding; import javax.faces.webapp.UIComponentBodyTag; import javax.faces.webapp.UIComponentTag; import javax.servlet.ServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.jstl.core.Config; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTag; import java.io.IOException; import java.util.Locale; /** * @author Manfred Geiler (latest modification by $Author$) * @version $Revision$ $Date$ */ public class ViewTag extends UIComponentBodyTag { private static final Log log = LogFactory.getLog(ViewTag.class); public String getComponentType() { return UIViewRoot.COMPONENT_TYPE; } public String getRendererType() { return null; } private String _locale; public void setLocale(String locale) { _locale = locale; } public int doStartTag() throws JspException { if (log.isTraceEnabled()) log.trace("entering ViewTag.doStartTag"); super.doStartTag(); FacesContext facesContext = FacesContext.getCurrentInstance(); ResponseWriter responseWriter = facesContext.getResponseWriter(); try { responseWriter.startDocument(); } catch (IOException e) { log.error("Error writing startDocument", e); throw new JspException(e); } if (log.isTraceEnabled()) log.trace("leaving ViewTag.doStartTag"); return BodyTag.EVAL_BODY_BUFFERED; } protected boolean isSuppressed() { return true; } public int doEndTag() throws JspException { if (log.isTraceEnabled()) log.trace("entering ViewTag.doEndTag"); FacesContext facesContext = FacesContext.getCurrentInstance(); ResponseWriter responseWriter = facesContext.getResponseWriter(); try { responseWriter.endDocument(); } catch (IOException e) { log.error("Error writing endDocument", e); throw new JspException(e); } if (log.isTraceEnabled()) log.trace("leaving ViewTag.doEndTag"); return super.doEndTag(); } public int doAfterBody() throws JspException { if (log.isTraceEnabled()) log.trace("entering ViewTag.doAfterBody"); try { BodyContent bodyContent = getBodyContent(); if (bodyContent != null) { FacesContext facesContext = FacesContext.getCurrentInstance(); StateManager stateManager = facesContext.getApplication().getStateManager(); StateManager.SerializedView serializedView = stateManager.saveSerializedView(facesContext); if (serializedView != null) { //until now we have written to a buffer ResponseWriter bufferWriter = facesContext.getResponseWriter(); bufferWriter.flush(); //now we switch to real output ResponseWriter realWriter = bufferWriter.cloneWithWriter(getPreviousOut()); facesContext.setResponseWriter(realWriter); String bodyStr = bodyContent.getString(); if ( stateManager.isSavingStateInClient(facesContext) ) { int form_marker = bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER); int url_marker = bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER); int lastMarkerEnd = 0; while (form_marker != -1 || url_marker != -1) { if (url_marker == -1 || (form_marker != -1 && form_marker < url_marker)) { //replace form_marker realWriter.write(bodyStr, lastMarkerEnd, form_marker - lastMarkerEnd); stateManager.writeState(facesContext, serializedView); lastMarkerEnd = form_marker + JspViewHandlerImpl.FORM_STATE_MARKER_LEN; form_marker = bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER, lastMarkerEnd); } else { //replace url_marker realWriter.write(bodyStr, lastMarkerEnd, url_marker - lastMarkerEnd); if (stateManager instanceof MyfacesStateManager) { ((MyfacesStateManager)stateManager).writeStateAsUrlParams(facesContext, serializedView); } else { log.error("Current StateManager is no MyfacesStateManager and does not support saving state in url parameters."); } lastMarkerEnd = url_marker + HtmlLinkRendererBase.URL_STATE_MARKER_LEN; url_marker = bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER, lastMarkerEnd); } } realWriter.write(bodyStr, lastMarkerEnd, bodyStr.length() - lastMarkerEnd); } else { realWriter.write( bodyStr ); } } else { bodyContent.writeOut(getPreviousOut()); } } } catch (IOException e) { log.error("Error writing body content", e); throw new JspException(e); } if (log.isTraceEnabled()) log.trace("leaving ViewTag.doAfterBody"); return super.doAfterBody(); } protected void setProperties(UIComponent component) { super.setProperties(component); if (_locale != null) { Locale locale; if (UIComponentTag.isValueReference(_locale)) { FacesContext context = FacesContext.getCurrentInstance(); ValueBinding vb = context.getApplication().createValueBinding(_locale); Object localeValue = vb.getValue(context); if (localeValue instanceof Locale) { locale = (Locale) localeValue; } else if (localeValue instanceof String) { locale = LocaleUtils.toLocale((String) localeValue); } else { if (localeValue != null) { throw new IllegalArgumentException( "Locale or String class expected. Expression: " + _locale + ". Return class: " + localeValue.getClass().getName()); } else { throw new IllegalArgumentException( "Locale or String class expected. Expression: " + _locale + ". Return value null"); } } } else { locale = LocaleUtils.toLocale(_locale); } ((UIViewRoot)component).setLocale(locale); Config.set((ServletRequest)getFacesContext().getExternalContext().getRequest(), Config.FMT_LOCALE, locale); } } }