001/*
002 * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025package Torello.Java.ReadOnly;
026
027import Torello.Java.Additional.RemoveUnsupportedIterator;
028
029import java.util.Map;
030import java.util.Spliterator;
031import java.util.stream.Stream;
032import java.util.function.Consumer;
033import java.util.function.IntFunction;
034import java.util.Collection;
035
036
037/**
038 * Immutable variant of Java Collections Framework interface
039 * <CODE>java&#46;util&#46;SequencedMap&lt;K, V&gt;</CODE>.
040 * 
041 * <EMBED CLASS='external-html' DATA-JDK=ReadOnlySequencedMap DATA-FILE-ID=INTERFACES>
042 * 
043 * @param <K> the type of keys maintained by this map
044 * @param <V> the type of mapped values
045 */
046@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_INTERFACE")
047public interface ReadOnlySequencedMap<K, V> extends ReadOnlyMap<K, V>
048{
049    // ********************************************************************************************
050    // ********************************************************************************************
051    // Original JDK Interface Methods
052    // ********************************************************************************************
053    // ********************************************************************************************
054
055
056    /**
057     * Returns a reverse-ordered view of this map.  The
058     * encounter order of mappings in the returned view is the inverse of the encounter order of
059     * mappings in this map. The reverse ordering affects all order-sensitive operations, including
060     * those on the view collections of the returned view.
061     * 
062     * @return a reverse-ordered view of this map
063     */
064    ReadOnlySequencedMap<K, V> reversed();
065
066    /**
067     * Returns the first key-value mapping in this map, or {@code null} if the map is empty.
068     *
069     * @implSpec
070     * The implementation in this interface obtains the iterator of this map's entrySet.
071     * If the iterator has an element, it returns an unmodifiable copy of that element.
072     * Otherwise, it returns null.
073     *
074     * @return the first key-value mapping, or {@code null} if this map is empty
075     */
076    default ReadOnlyMap.Entry<K,V> firstEntry()
077    {
078        RemoveUnsupportedIterator<ReadOnlyMap.Entry<K, V>> it = entrySet().iterator();
079
080        return it.hasNext() ? it.next() : null;
081        // return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null;
082    }
083
084    /**
085     * Returns the last key-value mapping in this map, or {@code null} if the map is empty.
086     *
087     * @implSpec
088     * The implementation in this interface obtains the iterator of the entrySet of this map's
089     * reversed view.  If the iterator has an element, it returns an unmodifiable copy of
090     * that element. Otherwise, it returns null.
091     *
092     * @return the last key-value mapping, or {@code null} if this map is empty
093     */
094    default ReadOnlyMap.Entry<K,V> lastEntry()
095    {
096        RemoveUnsupportedIterator<ReadOnlyMap.Entry<K, V>> it = reversed().entrySet().iterator();
097
098        return it.hasNext() ? it.next() : null;
099        // return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null;
100    }
101
102    /**
103     * Returns a {@code SequencedSet} view of this map's {@link #keySet keySet}.
104     *
105     * @implSpec
106     * The implementation in this interface returns a {@code SequencedSet} instance
107     * that behaves as follows. 
108     * 
109     * Its {@link ReadOnlySequencedSet#reversed reversed} method returns the
110     * {@link #sequencedKeySet sequencedKeySet} view of the {@link #reversed reversed} view of this
111     * map. Each of its other methods calls the corresponding method of the {@link #keySet keySet}
112     * view of this map.
113     * 
114     * @return a {@code SequencedSet} view of this map's {@code keySet}
115     */
116    default ReadOnlySequencedSet<K> sequencedKeySet()
117    {
118        class ReadOnlySeqKeySet
119            extends /* AbstractReadOnlyMap. */ ViewCollection<K>
120            implements ReadOnlySequencedSet<K>
121        {
122            public java.util.Set<K> wrapToImmutableSet() { throw new Error(); }
123            public java.util.Set<K> cloneToSet() { throw new Error(); }
124
125            public ReadOnlyCollection<K> view()
126            { return ReadOnlySequencedMap.this.keySet(); }
127
128            public ReadOnlySequencedSet<K> reversed()
129            { return ReadOnlySequencedMap.this.reversed().sequencedKeySet(); }
130
131            public boolean equals(Object other)
132            { return view().equals(other); }
133
134            public int hashCode()
135            { return view().hashCode(); }
136        }
137
138        return new ReadOnlySeqKeySet();
139    }
140
141    /**
142     * Returns a {@code SequencedCollection} view of this map's {@link #values values} collection.
143     *
144     * @implSpec
145     * The implementation in this interface returns a {@code SequencedCollection} instance
146     * that behaves as follows. 
147     * 
148     * Its {@link ReadOnlySequencedCollection#reversed reversed} method returns the
149     * {@link #sequencedValues sequencedValues} view of the {@link #reversed reversed} view of this
150     * map. Its {@code Object.equals} and {@code Object.hashCode} methods are inherited from
151     * {@code Object}. Each of its other methods calls the corresponding method of the
152     * {@link #values values} view of this map.
153     *
154     * @return a {@code SequencedCollection} view of this map's {@code values} collection
155     */
156    default ReadOnlySequencedCollection<V> sequencedValues()
157    {
158        class ReadOnlySeqValues
159            extends /* AbstractReadOnlyMap. */ ViewCollection<V>
160            implements ReadOnlySequencedCollection<V>
161        {
162            public ReadOnlyCollection<V> view()
163            { return ReadOnlySequencedMap.this.values(); }
164
165            public ReadOnlySequencedCollection<V> reversed()
166            { return ReadOnlySequencedMap.this.reversed().sequencedValues(); }
167        }
168
169        return new ReadOnlySeqValues();
170    }
171
172    /**
173     * Returns a {@code SequencedSet} view of this map's {@link #entrySet entrySet}.
174     * 
175     * @implSpec
176     * The implementation in this interface returns a {@code SequencedSet} instance that behaves as
177     * follows.  Its {@link ReadOnlySequencedSet#reversed reversed} method returns the
178     * {@link #sequencedEntrySet sequencedEntrySet} view of the {@link #reversed reversed} view of
179     * this map.  Each of its other methods calls the corresponding method of the
180     * {@link #entrySet entrySet} view of this map.
181     * 
182     * @return a {@code SequencedSet} view of this map's {@code entrySet}
183     */
184    default ReadOnlySequencedSet<ReadOnlyMap.Entry<K, V>> sequencedEntrySet()
185    {
186        class ReadOnlySeqEntrySet
187            extends /* AbstractReadOnlyMap. */ ViewCollection<ReadOnlyMap.Entry<K, V>>
188            implements ReadOnlySequencedSet<ReadOnlyMap.Entry<K, V>>
189        {
190            public java.util.Set<ReadOnlyMap.Entry<K, V>> wrapToImmutableSet()
191            { throw new Error(); }
192
193            public java.util.Set<ReadOnlyMap.Entry<K, V>> cloneToSet()
194            { throw new Error(); }
195
196            public ReadOnlyCollection<ReadOnlyMap.Entry<K, V>> view()
197            { return ReadOnlySequencedMap.this.entrySet(); }
198
199            public ReadOnlySequencedSet<ReadOnlyMap.Entry<K, V>> reversed()
200            { return ReadOnlySequencedMap.this.reversed().sequencedEntrySet(); }
201
202            public boolean equals(Object other)
203            { return view().equals(other); }
204
205            public int hashCode()
206            { return view().hashCode(); }
207        }
208
209        return new ReadOnlySeqEntrySet();
210    }
211
212}
213
214
215    // Copied from JDK
216abstract class ViewCollection<E> implements ReadOnlyCollection<E>
217{
218    UnsupportedOperationException uoe()
219    { return new UnsupportedOperationException(); }
220
221    abstract ReadOnlyCollection<E> view();
222
223    public boolean contains(Object o)                   { return view().contains(o); }
224    public boolean containsAll(Collection<?> c)         { return view().containsAll(c); }
225    public void forEach(Consumer<? super E> c)          { view().forEach(c); }
226    public boolean isEmpty()                            { return view().isEmpty(); }
227    public RemoveUnsupportedIterator<E> iterator()      { return view().iterator(); }
228    public Stream<E> parallelStream()                   { return view().parallelStream(); }
229    public int size()                                   { return view().size(); }
230    public Spliterator<E> spliterator()                 { return view().spliterator(); }
231    public Stream<E> stream()                           { return view().stream(); }
232    public Object[] toArray()                           { return view().toArray(); }
233    public <T> T[] toArray(IntFunction<T[]> generator)  { return view().toArray(generator); }
234    public <T> T[] toArray(T[] a)                       { return view().toArray(a); }
235    public String toString()                            { return view().toString(); }
236}