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 * 009 *****************************************************************************/ 010 package org.picocontainer.behaviors; 011 012 import java.io.Serializable; 013 import java.util.ArrayList; 014 import java.util.List; 015 import java.util.Properties; 016 017 import org.picocontainer.BehaviorFactory; 018 import org.picocontainer.Characteristics; 019 import org.picocontainer.ComponentAdapter; 020 import org.picocontainer.ComponentFactory; 021 import org.picocontainer.ComponentMonitor; 022 import org.picocontainer.LifecycleStrategy; 023 import org.picocontainer.Parameter; 024 import org.picocontainer.PicoCompositionException; 025 import org.picocontainer.PicoContainer; 026 import org.picocontainer.PicoVisitor; 027 import org.picocontainer.annotations.Cache; 028 import org.picocontainer.injectors.AdaptingInjection; 029 030 @SuppressWarnings("serial") 031 public class AdaptingBehavior implements BehaviorFactory, Serializable { 032 033 034 public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, 035 LifecycleStrategy lifecycleStrategy, 036 Properties componentProperties, 037 Object componentKey, 038 Class componentImplementation, 039 Parameter... parameters) throws PicoCompositionException { 040 List<BehaviorFactory> list = new ArrayList<BehaviorFactory>(); 041 ComponentFactory lastFactory = makeInjectionFactory(); 042 processSynchronizing(componentProperties, list); 043 processLocking(componentProperties, list); 044 processPropertyApplying(componentProperties, list); 045 processAutomatic(componentProperties, list); 046 processImplementationHiding(componentProperties, list); 047 processCaching(componentProperties, componentImplementation, list); 048 049 //Instantiate Chain of ComponentFactories 050 for (ComponentFactory componentFactory : list) { 051 if (lastFactory != null && componentFactory instanceof BehaviorFactory) { 052 ((BehaviorFactory)componentFactory).wrap(lastFactory); 053 } 054 lastFactory = componentFactory; 055 } 056 057 return lastFactory.createComponentAdapter(componentMonitor, 058 lifecycleStrategy, 059 componentProperties, 060 componentKey, 061 componentImplementation, 062 parameters); 063 } 064 065 066 public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, 067 LifecycleStrategy lifecycleStrategy, 068 Properties componentProperties, 069 ComponentAdapter adapter) { 070 List<BehaviorFactory> list = new ArrayList<BehaviorFactory>(); 071 processSynchronizing(componentProperties, list); 072 processImplementationHiding(componentProperties, list); 073 processCaching(componentProperties, adapter.getComponentImplementation(), list); 074 075 //Instantiate Chain of ComponentFactories 076 BehaviorFactory lastFactory = null; 077 for (BehaviorFactory componentFactory : list) { 078 if (lastFactory != null) { 079 componentFactory.wrap(lastFactory); 080 } 081 lastFactory = componentFactory; 082 } 083 084 if (lastFactory == null) { 085 return adapter; 086 } 087 088 089 return lastFactory.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); 090 } 091 092 public void verify(PicoContainer container) { 093 } 094 095 public void accept(PicoVisitor visitor) { 096 visitor.visitComponentFactory(this); 097 098 } 099 100 protected AdaptingInjection makeInjectionFactory() { 101 return new AdaptingInjection(); 102 } 103 104 protected void processSynchronizing(Properties componentProperties, List<BehaviorFactory> list) { 105 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE)) { 106 list.add(new Synchronizing()); 107 } 108 } 109 110 protected void processLocking(Properties componentProperties, List<BehaviorFactory> list) { 111 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.LOCK)) { 112 list.add(new Locking()); 113 } 114 } 115 116 protected void processCaching(Properties componentProperties, 117 Class componentImplementation, 118 List<BehaviorFactory> list) { 119 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE) || 120 componentImplementation.getAnnotation(Cache.class) != null) { 121 list.add(new Caching()); 122 } 123 AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE); 124 } 125 126 protected void processImplementationHiding(Properties componentProperties, 127 List<BehaviorFactory> list) { 128 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL)) { 129 list.add(new ImplementationHiding()); 130 } 131 AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL); 132 } 133 134 protected void processPropertyApplying(Properties componentProperties, 135 List<BehaviorFactory> list) { 136 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING)) { 137 list.add(new PropertyApplying()); 138 } 139 } 140 141 protected void processAutomatic(Properties componentProperties, 142 List<BehaviorFactory> list) { 143 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC)) { 144 list.add(new Automating()); 145 } 146 } 147 148 149 public ComponentFactory wrap(ComponentFactory delegate) { 150 throw new UnsupportedOperationException(); 151 } 152 }