1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.bean; |
16 |
| |
17 |
| import java.util.Collection; |
18 |
| import java.util.Collections; |
19 |
| import java.util.HashMap; |
20 |
| import java.util.HashSet; |
21 |
| import java.util.Iterator; |
22 |
| import java.util.List; |
23 |
| import java.util.Map; |
24 |
| import java.util.Set; |
25 |
| |
26 |
| import org.apache.commons.logging.Log; |
27 |
| import org.apache.commons.logging.LogFactory; |
28 |
| import org.apache.hivemind.ApplicationRuntimeException; |
29 |
| import org.apache.hivemind.ClassResolver; |
30 |
| import org.apache.tapestry.IBeanProvider; |
31 |
| import org.apache.tapestry.IComponent; |
32 |
| import org.apache.tapestry.IEngine; |
33 |
| import org.apache.tapestry.event.PageDetachListener; |
34 |
| import org.apache.tapestry.event.PageEndRenderListener; |
35 |
| import org.apache.tapestry.event.PageEvent; |
36 |
| import org.apache.tapestry.spec.BeanLifecycle; |
37 |
| import org.apache.tapestry.spec.IBeanSpecification; |
38 |
| import org.apache.tapestry.spec.IComponentSpecification; |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| |
47 |
| public class BeanProvider implements IBeanProvider, PageDetachListener, PageEndRenderListener |
48 |
| { |
49 |
| private static final Log LOG = LogFactory.getLog(BeanProvider.class); |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| private boolean _registeredForDetach = false; |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| private boolean _registeredForRender = false; |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| private IComponent _component; |
69 |
| |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
| private ClassResolver _resolver; |
75 |
| |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
| private Map _beans; |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| |
88 |
| private Set _beanNames; |
89 |
| |
90 |
47
| public BeanProvider(IComponent component)
|
91 |
| { |
92 |
47
| _component = component;
|
93 |
47
| IEngine engine = component.getPage().getEngine();
|
94 |
47
| _resolver = engine.getClassResolver();
|
95 |
| |
96 |
47
| if (LOG.isDebugEnabled())
|
97 |
0
| LOG.debug("Created BeanProvider for " + component);
|
98 |
| |
99 |
| } |
100 |
| |
101 |
| |
102 |
| |
103 |
42
| public Collection getBeanNames()
|
104 |
| { |
105 |
42
| if (_beanNames == null)
|
106 |
| { |
107 |
19
| Collection c = _component.getSpecification().getBeanNames();
|
108 |
| |
109 |
19
| if (c == null || c.isEmpty())
|
110 |
0
| _beanNames = Collections.EMPTY_SET;
|
111 |
| else |
112 |
19
| _beanNames = Collections.unmodifiableSet(new HashSet(c));
|
113 |
| } |
114 |
| |
115 |
42
| return _beanNames;
|
116 |
| } |
117 |
| |
118 |
| |
119 |
| |
120 |
| |
121 |
| |
122 |
3
| public IComponent getComponent()
|
123 |
| { |
124 |
3
| return _component;
|
125 |
| } |
126 |
| |
127 |
170
| public Object getBean(String name)
|
128 |
| { |
129 |
170
| if (LOG.isDebugEnabled())
|
130 |
0
| LOG.debug("getBean(" + name + ")");
|
131 |
| |
132 |
170
| Object bean = null;
|
133 |
| |
134 |
170
| if (_beans != null)
|
135 |
123
| bean = _beans.get(name);
|
136 |
| |
137 |
170
| if (bean != null)
|
138 |
85
| return bean;
|
139 |
| |
140 |
85
| IBeanSpecification spec = _component.getSpecification().getBeanSpecification(name);
|
141 |
| |
142 |
85
| if (spec == null)
|
143 |
0
| throw new ApplicationRuntimeException(BeanMessages.beanNotDefined(_component, name));
|
144 |
| |
145 |
85
| bean = instantiateBean(name, spec);
|
146 |
| |
147 |
85
| BeanLifecycle lifecycle = spec.getLifecycle();
|
148 |
| |
149 |
85
| if (lifecycle == BeanLifecycle.NONE)
|
150 |
0
| return bean;
|
151 |
| |
152 |
85
| if (_beans == null)
|
153 |
47
| _beans = new HashMap();
|
154 |
| |
155 |
85
| _beans.put(name, bean);
|
156 |
| |
157 |
| |
158 |
| |
159 |
| |
160 |
| |
161 |
85
| if (lifecycle == BeanLifecycle.REQUEST && !_registeredForDetach)
|
162 |
| { |
163 |
46
| _component.getPage().addPageDetachListener(this);
|
164 |
46
| _registeredForDetach = true;
|
165 |
| } |
166 |
| |
167 |
85
| if (lifecycle == BeanLifecycle.RENDER && !_registeredForRender)
|
168 |
| { |
169 |
0
| _component.getPage().addPageEndRenderListener(this);
|
170 |
0
| _registeredForRender = true;
|
171 |
| } |
172 |
| |
173 |
| |
174 |
| |
175 |
| |
176 |
85
| return bean;
|
177 |
| } |
178 |
| |
179 |
85
| private Object instantiateBean(String beanName, IBeanSpecification spec)
|
180 |
| { |
181 |
85
| String className = spec.getClassName();
|
182 |
85
| Object bean = null;
|
183 |
| |
184 |
85
| if (LOG.isDebugEnabled())
|
185 |
0
| LOG.debug("Instantiating instance of " + className);
|
186 |
| |
187 |
| |
188 |
| |
189 |
85
| try
|
190 |
| { |
191 |
85
| Class beanClass = _resolver.findClass(className);
|
192 |
| |
193 |
85
| bean = beanClass.newInstance();
|
194 |
| } |
195 |
| catch (Exception ex) |
196 |
| { |
197 |
0
| throw new ApplicationRuntimeException(BeanMessages.instantiationError(
|
198 |
| beanName, |
199 |
| _component, |
200 |
| className, |
201 |
| ex), spec.getLocation(), ex); |
202 |
| } |
203 |
| |
204 |
| |
205 |
| |
206 |
85
| List initializers = spec.getInitializers();
|
207 |
| |
208 |
85
| if (initializers == null)
|
209 |
84
| return bean;
|
210 |
| |
211 |
1
| Iterator i = initializers.iterator();
|
212 |
1
| while (i.hasNext())
|
213 |
| { |
214 |
3
| IBeanInitializer iz = (IBeanInitializer) i.next();
|
215 |
| |
216 |
3
| if (LOG.isDebugEnabled())
|
217 |
0
| LOG.debug("Initializing property " + iz.getPropertyName());
|
218 |
| |
219 |
3
| iz.setBeanProperty(this, bean);
|
220 |
| } |
221 |
| |
222 |
1
| return bean;
|
223 |
| } |
224 |
| |
225 |
| |
226 |
| |
227 |
| |
228 |
| |
229 |
| |
230 |
87
| public void pageDetached(PageEvent event)
|
231 |
| { |
232 |
87
| removeBeans(BeanLifecycle.REQUEST);
|
233 |
| } |
234 |
| |
235 |
| |
236 |
| |
237 |
| |
238 |
| |
239 |
| |
240 |
| |
241 |
87
| private void removeBeans(BeanLifecycle lifecycle)
|
242 |
| { |
243 |
87
| if (_beans == null)
|
244 |
0
| return;
|
245 |
| |
246 |
87
| IComponentSpecification spec = null;
|
247 |
| |
248 |
87
| Iterator i = _beans.entrySet().iterator();
|
249 |
87
| while (i.hasNext())
|
250 |
| { |
251 |
83
| Map.Entry e = (Map.Entry) i.next();
|
252 |
83
| String name = (String) e.getKey();
|
253 |
| |
254 |
83
| if (spec == null)
|
255 |
83
| spec = _component.getSpecification();
|
256 |
| |
257 |
83
| IBeanSpecification s = spec.getBeanSpecification(name);
|
258 |
| |
259 |
83
| if (s.getLifecycle() == lifecycle)
|
260 |
| { |
261 |
83
| Object bean = e.getValue();
|
262 |
| |
263 |
83
| if (LOG.isDebugEnabled())
|
264 |
0
| LOG.debug("Removing " + lifecycle.getName() + " bean " + name + ": " + bean);
|
265 |
| |
266 |
83
| i.remove();
|
267 |
| } |
268 |
| } |
269 |
| } |
270 |
| |
271 |
| |
272 |
| |
273 |
0
| public ClassResolver getClassResolver()
|
274 |
| { |
275 |
0
| return _resolver;
|
276 |
| } |
277 |
| |
278 |
| |
279 |
| |
280 |
0
| public void pageEndRender(PageEvent event)
|
281 |
| { |
282 |
0
| removeBeans(BeanLifecycle.RENDER);
|
283 |
| } |
284 |
| |
285 |
| |
286 |
| |
287 |
42
| public boolean canProvideBean(String name)
|
288 |
| { |
289 |
42
| return getBeanNames().contains(name);
|
290 |
| } |
291 |
| |
292 |
| } |