Source code: org/apache/myfaces/taglib/core/ViewTag.java
1 /*
2 * Copyright 2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.myfaces.taglib.core;
17
18 import org.apache.myfaces.application.MyfacesStateManager;
19 import org.apache.myfaces.application.jsp.JspViewHandlerImpl;
20 import org.apache.myfaces.renderkit.html.HtmlLinkRendererBase;
21 import org.apache.myfaces.util.LocaleUtils;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import javax.faces.application.StateManager;
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.UIViewRoot;
29 import javax.faces.context.FacesContext;
30 import javax.faces.context.ResponseWriter;
31 import javax.faces.el.ValueBinding;
32 import javax.faces.webapp.UIComponentBodyTag;
33 import javax.faces.webapp.UIComponentTag;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.jsp.JspException;
36 import javax.servlet.jsp.jstl.core.Config;
37 import javax.servlet.jsp.tagext.BodyContent;
38 import javax.servlet.jsp.tagext.BodyTag;
39 import java.io.IOException;
40 import java.util.Locale;
41
42 /**
43 * @author Manfred Geiler (latest modification by $Author: grantsmith $)
44 * @version $Revision: 169655 $ $Date: 2005-05-11 12:45:06 -0400 (Wed, 11 May 2005) $
45 */
46 public class ViewTag
47 extends UIComponentBodyTag
48 {
49 private static final Log log = LogFactory.getLog(ViewTag.class);
50
51 public String getComponentType()
52 {
53 return UIViewRoot.COMPONENT_TYPE;
54 }
55
56 public String getRendererType()
57 {
58 return null;
59 }
60
61 private String _locale;
62
63 public void setLocale(String locale)
64 {
65 _locale = locale;
66 }
67
68 public int doStartTag() throws JspException
69 {
70 if (log.isTraceEnabled()) log.trace("entering ViewTag.doStartTag");
71 super.doStartTag();
72 FacesContext facesContext = FacesContext.getCurrentInstance();
73 ResponseWriter responseWriter = facesContext.getResponseWriter();
74 try
75 {
76 responseWriter.startDocument();
77 }
78 catch (IOException e)
79 {
80 log.error("Error writing startDocument", e);
81 throw new JspException(e);
82 }
83
84 StateManager stateManager = facesContext.getApplication().getStateManager();
85 if (stateManager.isSavingStateInClient(facesContext))
86 {
87 if (log.isTraceEnabled()) log.trace("leaving ViewTag.doStartTag");
88 return BodyTag.EVAL_BODY_BUFFERED;
89 }
90 else
91 {
92 if (log.isTraceEnabled()) log.trace("leaving ViewTag.doStartTag");
93 return BodyTag.EVAL_BODY_INCLUDE;
94 }
95 }
96
97 protected boolean isSuppressed()
98 {
99 return true;
100 }
101
102 public int doEndTag() throws JspException
103 {
104 if (log.isTraceEnabled()) log.trace("entering ViewTag.doEndTag");
105 FacesContext facesContext = FacesContext.getCurrentInstance();
106 ResponseWriter responseWriter = facesContext.getResponseWriter();
107
108 try
109 {
110 responseWriter.endDocument();
111 }
112 catch (IOException e)
113 {
114 log.error("Error writing endDocument", e);
115 throw new JspException(e);
116 }
117
118 StateManager stateManager = facesContext.getApplication().getStateManager();
119 if (!stateManager.isSavingStateInClient(facesContext))
120 {
121 //save state in server
122 stateManager.saveSerializedView(facesContext);
123 }
124
125 if (log.isTraceEnabled()) log.trace("leaving ViewTag.doEndTag");
126 return super.doEndTag();
127 }
128
129 public int doAfterBody() throws JspException
130 {
131 if (log.isTraceEnabled()) log.trace("entering ViewTag.doAfterBody");
132 try
133 {
134 BodyContent bodyContent = getBodyContent();
135 if (bodyContent != null)
136 {
137 FacesContext facesContext = FacesContext.getCurrentInstance();
138 StateManager stateManager = facesContext.getApplication().getStateManager();
139 StateManager.SerializedView serializedView
140 = stateManager.saveSerializedView(facesContext);
141 if (serializedView != null)
142 {
143 //until now we have written to a buffer
144 ResponseWriter bufferWriter = facesContext.getResponseWriter();
145 bufferWriter.flush();
146 //now we switch to real output
147 ResponseWriter realWriter = bufferWriter.cloneWithWriter(getPreviousOut());
148 facesContext.setResponseWriter(realWriter);
149
150 String bodyStr = bodyContent.getString();
151 int form_marker = bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER);
152 int url_marker = bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER);
153 int lastMarkerEnd = 0;
154 while (form_marker != -1 || url_marker != -1)
155 {
156 if (url_marker == -1 || (form_marker != -1 && form_marker < url_marker))
157 {
158 //replace form_marker
159 realWriter.write(bodyStr, lastMarkerEnd, form_marker - lastMarkerEnd);
160 stateManager.writeState(facesContext, serializedView);
161 lastMarkerEnd = form_marker + JspViewHandlerImpl.FORM_STATE_MARKER_LEN;
162 form_marker = bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER, lastMarkerEnd);
163 }
164 else
165 {
166 //replace url_marker
167 realWriter.write(bodyStr, lastMarkerEnd, url_marker - lastMarkerEnd);
168 if (stateManager instanceof MyfacesStateManager)
169 {
170 ((MyfacesStateManager)stateManager).writeStateAsUrlParams(facesContext,
171 serializedView);
172 }
173 else
174 {
175 log.error("Current StateManager is no MyfacesStateManager and does not support saving state in url parameters.");
176 }
177 lastMarkerEnd = url_marker + HtmlLinkRendererBase.URL_STATE_MARKER_LEN;
178 url_marker = bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER, lastMarkerEnd);
179 }
180 }
181 realWriter.write(bodyStr, lastMarkerEnd, bodyStr.length() - lastMarkerEnd);
182 }
183 else
184 {
185 bodyContent.writeOut(getPreviousOut());
186 }
187 }
188 }
189 catch (IOException e)
190 {
191 log.error("Error writing body content", e);
192 throw new JspException(e);
193 }
194 if (log.isTraceEnabled()) log.trace("leaving ViewTag.doAfterBody");
195 return super.doAfterBody();
196 }
197
198 protected void setProperties(UIComponent component)
199 {
200 super.setProperties(component);
201
202 if (_locale != null)
203 {
204 Locale locale;
205 if (UIComponentTag.isValueReference(_locale))
206 {
207 FacesContext context = FacesContext.getCurrentInstance();
208 ValueBinding vb = context.getApplication().createValueBinding(_locale);
209 Object localeValue = vb.getValue(context);
210 if (localeValue instanceof Locale)
211 {
212 locale = (Locale) localeValue;
213 }
214 else if (localeValue instanceof String)
215 {
216 locale = LocaleUtils.toLocale((String) localeValue);
217 }
218 else
219 {
220 throw new IllegalArgumentException(
221 "Locale or String class expected. Expression: " + _locale
222 + ". Return class: " + localeValue.getClass().getName());
223 }
224 }
225 else
226 {
227 locale = LocaleUtils.toLocale(_locale);
228 }
229 ((UIViewRoot)component).setLocale(locale);
230 Config.set((ServletRequest)getFacesContext().getExternalContext().getRequest(),
231 Config.FMT_LOCALE,
232 locale);
233 }
234 }
235 }