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     *****************************************************************************/
009    package org.picocontainer.gems.util;
010    
011    import org.picocontainer.ComponentAdapter;
012    import org.picocontainer.MutablePicoContainer;
013    import org.picocontainer.adapters.InstanceAdapter;
014    import org.picocontainer.DefaultPicoContainer;
015    
016    import java.util.Collection;
017    import java.util.Collections;
018    import java.util.HashSet;
019    import java.util.Map;
020    import java.util.Set;
021    
022    
023    public 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    }