org.pentaho.di.core.ConcurrentMapProperties.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.core.ConcurrentMapProperties.java

Source

/*******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2018 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/
package org.pentaho.di.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;

import org.apache.commons.collections.IteratorUtils;

/**
 * Thread Safe version of Java Properties class.
 */
public class ConcurrentMapProperties extends Properties {

    private static final long serialVersionUID = -7444528393201025496L;

    protected ConcurrentMap<Object, Object> storageMap = new ConcurrentHashMap<>();

    public ConcurrentMapProperties() {
        this(null);
    }

    public ConcurrentMapProperties(Properties defaults) {
        if (defaults != null) {
            if (defaults instanceof ConcurrentMapProperties) {
                this.defaults = defaults;
            } else {
                this.defaults = convertProperties(defaults);
            }
        }
    }

    @Override
    public synchronized Object put(Object key, Object value) {
        return storageMap.put(key, value);
    }

    @Override
    public synchronized Object remove(Object key) {
        return storageMap.remove(key);
    }

    @Override
    public synchronized void clear() {
        storageMap.clear();
    }

    @Override
    public synchronized Object clone() {
        ConcurrentMapProperties cloned = new ConcurrentMapProperties();
        cloned.putAll(storageMap);
        return cloned;
    }

    @Override
    public boolean containsValue(Object value) {
        return storageMap.containsValue(value);
    }

    @Override
    public synchronized Object get(Object key) {
        return storageMap.get(key);
    }

    @Override
    public synchronized Object compute(Object key,
            BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
        return storageMap.compute(key, remappingFunction);
    }

    @Override
    public synchronized Object computeIfAbsent(Object key,
            Function<? super Object, ? extends Object> mappingFunction) {
        return storageMap.computeIfAbsent(key, mappingFunction);
    }

    @Override
    public synchronized Object computeIfPresent(Object key,
            BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
        return storageMap.computeIfPresent(key, remappingFunction);
    }

    @Override
    public synchronized boolean contains(Object value) {
        return storageMap.containsValue(value);
    }

    @Override
    public synchronized boolean isEmpty() {
        return storageMap.isEmpty();
    }

    @Override
    public synchronized int size() {
        return storageMap.size();
    }

