KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > kernel > plugins > dependency > AbstractKernelController


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.kernel.plugins.dependency;
23
24 import java.util.HashSet JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Set JavaDoc;
28
29 import org.jboss.beans.metadata.spi.BeanMetaData;
30 import org.jboss.beans.metadata.spi.SupplyMetaData;
31 import org.jboss.dependency.plugins.AbstractController;
32 import org.jboss.dependency.spi.ControllerContext;
33 import org.jboss.dependency.spi.ControllerState;
34 import org.jboss.kernel.Kernel;
35 import org.jboss.kernel.plugins.event.AbstractEventEmitter;
36 import org.jboss.kernel.spi.dependency.KernelController;
37 import org.jboss.kernel.spi.dependency.KernelControllerContext;
38 import org.jboss.kernel.spi.event.KernelEvent;
39 import org.jboss.kernel.spi.event.KernelEventFilter;
40 import org.jboss.kernel.spi.event.KernelEventListener;
41 import org.jboss.kernel.spi.registry.KernelRegistry;
42 import org.jboss.kernel.spi.registry.KernelRegistryEntry;
43 import org.jboss.kernel.spi.registry.KernelRegistryPlugin;
44 import org.jboss.util.collection.CollectionsFactory;
45
46 /**
47  * Abstract Kernel controller.
48  *
49  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
50  * @version $Revision: 57133 $
51  */

