All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cedarsoftware.util.SealableList Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
package com.cedarsoftware.util;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Supplier;

/**
 * SealableList provides a List or List wrapper that can be 'sealed' and 'unsealed.'  When
 * sealed, the List is mutable, when unsealed it is immutable (read-only). The iterator(),
 * listIterator(), and subList() return views that honor the Supplier's sealed state.
 * The sealed state can be changed as often as needed.
 * 

* NOTE: Please do not reformat this code as the current format makes it easy to see the overall structure. *

* @author John DeRegnaucourt ([email protected]) *
* Copyright (c) Cedar Software LLC *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* License *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class SealableList implements List { private final List list; private final transient Supplier sealedSupplier; /** * Create a SealableList. Since no List is being supplied, this will use an ConcurrentList internally. If you * want to use an ArrayList for example, use SealableList constructor that takes a List and pass it the instance * you want it to wrap. * @param sealedSupplier {@code Supplier} that returns 'true' to indicate sealed, 'false' for mutable. */ public SealableList(Supplier sealedSupplier) { this.list = new ConcurrentList<>(); this.sealedSupplier = sealedSupplier; } /** * Create a SealableList. Since a List is not supplied, the elements from the passed in Collection will be * copied to an internal ConcurrentList. If you want to use an ArrayList for example, use SealableList * constructor that takes a List and pass it the instance you want it to wrap. * @param col Collection to supply initial elements. These are copied to an internal ConcurrentList. * @param sealedSupplier {@code Supplier} that returns 'true' to indicate sealed, 'false' for mutable. */ public SealableList(Collection col, Supplier sealedSupplier) { this.list = new ConcurrentList<>(); this.list.addAll(col); this.sealedSupplier = sealedSupplier; } /** * Use this constructor to wrap a List (any kind of List) and make it a SealableList. * No duplicate of the List is created and the original list is operated on directly if unsealed, or protected * from changes if sealed. * @param list List instance to protect. * @param sealedSupplier {@code Supplier} that returns 'true' to indicate sealed, 'false' for mutable. */ public SealableList(List list, Supplier sealedSupplier) { this.list = list; this.sealedSupplier = sealedSupplier; } private void throwIfSealed() { if (sealedSupplier.get()) { throw new UnsupportedOperationException("This list has been sealed and is now immutable"); } } // Immutable APIs public boolean equals(Object other) { return list.equals(other); } public int hashCode() { return list.hashCode(); } public String toString() { return list.toString(); } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public boolean containsAll(Collection col) { return new HashSet<>(list).containsAll(col); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public T get(int index) { return list.get(index); } public Object[] toArray() { return list.toArray(); } public T1[] toArray(T1[] a) { return list.toArray(a);} public Iterator iterator() { return createSealHonoringIterator(list.iterator()); } public ListIterator listIterator() { return createSealHonoringListIterator(list.listIterator()); } public ListIterator listIterator(final int index) { return createSealHonoringListIterator(list.listIterator(index)); } public List subList(int fromIndex, int toIndex) { return new SealableList<>(list.subList(fromIndex, toIndex), sealedSupplier); } // Mutable APIs public boolean add(T t) { throwIfSealed(); return list.add(t); } public boolean remove(Object o) { throwIfSealed(); return list.remove(o); } public boolean addAll(Collection col) { throwIfSealed(); return list.addAll(col); } public boolean addAll(int index, Collection col) { throwIfSealed(); return list.addAll(index, col); } public boolean removeAll(Collection col) { throwIfSealed(); return list.removeAll(col); } public boolean retainAll(Collection col) { throwIfSealed(); return list.retainAll(col); } public void clear() { throwIfSealed(); list.clear(); } public T set(int index, T element) { throwIfSealed(); return list.set(index, element); } public void add(int index, T element) { throwIfSealed(); list.add(index, element); } public T remove(int index) { throwIfSealed(); return list.remove(index); } private Iterator createSealHonoringIterator(Iterator iterator) { return new Iterator() { public boolean hasNext() { return iterator.hasNext(); } public T next() { return iterator.next(); } public void remove() { throwIfSealed(); iterator.remove(); } }; } private ListIterator createSealHonoringListIterator(ListIterator iterator) { return new ListIterator() { public boolean hasNext() { return iterator.hasNext();} public T next() { return iterator.next(); } public boolean hasPrevious() { return iterator.hasPrevious(); } public T previous() { return iterator.previous(); } public int nextIndex() { return iterator.nextIndex(); } public int previousIndex() { return iterator.previousIndex(); } public void remove() { throwIfSealed(); iterator.remove(); } public void set(T e) { throwIfSealed(); iterator.set(e); } public void add(T e) { throwIfSealed(); iterator.add(e);} }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy