KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc6 > TomcatInjectionContainer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.web.tomcat.tc6;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.lang.annotation.Annotation JavaDoc;
27 import java.lang.reflect.AccessibleObject JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.LinkedHashMap JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37
38 import javax.naming.Context JavaDoc;
39 import javax.naming.InitialContext JavaDoc;
40 import javax.naming.NameNotFoundException JavaDoc;
41 import javax.naming.NamingException JavaDoc;
42
43 import org.apache.AnnotationProcessor;
44 import org.jboss.deployers.spi.deployer.DeploymentUnit;
45 import org.jboss.ejb3.Container;
46 import org.jboss.ejb3.DependencyPolicy;
47 import org.jboss.ejb3.DeploymentScope;
48 import org.jboss.ejb3.JmxDependencyPolicy;
49 import org.jboss.ejb3.enc.DeploymentPersistenceUnitResolver;
50 import org.jboss.ejb3.entity.PersistenceUnitDeployment;
51 import org.jboss.injection.DependsHandler;
52 import org.jboss.injection.EJBHandler;
53 import org.jboss.injection.EncInjector;
54 import org.jboss.injection.InjectionContainer;
55 import org.jboss.injection.InjectionHandler;
56 import org.jboss.injection.InjectionUtil;
57 import org.jboss.injection.Injector;
58 import org.jboss.injection.JndiInjectHandler;
59 import org.jboss.injection.PersistenceContextHandler;
60 import org.jboss.injection.PersistenceUnitHandler;
61 import org.jboss.injection.ResourceHandler;
62 import org.jboss.injection.WebServiceRefHandler;
63 import org.jboss.logging.Logger;
64 import org.jboss.metamodel.descriptor.EnvironmentRefGroup;
65 import org.jboss.metamodel.descriptor.Listener;
66 import org.jboss.virtual.VirtualFile;
67 import org.jboss.web.WebApplication;
68 import org.jboss.web.metamodel.descriptor.Filter;
69 import org.jboss.web.metamodel.descriptor.JBossWebDDObjectFactory;
70 import org.jboss.web.metamodel.descriptor.Servlet;
71 import org.jboss.web.metamodel.descriptor.WebDD;
72 import org.jboss.web.metamodel.descriptor.WebDDObjectFactory;
73 import org.jboss.xb.binding.JBossXBException;
74
75 /**
76  * Comment
77  *
78  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
79  * @version $Revision: 1.17 $
80  */