52 public class AbstractKernelController extends AbstractController implements KernelController, KernelRegistryPlugin
53 {
54    /** The kernel */
55    protected Kernel kernel;
56
57    /** The emitter delegate */
58    protected AbstractEventEmitter emitterDelegate = new AbstractEventEmitter();
59
60    /** The supplies */
61    protected Map JavaDoc<Object JavaDoc, List JavaDoc<KernelControllerContext>> suppliers = CollectionsFactory.createConcurrentReaderMap();
62
63    /** The contexts by class Map<Class, Set<ControllerContext>> */
64    protected Map JavaDoc<Class JavaDoc, ClassContext> contextsByClass = CollectionsFactory.createConcurrentReaderMap();
65
66    /**
67     * Create an abstract kernel controller
68     *
69     * @throws Exception for any error
70     */

71    public AbstractKernelController() throws Exception JavaDoc
72    {
73    }
74
75    public KernelControllerContext install(BeanMetaData metaData) throws Throwable JavaDoc
76    {
77       return install(metaData, null);
78    }
79
80    public KernelControllerContext install(BeanMetaData metaData, Object JavaDoc target) throws Throwable JavaDoc
81    {
82       KernelControllerContext context = new AbstractKernelControllerContext(null, metaData, target);
83       install(context);
84       return context;
85    }
86
87    public KernelRegistryEntry getEntry(Object JavaDoc name)
88    {
89       List JavaDoc<KernelControllerContext> list = suppliers.get(name);
90       if (list != null && list.isEmpty() == false)
91          return list.get(0);
92       else if (name instanceof Class JavaDoc)
93          return getContextByClass((Class JavaDoc)name);
94       else
95          return null;
96    }
97
98    public ControllerContext getContext(Object JavaDoc name, ControllerState state)
99    {
100       ControllerContext context = super.getContext(name, state);
101       if (context != null)
102          return context;
103       if (state == null || state == ControllerState.INSTALLED)
104       {
105          KernelRegistry registry = kernel.getRegistry();
106          try
107          {
108             return registry.getEntry(name);
109          }
110          catch (Throwable JavaDoc ignored)
111          {
112          }
113       }
114       return null;
115    }
116
117    public void addSupplies(KernelControllerContext context)
118    {
119       BeanMetaData metaData = context.getBeanMetaData();
120       Set JavaDoc<SupplyMetaData> supplies = metaData.getSupplies();
121       if (supplies != null)
122       {
123          boolean trace = log.isTraceEnabled();
124
125          if (supplies.isEmpty() == false)
126          {
127             lockWrite();
128             try
129             {
130                for (SupplyMetaData supplied : supplies)
131                {
132                   Object JavaDoc supply = supplied.getSupply();
133                   List JavaDoc<KernelControllerContext> list = suppliers.get(supply);
134                   if (list == null)
135                   {
136                      list = CollectionsFactory.createCopyOnWriteList();
137                      suppliers.put(supply, list);
138                   }
139                   list.add(context);
140                   if (trace)
141                      log.trace("Suppliers of " + supply + ": " + list);
142                }
143             }
144             finally
145             {
146                unlockWrite();
147             }
148          }
149       }
150    }
151
152    public void removeSupplies(KernelControllerContext context)
153    {
154       BeanMetaData metaData = context.getBeanMetaData();
155       Set JavaDoc<SupplyMetaData> supplies = metaData.getSupplies();
156       if (supplies != null)
157       {
158          boolean trace = log.isTraceEnabled();
159
160          if (supplies.isEmpty() == false)
161          {
162             lockWrite();
163             try
164             {
165                for (SupplyMetaData supplied : supplies)
166                {
167                   Object JavaDoc supply = supplied.getSupply();
168                   List JavaDoc<KernelControllerContext> list = suppliers.get(supply);
169                   if (list != null)
170                   {
171                      list.remove(context);
172                      if (list.isEmpty())
173                         suppliers.remove(supply);
174                      if (trace)
175                         log.trace("Suppliers of " + supply + ": " + list);
176                   }
177                }
178             }
179             finally
180             {
181                unlockWrite();
182             }
183          }
184       }
185    }
186
187    public Kernel getKernel()
188    {
189       Kernel.checkAccess();
190       return kernel;
191    }
192
193    public void setKernel(Kernel kernel) throws Throwable JavaDoc
194    {
195       Kernel.checkConfigure();
196       this.kernel = kernel;
197    }
198
199    public void fireKernelEvent(KernelEvent event)
200    {
201       emitterDelegate.fireKernelEvent(event);
202    }
203
204    public void registerListener(KernelEventListener listener, KernelEventFilter filter, Object JavaDoc handback) throws Throwable JavaDoc
205    {
206       emitterDelegate.registerListener(listener, filter, handback);
207    }
208
209    public void unregisterListener(KernelEventListener listener, KernelEventFilter filter, Object JavaDoc handback) throws Throwable JavaDoc
210    {
211       emitterDelegate.unregisterListener(listener, filter, handback);
212    }
213
214    /**
215     * @return all instantiated contexts whose target is instance of this class clazz param
216     */

217    public Set JavaDoc<KernelControllerContext> getInstantiatedContexts(Class JavaDoc clazz)
218    {
219       lockRead();
220       try
221       {
222          ClassContext classContext = contextsByClass.get(clazz);
223          if (classContext != null)
224          {
225             if (log.isTraceEnabled())
226             {
227                log.trace("Marking class " + clazz + " as used.");
228             }
229             classContext.used = true;
230             return classContext.contexts;
231          }
232          return null;
233       }
234       finally
235       {
236          unlockRead();
237       }
238    }
239
240    /**
241     * add instantiated context into contextsByClass map
242     * look at all target's superclasses and interfaces
243     */

244    public void addInstantiatedContext(KernelControllerContext context)
245    {
246       prepareToTraverse(context, true);
247    }
248
249    /**
250     * remove instantiated context from contextsByClass map
251     * look at all target's superclasses and interfaces
252     */

253    public void removeInstantiatedContext(KernelControllerContext context)
254    {
255       prepareToTraverse(context, false);
256    }
257
258    protected void prepareToTraverse(KernelControllerContext context, boolean addition)
259    {
260       lockWrite();
261       try
262       {
263          Object JavaDoc target = context.getTarget();
264          if (target != null)
265          {
266             traverseBean(context, target.getClass(), addition, log.isTraceEnabled());
267          }
268       }
269       finally
270       {
271          unlockWrite();
272       }
273    }
274
275    /**
276     * Traverse over target and map it to all its superclasses
277     * and interfaces - using recursion.
278     *
279     * @param context context whose target is instance of clazz
280     * @param clazz current class to map context to
281     * @param addition whether this is an addition
282     * @param trace whether trace is enabled
283     */

284    protected void traverseBean(KernelControllerContext context, Class JavaDoc clazz, boolean addition, boolean trace)
285    {
286       if (clazz == null || clazz == Object JavaDoc.class)
287       {
288          return;
289       }
290       ClassContext classContext = contextsByClass.get(clazz);
291       if (addition)
292       {
293          if (classContext == null)
294          {
295             classContext = new ClassContext();
296             classContext.contexts = new HashSet JavaDoc<KernelControllerContext>();
297             contextsByClass.put(clazz, classContext);
298          }
299          else if (classContext.used)
300          {
301             log.warn("Additional matching bean - contextual injection already used for class: " + clazz);
302          }
303          if (trace)
304          {
305             log.trace("Mapping contex " + context + " to class: " + clazz);
306          }
307          classContext.contexts.add(context);
308       }
309       else
310       {
311          if (classContext != null)
312          {
313             if (trace)
314             {
315                log.trace("Removing contex " + context + " to class: " + clazz);
316             }
317             classContext.contexts.remove(context);
318          }
319       }
320       // traverse superclass
321
traverseBean(context, clazz.getSuperclass(), addition, trace);
322       Class JavaDoc[] interfaces = clazz.getInterfaces();
323       // traverse interfaces
324
for(Class JavaDoc intface : interfaces)
325       {
326          traverseBean(context, intface, addition, trace);
327       }
328    }
329
330    private class ClassContext
331    {
332       private boolean used;
333       private Set JavaDoc<KernelControllerContext> contexts;
334    }
335
336    /**
337     * If zero or multiple instances match class clazz
338     * a warning is issued, but no throwable is thrown
339     *
340     * @return context whose target is instance of this class clazz param or null if zero or multiple such instances
341     */

342    public KernelControllerContext getContextByClass(Class JavaDoc clazz)
343    {
344       Set JavaDoc<KernelControllerContext> contexts = getInstantiatedContexts(clazz);
345       int numberOfMatchingBeans = 0;
346       if (contexts != null)
347       {
348          numberOfMatchingBeans = contexts.size();
349       }
350
351       if (log.isTraceEnabled())
352       {
353          log.trace("Checking for contextual injection, current matches: " + numberOfMatchingBeans + " - " + clazz);
354       }
355
356       if (numberOfMatchingBeans != 1)
357       {
358          if (numberOfMatchingBeans > 1)
359          {
360             log.warn("Multiple beans match class type: " + clazz);
361          }
362          return null;
363       }
364       return contexts.iterator().next();
365    }
366
367 }
368
Popular Tags