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
018package org.apache.commons.configuration;
019
020import java.util.AbstractMap;
021import java.util.AbstractSet;
022import java.util.Iterator;
023import java.util.Map;
024import 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 1301959 2012-03-17 16:43:18Z oheger $
036 * @since 1.0
037 */
038public class ConfigurationMap extends AbstractMap<Object, Object>
039{
040    /**
041     * The {@code Configuration} wrapped by this class.
042     */
043    private final 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 final 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 final 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}