    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.0-M1
    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}