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 processGuarding(componentProperties, componentImplementation, list); 049 050 //Instantiate Chain of ComponentFactories 051 for (ComponentFactory componentFactory : list) { 052 if (lastFactory != null && componentFactory instanceof BehaviorFactory) { 053 ((BehaviorFactory)componentFactory).wrap(lastFactory); 054 } 055 lastFactory = componentFactory; 056 } 057 058 return lastFactory.createComponentAdapter(componentMonitor, 059 lifecycleStrategy, 060 componentProperties, 061 componentKey, 062 componentImplementation, 063 parameters); 064 } 065 066 067 public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, 068 LifecycleStrategy lifecycleStrategy, 069 Properties componentProperties, 070 ComponentAdapter adapter) { 071 List<BehaviorFactory> list = new ArrayList<BehaviorFactory>(); 072 processSynchronizing(componentProperties, list); 073 processImplementationHiding(componentProperties, list); 074 processCaching(componentProperties, adapter.getComponentImplementation(), list); 075 processGuarding(componentProperties, adapter.getComponentImplementation(), list); 076 077 //Instantiate Chain of ComponentFactories 078 BehaviorFactory lastFactory = null; 079 for (BehaviorFactory componentFactory : list) { 080 if (lastFactory != null) { 081 componentFactory.wrap(lastFactory); 082 } 083 lastFactory = componentFactory; 084 } 085 086 if (lastFactory == null) { 087 return adapter; 088 } 089 090 091 return lastFactory.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); 092 } 093 094 public void verify(PicoContainer container) { 095 } 096 097 public void accept(PicoVisitor visitor) { 098 visitor.visitComponentFactory(this); 099 100 } 101 102 protected AdaptingInjection makeInjectionFactory() { 103 return new AdaptingInjection(); 104 } 105 106 protected void processSynchronizing(Properties componentProperties, List<BehaviorFactory> list) { 107 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE)) { 108 list.add(new Synchronizing()); 109 } 110 } 111 112 protected void processLocking(Properties componentProperties, List<BehaviorFactory> list) { 113 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.LOCK)) { 114 list.add(new Locking()); 115 } 116 } 117 118 protected void processCaching(Properties componentProperties, 119 Class componentImplementation, 120 List<BehaviorFactory> list) { 121 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE) || 122 componentImplementation.getAnnotation(Cache.class) != null) { 123 list.add(new Caching()); 124 } 125 AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE); 126 } 127 128 protected void processGuarding(Properties componentProperties, Class componentImplementation, List<BehaviorFactory> list) { 129 if (AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.GUARD, false)) { 130 list.add(new Guarding()); 131 } 132 } 133 134 protected void processImplementationHiding(Properties componentProperties, 135 List<BehaviorFactory> list) { 136 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL)) { 137 list.add(new ImplementationHiding()); 138 } 139 AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL); 140 } 141 142 protected void processPropertyApplying(Properties componentProperties, 143 List<BehaviorFactory> list) { 144 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING)) { 145 list.add(new PropertyApplying()); 146 } 147 } 148 149 protected void processAutomatic(Properties componentProperties, 150 List<BehaviorFactory> list) { 151 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC)) { 152 list.add(new Automating()); 153 } 154 } 155 156 157 public ComponentFactory wrap(ComponentFactory delegate) { 158 throw new UnsupportedOperationException(); 159 } 160 }