    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>
    028 * The {@code ConfigurationMap} wraps a configuration-collection {@link org.apache.commons.configuration2.Configuration}
    029 * instance to provide a {@code Map} interface.
    030 * </p>
    031 *
    032 * <p>
    033 * <em>Note:</em> This implementation is incomplete.
    034 * </p>
    035 *
    036 * @since 1.0
    037 */
    038public class ConfigurationMap extends AbstractMap<Object, Object> {
    039    /**
    040     * The {@code Configuration} wrapped by this class.
    041     */
    042    private final Configuration configuration;
    043
    044    /**
    045     * Creates a new instance of a {@code ConfigurationMap} that wraps the specified {@code Configuration} instance.
    046     *
    047     * @param configuration {@code Configuration} instance.
    048     */
    049    public ConfigurationMap(final Configuration configuration) {
    050        this.configuration = configuration;
    051    }
    052
    053    /**
    054     * Returns the wrapped {@code Configuration} object.
    055     *
    056     * @return the wrapped configuration
    057     * @since 1.2
    058     */
    059    public Configuration getConfiguration() {
    060        return configuration;
    061    }
    062
    063    /**
    064     * Returns a set with the entries contained in this configuration-based map.
    065     *
    066     * @return a set with the contained entries
    067     * @see java.util.Map#entrySet()
    068     */
    069    @Override
    070    public Set<Map.Entry<Object, Object>> entrySet() {
    071        return new ConfigurationSet(configuration);
    072    }
    073
    074    /**
    075     * Stores the value for the specified key. The value is stored in the underlying configuration.
    076     *
    077     * @param key the key (will be converted to a string)
    078     * @param value the value
    079     * @return the old value of this key or <b>null</b> if it is new
    080     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
    081     */
    082    @Override
    083    public Object put(final Object key, final Object value) {
    084        final String strKey = String.valueOf(key);
    085        final Object old = configuration.getProperty(strKey);
    086        configuration.setProperty(strKey, value);
    087        return old;
    088    }
    089
    090    /**
    091     * Returns the value of the specified key. The key is converted to a string and then passed to the underlying
    092     * configuration.
    093     *
    094     * @param key the key
    095     * @return the value of this key
    096     * @see java.util.Map#get(java.lang.Object)
    097     */
    098    @Override
    099    public Object get(final Object key) {
    100        return configuration.getProperty(String.valueOf(key));
    101    }
    102
    103    /**
    104     * Set of entries in the map.
    105     */
    106    static class ConfigurationSet extends AbstractSet<Map.Entry<Object, Object>> {
    107        /** The configuration mapped to this entry set. */
    108        private final Configuration configuration;
    109
    110        /**
    111         * A Map entry in the ConfigurationMap.
    112         */
    113        private final class Entry implements Map.Entry<Object, Object> {
    114            /** The key of the map entry. */
    115            private final Object key;
    116
    117            private Entry(final Object key) {
    118                this.key = key;
    119            }
    120
    121            @Override
    122            public Object getKey() {
    123                return key;
    124            }
    125
    126            @Override
    127            public Object getValue() {
    128                return configuration.getProperty((String) key);
    129            }
    130
    131            @Override
    132            public Object setValue(final Object value) {
    133                final Object old = getValue();
    134                configuration.setProperty((String) key, value);
    135                return old;
    136            }
    137        }
    138
    139        /**
    140         * Iterator over the entries in the ConfigurationMap.
    141         */
    142        private final class ConfigurationSetIterator implements Iterator<Map.Entry<Object, Object>> {
    143            /** An iterator over the keys in the configuration. */
    144            private final Iterator<String> keys;
    145
    146            private ConfigurationSetIterator() {
    147                keys = configuration.getKeys();
    148            }
    149
    150            @Override
    151            public boolean hasNext() {
    152                return keys.hasNext();
    153            }
    154
    155            @Override
    156            public Map.Entry<Object, Object> next() {
    157                return new Entry(keys.next());
    158            }
    159
    160            @Override
    161            public void remove() {
    162                keys.remove();
    163            }
    164        }
    165
    166        ConfigurationSet(final Configuration configuration) {
    167            this.configuration = configuration;
    168        }
    169
    170        /**
    171         * @see java.util.Collection#size()
    172         */
    173        @Override
    174        public int size() {
    175            // Ouch. Now _that_ one is expensive...
    176            int count = 0;
    177            for (final Iterator<String> iterator = configuration.getKeys(); iterator.hasNext();) {
    178                iterator.next();
    179                count++;
    180            }
    181            return count;
    182        }
    183
    184        /**
    185         * @see java.util.Collection#iterator()
    186         */
    187        @Override
    188        public Iterator<Map.Entry<Object, Object>> iterator() {
    189            return new ConfigurationSetIterator();
    190        }
    191    }
    192}