    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}