001 /***************************************************************************** 002 * Copyright (C) PicoContainer Organization. All rights reserved. * 003 * ------------------------------------------------------------------------- * 004 * The software in this package is published under the terms of the BSD * 005 * style license a copy of which has been included with this distribution in * 006 * the LICENSE.txt file. * 007 * * 008 * Original code by the committers * 009 *****************************************************************************/ 010 package org.picocontainer.alternatives; 011 012 import java.io.Serializable; 013 014 import org.picocontainer.MutablePicoContainer; 015 import org.picocontainer.PicoContainer; 016 import org.picocontainer.defaults.CachingComponentAdapterFactory; 017 import org.picocontainer.defaults.ComponentAdapterFactory; 018 import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory; 019 import org.picocontainer.defaults.DefaultPicoContainer; 020 021 /** 022 * This special MutablePicoContainer hides implementations of components if the key is an interface. 023 * It's very simple. Instances that are registered directly and components registered without key 024 * are not hidden. Hiding is achieved with dynamic proxies from Java's reflection api. It also exhibits caching 025 * functionality. 026 * 027 * @see CachingPicoContainer 028 * @see ImplementationHidingPicoContainer 029 * @author Paul Hammant 030 * @version $Revision: 2424 $ 031 * @since 1.1 032 */ 033 public class ImplementationHidingCachingPicoContainer extends AbstractDelegatingMutablePicoContainer implements Serializable { 034 private final ComponentAdapterFactory caf; 035 036 /** 037 * Creates a new container with a parent container. 038 */ 039 public ImplementationHidingCachingPicoContainer(ComponentAdapterFactory caf, PicoContainer parent) { 040 super(new DefaultPicoContainer(makeComponentAdapterFactory(caf), parent)); 041 this.caf = caf; 042 } 043 044 private static CachingComponentAdapterFactory makeComponentAdapterFactory(ComponentAdapterFactory caf) { 045 if (caf instanceof CachingComponentAdapterFactory) { 046 // assume that implementation hiding CAF inside Caching one. 047 return (CachingComponentAdapterFactory) caf; 048 } 049 if (caf instanceof ImplementationHidingComponentAdapterFactory) { 050 return new CachingComponentAdapterFactory(caf); 051 } 052 return new CachingComponentAdapterFactory(new ImplementationHidingComponentAdapterFactory(caf, false)); 053 } 054 055 /** 056 * Creates a new container with a parent container. 057 */ 058 public ImplementationHidingCachingPicoContainer(PicoContainer parent) { 059 this(makeComponentAdapterFactory(new ConstructorInjectionComponentAdapterFactory()), parent); 060 } 061 062 /** 063 * Creates a new container with a parent container. 064 */ 065 public ImplementationHidingCachingPicoContainer(ComponentAdapterFactory caf) { 066 this(makeComponentAdapterFactory(caf), null); 067 } 068 069 070 /** 071 * Creates a new container with no parent container. 072 */ 073 public ImplementationHidingCachingPicoContainer() { 074 this((PicoContainer) null); 075 } 076 077 078 public MutablePicoContainer makeChildContainer() { 079 ImplementationHidingCachingPicoContainer pc = new ImplementationHidingCachingPicoContainer(caf, this); 080 getDelegate().addChildContainer(pc); 081 return pc; 082 } 083 084 }