1 10 package org.picocontainer.defaults; 11 12 import org.picocontainer.ComponentAdapter; 13 import org.picocontainer.LifecycleManager; 14 import org.picocontainer.MutablePicoContainer; 15 import org.picocontainer.Parameter; 16 import org.picocontainer.PicoContainer; 17 import org.picocontainer.PicoException; 18 import org.picocontainer.PicoRegistrationException; 19 import org.picocontainer.PicoVerificationException; 20 import org.picocontainer.PicoVisitor; 21 import org.picocontainer.Startable; 22 import org.picocontainer.Disposable; 23 import org.picocontainer.alternatives.ImmutablePicoContainer; 24 25 import java.io.Serializable ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 35 61 public class DefaultPicoContainer implements MutablePicoContainer, Serializable { 62 63 private Map componentKeyToAdapterCache = new HashMap (); 64 private ComponentAdapterFactory componentAdapterFactory; 65 private PicoContainer parent; 66 private List componentAdapters = new ArrayList (); 67 68 private List orderedComponentAdapters = new ArrayList (); 70 71 private boolean started = false; 72 private boolean disposed = false; 73 private HashSet children = new HashSet (); 74 private LifecycleManager lifecycleManager; 75 76 90 public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent, 91 LifecycleManager lifecycleManager) { 92 this.lifecycleManager = lifecycleManager; 93 if (componentAdapterFactory == null) throw new NullPointerException ("componentAdapterFactory"); 94 this.componentAdapterFactory = componentAdapterFactory; 95 this.parent = parent == null ? null : new ImmutablePicoContainer(parent); 96 } 97 98 99 112 public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) { 113 this(componentAdapterFactory, parent, new DefaultLifecycleManager()); 114 } 115 116 120 public DefaultPicoContainer(PicoContainer parent) { 121 this(new DefaultComponentAdapterFactory(), parent); 122 } 123 124 129 public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory) { 130 this(componentAdapterFactory, null); 131 } 132 133 138 public DefaultPicoContainer(LifecycleManager lifecycleManager) { 139 this(new DefaultComponentAdapterFactory(), null, lifecycleManager); 140 } 141 142 145 public DefaultPicoContainer() { 146 this(new DefaultComponentAdapterFactory(), null); 147 } 148 149 public Collection getComponentAdapters() { 150 return Collections.unmodifiableList(componentAdapters); 151 } 152 153 public final ComponentAdapter getComponentAdapter(Object componentKey) throws AmbiguousComponentResolutionException { 154 ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.get(componentKey); 155 if (adapter == null && parent != null) { 156 adapter = parent.getComponentAdapter(componentKey); 157 } 158 return adapter; 159 } 160 161 public ComponentAdapter getComponentAdapterOfType(Class componentType) { 162 ComponentAdapter adapterByKey = getComponentAdapter(componentType); 164 if (adapterByKey != null) { 165 return adapterByKey; 166 } 167 168 List found = getComponentAdaptersOfType(componentType); 169 170 if (found.size() == 1) { 171 return ((ComponentAdapter) found.get(0)); 172 } else if (found.size() == 0) { 173 if (parent != null) { 174 return parent.getComponentAdapterOfType(componentType); 175 } else { 176 return null; 177 } 178 } else { 179 Class [] foundClasses = new Class [found.size()]; 180 for (int i = 0; i < foundClasses.length; i++) { 181 foundClasses[i] = ((ComponentAdapter) found.get(i)).getComponentImplementation(); 182 } 183 184 throw new AmbiguousComponentResolutionException(componentType, foundClasses); 185 } 186 } 187 188 public List getComponentAdaptersOfType(Class componentType) { 189 if (componentType == null) { 190 return Collections.EMPTY_LIST; 191 } 192 List found = new ArrayList (); 193 for (Iterator iterator = getComponentAdapters().iterator(); iterator.hasNext();) { 194 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 195 196 if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) { 197 found.add(componentAdapter); 198 } 199 } 200 return found; 201 } 202 203 208 public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws DuplicateComponentKeyRegistrationException { 209 Object componentKey = componentAdapter.getComponentKey(); 210 if (componentKeyToAdapterCache.containsKey(componentKey)) { 211 throw new DuplicateComponentKeyRegistrationException(componentKey); 212 } 213 componentAdapters.add(componentAdapter); 214 componentKeyToAdapterCache.put(componentKey, componentAdapter); 215 return componentAdapter; 216 } 217 218 public ComponentAdapter unregisterComponent(Object componentKey) { 219 ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.remove(componentKey); 220 componentAdapters.remove(adapter); 221 orderedComponentAdapters.remove(adapter); 222 return adapter; 223 } 224 225 229 public ComponentAdapter registerComponentInstance(Object component) throws PicoRegistrationException { 230 return registerComponentInstance(component.getClass(), component); 231 } 232 233 237 public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException { 238 ComponentAdapter componentAdapter = new InstanceComponentAdapter(componentKey, componentInstance); 239 registerComponent(componentAdapter); 240 return componentAdapter; 241 } 242 243 248 public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException { 249 return registerComponentImplementation(componentImplementation, componentImplementation); 250 } 251 252 257 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) throws PicoRegistrationException { 258 return registerComponentImplementation(componentKey, componentImplementation, (Parameter[]) null); 259 } 260 261 266 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException { 267 ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters); 268 registerComponent(componentAdapter); 269 return componentAdapter; 270 } 271 272 276 public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, List parameters) throws PicoRegistrationException { 277 Parameter[] parametersAsArray = (Parameter[]) parameters.toArray(new Parameter[parameters.size()]); 278 return registerComponentImplementation(componentKey, componentImplementation, parametersAsArray); 279 } 280 281 private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) { 282 if (!orderedComponentAdapters.contains(componentAdapter)) { 283 orderedComponentAdapters.add(componentAdapter); 284 } 285 } 286 287 public List getComponentInstances() throws PicoException { 288 return getComponentInstancesOfType(Object .class); 289 } 290 291 public List getComponentInstancesOfType(Class componentType) throws PicoException { 292 if (componentType == null) { 293 return Collections.EMPTY_LIST; 294 } 295 296 Map adapterToInstanceMap = new HashMap (); 297 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 298 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 299 if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) { 300 Object componentInstance = getInstance(componentAdapter); 301 adapterToInstanceMap.put(componentAdapter, componentInstance); 302 303 addOrderedComponentAdapter(componentAdapter); 306 } 307 } 308 List result = new ArrayList (); 309 for (Iterator iterator = orderedComponentAdapters.iterator(); iterator.hasNext();) { 310 Object componentAdapter = iterator.next(); 311 final Object componentInstance = adapterToInstanceMap.get(componentAdapter); 312 if (componentInstance != null) { 313 result.add(componentInstance); 316 } 317 } 318 return result; 319 } 320 321 public Object getComponentInstance(Object componentKey) throws PicoException { 322 ComponentAdapter componentAdapter = getComponentAdapter(componentKey); 323 if (componentAdapter != null) { 324 return getInstance(componentAdapter); 325 } else { 326 return null; 327 } 328 } 329 330 public Object getComponentInstanceOfType(Class componentType) { 331 final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType); 332 return componentAdapter == null ? null : getInstance(componentAdapter); 333 } 334 335 private Object getInstance(ComponentAdapter componentAdapter) { 336 final boolean isLocal = componentAdapters.contains(componentAdapter); 339 340 if (isLocal) { 341 Object instance = componentAdapter.getComponentInstance(this); 342 343 addOrderedComponentAdapter(componentAdapter); 344 345 return instance; 346 } else if (parent != null) { 347 return parent.getComponentInstance(componentAdapter.getComponentKey()); 348 } 349 350 return null; 353 } 354 355 356 public PicoContainer getParent() { 357 return parent; 358 } 359 360 public ComponentAdapter unregisterComponentByInstance(Object componentInstance) { 361 Collection componentAdapters = getComponentAdapters(); 362 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 363 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 364 if (getInstance(componentAdapter).equals(componentInstance)) { 365 return unregisterComponent(componentAdapter.getComponentKey()); 366 } 367 } 368 return null; 369 } 370 371 374 public void verify() throws PicoVerificationException { 375 new VerifyingVisitor().traverse(this); 376 } 377 378 386 public void start() { 387 if (disposed) throw new IllegalStateException ("Already disposed"); 388 if (started) throw new IllegalStateException ("Already started"); 389 lifecycleManager.start(this); 390 for (Iterator iterator = children.iterator(); iterator.hasNext();) { 391 PicoContainer child = (PicoContainer) iterator.next(); 392 if (child instanceof Startable) { 393 child.start(); 394 } 395 } 396 started = true; 397 } 398 399 407 public void stop() { 408 if (disposed) throw new IllegalStateException ("Already disposed"); 409 if (!started) throw new IllegalStateException ("Not started"); 410 for (Iterator iterator = children.iterator(); iterator.hasNext();) { 411 PicoContainer child = (PicoContainer) iterator.next(); 412 if (child instanceof Startable) { 413 child.stop(); 414 } 415 } 416 lifecycleManager.stop(this); 417 started = false; 418 } 419 420 428 public void dispose() { 429 if (disposed) throw new IllegalStateException ("Already disposed"); 430 for (Iterator iterator = children.iterator(); iterator.hasNext();) { 431 PicoContainer child = (PicoContainer) iterator.next(); 432 if (child instanceof Disposable) { 433 child.dispose(); 434 } 435 } 436 lifecycleManager.dispose(this); 437 disposed = true; 438 } 439 440 public MutablePicoContainer makeChildContainer() { 441 DefaultPicoContainer pc = new DefaultPicoContainer(componentAdapterFactory, this, lifecycleManager); 442 addChildContainer(pc); 443 return pc; 444 } 445 446 public boolean addChildContainer(PicoContainer child) { 447 return children.add(child); 448 } 449 450 public boolean removeChildContainer(PicoContainer child) { 451 final boolean result = children.remove(child); 452 return result; 453 } 454 455 public void accept(PicoVisitor visitor) { 456 visitor.visitContainer(this); 457 final List componentAdapters = new ArrayList (getComponentAdapters()); 458 for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) { 459 ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next(); 460 componentAdapter.accept(visitor); 461 } 462 final List allChildren = new ArrayList (children); 463 for (Iterator iterator = allChildren.iterator(); iterator.hasNext();) { 464 PicoContainer child = (PicoContainer) iterator.next(); 465 child.accept(visitor); 466 } 467 } 468 } 469 | Popular Tags |