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