1 16 package com.jdon.container.pico; 17 18 import java.io.Serializable ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import org.picocontainer.ComponentAdapter; 29 import org.picocontainer.MutablePicoContainer; 30 import org.picocontainer.Parameter; 31 import org.picocontainer.PicoContainer; 32 import org.picocontainer.PicoException; 33 import org.picocontainer.PicoRegistrationException; 34 import org.picocontainer.PicoVerificationException; 35 import org.picocontainer.PicoVisitor; 36 import org.picocontainer.alternatives.ImmutablePicoContainer; 37 import org.picocontainer.defaults.AmbiguousComponentResolutionException; 38 import org.picocontainer.defaults.CachingComponentAdapter; 39 import org.picocontainer.defaults.CachingComponentAdapterFactory; 40 import org.picocontainer.defaults.ComponentAdapterFactory; 41 import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory; 42 import org.picocontainer.defaults.DefaultComponentAdapterFactory; 43 import org.picocontainer.defaults.DefaultPicoContainer; 44 import org.picocontainer.defaults.DuplicateComponentKeyRegistrationException; 45 import org.picocontainer.defaults.InstanceComponentAdapter; 46 import org.picocontainer.defaults.LifecycleVisitor; 47 import org.picocontainer.defaults.VerifyingVisitor; 48 49 import com.jdon.util.Debug; 50 51 57 public class JdonPicoContainer implements MutablePicoContainer, Serializable { 58 public final static String module = JdonPicoContainer.class.getName(); 59 60 61 private Map componentKeyToAdapterCache = new HashMap (); 62 63 private Map componentKeyToInstanceCache = new HashMap (); 64 65 private ComponentAdapterFactory componentAdapterFactory; 66 private PicoContainer parent; 67 private List componentAdapters = new ArrayList (); 68 69 private List orderedComponentAdapters = new ArrayList (); 71 72 private boolean started = false; 73 private boolean disposed = false; 74 private HashSet children = new HashSet (); 75 76 89 public JdonPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) { 90 if(componentAdapterFactory == null) throw new NullPointerException ("componentAdapterFactory"); 91 this.componentAdapterFactory = componentAdapterFactory; 92 this.parent = parent == null ? null : new ImmutablePicoContainer(parent); 93 } 94 95 99 public JdonPicoContainer(PicoContainer parent) { 100 this(new DefaultComponentAdapterFactory(), parent); 101 } 102 103 108 public JdonPicoContainer(ComponentAdapterFactory componentAdapterFactory) { 109 this(componentAdapterFactory, null); 110 } 111 112 115 public JdonPicoContainer() { 116 this(new DefaultComponentAdapterFactory(), null); 117 } 118 119 public Collection getComponentAdapters() { 120 return Collections.unmodifiableList(componentAdapters); 121 } 122 123 public final ComponentAdapter getComponentAdapter(Object componentKey) throws AmbiguousComponentResolutionException { 124 ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.get(componentKey); 125 if (adapter == null && parent != null) { 126 adapter = parent.getComponentAdapter(componentKey); 127 } 128 return adapter; 129 } 130 131 public ComponentAdapter getComponentAdapterOfType(Class componentType) { 132 ComponentAdapter adapterByKey = getComponentAdapter(componentType); 134 if (adapterByKey != null) { 135 return adapterByKey; 136 } 137 138 List found = getComponentAdaptersOfType(componentType); 139 140 if (found.size() == 1) { 141 return ((ComponentAdapter) found.get(0)); 142 } else if (found.size() == 0) { 143 if (parent != null) { 144 return parent.getComponentAdapterOfType(componentType); 145 } else { 146 return null; 147 } 148 } else { 149 Class [] foundClasses = new Class [found.size()]; 150 for (int i = 0; i < foundClasses.length; i++) { 151 ComponentAdapter componentAdapter = (ComponentAdapter) found.get(i); 152 foundClasses[i] = componentAdapter.getComponentImplementation(); 153 } 154 155 throw new AmbiguousComponentResolutionException(componentType, foundClasses); 156 } 157 } 158 159 public List getComponentAdaptersOfType(Class componentType) { 160 if(componentType == null) { 161 return Collections.EMPTY_LIST; 162 } 163 List found = new ArrayList (); 164 for (Iterator iterator = getComponentAdapters().iterator(); iterator.hasNext();) { 165 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 166 167 if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) { 168 found.add(componentAdapter); 169 } 170 } 171 return found; 172 } 173 174 179 public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws DuplicateComponentKeyRegistrationException { 180 Object componentKey = componentAdapter.getComponentKey(); 181 if (componentKeyToAdapterCache.containsKey(componentKey)) { 182 throw new DuplicateComponentKeyRegistrationException(componentKey); 183 } 184 componentAdapters.add(componentAdapter); 185 componentKeyToAdapterCache.put(componentKey, componentAdapter); 186 return componentAdapter; 187 } 188 189 public ComponentAdapter unregisterComponent(Object componentKey) { 190 ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.remove(componentKey); 191 componentAdapters.remove(adapter); 192 orderedComponentAdapters.remove(adapter); 193 return adapter; 194 } 195 196 200 public ComponentAdapter registerComponentInstance(Object component) throws PicoRegistrationException { 201 return registerComponentInstance(component.getClass(), component); 202 } 203 204 208 public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException { 209 if (componentInstance instanceof MutablePicoContainer) { 210 MutablePicoContainer pc = (MutablePicoContainer) componentInstance; 211 Object contrivedKey = new Object (); 212 String contrivedComp = ""; 213 pc.registerComponentInstance(contrivedKey, contrivedComp); 214 try { 215 if (this.getComponentInstance(contrivedKey) != null) { 216 throw new PicoRegistrationException("Cannot register a container to itself. The container is already implicitly registered."); 217 } 218 } finally { 219 pc.unregisterComponent(contrivedKey); 220 } 221 222 } 223 ComponentAdapter componentAdapter = new InstanceComponentAdapter(componentKey, componentInstance); 224 registerComponent(componentAdapter); 225 return componentAdapter; 226 } 227 228 233 public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException { 234 return registerComponentImplementation(componentImplementation, componentImplementation); 235 } 236 237 242 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) throws PicoRegistrationException { 243 return registerComponentImplementation(componentKey, componentImplementation, (Parameter[]) null); 244 } 245 246 251 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException { 252 ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters); 253 registerComponent(componentAdapter); 254 return componentAdapter; 255 } 256 257 261 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, List parameters) throws PicoRegistrationException { 262 Parameter[] parametersAsArray = (Parameter[]) parameters.toArray(new Parameter[parameters.size()]); 263 return registerComponentImplementation(componentKey, componentImplementation, parametersAsArray); 264 } 265 266 private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) { 267 if (!orderedComponentAdapters.contains(componentAdapter)) { 268 orderedComponentAdapters.add(componentAdapter); 269 } 270 } 271 272 public List getComponentInstances() throws PicoException { 273 return getComponentInstancesOfType(Object .class); 274 } 275 276 public List getComponentInstancesOfType(Class componentType) throws PicoException { 277 if(componentType == null) { 278 return Collections.EMPTY_LIST; 279 } 280 281 Map adapterToInstanceMap = new HashMap (); 282 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 283 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 284 if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) { 285 Object componentInstance = getInstance(componentAdapter); 286 adapterToInstanceMap.put(componentAdapter, componentInstance); 287 288 addOrderedComponentAdapter(componentAdapter); 291 } 292 } 293 List result = new ArrayList (); 294 for (Iterator iterator = orderedComponentAdapters.iterator(); iterator.hasNext();) { 295 Object componentAdapter = iterator.next(); 296 final Object componentInstance = adapterToInstanceMap.get(componentAdapter); 297 if (componentInstance != null) { 298 result.add(componentInstance); 301 } 302 } 303 return result; 304 } 305 306 public Object getComponentInstance(Object componentKey) throws PicoException { 307 ComponentAdapter componentAdapter = getComponentAdapter(componentKey); 308 if (componentAdapter != null) { 309 return getInstance(componentAdapter); 310 } else { 311 return null; 312 } 313 } 314 315 public Object getComponentInstanceOfType(Class componentType) { 316 final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType); 317 return componentAdapter == null ? null : getInstance(componentAdapter); 318 } 319 320 325 public Object getInstance(ComponentAdapter componentAdapter) { 326 Object componentKey = componentAdapter.getComponentKey(); 327 Object instance = componentKeyToInstanceCache.get(componentKey); 328 if (instance == null) { 329 if (componentAdapter != null) { 330 instance = getTrueInstance(componentAdapter); 331 if (instance != null){ 332 componentKeyToInstanceCache.put(componentKey, instance); 333 } 334 } 335 } 336 return instance; 337 338 } 339 340 private Object getTrueInstance(ComponentAdapter componentAdapter) { 341 342 final boolean isLocal = componentAdapters.contains(componentAdapter); 345 346 if (isLocal) { 347 Object instance = componentAdapter.getComponentInstance(this); 348 349 addOrderedComponentAdapter(componentAdapter); 350 351 return instance; 352 } else if (parent != null) { 353 return parent.getComponentInstance(componentAdapter.getComponentKey()); 354 } 355 356 return null; 359 } 360 361 362 363 public PicoContainer getParent() { 364 return parent; 365 } 366 367 public ComponentAdapter unregisterComponentByInstance(Object componentInstance) { 368 Collection componentAdapters = getComponentAdapters(); 369 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 370 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 371 if (getInstance(componentAdapter).equals(componentInstance)) { 372 return unregisterComponent(componentAdapter.getComponentKey()); 373 } 374 } 375 return null; 376 } 377 378 381 public void verify() throws PicoVerificationException { 382 new VerifyingVisitor().traverse(this); 383 } 384 385 392 public void start() { 393 if (disposed) throw new IllegalStateException ("Already disposed"); 394 if (started) throw new IllegalStateException ("Already started"); 395 LifecycleVisitor.start(this); 396 started = true; 397 } 398 399 406 public void stop() { 407 if (disposed) throw new IllegalStateException ("Already disposed"); 408 if (!started) throw new IllegalStateException ("Not started"); 409 LifecycleVisitor.stop(this); 410 started = false; 411 } 412 413 420 public void dispose() { 421 if (disposed) throw new IllegalStateException ("Already disposed"); 422 LifecycleVisitor.dispose(this); 423 disposed = true; 424 } 425 426 public MutablePicoContainer makeChildContainer() { 427 DefaultPicoContainer pc = new DefaultPicoContainer(componentAdapterFactory, this); 428 addChildContainer(pc); 429 return pc; 430 } 431 432 public boolean addChildContainer(PicoContainer child) { 433 return children.add(child); 434 } 435 436 public boolean removeChildContainer(PicoContainer child) { 437 final boolean result = children.remove(child); 438 return result; 439 } 440 441 public void accept(PicoVisitor visitor) { 442 visitor.visitContainer(this); 443 final List componentAdapters = new ArrayList (getComponentAdapters()); 444 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 445 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 446 componentAdapter.accept(visitor); 447 } 448 final List allChildren = new ArrayList (children); 449 for (Iterator iterator = allChildren.iterator(); iterator.hasNext();) { 450 PicoContainer child = (PicoContainer) iterator.next(); 451 child.accept(visitor); 452 } 453 } 454 } | Popular Tags |