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 *****************************************************************************/
009package org.picocontainer.gems.util;
010
011import org.picocontainer.ComponentAdapter;
012import org.picocontainer.MutablePicoContainer;
013import org.picocontainer.adapters.InstanceAdapter;
014import org.picocontainer.DefaultPicoContainer;
015
016import java.util.Collection;
017import java.util.Collections;
018import java.util.HashSet;
019import java.util.Map;
020import java.util.Set;
021
022
023public class PicoMap implements Map {
024
025    private final MutablePicoContainer mutablePicoContainer;
026
027    public PicoMap(final MutablePicoContainer mutablePicoContainer) {
028        this.mutablePicoContainer = mutablePicoContainer;
029    }
030
031    public PicoMap() {
032        mutablePicoContainer = new DefaultPicoContainer();
033    }
034
035    public int size() {
036        return mutablePicoContainer.getComponentAdapters().size();
037    }
038
039    public boolean isEmpty() {
040        return mutablePicoContainer.getComponentAdapters().size() == 0;
041    }
042
043    public boolean containsKey(final Object o) {
044        if (o instanceof Class) {
045            return mutablePicoContainer.getComponent((Class<?>)o) != null;
046        } else {
047            return mutablePicoContainer.getComponent(o) != null;
048        }
049    }
050
051    public boolean containsValue(final Object o) {
052        return false;
053    }
054
055    public Object get(final Object o) {
056        if (o instanceof Class) {
057            return mutablePicoContainer.getComponent((Class<?>)o);
058        } else {
059            return mutablePicoContainer.getComponent(o);
060        }
061    }
062
063    public Object put(final Object o, final Object o1) {
064        Object object = remove(o);
065        mutablePicoContainer.addComponent(o, o1);
066        return object;
067    }
068
069    public Object remove(final Object o) {
070        ComponentAdapter adapter = mutablePicoContainer.removeComponent(o);
071        if (adapter != null) {
072            // if previously an instance was registered, return it, otherwise return the type
073            return adapter instanceof InstanceAdapter ? adapter
074                    .getComponentInstance(mutablePicoContainer, ComponentAdapter.NOTHING.class) : adapter
075                    .getComponentImplementation();
076        } else {
077            return null;
078        }
079    }
080
081    public void putAll(final Map map) {
082        for (Object o : map.entrySet()) {
083            final Entry entry = (Entry) o;
084            put(entry.getKey(), entry.getValue());
085        }
086    }
087
088    public void clear() {
089        Set adapters = keySet();
090        for (Object adapter : adapters) {
091            mutablePicoContainer.removeComponent(adapter);
092        }
093    }
094
095    public Set keySet() {
096        Set<Object> set = new HashSet<Object>();
097        Collection<ComponentAdapter<?>> adapters = mutablePicoContainer.getComponentAdapters();
098        for (final ComponentAdapter<?> adapter : adapters) {
099            set.add(adapter.getComponentKey());
100        }
101        return Collections.unmodifiableSet(set);
102    }
103
104    @SuppressWarnings({ "unchecked" })
105    public Collection values() {
106        return Collections.unmodifiableCollection(mutablePicoContainer.getComponents());
107    }
108
109    public Set entrySet() {
110        Set<Entry> set = new HashSet<Entry>();
111        Collection<ComponentAdapter<?>> adapters = mutablePicoContainer.getComponentAdapters();
112        for (ComponentAdapter<?> adapter : adapters) {
113            final Object key = adapter.getComponentKey();
114            final Object component = mutablePicoContainer.getComponent(key);
115            set.add(new Entry() {
116                public Object getKey() {
117                    return key;
118                }
119
120                public Object getValue() {
121                    return component;
122                }
123
124                public Object setValue(final Object value) {
125                    throw new UnsupportedOperationException("Cannot set addComponent");
126                }
127            });
128        }
129        return Collections.unmodifiableSet(set);
130    }
131}