1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts.faces.renderer;
23
24
25 import java.io.IOException;
26 import java.util.Iterator;
27
28 import javax.faces.component.NamingContainer;
29 import javax.faces.component.UICommand;
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UIForm;
32 import javax.faces.component.UIParameter;
33 import javax.faces.context.FacesContext;
34 import javax.faces.context.ResponseWriter;
35 import javax.faces.event.ActionEvent;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.struts.Globals;
40 import org.apache.struts.config.ActionConfig;
41 import org.apache.struts.config.ModuleConfig;
42
43
44
45
46
47
48
49
50
51 public class CommandLinkRenderer extends AbstractRenderer {
52
53
54
55
56
57
58
59
60 private static final String TOKEN =
61 "org_apache_struts_faces_renderer_CommandLinkRenderer";
62
63
64
65
66
67 private static Log log = LogFactory.getLog(CommandLinkRenderer.class);
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public void decode(FacesContext context, UIComponent component) {
84
85
86 if ((context == null) || (component == null)) {
87 throw new NullPointerException();
88 }
89
90
91 if (!component.isRendered() || isDisabled(component) ||
92 isReadOnly(component)) {
93 return;
94 }
95
96
97 UIForm form = null;
98 UIComponent parent = component.getParent();
99 while (parent != null) {
100 if (parent instanceof UIForm) {
101 form = (UIForm) parent;
102 break;
103 }
104 parent = parent.getParent();
105 }
106 if (form == null) {
107 log.warn("CommandLinkComponent not nested inside UIForm, ignored");
108 return;
109 }
110
111
112 String paramId = TOKEN;
113 String value = (String)
114 context.getExternalContext().getRequestParameterMap().get(paramId);
115 if ((value == null) || !value.equals(component.getClientId(context))) {
116 if (log.isTraceEnabled()) {
117 log.trace("decode(" + component.getId() + ") --> not active");
118 }
119 return;
120 }
121
122
123 if (log.isTraceEnabled()) {
124 log.trace("decode(" + component.getId() + ") --> queueEvent()");
125 }
126 component.queueEvent(new ActionEvent(component));
127
128 }
129
130
131 private static String passThrough[] =
132 { "accesskey", "charset", "dir", "hreflang", "lang", "onblur",
133
134 "onkeypress", "onkeyup", "onmousedown", "onmousemove",
135 "onmouseout", "onmouseover", "onmouseup", "rel", "rev",
136 "style", "tabindex", "target", "title", "type" };
137
138
139
140
141
142
143
144
145
146
147
148
149
150 public void renderStart(FacesContext context, UIComponent component,
151 ResponseWriter writer)
152 throws IOException {
153
154
155 if (!component.isRendered() || isDisabled(component) ||
156 isReadOnly(component)) {
157 return;
158 }
159
160
161 UIForm form = null;
162 UIComponent parent = component.getParent();
163 while (parent != null) {
164 if (parent instanceof UIForm) {
165 form = (UIForm) parent;
166 break;
167 }
168 parent = parent.getParent();
169 }
170 if (form == null) {
171 log.warn("CommandLinkComponent not nested inside UIForm, ignored");
172 return;
173 }
174 String formClientId = form.getClientId(context);
175
176
177
178 String key = formClientId + NamingContainer.SEPARATOR_CHAR + TOKEN;
179 if (context.getExternalContext().getRequestMap().get(key) == null) {
180 writer.startElement("input", null);
181 writer.writeAttribute("name", TOKEN, null);
182 writer.writeAttribute("type", "hidden", null);
183 writer.writeAttribute("value", "", null);
184 writer.endElement("input");
185 context.getExternalContext().getRequestMap().put
186 (key, Boolean.TRUE);
187 }
188
189
190
191 writer.startElement("a", component);
192
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207 public void renderAttributes(FacesContext context, UIComponent component,
208 ResponseWriter writer)
209 throws IOException {
210
211
212 if (!component.isRendered() || isDisabled(component) ||
213 isReadOnly(component)) {
214 return;
215 }
216
217
218 UIComponent form = null;
219 UIComponent parent = component.getParent();
220 while (parent != null) {
221 if (parent instanceof UIForm ||
222 "org.apache.myfaces.trinidad.Form".equals(parent.getFamily()) ||
223 "oracle.adf.Form".equals(parent.getFamily())) {
224 form = parent;
225 break;
226 }
227 parent = parent.getParent();
228 }
229 if (form == null) {
230 log.warn("CommandLinkComponent not nested inside UIForm, ignored");
231 return;
232 }
233 String formClientId = form.getClientId(context);
234
235
236 if (component.getId() != null) {
237 writer.writeAttribute("id", component.getClientId(context), "id");
238 }
239 writer.writeAttribute("href", "#", null);
240 String styleClass = (String)
241 component.getAttributes().get("styleClass");
242 if (styleClass != null) {
243 writer.writeAttribute("class", styleClass, "styleClass");
244 }
245 renderPassThrough(context, component, writer, passThrough);
246
247
248 StringBuffer sb = new StringBuffer();
249 sb.append("document.forms['");
250 sb.append(formClientId);
251 sb.append("']['");
252 sb.append(TOKEN);
253 sb.append("'].value='");
254 sb.append(component.getClientId(context));
255 sb.append("';");
256 Iterator kids = component.getChildren().iterator();
257 while (kids.hasNext()) {
258 UIComponent kid = (UIComponent) kids.next();
259 if (!(kid instanceof UIParameter)) {
260 continue;
261 }
262 sb.append("document.forms['");
263 sb.append(formClientId);
264 sb.append("']['");
265 sb.append((String) kid.getAttributes().get("name"));
266 sb.append("'].value='");
267 sb.append((String) kid.getAttributes().get("value"));
268 sb.append("';");
269 }
270 sb.append("document.forms['");
271 sb.append(formClientId);
272 sb.append("'].submit(); return false;");
273 writer.writeAttribute("onclick", sb.toString(), null);
274
275
276 Object value = component.getAttributes().get("value");
277 if (value != null) {
278 if (value instanceof String) {
279 writer.write((String) value);
280 } else {
281 writer.write(value.toString());
282 }
283 }
284
285 }
286
287
288
289
290
291
292
293
294
295
296
297
298
299 public void renderEnd(FacesContext context, UIComponent component,
300 ResponseWriter writer)
301 throws IOException {
302
303
304 if (!component.isRendered() || isDisabled(component) ||
305 isReadOnly(component)) {
306 return;
307 }
308
309
310 writer.endElement("a");
311
312 }
313
314
315 }