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

org.jhotdraw8.icollection.facade.SequencedCollectionFacade Maven / Gradle / Ivy

/*
 * @(#)SequencedCollectionFacade.java
 * Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
 */
package org.jhotdraw8.icollection.facade;

import org.jhotdraw8.icollection.readonly.ReadOnlyCollection;
import org.jhotdraw8.icollection.readonly.ReadOnlySequencedCollection;
import org.jspecify.annotations.Nullable;

import java.util.Collection;
import java.util.Iterator;
import java.util.SequencedCollection;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Provides a {@link SequencedCollection} facade to a set of {@code Collection} functions.
 *
 * @param  the element type
 * @author Werner Randelshofer
 */
public class SequencedCollectionFacade extends CollectionFacade implements SequencedCollection {
    private final Supplier getFirstFunction;
    private final Supplier getLastFunction;

    private final Consumer addFirstFunction;
    private final Consumer addLastFunction;
    private final Supplier> reverseIteratorFunction;

    public SequencedCollectionFacade(ReadOnlySequencedCollection backingCollection) {
        this(backingCollection::iterator, () -> backingCollection.readOnlyReversed().iterator(), backingCollection::size,
                backingCollection::contains, null, null, null, null, null, null, null);
    }

    public SequencedCollectionFacade(ReadOnlyCollection backingCollection,
                                     Supplier> reverseIteratorFunction) {
        this(backingCollection::iterator, reverseIteratorFunction, backingCollection::size,
                backingCollection::contains, null, null, null, null, null, null, null);
    }

    public SequencedCollectionFacade(Collection backingCollection,
                                     Supplier> reverseIteratorFunction) {
        this(backingCollection::iterator, reverseIteratorFunction, backingCollection::size,
                backingCollection::contains, backingCollection::clear, backingCollection::remove,
                null, null, null, null, null);
    }

    public SequencedCollectionFacade(Supplier> iteratorFunction,
                                     Supplier> reverseIteratorFunction,
                                     IntSupplier sizeFunction,
                                     Predicate containsFunction) {
        this(iteratorFunction, reverseIteratorFunction, sizeFunction, containsFunction, null, null, null, null, null, null, null);
    }

    public SequencedCollectionFacade(Supplier> iteratorFunction,
                                     Supplier> reverseIteratorFunction,
                                     IntSupplier sizeFunction,
                                     Predicate containsFunction,
                                     @Nullable Runnable clearFunction,
                                     @Nullable Predicate removeFunction,
                                     @Nullable Supplier getFirstFunction,
                                     @Nullable Supplier getLastFunction,
                                     @Nullable Consumer addFirstFunction,
                                     @Nullable Consumer addLastFunction,
                                     @Nullable Predicate addFunction) {
        super(iteratorFunction, null, sizeFunction, containsFunction, clearFunction, addFunction, removeFunction);
        this.getFirstFunction = getFirstFunction == null ? () -> {
            throw new UnsupportedOperationException();
        } : getFirstFunction;
        this.getLastFunction = getLastFunction == null ? () -> {
            throw new UnsupportedOperationException();
        } : getLastFunction;
        this.addFirstFunction = addFirstFunction == null ? e -> {
            throw new UnsupportedOperationException();
        } : addFirstFunction;
        this.addLastFunction = addLastFunction == null ? e -> {
            throw new UnsupportedOperationException();
        } : addLastFunction;
        this.reverseIteratorFunction = reverseIteratorFunction;
    }

    @Override
    public void addFirst(E e) {
        addFirstFunction.accept(e);
    }

    @Override
    public void addLast(E e) {
        addLastFunction.accept(e);
    }

    @Override
    public E getFirst() {
        return getFirstFunction.get();
    }

    @Override
    public E getLast() {
        return getLastFunction.get();
    }

    @Override
    public SequencedCollection reversed() {
        return new SequencedCollectionFacade<>(
                reverseIteratorFunction,
                iteratorFunction,
                sizeFunction,
                containsFunction,
                clearFunction,
                removeFunction,
                getLastFunction,
                getFirstFunction,
                addLastFunction,
                addFirstFunction, addFunction);
    }

    @Override
    public Spliterator spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}