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 /**
42 * Sets of entries in the map.
43 */
44 static class ConfigurationSet extends AbstractSet<Map.Entry<Object, Object>> {
45
46 /**
47 * Iterator over the entries in the ConfigurationMap.
48 */
49 private final class ConfigurationSetIterator implements Iterator<Map.Entry<Object, Object>> {
50
51 /** An iterator over the keys in the configuration. */
52 private final Iterator<String> keys;
53
54 private ConfigurationSetIterator() {
55 keys = configuration.getKeys();
56 }
57
58 @Override
59 public boolean hasNext() {
60 return keys.hasNext();
61 }
62
63 @Override
64 public Map.Entry<Object, Object> next() {
65 return new Entry(keys.next());
66 }
67
68 @Override
69 public void remove() {
70 keys.remove();
71 }
72 }
73
74 /**
75 * A Map entry in the ConfigurationMap.
76 */
77 private final class Entry implements Map.Entry<Object, Object> {
78
79 /** The key of the map entry. */
80 private final Object key;
81
82 private Entry(final Object key) {
83 this.key = key;
84 }
85
86 @Override
87 public Object getKey() {
88 return key;
89 }
90
91 @Override
92 public Object getValue() {
93 return configuration.getProperty((String) key);
94 }
95
96 @Override
97 public Object setValue(final Object value) {
98 final Object old = getValue();
99 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 }