UnmodifiableSortedMap.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.map;

  18. import java.io.IOException;
  19. import java.io.ObjectInputStream;
  20. import java.io.ObjectOutputStream;
  21. import java.io.Serializable;
  22. import java.util.Collection;
  23. import java.util.Comparator;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.SortedMap;

  27. import org.apache.commons.collections4.Unmodifiable;
  28. import org.apache.commons.collections4.collection.UnmodifiableCollection;
  29. import org.apache.commons.collections4.set.UnmodifiableSet;

  30. /**
  31.  * Decorates another {@code SortedMap} to ensure it can't be altered.
  32.  * <p>
  33.  * This class is Serializable from Commons Collections 3.1.
  34.  * </p>
  35.  * <p>
  36.  * Attempts to modify it will result in an UnsupportedOperationException.
  37.  * </p>
  38.  *
  39.  * @param <K> the type of the keys in this map
  40.  * @param <V> the type of the values in this map
  41.  * @since 3.0
  42.  */
  43. public final class UnmodifiableSortedMap<K, V>
  44.         extends AbstractSortedMapDecorator<K, V>
  45.         implements Unmodifiable, Serializable {

  46.     /** Serialization version */
  47.     private static final long serialVersionUID = 5805344239827376360L;

  48.     /**
  49.      * Factory method to create an unmodifiable sorted map.
  50.      *
  51.      * @param <K>  the key type
  52.      * @param <V>  the value type
  53.      * @param map  the map to decorate, must not be null
  54.      * @return a new unmodifiable sorted map
  55.      * @throws NullPointerException if map is null
  56.      * @since 4.0
  57.      */
  58.     public static <K, V> SortedMap<K, V> unmodifiableSortedMap(final SortedMap<K, ? extends V> map) {
  59.         if (map instanceof Unmodifiable) {
  60.             @SuppressWarnings("unchecked") // safe to upcast
  61.             final SortedMap<K, V> tmpMap = (SortedMap<K, V>) map;
  62.             return tmpMap;
  63.         }
  64.         return new UnmodifiableSortedMap<>(map);
  65.     }

  66.     /**
  67.      * Constructor that wraps (not copies).
  68.      *
  69.      * @param map  the map to decorate, must not be null
  70.      * @throws NullPointerException if map is null
  71.      */
  72.     @SuppressWarnings("unchecked") // safe to upcast
  73.     private UnmodifiableSortedMap(final SortedMap<K, ? extends V> map) {
  74.         super((SortedMap<K, V>) map);
  75.     }

  76.     @Override
  77.     public void clear() {
  78.         throw new UnsupportedOperationException();
  79.     }

  80.     @Override
  81.     public Comparator<? super K> comparator() {
  82.         return decorated().comparator();
  83.     }

  84.     @Override
  85.     public Set<Map.Entry<K, V>> entrySet() {
  86.         return UnmodifiableEntrySet.unmodifiableEntrySet(super.entrySet());
  87.     }

  88.     @Override
  89.     public K firstKey() {
  90.         return decorated().firstKey();
  91.     }

  92.     @Override
  93.     public SortedMap<K, V> headMap(final K toKey) {
  94.         return new UnmodifiableSortedMap<>(decorated().headMap(toKey));
  95.     }

  96.     @Override
  97.     public Set<K> keySet() {
  98.         return UnmodifiableSet.unmodifiableSet(super.keySet());
  99.     }

  100.     @Override
  101.     public K lastKey() {
  102.         return decorated().lastKey();
  103.     }

  104.     @Override
  105.     public V put(final K key, final V value) {
  106.         throw new UnsupportedOperationException();
  107.     }

  108.     @Override
  109.     public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
  110.         throw new UnsupportedOperationException();
  111.     }

  112.     /**
  113.      * Deserializes the map in using a custom routine.
  114.      *
  115.      * @param in  the input stream
  116.      * @throws IOException if an error occurs while reading from the stream
  117.      * @throws ClassNotFoundException if an object read from the stream cannot be loaded
  118.      * @since 3.1
  119.      */
  120.     @SuppressWarnings("unchecked")
  121.     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
  122.         in.defaultReadObject();
  123.         map = (Map<K, V>) in.readObject();
  124.     }

  125.     @Override
  126.     public V remove(final Object key) {
  127.         throw new UnsupportedOperationException();
  128.     }

  129.     @Override
  130.     public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
  131.         return new UnmodifiableSortedMap<>(decorated().subMap(fromKey, toKey));
  132.     }

  133.     @Override
  134.     public SortedMap<K, V> tailMap(final K fromKey) {
  135.         return new UnmodifiableSortedMap<>(decorated().tailMap(fromKey));
  136.     }

  137.     @Override
  138.     public Collection<V> values() {
  139.         return UnmodifiableCollection.unmodifiableCollection(super.values());
  140.     }

  141.     /**
  142.      * Serializes this object to an ObjectOutputStream.
  143.      *
  144.      * @param out the target ObjectOutputStream.
  145.      * @throws IOException thrown when an I/O errors occur writing to the target stream.
  146.      * @since 3.1
  147.      */
  148.     private void writeObject(final ObjectOutputStream out) throws IOException {
  149.         out.defaultWriteObject();
  150.         out.writeObject(map);
  151.     }

  152. }