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 */
017package org.apache.commons.collections4.map;
018
019import java.util.Collection;
020import java.util.Map;
021import java.util.Objects;
022import java.util.Set;
023
024/**
025 * Provides a base decorator that enables additional functionality to be added
026 * to a Map via decoration.
027 * <p>
028 * Methods are forwarded directly to the decorated map.
029 * </p>
030 * <p>
031 * This implementation does not perform any special processing with
032 * {@link #entrySet()}, {@link #keySet()} or {@link #values()}. Instead
033 * it simply returns the set/collection from the wrapped map. This may be
034 * undesirable, for example if you are trying to write a validating
035 * implementation it would provide a loophole around the validation.
036 * But, you might want that loophole, so this class is kept simple.
037 * </p>
038 *
039 * @param <K> The type of the keys in the map
040 * @param <V> The type of the values in the map
041 * @since 3.0
042 */
043public abstract class AbstractMapDecorator<K, V> extends AbstractIterableMap<K, V> {
044
045    /** The map to decorate */
046    transient Map<K, V> map;
047
048    /**
049     * Constructor only used in deserialization, do not use otherwise.
050     *
051     * @since 3.1
052     */
053    protected AbstractMapDecorator() {
054    }
055
056    /**
057     * Constructor that wraps (not copies).
058     *
059     * @param map  The map to decorate, must not be null
060     * @throws NullPointerException if the map is null
061     */
062    protected AbstractMapDecorator(final Map<K, V> map) {
063        this.map = Objects.requireNonNull(map, "map");
064    }
065
066    @Override
067    public void clear() {
068        decorated().clear();
069    }
070
071    @Override
072    public boolean containsKey(final Object key) {
073        return decorated().containsKey(key);
074    }
075
076    @Override
077    public boolean containsValue(final Object value) {
078        return decorated().containsValue(value);
079    }
080
081    /**
082     * Gets the map being decorated.
083     *
084     * @return The decorated map
085     */
086    protected Map<K, V> decorated() {
087        return map;
088    }
089
090    @Override
091    public Set<Map.Entry<K, V>> entrySet() {
092        return decorated().entrySet();
093    }
094
095    @Override
096    public boolean equals(final Object object) {
097        if (object == this) {
098            return true;
099        }
100        return decorated().equals(object);
101    }
102
103    @Override
104    public V get(final Object key) {
105        return decorated().get(key);
106    }
107
108    @Override
109    public int hashCode() {
110        return decorated().hashCode();
111    }
112
113    @Override
114    public boolean isEmpty() {
115        return decorated().isEmpty();
116    }
117
118    @Override
119    public Set<K> keySet() {
120        return decorated().keySet();
121    }
122
123    @Override
124    public V put(final K key, final V value) {
125        return decorated().put(key, value);
126    }
127
128    @Override
129    public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
130        decorated().putAll(mapToCopy);
131    }
132
133    @Override
134    public V remove(final Object key) {
135        return decorated().remove(key);
136    }
137
138    @Override
139    public int size() {
140        return decorated().size();
141    }
142
143    @Override
144    public String toString() {
145        return decorated().toString();
146    }
147
148    @Override
149    public Collection<V> values() {
150        return decorated().values();
151    }
152
153}