1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.struts.faces.renderer;
18
19
20 import java.io.IOException;
21 import java.util.Map;
22
23 import javax.faces.component.NamingContainer;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.faces.context.ResponseWriter;
27 import javax.servlet.http.HttpSession;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.struts.Globals;
32 import org.apache.struts.config.ActionConfig;
33 import org.apache.struts.config.ModuleConfig;
34 import org.apache.struts.faces.component.FormComponent;
35
36
37 /***
38 * <p><code>Renderer</code> implementation for the <code>form</code> tag
39 * from the <em>Struts-Faces Integration Library</em>.</p>
40 *
41 * @version $Rev: 421138 $ $Date: 2006-07-11 22:41:40 -0700 (Tue, 11 Jul 2006) $
42 */
43
44 public class FormRenderer extends AbstractRenderer {
45
46
47
48
49
50 /***
51 * <p>The <code>Log</code> instance for this class.</p>
52 */
53 private static Log log = LogFactory.getLog(FormRenderer.class);
54
55
56
57
58
59 /***
60 * <p>Perform setup processing that will be required for decoding the
61 * incoming request.</p>
62 *
63 * @param context FacesContext for the request we are processing
64 * @param component UIComponent to be processed
65 *
66 * @exception NullPointerException if <code>context</code>
67 * or <code>component</code> is null
68 */
69 public void decode(FacesContext context, UIComponent component) {
70
71 if ((context == null) || (component == null)) {
72 throw new NullPointerException();
73 }
74 String clientId = component.getClientId(context);
75 Map map = context.getExternalContext().getRequestParameterMap();
76 if (log.isDebugEnabled()) {
77 log.debug("decode(" + clientId + ") --> " +
78 map.containsKey(clientId));
79 }
80 component.getAttributes().put
81 ("submitted",
82 map.containsKey(clientId) ? Boolean.TRUE : Boolean.FALSE);
83
84 }
85
86
87 private static String passThrough[] =
88 { "enctype", "method", "onreset", "onsubmit", "style", "target", };
89
90
91 /***
92 * <p>Render the beginning of an HTML <code><form></code>
93 * control.</p>
94 *
95 * @param context FacesContext for the request we are processing
96 * @param component UIComponent to be rendered
97 *
98 * @exception IOException if an input/output error occurs while rendering
99 * @exception NullPointerException if <code>context</code>
100 * or <code>component</code> is null
101 */
102 public void encodeBegin(FacesContext context, UIComponent component)
103 throws IOException {
104
105 if ((context == null) || (component == null)) {
106 throw new NullPointerException();
107 }
108
109
110 FormComponent form = (FormComponent) component;
111 String action = form.getAction();
112 ModuleConfig moduleConfig = form.lookupModuleConfig(context);
113 ActionConfig actionConfig = moduleConfig.findActionConfig(action);
114 if (actionConfig == null) {
115 throw new IllegalArgumentException("Cannot find action '" +
116 action + "' configuration");
117 }
118 String beanName = actionConfig.getAttribute();
119 if (beanName != null) {
120 form.getAttributes().put("beanName", beanName);
121 }
122
123
124 String clientId = component.getClientId(context);
125 if (log.isDebugEnabled()) {
126 log.debug("encodeBegin(" + clientId + ")");
127 }
128 String styleClass =
129 (String) component.getAttributes().get("styleClass");
130
131
132 ResponseWriter writer = context.getResponseWriter();
133 writer.startElement("form", form);
134 writer.writeAttribute("id", clientId, "clientId");
135 if (beanName != null) {
136 writer.writeAttribute("name", beanName, null);
137 }
138 writer.writeAttribute("action", action(context, component), "action");
139 if (styleClass != null) {
140 writer.writeAttribute("class", styleClass, "styleClass");
141 }
142 if (component.getAttributes().get("method") == null) {
143 writer.writeAttribute("method", "post", null);
144 }
145 renderPassThrough(context, component, writer, passThrough);
146 writer.writeText("\n", null);
147
148
149 writer.startElement("input", form);
150 writer.writeAttribute("type", "hidden", null);
151 writer.writeAttribute("name", clientId, null);
152 writer.writeAttribute("value", clientId, null);
153 writer.endElement("input");
154 writer.writeText("\n", null);
155
156
157 HttpSession session = (HttpSession)
158 context.getExternalContext().getSession(false);
159 if (session != null) {
160 String token = (String)
161 session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
162 if (token != null) {
163 writer.startElement("input", form);
164 writer.writeAttribute("type", "hidden", null);
165 writer.writeAttribute
166 ("name", "org.apache.struts.taglib.html.TOKEN", null);
167 writer.writeAttribute("value", token, null);
168 writer.endElement("input");
169 writer.writeText("\n", null);
170 }
171 }
172
173
174 if (component instanceof FormComponent) {
175 ((FormComponent) component).createActionForm(context);
176 }
177
178 }
179
180
181 /***
182 * <p>Render the ending of an HTML <code><form></code>
183 * control.</p>
184 *
185 * @param context FacesContext for the request we are processing
186 * @param component UIComponent to be rendered
187 *
188 * @exception IOException if an input/output error occurs while rendering
189 * @exception NullPointerException if <code>context</code>
190 * or <code>component</code> is null
191 */
192 public void encodeEnd(FacesContext context, UIComponent component)
193 throws IOException {
194
195 if ((context == null) || (component == null)) {
196 throw new NullPointerException();
197 }
198 String clientId = component.getClientId(context);
199 if (log.isDebugEnabled()) {
200 log.debug("encodeEnd(" + clientId + ")");
201 }
202 ResponseWriter writer = context.getResponseWriter();
203
204
205 writer.startElement("input", component);
206 writer.writeAttribute("type", "hidden", null);
207 writer.writeAttribute("name", component.getClientId(context), null);
208 writer.writeAttribute("value", component.getClientId(context), null);
209 writer.endElement("input");
210 writer.write("\n");
211
212
213 context.getApplication().getViewHandler().writeState(context);
214
215
216 writer.endElement("form");
217 writer.writeText("\n", null);
218
219
220 if (!(component instanceof FormComponent)) {
221 return;
222 }
223 String focus = (String) component.getAttributes().get("focus");
224 if (focus == null) {
225 return;
226 }
227 String focusIndex =
228 (String) component.getAttributes().get("focusIndex");
229 writer.writeText("\n", null);
230 FormComponent form = (FormComponent) component;
231 writer.startElement("script", form);
232 writer.writeAttribute("type", "text/javascript", null);
233 if (!isXhtml(component)) {
234 writer.writeAttribute("language", "JavaScript", null);
235 }
236 writer.writeText("\n", null);
237 if (!isXhtml(component)) {
238 writer.write("<!--\n");
239 }
240
241 StringBuffer sb = new StringBuffer("document.forms[\"");
242 sb.append(clientId);
243 sb.append("\"].elements[\"");
244 sb.append(component.getClientId(context));
245 sb.append(NamingContainer.SEPARATOR_CHAR);
246 sb.append(focus);
247 sb.append("\"]");
248 String focusControl = sb.toString();
249
250 writer.write(" var focusControl = ");
251 writer.write(focusControl);
252 writer.write(";\n");
253 writer.write(" if (focusControl.type != \"hidden\") {\n");
254 writer.write(" ");
255 writer.write(focusControl);
256 if (focusIndex != null) {
257 writer.write("[");
258 writer.write(focusIndex);
259 writer.write("]");
260 }
261 writer.write(".focus();\n");
262 writer.write(" }\n");
263
264 if (!isXhtml(component)) {
265 writer.write("// -->\n");
266 }
267 writer.endElement("script");
268 writer.writeText("\n", null);
269
270 }
271
272
273
274
275
276 /***
277 * <p>Calculate and return the value to be specifed for the
278 * <code>action</action> attribute on the <code><form></code>
279 * element to be rendered.</p>
280 *
281 * @param context FacesContext for the current request
282 * @param component Component being processed
283 */
284 protected String action(FacesContext context, UIComponent component) {
285
286 String actionURL =
287 context.getApplication().getViewHandler().
288 getActionURL(context, context.getViewRoot().getViewId());
289 if (log.isTraceEnabled()) {
290 log.trace("getActionURL(" + context.getViewRoot().getViewId() +
291 ") --> " + actionURL);
292 }
293 return (context.getExternalContext().encodeActionURL(actionURL));
294
295 }
296
297
298 /***
299 * <p>Return <code>true</code> if we should render as XHTML.</p>
300 *
301 * @param component The component we are rendering
302 */
303 protected boolean isXhtml(UIComponent component) {
304
305 return (false);
306
307 }
308
309
310 }