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