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.trie;
018
019import java.io.Serializable;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.Comparator;
023import java.util.Map;
024import java.util.Set;
025import java.util.SortedMap;
026
027import org.apache.commons.collections4.OrderedMapIterator;
028import org.apache.commons.collections4.Trie;
029import org.apache.commons.collections4.Unmodifiable;
030import org.apache.commons.collections4.iterators.UnmodifiableOrderedMapIterator;
031
032/**
033 * An unmodifiable {@link Trie}.
034 *
035 * @since 4.0
036 * @version $Id: UnmodifiableTrie.html 972421 2015-11-14 20:00:04Z tn $
037 */
038public class UnmodifiableTrie<K, V> implements Trie<K, V>, Serializable, Unmodifiable {
039
040    /** Serialization version */
041    private static final long serialVersionUID = -7156426030315945159L;
042
043    private final Trie<K, V> delegate;
044
045    /**
046     * Factory method to create a unmodifiable trie.
047     *
048     * @param <K>  the key type
049     * @param <V>  the value type
050     * @param trie  the trie to decorate, must not be null
051     * @return a new unmodifiable trie
052     * @throws IllegalArgumentException if trie is null
053     */
054    public static <K, V> Trie<K, V> unmodifiableTrie(final Trie<K, ? extends V> trie) {
055        if (trie instanceof Unmodifiable) {
056            @SuppressWarnings("unchecked") // safe to upcast
057            final Trie<K, V> tmpTrie = (Trie<K, V>) trie;
058            return tmpTrie;
059        }
060        return new UnmodifiableTrie<K, V>(trie);
061    }
062
063    //-----------------------------------------------------------------------
064    /**
065     * Constructor that wraps (not copies).
066     *
067     * @param trie  the trie to decorate, must not be null
068     * @throws IllegalArgumentException if trie is null
069     */
070    public UnmodifiableTrie(final Trie<K, ? extends V> trie) {
071        if (trie == null) {
072            throw new IllegalArgumentException("Trie must not be null");
073        }
074        @SuppressWarnings("unchecked") // safe to upcast
075        final Trie<K, V> tmpTrie = (Trie<K, V>) trie;
076        this.delegate = tmpTrie;
077    }
078
079    //-----------------------------------------------------------------------
080
081    public Set<Entry<K, V>> entrySet() {
082        return Collections.unmodifiableSet(delegate.entrySet());
083    }
084
085    public Set<K> keySet() {
086        return Collections.unmodifiableSet(delegate.keySet());
087    }
088
089    public Collection<V> values() {
090        return Collections.unmodifiableCollection(delegate.values());
091    }
092
093    public void clear() {
094        throw new UnsupportedOperationException();
095    }
096
097    public boolean containsKey(final Object key) {
098        return delegate.containsKey(key);
099    }
100
101    public boolean containsValue(final Object value) {
102        return delegate.containsValue(value);
103    }
104
105    public V get(final Object key) {
106        return delegate.get(key);
107    }
108
109    public boolean isEmpty() {
110        return delegate.isEmpty();
111    }
112
113    public V put(final K key, final V value) {
114        throw new UnsupportedOperationException();
115    }
116
117    public void putAll(final Map<? extends K, ? extends V> m) {
118        throw new UnsupportedOperationException();
119    }
120
121    public V remove(final Object key) {
122        throw new UnsupportedOperationException();
123    }
124
125    public int size() {
126        return delegate.size();
127    }
128
129    public K firstKey() {
130        return delegate.firstKey();
131    }
132
133    public SortedMap<K, V> headMap(final K toKey) {
134        return Collections.unmodifiableSortedMap(delegate.headMap(toKey));
135    }
136
137    public K lastKey() {
138        return delegate.lastKey();
139    }
140
141    public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
142        return Collections.unmodifiableSortedMap(delegate.subMap(fromKey, toKey));
143    }
144
145    public SortedMap<K, V> tailMap(final K fromKey) {
146        return Collections.unmodifiableSortedMap(delegate.tailMap(fromKey));
147    }
148
149    public SortedMap<K, V> prefixMap(final K key) {
150        return Collections.unmodifiableSortedMap(delegate.prefixMap(key));
151    }
152
153    public Comparator<? super K> comparator() {
154        return delegate.comparator();
155    }
156
157    //-----------------------------------------------------------------------
158    public OrderedMapIterator<K, V> mapIterator() {
159        final OrderedMapIterator<K, V> it = delegate.mapIterator();
160        return UnmodifiableOrderedMapIterator.unmodifiableOrderedMapIterator(it);
161    }
162
163    public K nextKey(K key) {
164        return delegate.nextKey(key);
165    }
166
167    public K previousKey(K key) {
168        return delegate.previousKey(key);
169    }
170
171    //-----------------------------------------------------------------------
172    @Override
173    public int hashCode() {
174        return delegate.hashCode();
175    }
176
177    @Override
178    public boolean equals(final Object obj) {
179        return delegate.equals(obj);
180    }
181
182    @Override
183    public String toString() {
184        return delegate.toString();
185    }
186
187}