    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 */
    017package org.apache.commons.collections4.bidimap;
    018
    019import java.util.Map;
    020import java.util.Set;
    021import java.util.SortedMap;
    022
    023import org.apache.commons.collections4.OrderedMapIterator;
    024import org.apache.commons.collections4.SortedBidiMap;
    025import org.apache.commons.collections4.Unmodifiable;
    026import org.apache.commons.collections4.iterators.UnmodifiableOrderedMapIterator;
    027import org.apache.commons.collections4.map.UnmodifiableEntrySet;
    028import org.apache.commons.collections4.map.UnmodifiableSortedMap;
    029import org.apache.commons.collections4.set.UnmodifiableSet;
    030
    031/**
    032 * Decorates another {@link SortedBidiMap} to ensure it can't be altered.
    033 * <p>
    034 * Attempts to modify it will result in an {@link UnsupportedOperationException}.
    035 * </p>
    036 *
    037 * @param <K> the type of the keys in this map
    038 * @param <V> the type of the values in this map
    039 * @since 3.0
    040 */
    041public final class UnmodifiableSortedBidiMap<K, V>
    042        extends AbstractSortedBidiMapDecorator<K, V> implements Unmodifiable {
    043
    044    /** The inverse unmodifiable map */
    045    private UnmodifiableSortedBidiMap<V, K> inverse;
    046
    047    /**
    048     * Factory method to create an unmodifiable map.
    049     * <p>
    050     * If the map passed in is already unmodifiable, it is returned.
    051     *
    052     * @param <K> the key type
    053     * @param <V> the value type
    054     * @param map  the map to decorate, must not be null
    055     * @return an unmodifiable SortedBidiMap
    056     * @throws NullPointerException if map is null
    057     * @since 4.0
    058     */
    059    public static <K, V> SortedBidiMap<K, V> unmodifiableSortedBidiMap(final SortedBidiMap<K, ? extends V> map) {
    060        if (map instanceof Unmodifiable) {
    061            @SuppressWarnings("unchecked") // safe to upcast
    062            final SortedBidiMap<K, V> tmpMap = (SortedBidiMap<K, V>) map;
    063            return tmpMap;
    064        }
    065        return new UnmodifiableSortedBidiMap<>(map);
    066    }
    067
    068    //-----------------------------------------------------------------------
    069    /**
    070     * Constructor that wraps (not copies).
    071     *
    072     * @param map  the map to decorate, must not be null
    073     * @throws NullPointerException if map is null
    074     */
    075    @SuppressWarnings("unchecked") // safe to upcast
    076    private UnmodifiableSortedBidiMap(final SortedBidiMap<K, ? extends V> map) {
    077        super((SortedBidiMap<K, V>) map);
    078    }
    079
    080    //-----------------------------------------------------------------------
    081    @Override
    082    public void clear() {
    083        throw new UnsupportedOperationException();
    084    }
    085
    086    @Override
    087    public V put(final K key, final V value) {
    088        throw new UnsupportedOperationException();
    089    }
    090
    091    @Override
    092    public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
    093        throw new UnsupportedOperationException();
    094    }
    095
    096    @Override
    097    public V remove(final Object key) {
    098        throw new UnsupportedOperationException();
    099    }
    100
    101    @Override
    102    public Set<Map.Entry<K, V>> entrySet() {
    103        final Set<Map.Entry<K, V>> set = super.entrySet();
    104        return UnmodifiableEntrySet.unmodifiableEntrySet(set);
    105    }
    106
    107    @Override
    108    public Set<K> keySet() {
    109        final Set<K> set = super.keySet();
    110        return UnmodifiableSet.unmodifiableSet(set);
    111    }
    112
    113    @Override
    114    public Set<V> values() {
    115        final Set<V> set = super.values();
    116        return UnmodifiableSet.unmodifiableSet(set);
    117    }
    118
    119    //-----------------------------------------------------------------------
    120    @Override
    121    public K removeValue(final Object value) {
    122        throw new UnsupportedOperationException();
    123    }
    124
    125    //-----------------------------------------------------------------------
    126    @Override
    127    public OrderedMapIterator<K, V> mapIterator() {
    128        final OrderedMapIterator<K, V> it = decorated().mapIterator();
    129        return UnmodifiableOrderedMapIterator.unmodifiableOrderedMapIterator(it);
    130    }
    131
    132    //-----------------------------------------------------------------------
    133    @Override
    134    public SortedBidiMap<V, K> inverseBidiMap() {
    135        if (inverse == null) {
    136            inverse = new UnmodifiableSortedBidiMap<>(decorated().inverseBidiMap());
    137            inverse.inverse = this;
    138        }
    139        return inverse;
    140    }
    141
    142    @Override
    143    public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
    144        final SortedMap<K, V> sm = decorated().subMap(fromKey, toKey);
    145        return UnmodifiableSortedMap.unmodifiableSortedMap(sm);
    146    }
    147
    148    @Override
    149    public SortedMap<K, V> headMap(final K toKey) {
    150        final SortedMap<K, V> sm = decorated().headMap(toKey);
    151        return UnmodifiableSortedMap.unmodifiableSortedMap(sm);
    152    }
    153
    154    @Override
    155    public SortedMap<K, V> tailMap(final K fromKey) {
    156        final SortedMap<K, V> sm = decorated().tailMap(fromKey);
    157        return UnmodifiableSortedMap.unmodifiableSortedMap(sm);
    158    }
    159
    160}