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