001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.configuration;
019    
020    import java.util.AbstractMap;
021    import java.util.AbstractSet;
022    import java.util.Iterator;
023    import java.util.Map;
024    import java.util.Set;
025    
026    /**
027     * <p>The {@code ConfigurationMap} wraps a
028     * configuration-collection
029     * {@link org.apache.commons.configuration.Configuration}
030     * instance to provide a {@code Map} interface.</p>
031     *
032     * <p><em>Note:</em> This implementation is incomplete.</p>
033     *
034     * @author <a href="mailto:ricardo.gladwell@btinternet.com">Ricardo Gladwell</a>
035     * @version $Id: ConfigurationMap.java 1208794 2011-11-30 21:17:44Z oheger $
036     * @since 1.0
037     */
038    public class ConfigurationMap extends AbstractMap<Object, Object>
039    {
040        /**
041         * The {@code Configuration} wrapped by this class.
042         */
043        private Configuration configuration;
044    
045        /**
046         * Creates a new instance of a {@code ConfigurationMap}
047         * that wraps the specified {@code Configuration}
048         * instance.
049         * @param configuration {@code Configuration}
050         * instance.
051         */
052        public ConfigurationMap(Configuration configuration)
053        {
054            this.configuration = configuration;
055        }
056    
057        /**
058         * Returns the wrapped {@code Configuration} object.
059         *
060         * @return the wrapped configuration
061         * @since 1.2
062         */
063        public Configuration getConfiguration()
064        {
065            return configuration;
066        }
067    
068        /**
069         * Returns a set with the entries contained in this configuration-based map.
070         *
071         * @return a set with the contained entries
072         * @see java.util.Map#entrySet()
073         */
074        @Override
075        public Set<Map.Entry<Object, Object>> entrySet()
076        {
077            return new ConfigurationSet(configuration);
078        }
079    
080        /**
081         * Stores the value for the specified key. The value is stored in the
082         * underlying configuration.
083         *
084         * @param key the key (will be converted to a string)
085         * @param value the value
086         * @return the old value of this key or <b>null</b> if it is new
087         * @see java.util.Map#put(java.lang.Object, java.lang.Object)
088         */
089        @Override
090        public Object put(Object key, Object value)
091        {
092            String strKey = String.valueOf(key);
093            Object old = configuration.getProperty(strKey);
094            configuration.setProperty(strKey, value);
095            return old;
096        }
097    
098        /**
099         * Returns the value of the specified key. The key is converted to a string
100         * and then passed to the underlying configuration.
101         *
102         * @param key the key
103         * @return the value of this key
104         * @see java.util.Map#get(java.lang.Object)
105         */
106        @Override
107        public Object get(Object key)
108        {
109            return configuration.getProperty(String.valueOf(key));
110        }
111    
112        /**
113         * Set of entries in the map.
114         */
115        static class ConfigurationSet extends AbstractSet<Map.Entry<Object, Object>>
116        {
117            /** The configuration mapped to this entry set. */
118            private Configuration configuration;
119    
120            /**
121             * A Map entry in the ConfigurationMap.
122             */
123            private final class Entry implements Map.Entry<Object, Object>
124            {
125                /** The key of the map entry. */
126                private Object key;
127    
128                private Entry(Object key)
129                {
130                    this.key = key;
131                }
132    
133                public Object getKey()
134                {
135                    return key;
136                }
137    
138                public Object getValue()
139                {
140                    return configuration.getProperty((String) key);
141                }
142    
143                public Object setValue(Object value)
144                {
145                    Object old = getValue();
146                    configuration.setProperty((String) key, value);
147                    return old;
148                }
149            }
150    
151            /**
152             * Iterator over the entries in the ConfigurationMap.
153             */
154            private final class ConfigurationSetIterator implements Iterator<Map.Entry<Object, Object>>
155            {
156                /** An iterator over the keys in the configuration. */
157                private Iterator<String> keys;
158    
159                private ConfigurationSetIterator()
160                {
161                    keys = configuration.getKeys();
162                }
163    
164                public boolean hasNext()
165                {
166                    return keys.hasNext();
167                }
168    
169                public Map.Entry<Object, Object> next()
170                {
171                    return new Entry(keys.next());
172                }
173    
174                public void remove()
175                {
176                    keys.remove();
177                }
178            }
179    
180            ConfigurationSet(Configuration configuration)
181            {
182                this.configuration = configuration;
183            }
184    
185            /**
186             * @see java.util.Collection#size()
187             */
188            @Override
189            public int size()
190            {
191                // Ouch. Now _that_ one is expensive...
192                int count = 0;
193                for (Iterator<String> iterator = configuration.getKeys(); iterator.hasNext();)
194                {
195                    iterator.next();
196                    count++;
197                }
198                return count;
199            }
200    
201            /**
202             * @see java.util.Collection#iterator()
203             */
204            @Override
205            public Iterator<Map.Entry<Object, Object>> iterator()
206            {
207                return new ConfigurationSetIterator();
208            }
209        }
210    }