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