    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}