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 ******************************************************************************/
008package org.picocontainer.behaviors;
009
010import java.io.Serializable;
011import java.util.Enumeration;
012import java.util.Properties;
013
014import org.picocontainer.BehaviorFactory;
015import org.picocontainer.ComponentAdapter;
016import org.picocontainer.ComponentFactory;
017import org.picocontainer.ComponentMonitor;
018import org.picocontainer.LifecycleStrategy;
019import org.picocontainer.Parameter;
020import org.picocontainer.PicoCompositionException;
021import org.picocontainer.PicoContainer;
022import org.picocontainer.PicoVisitor;
023import org.picocontainer.Characteristics;
024import org.picocontainer.InjectionFactory;
025import org.picocontainer.injectors.AdaptingInjection;
026
027@SuppressWarnings("serial")
028public 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}