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 }