001    /*******************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved. *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD * style
005     * license a copy of which has been included with this distribution in * the
006     * LICENSE.txt file. * * Original code by *
007     ******************************************************************************/
008    package org.picocontainer.behaviors;
009    
010    import java.io.Serializable;
011    import java.util.Enumeration;
012    import java.util.Properties;
013    
014    import org.picocontainer.BehaviorFactory;
015    import org.picocontainer.ComponentAdapter;
016    import org.picocontainer.ComponentFactory;
017    import org.picocontainer.ComponentMonitor;
018    import org.picocontainer.LifecycleStrategy;
019    import org.picocontainer.Parameter;
020    import org.picocontainer.PicoCompositionException;
021    import org.picocontainer.PicoContainer;
022    import org.picocontainer.PicoVisitor;
023    import org.picocontainer.Characteristics;
024    import org.picocontainer.InjectionFactory;
025    import org.picocontainer.injectors.AdaptingInjection;
026    
027    @SuppressWarnings("serial")
028    public class AbstractBehaviorFactory implements ComponentFactory, Serializable, BehaviorFactory {
029    
030        private ComponentFactory delegate;
031    
032    
033        public ComponentFactory wrap(ComponentFactory delegate) {
034            this.delegate = delegate;
035            return this;
036        }
037    
038        public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor,
039                LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey,
040                Class<T> componentImplementation, Parameter... parameters) throws PicoCompositionException {
041            if (delegate == null) {
042                delegate = new AdaptingInjection();
043            }
044            ComponentAdapter<T> compAdapter = delegate.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey,
045                    componentImplementation, parameters);
046    
047            boolean enableCircular = removePropertiesIfPresent(componentProperties, Characteristics.ENABLE_CIRCULAR);
048            if (enableCircular && delegate instanceof InjectionFactory) {
049                return componentMonitor.newBehavior(new HiddenImplementation(compAdapter));
050            } else {
051                return compAdapter;
052            }
053        }
054    
055        public void verify(PicoContainer container) {
056            delegate.verify(container);
057        }
058    
059        public void accept(PicoVisitor visitor) {
060            visitor.visitComponentFactory(this);
061            if (delegate != null) {
062                delegate.accept(visitor);
063            }
064        }
065    
066    
067        public <T> ComponentAdapter<T> addComponentAdapter(ComponentMonitor componentMonitor,
068                LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter<T> adapter) {
069            if (delegate != null && delegate instanceof BehaviorFactory) {
070                return ((BehaviorFactory) delegate).addComponentAdapter(componentMonitor, lifecycleStrategy,
071                        componentProperties, adapter);
072            }
073            return adapter;
074        }
075    
076        public static boolean arePropertiesPresent(Properties current, Properties present, boolean compareValueToo) {
077            Enumeration<?> keys = present.keys();
078            while (keys.hasMoreElements()) {
079                String key = (String) keys.nextElement();
080                String presentValue = present.getProperty(key);
081                String currentValue = current.getProperty(key);
082                if (currentValue == null) {
083                    return false;
084                }
085                if (!presentValue.equals(currentValue) && compareValueToo) {
086                    return false;
087                }
088            }
089            return true;
090        }
091    
092        public static boolean removePropertiesIfPresent(Properties current, Properties present) {
093            if (!arePropertiesPresent(current, present, true)) {
094                return false;
095            }
096            Enumeration<?> keys = present.keys();
097            while (keys.hasMoreElements()) {
098                Object key = keys.nextElement();
099                current.remove(key);
100            }
101            return true;
102        }
103    
104        public static String getAndRemovePropertiesIfPresentByKey(Properties current, Properties present) {
105            if (!arePropertiesPresent(current, present, false)) {
106                return null;
107            }
108            Enumeration<?> keys = present.keys();
109            String value = null;
110            while (keys.hasMoreElements()) {
111                Object key = keys.nextElement();
112                value = (String) current.remove(key);
113            }
114            return value;
115        }
116    
117        protected void mergeProperties(Properties into, Properties from) {
118            Enumeration<?> e = from.propertyNames();
119            while (e.hasMoreElements()) {
120                String s = (String) e.nextElement();
121                into.setProperty(s, from.getProperty(s));
122            }
123    
124        }
125    
126    }