    @Override
    public synchronized boolean containsKey(Object key) {
        return storageMap.containsKey(key);
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized Enumeration<Object> elements() {
        return (Enumeration<Object>) IteratorUtils.asEnumeration(storageMap.values().iterator());
    }

    @Override
    public Set<java.util.Map.Entry<Object, Object>> entrySet() {
        return storageMap.entrySet();
    }

    @Override
    public synchronized void forEach(BiConsumer<? super Object, ? super Object> action) {
        storageMap.forEach(action);
    }

    @Override
    public synchronized Object getOrDefault(Object key, Object defaultValue) {
        return storageMap.getOrDefault(key, defaultValue);
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized Enumeration<Object> keys() {
        return (Enumeration<Object>) IteratorUtils.asEnumeration(storageMap.keySet().iterator());
    }

    @Override
    public Set<Object> keySet() {
        return storageMap.keySet();
    }

    @Override
    public synchronized Object merge(Object key, Object value,
            BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
        return storageMap.merge(key, value, remappingFunction);
    }

    @Override
    public synchronized void putAll(Map<? extends Object, ? extends Object> t) {
        storageMap.putAll(t);
    }

    @Override
    public synchronized Object putIfAbsent(Object key, Object value) {
        return storageMap.putIfAbsent(key, value);
    }

    @Override
    public synchronized boolean remove(Object key, Object value) {
        return storageMap.remove(key, value);
    }

    @Override
    public synchronized boolean replace(Object key, Object oldValue, Object newValue) {
        return storageMap.replace(key, oldValue, newValue);
    }

    @Override
    public synchronized void replaceAll(BiFunction<? super Object, ? super Object, ? extends Object> function) {
        storageMap.replaceAll(function);
    }

    @Override
    public synchronized Object replace(Object key, Object value) {
        return storageMap.replace(key, value);
    }

    @Override
    public Collection<Object> values() {
        return storageMap.values();
    }

    @Override
    public String getProperty(String key) {
        Object oval = storageMap.get(key);
        String sval = (oval instanceof String) ? (String) oval : null;
        return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
    }

    @Override
    public String getProperty(String key, String defaultValue) {
        /*
         * This method simply uses getProperty(String key), so it is fine to use the original implementation
         */
        return super.getProperty(key, defaultValue);
    }

    @Override
    public synchronized Object setProperty(String key, String value) {
        return storageMap.put(key, value);
    }

    @Override
    public synchronized boolean equals(Object o) {
        super.putAll(storageMap);
        boolean result = super.equals(o);
        super.clear();
        return result;
    }

    @Override
    public synchronized String toString() {
        super.putAll(storageMap);
        String result = super.toString();
        super.clear();
        return result;
    }

    @Override
    public synchronized int hashCode() {
        super.putAll(storageMap);
        int result = super.hashCode();
        super.clear();
        return result;
    }

    @Override
    public synchronized Enumeration<?> propertyNames() {
        return IteratorUtils.asEnumeration(stringPropertyNames().iterator());
    }

    @Override
    public synchronized Set<String> stringPropertyNames() {
        Set<String> copiedSet = new HashSet<>();
        if (defaults != null) {
            defaults.keySet().forEach(x -> copiedSet.add((String) x));
        }
        storageMap.keySet().forEach(x -> copiedSet.add((String) x));
        return copiedSet;
    }

    @Override
    public synchronized void list(PrintStream out) {
        super.putAll(storageMap);
        super.list(out);
        super.clear();
    }

    @Override
    public synchronized void list(PrintWriter out) {
        super.putAll(storageMap);
        super.list(out);
        super.clear();
    }

    @Override
    public synchronized void load(InputStream inStream) throws IOException {
        super.putAll(storageMap);
        super.load(inStream);
        super.forEach((key, value) -> storageMap.put(key, value));
        super.clear();
    }

    @Override
    public synchronized void load(Reader reader) throws IOException {
        super.putAll(storageMap);
        super.load(reader);
        super.forEach((key, value) -> storageMap.put(key, value));
        super.clear();
    }

    @Override
    public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException {
        super.putAll(storageMap);
        super.loadFromXML(in);
        super.forEach((key, value) -> storageMap.putIfAbsent(key, value));
        super.clear();
    }

    @Override
    @Deprecated
    public synchronized void save(OutputStream out, String comments) {
        super.putAll(storageMap);
        super.save(out, comments);
        super.clear();
    }

    @Override
    public synchronized void store(OutputStream out, String comments) throws IOException {
        super.putAll(storageMap);
        super.store(out, comments);
        super.clear();
    }

    @Override
    public synchronized void store(Writer writer, String comments) throws IOException {
        super.putAll(storageMap);
        super.store(writer, comments);
        super.clear();
    }

    @Override
    public synchronized void storeToXML(OutputStream os, String comment) throws IOException {
        super.putAll(storageMap);
        super.storeToXML(os, comment);
        super.clear();
    }

    @Override
    public synchronized void storeToXML(OutputStream os, String comment, String encoding) throws IOException {
        super.putAll(storageMap);
        super.storeToXML(os, comment, encoding);
        super.clear();
    }

    /**
     * Converts a Properties object to a ConcurrentMapProperties object
     *
     * @param props
     * @return A new ConcurrentMapProperties with all properties enumerated (including defaults)
     */
    public static ConcurrentMapProperties convertProperties(Properties props) {
        if (props != null) {
            if (!(props instanceof ConcurrentMapProperties)) {
                ConcurrentMapProperties result = new ConcurrentMapProperties(null);
                synchronized (props) {
                    for (String prop : props.stringPropertyNames()) {
                        result.put(prop, props.getProperty(prop));
                    }
                }
                return result;
            } else {
                //Already a ConcurrentMapProperties
                return (ConcurrentMapProperties) props;
            }
        }
        return null;
    }

}