1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import javax.faces.application.ViewHandler;
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.UIForm;
30 import javax.faces.component.behavior.ClientBehavior;
31 import javax.faces.component.behavior.ClientBehaviorHolder;
32 import javax.faces.component.html.HtmlForm;
33 import javax.faces.context.FacesContext;
34 import javax.faces.context.ResponseWriter;
35
36 import org.apache.myfaces.shared.config.MyfacesConfig;
37 import org.apache.myfaces.shared.renderkit.JSFAttr;
38 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
39 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
40
41
42
43
44
45
46
47 public class HtmlFormRendererBase
48 extends HtmlRenderer
49 {
50
51 private static final String FORM_TARGET = HTML.FORM_ELEM;
52 private static final String HIDDEN_SUBMIT_INPUT_SUFFIX = "_SUBMIT";
53 private static final String HIDDEN_SUBMIT_INPUT_VALUE = "1";
54
55 private static final String HIDDEN_COMMAND_INPUTS_SET_ATTR
56 = UIForm.class.getName() + ".org.apache.myfaces.HIDDEN_COMMAND_INPUTS_SET";
57
58 private static final String SCROLL_HIDDEN_INPUT = "org.apache.myfaces.SCROLL_HIDDEN_INPUT";
59
60 public void encodeBegin(FacesContext facesContext, UIComponent component)
61 throws IOException
62 {
63 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIForm.class);
64
65 UIForm htmlForm = (UIForm)component;
66
67 ResponseWriter writer = facesContext.getResponseWriter();
68 String clientId = htmlForm.getClientId(facesContext);
69 String acceptCharset = getAcceptCharset(facesContext, htmlForm);
70 String actionURL = getActionUrl(facesContext, htmlForm);
71 String method = getMethod(facesContext, htmlForm);
72
73 Map<String, List<ClientBehavior>> behaviors = null;
74 if (component instanceof ClientBehaviorHolder)
75 {
76 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
77 if (!behaviors.isEmpty())
78 {
79 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
80 }
81 }
82
83 writer.startElement(HTML.FORM_ELEM, htmlForm);
84 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
85 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
86 writer.writeAttribute(HTML.METHOD_ATTR, method, null);
87 if (acceptCharset != null)
88 {
89 writer.writeAttribute(HTML.ACCEPT_CHARSET_ATTR, acceptCharset, null);
90 }
91 String encodedActionURL = facesContext.getExternalContext().encodeActionURL(actionURL);
92
93 writer.writeURIAttribute(HTML.ACTION_ATTR,
94 encodedActionURL,
95 null);
96
97 if (htmlForm instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
98 facesContext.getExternalContext()))
99 {
100 behaviors = ((ClientBehaviorHolder) htmlForm).getClientBehaviors();
101 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
102 {
103 CommonPropertyUtils.renderEventProperties(writer,
104 CommonPropertyUtils.getCommonPropertiesMarked(htmlForm), htmlForm);
105 }
106 else
107 {
108 if (isCommonEventsOptimizationEnabled(facesContext))
109 {
110 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
111 CommonPropertyUtils.getCommonPropertiesMarked(htmlForm),
112 CommonEventUtils.getCommonEventsMarked(htmlForm), htmlForm, behaviors);
113 }
114 else
115 {
116 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, htmlForm, behaviors);
117 }
118 }
119 if (isCommonPropertiesOptimizationEnabled(facesContext))
120 {
121 CommonPropertyUtils.renderCommonPassthroughPropertiesWithoutEvents(writer,
122 CommonPropertyUtils.getCommonPropertiesMarked(component), component);
123 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_ATTRIBUTES);
124 }
125 else
126 {
127 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm,
128 HTML.FORM_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
129 }
130 }
131 else
132 {
133 if (isCommonPropertiesOptimizationEnabled(facesContext))
134 {
135 CommonPropertyUtils.renderCommonPassthroughProperties(writer,
136 CommonPropertyUtils.getCommonPropertiesMarked(component), component);
137 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_ATTRIBUTES);
138 }
139 else
140 {
141 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES);
142 }
143 }
144
145 writer.write("");
146
147 String encodedPartialActionURL = facesContext.getExternalContext().encodePartialActionURL(actionURL);
148
149 if (encodedActionURL != null && encodedPartialActionURL != null
150 && (!encodedActionURL.equals(encodedPartialActionURL)))
151 {
152 HtmlRendererUtils.renderHiddenInputField(writer, "javax.faces.encodedURL", encodedPartialActionURL);
153 }
154
155
156
157
158 beforeFormElementsStart(facesContext, component);
159 afterFormElementsStart(facesContext, component);
160 }
161
162 protected String getActionUrl(FacesContext facesContext, UIForm form)
163 {
164 return getActionUrl(facesContext);
165 }
166
167 protected String getMethod(FacesContext facesContext, UIForm form)
168 {
169 return "post";
170 }
171
172 protected String getAcceptCharset(FacesContext facesContext, UIForm form )
173 {
174 return (String)form.getAttributes().get( JSFAttr.ACCEPTCHARSET_ATTR );
175 }
176
177 public void encodeEnd(FacesContext facesContext, UIComponent component)
178 throws IOException
179 {
180 ResponseWriter writer = facesContext.getResponseWriter();
181
182 beforeFormElementsEnd(facesContext, component);
183
184
185 Set set = (Set) facesContext.getExternalContext().getRequestMap().get(
186 getHiddenCommandInputsSetName(facesContext, component));
187 if (set != null && !set.isEmpty())
188 {
189 HtmlRendererUtils.renderHiddenCommandFormParams(writer, set);
190
191 String target;
192 if (component instanceof HtmlForm)
193 {
194 target = ((HtmlForm)component).getTarget();
195 }
196 else
197 {
198 target = (String)component.getAttributes().get(HTML.TARGET_ATTR);
199 }
200 HtmlRendererUtils.renderClearHiddenCommandFormParamsFunction(writer,
201 component.getClientId(facesContext),
202 set,
203 target);
204 }
205
206
207 writer.startElement(HTML.INPUT_ELEM, component);
208 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
209 writer.writeAttribute(HTML.NAME_ATTR, component.getClientId(facesContext) +
210 HIDDEN_SUBMIT_INPUT_SUFFIX, null);
211 writer.writeAttribute(HTML.VALUE_ATTR, HIDDEN_SUBMIT_INPUT_VALUE, null);
212 writer.endElement(HTML.INPUT_ELEM);
213
214 renderScrollHiddenInputIfNecessary(component, facesContext, writer);
215
216
217
218
219 ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
220 viewHandler.writeState(facesContext);
221
222 afterFormElementsEnd(facesContext, component);
223
224 List<UIComponent> componentResources = facesContext.getViewRoot().getComponentResources(facesContext,
225 FORM_TARGET);
226
227 for (int i = 0, size = componentResources.size(); i < size; i++)
228 {
229 UIComponent child = componentResources.get(i);
230 child.encodeAll (facesContext);
231 }
232
233 writer.endElement(HTML.FORM_ELEM);
234 }
235
236 private static String getHiddenCommandInputsSetName(FacesContext facesContext, UIComponent form)
237 {
238 StringBuilder buf = new StringBuilder(HIDDEN_COMMAND_INPUTS_SET_ATTR.length()+20);
239 buf.append(HIDDEN_COMMAND_INPUTS_SET_ATTR);
240 buf.append("_");
241 buf.append(form.getClientId(facesContext));
242 return buf.toString();
243 }
244
245 private static String getScrollHiddenInputName(FacesContext facesContext, UIComponent form)
246 {
247 StringBuilder buf = new StringBuilder(SCROLL_HIDDEN_INPUT.length()+20);
248 buf.append(SCROLL_HIDDEN_INPUT);
249 buf.append("_");
250 buf.append(form.getClientId(facesContext));
251 return buf.toString();
252 }
253
254
255 public void decode(FacesContext facesContext, UIComponent component)
256 {
257 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIForm.class);
258
259
260
261
262
263
264
265
266 UIForm htmlForm = (UIForm)component;
267
268 Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
269 String submittedValue = (String)paramMap.get(component.getClientId(facesContext) +
270 HIDDEN_SUBMIT_INPUT_SUFFIX);
271 if (submittedValue != null && submittedValue.equals(HIDDEN_SUBMIT_INPUT_VALUE))
272 {
273 htmlForm.setSubmitted(true);
274 }
275 else
276 {
277 htmlForm.setSubmitted(false);
278 }
279
280 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
281 }
282
283
284 public static void addHiddenCommandParameter(FacesContext facesContext, UIComponent form, String paramName)
285 {
286 Set set = (Set) facesContext.getExternalContext().getRequestMap().get(
287 getHiddenCommandInputsSetName(facesContext, form));
288 if (set == null)
289 {
290 set = new HashSet();
291 facesContext.getExternalContext().getRequestMap().put(
292 getHiddenCommandInputsSetName(facesContext, form), set);
293 }
294 set.add(paramName);
295 }
296
297 public static void renderScrollHiddenInputIfNecessary(
298 UIComponent form, FacesContext facesContext, ResponseWriter writer)
299 throws IOException
300 {
301 if (form == null)
302 {
303 return;
304 }
305
306 if (facesContext.getExternalContext().getRequestMap().get(
307 getScrollHiddenInputName(facesContext, form)) == null)
308 {
309 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll())
310 {
311 HtmlRendererUtils.renderAutoScrollHiddenInput(facesContext, writer);
312 }
313 facesContext.getExternalContext().getRequestMap().put(getScrollHiddenInputName(
314 facesContext, form), Boolean.TRUE);
315 }
316 }
317
318 private String getAcceptCharset(UIComponent uiComponent)
319 {
320 if (uiComponent instanceof HtmlForm)
321 {
322 return ((HtmlForm)uiComponent).getAcceptcharset();
323 }
324 return (String)uiComponent.getAttributes().get(JSFAttr.ACCEPTCHARSET_ATTR);
325 }
326
327
328
329
330
331 protected void beforeFormElementsStart(FacesContext facesContext, UIComponent component)
332 throws IOException
333 {
334
335 }
336
337
338
339
340
341 protected void afterFormElementsStart(FacesContext facesContext, UIComponent component)
342 throws IOException
343 {
344
345 }
346
347
348
349
350
351 protected void beforeFormElementsEnd(FacesContext facesContext, UIComponent component)
352 throws IOException
353 {
354
355 }
356
357
358
359
360
361 protected void afterFormElementsEnd(FacesContext facesContext, UIComponent component)
362 throws IOException
363 {
364
365 }
366 }