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.configuration2;
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.configuration2.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 1624601 2014-09-12 18:04:36Z 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 final Object key;
127
128            private Entry(Object key)
129            {
130                this.key = key;
131            }
132
133            @Override
134            public Object getKey()
135            {
136                return key;
137            }
138
139            @Override
140            public Object getValue()
141            {
142                return configuration.getProperty((String) key);
143            }
144
145            @Override
146            public Object setValue(Object value)
147            {
148                Object old = getValue();
149                configuration.setProperty((String) key, value);
150                return old;
151            }
152        }
153
154        /**
155         * Iterator over the entries in the ConfigurationMap.
156         */
157        private final class ConfigurationSetIterator implements Iterator<Map.Entry<Object, Object>>
158        {
159            /** An iterator over the keys in the configuration. */
160            private final Iterator<String> keys;
161
162            private ConfigurationSetIterator()
163            {
164                keys = configuration.getKeys();
165            }
166
167            @Override
168            public boolean hasNext()
169            {
170                return keys.hasNext();
171            }
172
173            @Override
174            public Map.Entry<Object, Object> next()
175            {
176                return new Entry(keys.next());
177            }
178
179            @Override
180            public void remove()
181            {
182                keys.remove();
183            }
184        }
185
186        ConfigurationSet(Configuration configuration)
187        {
188            this.configuration = configuration;
189        }
190
191        /**
192         * @see java.util.Collection#size()
193         */
194        @Override
195        public int size()
196        {
197            // Ouch. Now _that_ one is expensive...
198            int count = 0;
199            for (Iterator<String> iterator = configuration.getKeys(); iterator.hasNext();)
200            {
201                iterator.next();
202                count++;
203            }
204            return count;
205        }
206
207        /**
208         * @see java.util.Collection#iterator()
209         */
210        @Override
211        public Iterator<Map.Entry<Object, Object>> iterator()
212        {
213            return new ConfigurationSetIterator();
214        }
215    }
216}