    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 1842194 2018-09-27 22:24:23Z ggregory $
    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(final 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(final Object key, final Object value)
    091    {
    092        final String strKey = String.valueOf(key);
    093        final 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(final 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(final 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(final Object value)
    147            {
    148                final 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(final 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 (final 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}