1
2
3
4
5
6
7
8
9
10
11
12
13
14 package net.sf.tacos.components.dojo;
15
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21
22 import net.sf.tacos.binding.ICallbackFunction;
23 import net.sf.tacos.util.JSONMarkupWriter;
24
25 import org.apache.tapestry.IActionListener;
26 import org.apache.tapestry.IBinding;
27 import org.apache.tapestry.IDirect;
28 import org.apache.tapestry.IMarkupWriter;
29 import org.apache.tapestry.IRequestCycle;
30 import org.apache.tapestry.IScript;
31 import org.apache.tapestry.Tapestry;
32 import org.apache.tapestry.TapestryUtils;
33 import org.apache.tapestry.dojo.IWidget;
34 import org.apache.tapestry.engine.DirectServiceParameter;
35 import org.apache.tapestry.engine.IEngineService;
36 import org.apache.tapestry.engine.ILink;
37 import org.apache.tapestry.event.BrowserEvent;
38 import org.apache.tapestry.json.JSONObject;
39 import org.apache.tapestry.link.DirectLink;
40 import org.apache.tapestry.listener.ListenerInvoker;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public abstract class DojoWidget extends GenericWidget implements IDojoContainer, IDirect{
93
94 public static final String CONTAINER_ATTRIBUTE = DojoWidget.class.getName();
95
96
97
98
99
100
101
102
103
104
105
106 public boolean getContainerState() {
107 if (isParameterBound("isContainer")) {
108 return getIsContainer();
109 } else {
110 String type = getDojoType();
111 return (type.endsWith("Container") || type.equals("ContentPane"));
112 }
113 }
114
115
116
117
118 public void renderWidget(IMarkupWriter writer, IRequestCycle cycle){
119 boolean isContainer = getContainerState();
120 IDojoContainer previousContainer = (IDojoContainer) cycle.getAttribute(CONTAINER_ATTRIBUTE);
121 boolean rewinding = cycle.isRewinding();
122
123 if (!rewinding) {
124 writer.begin(getTemplateTagName());
125 renderIdAttribute(writer, cycle);
126 String style = getStyle();
127 if (style!=null)
128 writer.attribute("style", style);
129
130 if(isContainer){
131 cycle.setAttribute(CONTAINER_ATTRIBUTE, this);
132 }
133 }
134
135 renderBody(writer, cycle);
136
137 if (!rewinding) {
138 writer.end();
139
140 if (previousContainer!=null)
141 previousContainer.addChild(this);
142
143 JSONMarkupWriter jsonWriter = new JSONMarkupWriter();
144 renderInformalParameters(jsonWriter, cycle);
145 JSONObject json = jsonWriter.getAttributes();
146
147 Map asynclisteners = getAsyncListenerBindings();
148 Map listeners = getListenerBindings();
149 Map callbacks = getCallbackBindings();
150 removeListenersFromInputSymbols(json, asynclisteners);
151 removeListenersFromInputSymbols(json, listeners);
152 removeListenersFromInputSymbols(json, callbacks);
153
154 Map parms = new HashMap();
155 String url = getLink().getURL();
156 parms.put("component", this);
157 parms.put("type", getDojoType());
158 parms.put("url", url);
159 parms.put("props", json.toString());
160 parms.put("asynclisteners", asynclisteners);
161 parms.put("listeners", listeners);
162 parms.put("callbacks", callbacks);
163 getScript().execute(this, cycle, TapestryUtils.getPageRenderSupport(cycle, this), parms);
164
165 cycle.setAttribute(CONTAINER_ATTRIBUTE, previousContainer);
166 }
167 }
168
169
170
171
172
173 public void addChild(IWidget widget) {
174
175
176 getChildren().add(widget.getClientId());
177 }
178
179
180
181
182
183
184
185
186
187
188 private void removeListenersFromInputSymbols(JSONObject json, Map bindings){
189 Iterator i = bindings.keySet().iterator();
190 while(i.hasNext()){
191 json.remove((String)i.next());
192 }
193 }
194
195
196
197
198
199 private Map getAllListenerBindings(){
200 return getBindingsByClass(getBindingNames(), IActionListener.class);
201 }
202
203
204
205
206
207
208 public Map getListenerBindings(){
209 Map listeners = getBindingsByClass(getBindingNames(), IActionListener.class);
210 Map result = new HashMap();
211 String[] noAsync = constructNoAsync();
212 if (noAsync != null) {
213 for (int i = 0; i < noAsync.length; i++) {
214 if (listeners.get(noAsync[i]) != null) {
215 result.put(noAsync[i], listeners.get(noAsync[i]));
216 }
217 }
218 }
219 return result;
220 }
221
222
223
224
225
226 public Map getAsyncListenerBindings(){
227 Map listeners = getBindingsByClass(getBindingNames(), IActionListener.class);
228 String[] noAsync = constructNoAsync();
229 if (noAsync != null) {
230 for (int i = 0; i < noAsync.length; i++) {
231 listeners.remove(noAsync[i]);
232 }
233 }
234 return listeners;
235 }
236
237
238
239
240
241 private String[] constructNoAsync() {
242 String noAsync = getNoAsync();
243 if (noAsync != null) {
244 if (noAsync.indexOf(",") != -1) {
245 return noAsync.split(",");
246 } else {
247 String[] result = {noAsync};
248 return result;
249 }
250 }
251 return null;
252 }
253
254
255
256
257
258 public Map getCallbackBindings(){
259 return getBindingsByClass(getBindingNames(), ICallbackFunction.class);
260 }
261
262
263
264
265
266
267
268
269
270 protected Map getBindingsByClass(Collection names, Class clazz){
271 Map result = new HashMap();
272 Iterator i = names.iterator();
273 while(i.hasNext()){
274 String name = (String)i.next();
275 IBinding binding = getBinding(name);
276 if(clazz.isAssignableFrom(binding.getClass())){
277 result.put(name, binding);
278 }
279 }
280 return result;
281 }
282
283
284 private ILink getLink(){
285 Object[] parameters = DirectLink.constructServiceParameters(getParameters());
286 DirectServiceParameter dsp = new DirectServiceParameter(this, parameters);
287 return getEngine().getLink(isStateful(), dsp);
288 }
289
290
291 public String getNoAsyncEventUrl(String eventName){
292 Object[] parameters = DirectLink.constructServiceParameters(getParameters());
293 DirectServiceParameter dsp = new DirectServiceParameter(this, parameters);
294 return getEngine().getLink(isStateful(), dsp).getURL() + "&"
295 + BrowserEvent.NAME + "=" + eventName;
296 }
297
298
299
300
301
302 public void trigger(IRequestCycle cycle) {
303 String event = cycle.getParameter(BrowserEvent.NAME);
304 IActionListener listener = (IActionListener)getAllListenerBindings().get(event);
305 if (listener == null)
306 throw Tapestry.createRequiredParameterException(this, event);
307 getListenerInvoker().invokeListener(listener, this, cycle);
308
309 }
310
311
312 public abstract IScript getScript();
313
314
315 public abstract IEngineService getEngine();
316
317
318 public abstract ListenerInvoker getListenerInvoker();
319
320
321 public abstract String getStyle();
322
323
324 public abstract String getDojoType();
325
326
327 public abstract Object getParameters();
328
329
330 public abstract String getNoAsync();
331
332
333
334
335
336 public abstract List getChildren();
337 }