/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     James Sutherland - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.helper;

import java.util.*;
import java.util.Map.Entry;

/**
 * Properties subclass that removes the synchronization.
 */
public class NonSynchronizedProperties extends Properties {

    protected Map<Object, Object> values;

    public NonSynchronizedProperties(int size) {
        super();
        this.values = new HashMap<>(size);
    }

    @Override
    public void clear() {
        this.values.clear();
    }

    @Override
    public Object clone() {
        NonSynchronizedProperties properties = new NonSynchronizedProperties(size());
        properties.putAll(this);
        return properties;

    }

    @Override
    public boolean contains(Object value) {
        return this.values.containsValue(value);
    }

    @Override
    public boolean containsKey(Object key) {
        return this.values.containsKey(key);
    }

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

    @Override
    public Enumeration<Object> elements() {
        return new Hashtable<>(this.values).elements();
    }

    @Override
    public Set<Entry<Object, Object>> entrySet() {
        return this.values.entrySet();
    }

    @Override
    public boolean equals(Object o) {
        return this.values.equals(o);
    }

    @Override
    public Object get(Object key) {
        return this.values.get(key);
    }

    @Override
    public int hashCode() {
        return this.values.hashCode();
    }

    @Override
    public boolean isEmpty() {
        return this.values.isEmpty();
    }

    @Override
    public Enumeration<Object> keys() {
        return new Hashtable<>(this.values).keys();
    }

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

    @Override
    public Object put(Object key, Object value) {
        // Properties cannot store null.
        if (value == null) {
            return this.values.remove(key);
        }
        return this.values.put(key, value);
    }

    @Override
    public void putAll(Map<?, ?> t) {
        this.values.putAll(t);
    }

    @Override
    public Object remove(Object key) {
        return this.values.remove(key);
    }

    @Override
    public int size() {
        return this.values.size();
    }

    @Override
    public String toString() {
        return this.values.toString();
    }

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

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

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

