1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.configuration2;
19
20 import java.util.AbstractMap;
21 import java.util.AbstractSet;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.Objects;
25 import java.util.Set;
26
27 /**
28 * <p>
29 * The {@code ConfigurationMap} wraps a configuration-collection {@link org.apache.commons.configuration2.Configuration}
30 * instance to provide a {@code Map} interface.
31 * </p>
32 *
33 * <p>
34 * <em>Note:</em> This implementation is incomplete.
35 * </p>
36 *
37 * @since 1.0
38 */
39 public class ConfigurationMap extends AbstractMap<Object, Object> {
40 /**
41 * Sets of entries in the map.
42 */
43 static class ConfigurationSet extends AbstractSet<Map.Entry<Object, Object>> {
44 /**
45 * Iterator over the entries in the ConfigurationMap.
46 */
47 private final class ConfigurationSetIterator implements Iterator<Map.Entry<Object, Object>> {
48 /** An iterator over the keys in the configuration. */
49 private final Iterator<String> keys;
50
51 private ConfigurationSetIterator() {
52 keys = configuration.getKeys();
53 }
54
55 @Override
56 public boolean hasNext() {
57 return keys.hasNext();
58 }
59
60 @Override
61 public Map.Entry<Object, Object> next() {
62 return new Entry(keys.next());
63 }
64
65 @Override
66 public void remove() {
67 keys.remove();
68 }
69 }
70
71 /**
72 * A Map entry in the ConfigurationMap.
73 */
74 private final class Entry implements Map.Entry<Object, Object> {
75 /** The key of the map entry. */
76 private final Object key;
77
78 private Entry(final Object key) {
79 this.key = key;
80 }
81
82 @Override
83 public Object getKey() {
84 return key;
85 }
86
87 @Override
88 public Object getValue() {
89 return configuration.getProperty((String) key);
90 }
91
92 @Override
93 public Object setValue(final Object value) {
94 final Object old = getValue();
95 configuration.setProperty((String) key, value);
96 return old;
97 }
98 }
99
100 /** The configuration mapped to this entry set. */
101 private final Configuration configuration;
102
103 ConfigurationSet(final Configuration configuration) {
104 this.configuration = configuration;
105 }
106
107 /**
108 * @see java.util.Collection#iterator()
109 */
110 @Override
111 public Iterator<Map.Entry<Object, Object>> iterator() {
112 return new ConfigurationSetIterator();
113 }
114
115 /**
116 * @see java.util.Collection#size()
117 */
118 @Override
119 public int size() {
120 // Ouch. Now _that_ one is expensive...
121 int count = 0;
122 for (final Iterator<String> iterator = configuration.getKeys(); iterator.hasNext();) {
123 iterator.next();
124 count++;
125 }
126 return count;
127 }
128 }
129
130 /**
131 * The {@code Configuration} wrapped by this class.
132 */
133 private final Configuration configuration;
134
135 /**
136 * Creates a new instance of a {@code ConfigurationMap} that wraps the specified {@code Configuration} instance.
137 *
138 * @param configuration {@code Configuration} instance.
139 */
140 public ConfigurationMap(final Configuration configuration) {
141 this.configuration = Objects.requireNonNull(configuration, "configuration");
142 }
143
144 /**
145 * Returns a set with the entries contained in this configuration-based map.
146 *
147 * @return a set with the contained entries
148 * @see Map#entrySet()
149 */
150 @Override
151 public Set<Map.Entry<Object, Object>> entrySet() {
152 return new ConfigurationSet(configuration);
153 }
154
155 /**
156 * Gets the value of the specified key. The key is converted to a string and then passed to the underlying
157 * configuration.
158 *
159 * @param key the key
160 * @return the value of this key
161 * @see Map#get(Object)
162 */
163 @Override
164 public Object get(final Object key) {
165 return configuration.getProperty(String.valueOf(key));
166 }
167
168 /**
169 * Gets the wrapped {@code Configuration} object.
170 *
171 * @return the wrapped configuration
172 * @since 1.2
173 */
174 public Configuration getConfiguration() {
175 return configuration;
176 }
177
178 /**
179 * Stores the value for the specified key. The value is stored in the underlying configuration.
180 *
181 * @param key the key (will be converted to a string)
182 * @param value the value
183 * @return the old value of this key or <strong>null</strong> if it is new
184 * @see Map#put(Object, Object)
185 */
186 @Override
187 public Object put(final Object key, final Object value) {
188 final String strKey = String.valueOf(key);
189 final Object old = configuration.getProperty(strKey);
190 configuration.setProperty(strKey, value);
191 return old;
192 }
193 }