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