1 | |
package org.apache.tapestry.pageload; |
2 | |
|
3 | |
import org.apache.hivemind.ApplicationRuntimeException; |
4 | |
import org.apache.hivemind.PoolManageable; |
5 | |
import org.apache.tapestry.IComponent; |
6 | |
import org.apache.tapestry.IForm; |
7 | |
import org.apache.tapestry.IPage; |
8 | |
import org.apache.tapestry.IRender; |
9 | |
import org.apache.tapestry.form.IFormComponent; |
10 | |
import org.apache.tapestry.internal.Component; |
11 | |
import org.apache.tapestry.internal.event.ComponentEventProperty; |
12 | |
import org.apache.tapestry.internal.event.EventBoundListener; |
13 | |
import org.apache.tapestry.internal.event.IComponentEventInvoker; |
14 | |
import org.apache.tapestry.spec.IComponentSpecification; |
15 | |
|
16 | |
import java.util.*; |
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | 0 | public class EventConnectionVisitor implements IComponentVisitor, PoolManageable { |
22 | |
|
23 | |
IComponentEventInvoker _invoker; |
24 | |
|
25 | 0 | IPage _currentPage = null; |
26 | 0 | List _forms = new ArrayList(); |
27 | |
|
28 | |
public void visitComponent(IComponent component) |
29 | |
{ |
30 | 0 | checkComponentPage(component); |
31 | |
|
32 | 0 | Map events = component.getSpecification().getComponentEvents(); |
33 | 0 | Set keySet = events.keySet(); |
34 | 0 | String[] compIds = (String[]) keySet.toArray(new String[keySet.size()]); |
35 | |
|
36 | 0 | for (int i=0; i < compIds.length; i++) |
37 | |
{ |
38 | 0 | String compId = compIds[i]; |
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | 0 | IComponent comp = findComponent(compId, component); |
44 | |
|
45 | 0 | if (comp == null && !IPage.class.isInstance(component)) |
46 | |
{ |
47 | 0 | comp = findComponent(compId, component.getPage()); |
48 | |
} |
49 | |
|
50 | 0 | if (comp == null) |
51 | 0 | continue; |
52 | |
|
53 | 0 | if (Component.class.isInstance(comp)) |
54 | 0 | ((Component)comp).setHasEvents(true); |
55 | |
|
56 | |
|
57 | |
|
58 | 0 | String idPath = comp.getExtendedId(); |
59 | |
|
60 | 0 | component.getSpecification().rewireComponentId(compId, idPath, component.getIdPath()); |
61 | |
|
62 | 0 | _invoker.addEventListener(idPath, component.getSpecification()); |
63 | 0 | wireFormEvents(comp, component.getSpecification()); |
64 | |
} |
65 | |
|
66 | |
|
67 | |
|
68 | 0 | events = component.getSpecification().getElementEvents(); |
69 | 0 | Iterator it = events.keySet().iterator(); |
70 | |
|
71 | |
|
72 | |
|
73 | 0 | if (events.size() > 0 && Component.class.isInstance(component)) |
74 | |
{ |
75 | 0 | ((Component)component).setHasEvents(true); |
76 | |
} |
77 | |
|
78 | 0 | while (it.hasNext()) |
79 | |
{ |
80 | 0 | String elementId = (String) it.next(); |
81 | 0 | ComponentEventProperty property = (ComponentEventProperty) events.get(elementId); |
82 | |
|
83 | 0 | Iterator bindingIt = property.getFormEvents().iterator(); |
84 | 0 | while (bindingIt.hasNext()) |
85 | |
{ |
86 | 0 | String key = (String) bindingIt.next(); |
87 | 0 | List listeners = property.getFormEventListeners(key); |
88 | |
|
89 | 0 | for (int i=0; i < listeners.size(); i++) |
90 | |
{ |
91 | 0 | EventBoundListener listener = (EventBoundListener) listeners.get(i); |
92 | 0 | wireElementFormEvents(listener, component, component.getSpecification()); |
93 | |
} |
94 | 0 | } |
95 | 0 | } |
96 | 0 | } |
97 | |
|
98 | |
void wireElementFormEvents(EventBoundListener listener, IComponent component, IComponentSpecification spec) |
99 | |
{ |
100 | 0 | if (listener.getFormId() == null) |
101 | 0 | return; |
102 | |
|
103 | 0 | if (_forms.size() < 1) |
104 | 0 | discoverPageForms(component.getPage()); |
105 | |
|
106 | 0 | IForm form = null; |
107 | 0 | for (int i=0; i < _forms.size(); i++) |
108 | |
{ |
109 | 0 | IForm f = (IForm) _forms.get(i); |
110 | 0 | if (listener.getFormId().equals(f.getExtendedId()) || listener.getFormId().equals(f.getId())) |
111 | |
{ |
112 | 0 | form = f; |
113 | 0 | break; |
114 | |
} |
115 | |
} |
116 | |
|
117 | |
|
118 | |
|
119 | 0 | if (form == null) |
120 | 0 | throw new ApplicationRuntimeException(PageloadMessages.componentNotFound(listener.getFormId()), |
121 | |
component, component.getLocation(), null); |
122 | |
|
123 | 0 | String idPath = form.getExtendedId(); |
124 | |
|
125 | 0 | listener.setFormId(idPath); |
126 | 0 | _invoker.addFormEventListener(idPath, spec); |
127 | 0 | } |
128 | |
|
129 | |
void wireFormEvents(IComponent component, IComponentSpecification listener) |
130 | |
{ |
131 | 0 | if (!IFormComponent.class.isInstance(component)) |
132 | 0 | return; |
133 | |
|
134 | 0 | IFormComponent fcomp = (IFormComponent) component; |
135 | |
|
136 | 0 | if (_forms.size() < 1) |
137 | 0 | discoverPageForms(fcomp.getPage()); |
138 | |
|
139 | 0 | IForm form = findComponentForm(fcomp); |
140 | 0 | if (form == null) |
141 | 0 | return; |
142 | |
|
143 | 0 | listener.connectAutoSubmitEvents(component, form); |
144 | 0 | _invoker.addFormEventListener(form.getExtendedId(), listener); |
145 | 0 | } |
146 | |
|
147 | |
IComponent findComponent(String id, IComponent target) |
148 | |
{ |
149 | 0 | Map components = target.getComponents(); |
150 | 0 | if (components == null) |
151 | 0 | return null; |
152 | |
|
153 | 0 | IComponent comp = (IComponent) components.get(id); |
154 | 0 | if (comp != null) |
155 | 0 | return comp; |
156 | |
|
157 | 0 | Iterator children = components.values().iterator(); |
158 | |
|
159 | 0 | while (children.hasNext()) |
160 | |
{ |
161 | 0 | IComponent child = (IComponent) children.next(); |
162 | |
|
163 | 0 | comp = findComponent(id, child); |
164 | 0 | if (comp != null) |
165 | 0 | return comp; |
166 | 0 | } |
167 | |
|
168 | 0 | return null; |
169 | |
} |
170 | |
|
171 | |
void discoverPageForms(IComponent parent) |
172 | |
{ |
173 | 0 | if (IForm.class.isInstance(parent)) |
174 | 0 | _forms.add(parent); |
175 | |
|
176 | 0 | Iterator it = parent.getComponents().values().iterator(); |
177 | 0 | while (it.hasNext()) |
178 | |
{ |
179 | 0 | IComponent comp = (IComponent)it.next(); |
180 | |
|
181 | 0 | discoverPageForms(comp); |
182 | 0 | } |
183 | 0 | } |
184 | |
|
185 | |
IForm findComponentForm(IFormComponent child) |
186 | |
{ |
187 | 0 | for (int i = 0; i < _forms.size(); i++) |
188 | |
{ |
189 | 0 | IForm form = (IForm) _forms.get(i); |
190 | |
|
191 | 0 | IComponent match = findContainedComponent(child.getExtendedId(), (Component)form); |
192 | 0 | if (match != null) |
193 | 0 | return form; |
194 | |
} |
195 | |
|
196 | 0 | return null; |
197 | |
} |
198 | |
|
199 | |
IComponent findContainedComponent(String idPath, Component container) |
200 | |
{ |
201 | 0 | IComponent comp = (IComponent) container; |
202 | |
|
203 | 0 | if (idPath.equals(comp.getExtendedId())) |
204 | 0 | return comp; |
205 | |
|
206 | 0 | IRender[] children = container.getContainedRenderers(); |
207 | 0 | if (children == null) |
208 | 0 | return null; |
209 | |
|
210 | 0 | for (int i=0; i < children.length; i++) |
211 | |
{ |
212 | 0 | if (children[i] == null) |
213 | 0 | return null; |
214 | |
|
215 | 0 | if (!Component.class.isInstance(children[i])) |
216 | 0 | continue; |
217 | |
|
218 | 0 | IComponent found = findContainedComponent(idPath, (Component)children[i]); |
219 | 0 | if (found != null) |
220 | 0 | return found; |
221 | |
} |
222 | |
|
223 | 0 | return null; |
224 | |
} |
225 | |
|
226 | |
void checkComponentPage(IComponent component) |
227 | |
{ |
228 | 0 | if (_currentPage == null) |
229 | |
{ |
230 | 0 | _currentPage = component.getPage(); |
231 | 0 | _forms.clear(); |
232 | 0 | } else if (component.getPage() != _currentPage) |
233 | |
{ |
234 | 0 | _currentPage = component.getPage(); |
235 | 0 | _forms.clear(); |
236 | |
} |
237 | 0 | } |
238 | |
|
239 | |
public void activateService() |
240 | |
{ |
241 | 0 | _currentPage = null; |
242 | 0 | _forms.clear(); |
243 | 0 | } |
244 | |
|
245 | |
public void passivateService() |
246 | |
{ |
247 | 0 | _currentPage = null; |
248 | 0 | _forms.clear(); |
249 | 0 | } |
250 | |
|
251 | |
|
252 | |
public void setEventInvoker(IComponentEventInvoker invoker) |
253 | |
{ |
254 | 0 | _invoker = invoker; |
255 | 0 | } |
256 | |
} |