1 22 package org.jboss.kernel.plugins.dependency; 23 24 import java.util.HashSet ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Set ; 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 52 public class AbstractKernelController extends AbstractController implements KernelController, KernelRegistryPlugin 53 { 54 55 protected Kernel kernel; 56 57 58 protected AbstractEventEmitter emitterDelegate = new AbstractEventEmitter(); 59 60 61 protected Map <Object , List <KernelControllerContext>> suppliers = CollectionsFactory.createConcurrentReaderMap(); 62 63 64 protected Map <Class , ClassContext> contextsByClass = CollectionsFactory.createConcurrentReaderMap(); 65 66 71 public AbstractKernelController() throws Exception 72 { 73 } 74 75 public KernelControllerContext install(BeanMetaData metaData) throws Throwable 76 { 77 return install(metaData, null); 78 } 79 80 public KernelControllerContext install(BeanMetaData metaData, Object target) throws Throwable 81 { 82 KernelControllerContext context = new AbstractKernelControllerContext(null, metaData, target); 83 install(context); 84 return context; 85 } 86 87 public KernelRegistryEntry getEntry(Object name) 88 { 89 List <KernelControllerContext> list = suppliers.get(name); 90 if (list != null && list.isEmpty() == false) 91 return list.get(0); 92 else if (name instanceof Class ) 93 return getContextByClass((Class )name); 94 else 95 return null; 96 } 97 98 public ControllerContext getContext(Object 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 ignored) 111 { 112 } 113 } 114 return null; 115 } 116 117 public void addSupplies(KernelControllerContext context) 118 { 119 BeanMetaData metaData = context.getBeanMetaData(); 120 Set <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 supply = supplied.getSupply(); 133 List <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 <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 supply = supplied.getSupply(); 168 List <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 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 handback) throws Throwable 205 { 206 emitterDelegate.registerListener(listener, filter, handback); 207 } 208 209 public void unregisterListener(KernelEventListener listener, KernelEventFilter filter, Object handback) throws Throwable 210 { 211 emitterDelegate.unregisterListener(listener, filter, handback); 212 } 213 214 217 public Set <KernelControllerContext> getInstantiatedContexts(Class 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 244 public void addInstantiatedContext(KernelControllerContext context) 245 { 246 prepareToTraverse(context, true); 247 } 248 249 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 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 284 protected void traverseBean(KernelControllerContext context, Class clazz, boolean addition, boolean trace) 285 { 286 if (clazz == null || clazz == Object .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 <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 traverseBean(context, clazz.getSuperclass(), addition, trace); 322 Class [] interfaces = clazz.getInterfaces(); 323 for(Class intface : interfaces) 325 { 326 traverseBean(context, intface, addition, trace); 327 } 328 } 329 330 private class ClassContext 331 { 332 private boolean used; 333 private Set <KernelControllerContext> contexts; 334 } 335 336 342 public KernelControllerContext getContextByClass(Class clazz) 343 { 344 Set <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 |