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