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.collections4.properties;
019
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.Reader;
023import java.util.Collection;
024import java.util.Collections;
025import java.util.Enumeration;
026import java.util.InvalidPropertiesFormatException;
027import java.util.Map;
028import java.util.Map.Entry;
029import java.util.Objects;
030import java.util.Properties;
031import java.util.Set;
032import java.util.function.BiConsumer;
033import java.util.function.BiFunction;
034import java.util.function.Function;
035
036/**
037 * Creates and loads {@link Properties}.
038 *
039 * @see Properties
040 * @since 4.4
041 */
042public class PropertiesFactory extends AbstractPropertiesFactory<Properties> {
043
044    private static final class EmptyProperties extends Properties {
045
046        private static final long serialVersionUID = 1L;
047
048        @Override
049        public synchronized void clear() {
050            // Noop
051        }
052
053        @Override
054        public synchronized Object compute(final Object key,
055            final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
056            Objects.requireNonNull(key, "key");
057            throw new UnsupportedOperationException();
058        }
059
060        @Override
061        public synchronized Object computeIfAbsent(final Object key,
062            final Function<? super Object, ? extends Object> mappingFunction) {
063            Objects.requireNonNull(key, "key");
064            throw new UnsupportedOperationException();
065        }
066
067        @Override
068        public synchronized Object computeIfPresent(final Object key,
069            final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
070            Objects.requireNonNull(key, "key");
071            throw new UnsupportedOperationException();
072        }
073
074        @Override
075        public synchronized boolean contains(final Object value) {
076            return false;
077        }
078
079        @Override
080        public synchronized boolean containsKey(final Object key) {
081            return false;
082        }
083
084        @Override
085        public boolean containsValue(final Object value) {
086            return false;
087        }
088
089        @Override
090        public synchronized Enumeration<Object> elements() {
091            return Collections.emptyEnumeration();
092        }
093
094        @Override
095        public Set<Entry<Object, Object>> entrySet() {
096            return Collections.emptySet();
097        }
098
099        @Override
100        public synchronized boolean equals(final Object o) {
101            return o instanceof Properties && ((Properties) o).isEmpty();
102        }
103
104        @Override
105        public synchronized void forEach(final BiConsumer<? super Object, ? super Object> action) {
106            Objects.requireNonNull(action, "action");
107        }
108
109        @Override
110        public synchronized Object get(final Object key) {
111            return null;
112        }
113
114        @Override
115        public synchronized Object getOrDefault(final Object key, final Object defaultValue) {
116            return defaultValue;
117        }
118
119        @Override
120        public String getProperty(final String key) {
121            return null;
122        }
123
124        @Override
125        public String getProperty(final String key, final String defaultValue) {
126            return defaultValue;
127        }
128
129        @Override
130        public synchronized int hashCode() {
131            return 0;
132        }
133
134        @Override
135        public synchronized boolean isEmpty() {
136            return true;
137        }
138
139        @Override
140        public synchronized Enumeration<Object> keys() {
141            return Collections.emptyEnumeration();
142        }
143
144        @Override
145        public Set<Object> keySet() {
146            return Collections.emptySet();
147        }
148
149        /**
150         * Throws {@link UnsupportedOperationException}.
151         * Caller should use try-with-resources statement.
152         */
153        @SuppressWarnings("resource")
154        @Override
155        public synchronized void load(final InputStream inputStream) throws IOException {
156            Objects.requireNonNull(inputStream, "inputStream");
157            throw new UnsupportedOperationException();
158        }
159
160        /**
161         * Throws {@link UnsupportedOperationException}.
162         * Caller should use try-with-resources statement.
163         */
164        @SuppressWarnings("resource")
165        @Override
166        public synchronized void load(final Reader reader) throws IOException {
167            Objects.requireNonNull(reader, "reader");
168            throw new UnsupportedOperationException();
169        }
170
171        /**
172         * Throws {@link UnsupportedOperationException}.
173         * Caller should use try-with-resources statement.
174         */
175        @SuppressWarnings("resource")
176        @Override
177        public synchronized void loadFromXML(final InputStream inputStream)
178            throws IOException, InvalidPropertiesFormatException {
179            Objects.requireNonNull(inputStream, "inputStream");
180            throw new UnsupportedOperationException();
181        }
182
183        @Override
184        public synchronized Object merge(final Object key, final Object value,
185            final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
186            Objects.requireNonNull(key, "key");
187            Objects.requireNonNull(value, "value");
188            throw new UnsupportedOperationException();
189        }
190
191        @Override
192        public Enumeration<?> propertyNames() {
193            return Collections.emptyEnumeration();
194        }
195
196        @Override
197        public synchronized Object put(final Object key, final Object value) {
198            Objects.requireNonNull(key, "key");
199            Objects.requireNonNull(value, "value");
200            throw new UnsupportedOperationException();
201        }
202
203        @Override
204        public synchronized void putAll(final Map<? extends Object, ? extends Object> map) {
205            Objects.requireNonNull(map, "map");
206            throw new UnsupportedOperationException();
207        }
208
209        @Override
210        public synchronized Object putIfAbsent(final Object key, final Object value) {
211            Objects.requireNonNull(key, "key");
212            Objects.requireNonNull(value, "value");
213            throw new UnsupportedOperationException();
214        }
215
216        @Override
217        protected void rehash() {
218            // Noop
219        }
220
221        @Override
222        public synchronized Object remove(final Object key) {
223            Objects.requireNonNull(key, "key");
224            throw new UnsupportedOperationException();
225        }
226
227        @Override
228        public synchronized boolean remove(final Object key, final Object value) {
229            Objects.requireNonNull(key, "key");
230            Objects.requireNonNull(value, "value");
231            throw new UnsupportedOperationException();
232        }
233
234        @Override
235        public synchronized Object replace(final Object key, final Object value) {
236            Objects.requireNonNull(key, "key");
237            Objects.requireNonNull(value, "value");
238            throw new UnsupportedOperationException();
239        }
240
241        @Override
242        public synchronized boolean replace(final Object key, final Object oldValue, final Object newValue) {
243            Objects.requireNonNull(key, "key");
244            Objects.requireNonNull(oldValue, "oldValue");
245            Objects.requireNonNull(newValue, "newValue");
246            throw new UnsupportedOperationException();
247        }
248
249        @Override
250        public synchronized void replaceAll(
251            final BiFunction<? super Object, ? super Object, ? extends Object> function) {
252            Objects.requireNonNull(function, "function");
253            throw new UnsupportedOperationException();
254        }
255
256        @Override
257        public synchronized Object setProperty(final String key, final String value) {
258            Objects.requireNonNull(key, "key");
259            Objects.requireNonNull(value, "value");
260            throw new UnsupportedOperationException();
261        }
262
263        @Override
264        public synchronized int size() {
265            return 0;
266        }
267
268        @Override
269        public Set<String> stringPropertyNames() {
270            return Collections.emptySet();
271        }
272
273        @Override
274        public Collection<Object> values() {
275            return Collections.emptyList();
276        }
277
278    }
279
280    /**
281     * The empty map (immutable). This map is serializable.
282     *
283     * @since 4.5.0-M1
284     */
285    public static final Properties EMPTY_PROPERTIES = new EmptyProperties();
286
287    /**
288     * The singleton instance.
289     */
290    public static final PropertiesFactory INSTANCE = new PropertiesFactory();
291
292    /**
293     * Constructs an instance.
294     */
295    private PropertiesFactory() {
296        // There is only one instance.
297    }
298
299    /**
300     * Subclasses override to provide customized properties instances.
301     *
302     * @return A new Properties instance.
303     */
304    @Override
305    protected Properties createProperties() {
306        return new Properties();
307    }
308
309}