81 public class TomcatInjectionContainer implements InjectionContainer, AnnotationProcessor
82 {
83    private static final Logger log = Logger.getLogger(TomcatInjectionContainer.class);
84
85    private static class EncMap extends HashMap JavaDoc<String JavaDoc, EncInjector>
86    {
87       private HashMap JavaDoc<String JavaDoc, EncInjector> added;
88
89       public void recordAdded()
90       {
91          added = new HashMap JavaDoc<String JavaDoc, EncInjector>();
92       }
93
94       public void clearAdded()
95       {
96          added = null;
97       }
98
99       public Map JavaDoc<String JavaDoc, EncInjector> getAdded() { return added; }
100
101
102       @Override JavaDoc
103       public EncInjector put(String JavaDoc key, EncInjector value)
104       {
105          if (added != null) added.put(key, value);
106          return super.put(key, value);
107       }
108
109       @Override JavaDoc
110       public void putAll(Map JavaDoc<? extends String JavaDoc, ? extends EncInjector> m)
111       {
112          if (added != null) added.putAll(m);
113          super.putAll(m);
114       }
115    }
116
117    protected EncMap encInjectors = new EncMap();
118    protected Map JavaDoc<String JavaDoc, Map JavaDoc<AccessibleObject JavaDoc, Injector>> encInjections = new HashMap JavaDoc<String JavaDoc, Map JavaDoc<AccessibleObject JavaDoc, Injector>>();
119    protected Map JavaDoc<String JavaDoc, Map JavaDoc<AccessibleObject JavaDoc, Injector>> resolvedClassInjections = new HashMap JavaDoc<String JavaDoc, Map JavaDoc<AccessibleObject JavaDoc, Injector>>();
120
121
122    protected List JavaDoc<PersistenceUnitDeployment> persistenceUnitDeployments = new ArrayList JavaDoc<PersistenceUnitDeployment>();
123    protected LinkedHashMap JavaDoc ejbContainers = new LinkedHashMap JavaDoc(); // will always be empty.
124
protected DeploymentPersistenceUnitResolver persistenceUnitResolver;
125    protected WarEjbResolver ejbResolver;
126    protected DependencyPolicy dependencyPolicy = new JmxDependencyPolicy();
127    protected Collection JavaDoc<InjectionHandler> handlers;
128    protected DeploymentUnit unit;
129    protected ClassLoader JavaDoc webLoader;
130    protected WebApplication appInfo;
131
132    public TomcatInjectionContainer(WebApplication appInfo, DeploymentUnit unit)
133    {
134       this.unit = unit;
135       DeploymentScope deploymentScope = null;
136       this.appInfo = appInfo;
137
138       persistenceUnitResolver = new DeploymentPersistenceUnitResolver(persistenceUnitDeployments, deploymentScope, ejbContainers);
139       ejbResolver = new WarEjbResolver(deploymentScope, unit.getSimpleName());
140    }
141    
142    public EnvironmentRefGroup getEnvironmentRefGroup()
143    {
144       return null;
145    }
146
147    public void postConstruct(Object JavaDoc object) throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc
148    {
149       // ignore for now
150
}
151
152    public void preDestroy(Object JavaDoc object) throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc
153    {
154       // ignore for now
155
}
156
157    /**
158     * When we get here, we are assuming that any XML defined ENC has been set up. We will set up more here
159     * if the class being processed is a JSP
160     *
161     *
162     * @param object
163     * @throws IllegalAccessException
164     * @throws InvocationTargetException
165     * @throws NamingException
166     */

167    public void processAnnotations(Object JavaDoc object) throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc, NamingException JavaDoc
168    {
169       log.debug("**************** Processing annotations for: " + object.getClass().getName());
170       Map JavaDoc<AccessibleObject JavaDoc, Injector> injectors = resolvedClassInjections.get(object.getClass().getName());
171       if (injectors == null)
172       {
173          log.debug("-- there was no prior annotation preprocessing done");
174          encInjectors.recordAdded();
175          // let's assume this is a JSP or some other artifact that cannot be found within XML
176
injectors = InjectionUtil.processAnnotations(this, handlers, object.getClass());
177          resolvedClassInjections.put(object.getClass().getName(), injectors);
178
179          // only execute injectors that were added additionally
180
if (encInjectors.getAdded().size() > 0)
181          {
182             for (EncInjector encInjector : encInjectors.getAdded().values())
183             {
184                encInjector.inject(this);
185             }
186             encInjectors.clearAdded();
187          }
188       }
189       if (injectors == null || injectors.size() == 0)
190       {
191          log.debug("-- no injectors found: " + injectors);
192          return;
193       }
194
195       log.debug("-- doing injections");
196       for (Injector injector : injectors.values())
197       {
198          injector.inject(object);
199       }
200    }
201
202    public void populateEnc(ClassLoader JavaDoc loader)
203    {
204       for (EncInjector injector : encInjectors.values())
205       {
206          injector.inject(this);
207       }
208    }
209
210    private InputStream JavaDoc[] getInputStreams()
211    {
212       InputStream JavaDoc jbossWebIS = null;
213       InputStream JavaDoc webIS = null;
214
215       try
216       {
217          VirtualFile webDD = unit.getMetaDataFile("web.xml");
218          if (webDD != null)
219             webIS = webDD.openStream();
220       }
221       catch (IOException JavaDoc e)
222       {
223          log.debug("Failed to find web.xml");
224       }
225       try
226       {
227          VirtualFile webDD = unit.getMetaDataFile("jboss-web.xml");
228          if (webDD != null)
229             jbossWebIS = webDD.openStream();
230       }
231       catch (IOException JavaDoc e)
232       {
233          log.debug("Failed to find jboss-web.xml");
234       }
235
236       InputStream JavaDoc[] streams = {webIS, jbossWebIS};
237       return streams;
238    }
239
240    /**
241     * introspects EJB container to find all dependencies
242     * and initialize any extra metadata.
243     * <p/>
244     * This must be called before container is registered with any microcontainer
245     *
246     * @param dependencyPolicy
247     */

248    public void processMetadata()
249    {
250       WebDD xml = null;
251       InputStream JavaDoc[] streams = getInputStreams();
252       if (streams[0] != null)
253       {
254          try
255          {
256             xml = WebDDObjectFactory.parse(streams[0]);
257             if (streams[1] != null)
258             {
259                xml = JBossWebDDObjectFactory.parse(xml, streams[1]);
260             }
261          }
262          catch (JBossXBException e)
263          {
264             throw new RuntimeException JavaDoc(e);
265          }
266       }
267       else
268       {
269          throw new RuntimeException JavaDoc("web.xml is required");
270       }
271
272       // XML must be done first so that any annotation overrides are initialized
273

274       // todo injection handlers should be pluggable from XML
275
handlers = new ArrayList JavaDoc<InjectionHandler>();
276       handlers.add(new EJBHandler());
277       handlers.add(new DependsHandler());
278       handlers.add(new JndiInjectHandler());
279       handlers.add(new PersistenceContextHandler());
280       handlers.add(new PersistenceUnitHandler());
281       handlers.add(new ResourceHandler());
282       handlers.add(new WebServiceRefHandler());
283
284       ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
285       ClassLoader JavaDoc webLoader = getClassloader();
286       Thread.currentThread().setContextClassLoader(webLoader);
287       try
288       {
289          for (InjectionHandler handler : handlers) handler.loadXml(xml, this);
290
291          for (Object JavaDoc obj : xml.getServlets())
292          {
293             Servlet servlet = (Servlet)obj;
294             try
295             {
296                if (servlet.getServletClass() == null)
297                   continue; // jsp
298
if (resolvedClassInjections.containsKey(servlet.getServletClass()))
299                   continue;
300                Class JavaDoc servletClass = webLoader.loadClass(servlet.getServletClass());
301                Map JavaDoc<AccessibleObject JavaDoc, Injector> tmp = InjectionUtil.processAnnotations(this, handlers, servletClass);
302                resolvedClassInjections.put(servlet.getServletClass(), tmp);
303             }
304             catch (ClassNotFoundException JavaDoc e)
305             {
306                log.warn("could not find servlet class " + servlet.getServletClass() + " in classpath when processing annotations.");
307             }
308
309          }
310          for (Object JavaDoc obj : xml.getFilters())
311          {
312             Filter filter = (Filter)obj;
313             try
314             {
315                if (resolvedClassInjections.containsKey(filter.getFilterClass()))
316                   continue;
317                Class JavaDoc servletClass = webLoader.loadClass(filter.getFilterClass());
318                Map JavaDoc<AccessibleObject JavaDoc, Injector> tmp = InjectionUtil.processAnnotations(this, handlers, servletClass);
319                resolvedClassInjections.put(filter.getFilterClass(), tmp);
320             }
321             catch (ClassNotFoundException JavaDoc e)
322             {
323                throw new RuntimeException JavaDoc("could not find filter class in classpath", e);
324             }
325          }
326          for (Object JavaDoc obj : xml.getListeners())
327          {
328             Listener listener = (Listener)obj;
329             try
330             {
331                if (resolvedClassInjections.containsKey(listener.getListenerClass()))
332                   continue;
333                Class JavaDoc servletClass = webLoader.loadClass(listener.getListenerClass());
334                Map JavaDoc<AccessibleObject JavaDoc, Injector> tmp = InjectionUtil.processAnnotations(this, handlers, servletClass);
335                resolvedClassInjections.put(listener.getListenerClass(), tmp);
336             }
337             catch (ClassNotFoundException JavaDoc e)
338             {
339                throw new RuntimeException JavaDoc("could not find listener class in classpath", e);
340             }
341          }
342       }
343       finally
344       {
345          Thread.currentThread().setContextClassLoader(old);
346       }
347    }
348
349    public Map JavaDoc<String JavaDoc, EncInjector> getEncInjectors()
350    {
351       return encInjectors;
352    }
353
354    public Map JavaDoc<String JavaDoc, Map JavaDoc<AccessibleObject JavaDoc, Injector>> getEncInjections()
355    {
356       return encInjections;
357    }
358
359    // EncInjectors/Handlers may need to add extra instance injectors
360
public List JavaDoc<Injector> getInjectors()
361    {
362       return new ArrayList JavaDoc<Injector>(); // no equivalent in WAR
363
}
364
365
366    public String JavaDoc getIdentifier()
367    {
368       return unit.getSimpleName();
369    }
370
371    public String JavaDoc getDeploymentDescriptorType()
372    {
373       return "web.xml";
374    }
375
376    public ClassLoader JavaDoc getClassloader()
377    {
378       return webLoader;
379    }
380
381    public void setClassLoader(ClassLoader JavaDoc loader)
382    {
383       this.webLoader = loader;
384    }
385
386    public Context JavaDoc getEnc()
387    {
388       ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
389       try
390       {
391          Thread.currentThread().setContextClassLoader(getClassloader());
392          try
393          {
394             return (Context JavaDoc) new InitialContext JavaDoc().lookup("java:comp");
395          }
396          catch (NamingException JavaDoc e)
397          {
398             throw new RuntimeException JavaDoc(e);
399          }
400       }
401       finally
402       {
403          Thread.currentThread().setContextClassLoader(old);
404       }
405    }
406
407    public Context JavaDoc getEncEnv()
408    {
409       ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
410       try
411       {
412          Thread.currentThread().setContextClassLoader(getClassloader());
413          try
414          {
415             return (Context JavaDoc) new InitialContext JavaDoc().lookup("java:comp/env");
416          }
417          catch (NamingException JavaDoc e)
418          {
419             throw new RuntimeException JavaDoc(e);
420          }
421       }
422       finally
423       {
424          Thread.currentThread().setContextClassLoader(old);
425       }
426    }
427
428    public PersistenceUnitDeployment getPersistenceUnitDeployment(String JavaDoc unitName) throws NameNotFoundException JavaDoc
429    {
430       return persistenceUnitResolver.getPersistenceUnitDeployment(unitName);
431    }
432
433    public Container resolveEjbContainer(String JavaDoc link, Class JavaDoc businessIntf)
434    {
435       return ejbResolver.getEjbContainer(link, businessIntf);
436    }
437
438    public Container resolveEjbContainer(Class JavaDoc businessIntf) throws NameNotFoundException JavaDoc
439    {
440       return ejbResolver.getEjbContainer(businessIntf);
441    }
442
443    public String JavaDoc getEjbJndiName(Class JavaDoc businessInterface) throws NameNotFoundException JavaDoc
444    {
445       return ejbResolver.getEjbJndiName(businessInterface);
446    }
447
448    public String JavaDoc getEjbJndiName(String JavaDoc link, Class JavaDoc businessInterface)
449    {
450       return ejbResolver.getEjbJndiName(link, businessInterface);
451    }
452
453    public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationType, Class JavaDoc<?> clazz)
454    {
455       return clazz.getAnnotation(annotationType);
456    }
457
458    public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationType, Class JavaDoc<?> clazz, Method JavaDoc method)
459    {
460       return method.getAnnotation(annotationType);
461    }
462    
463    public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationType, Method JavaDoc method)
464    {
465       return method.getAnnotation(annotationType);
466    }
467
468    public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationType, Class JavaDoc<?> clazz, Field JavaDoc field)
469    {
470       return field.getAnnotation(annotationType);
471    }
472    
473    public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationType, Field JavaDoc field)
474    {
475       return field.getAnnotation(annotationType);
476    }
477
478    public DependencyPolicy getDependencyPolicy()
479    {
480       return dependencyPolicy;
481    }
482
483 }
Popular Tags