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

org.opendaylight.yangtools.util.CollectionWrappers Maven / Gradle / Ivy

There is a newer version: 14.0.4
Show newest version
/*
 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.util;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import java.util.AbstractList;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Spliterator;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.concepts.Delegator;
import org.opendaylight.yangtools.concepts.Immutable;

/**
 * Utility class for adapting a {@link Collection}s to {@link Set}s and {@link List}s.
 *
 * @author Robert Varga
 */
@Beta
@NonNullByDefault
public final class CollectionWrappers {
    private static final class ListWrapper extends AbstractList implements Delegator> {
        private final Collection delegate;

        ListWrapper(final Collection delegate) {
            this.delegate = requireNonNull(delegate);
        }

        @Override
        public Collection getDelegate() {
            return delegate;
        }

        @Override
        public Iterator iterator() {
            return Iterators.unmodifiableIterator(delegate.iterator());
        }

        @Override
        public int size() {
            return delegate.size();
        }

        @Override
        public Spliterator spliterator() {
            return delegate.spliterator();
        }

        @Override
        public Stream parallelStream() {
            return delegate.parallelStream();
        }

        @Override
        public Stream stream() {
            return delegate.stream();
        }

        @Override
        public E get(final int index) {
            return Iterables.get(delegate, index);
        }
    }

    private static final class SetWrapper extends AbstractSet implements Delegator> {
        private final Collection delegate;

        SetWrapper(final Collection delegate) {
            this.delegate = requireNonNull(delegate);
        }

        @Override
        public Collection getDelegate() {
            return delegate;
        }

        @Override
        public Iterator iterator() {
            return Iterators.unmodifiableIterator(delegate.iterator());
        }

        @Override
        public int size() {
            return delegate.size();
        }

        @Override
        public Spliterator spliterator() {
            return delegate.spliterator();
        }

        @Override
        public Stream parallelStream() {
            return delegate.parallelStream();
        }

        @Override
        public Stream stream() {
            return delegate.stream();
        }
    }

    private CollectionWrappers() {

    }

    /**
     * Wrap the specified {@link Collection} as a {@link List}. If the collection is already a List, it is wrapped in
     * a {@link Collections#unmodifiableList(List)} to prevent mutability leaking. If the collection is determined
     * to be empty, an empty list is returned instead. If the collection is a known-immutable implementation of List
     * interface, it is returned unwrapped. Backing collection is required to be effectively immutable. If this
     * requirement is violated, the returned object may behave in unpredictable ways.
     *
     * @param  the type of elements in the collection
     * @param collection Collection to be wrapped
     * @return An effectively-immutable wrapper of the collection.
     * @throws NullPointerException if collection is null
     */
    public static  List wrapAsList(final Collection collection) {
        if (collection.isEmpty()) {
            return ImmutableList.of();
        }
        if (collection instanceof SetWrapper) {
            return wrapAsList(((SetWrapper) collection).getDelegate());
        }
        if (collection instanceof List) {
            final List cast = (List) collection;
            return cast instanceof ListWrapper || cast instanceof Immutable || cast instanceof ImmutableList
                    ? cast : Collections.unmodifiableList(cast);
        }

        return new ListWrapper<>(collection);
    }

    /**
     * Wrap the specified {@link Collection} as a {@link Set}. If the collection is already a Set, it is wrapped in
     * a {@link Collections#unmodifiableSet(Set)} to prevent mutability leaking. If the collection is determined
     * to be empty, an empty set is returned instead. If the collection is a known-immutable implementation of Set
     * interface, it is returned unwrapped. The collection is checked for duplicates at instantiation time, such that
     * it effectively implements the Set contract. Backing collection is required to be effectively immutable. If this
     * requirement is violated, the returned object may behave in unpredictable ways.
     *
     * @param  the type of elements in the collection
     * @param collection Collection to be wrapped
     * @return An effectively-immutable wrapper of the collection.
     * @throws NullPointerException if collection is null or any of its elements is null
     * @throws IllegalArgumentException if the collection's contents do not conform to the Set contract
     */
    public static  Set wrapAsSet(final Collection collection) {
        if (collection.isEmpty()) {
            return ImmutableSet.of();
        }
        if (collection instanceof ListWrapper) {
            return wrapAsSet(((ListWrapper) collection).getDelegate());
        }
        if (collection instanceof Set) {
            final Set cast = (Set) collection;
            return cast instanceof SetWrapper || cast instanceof Immutable || cast instanceof SingletonSet
                    || cast instanceof ImmutableSet ? cast : Collections.unmodifiableSet(cast);
        }

        final Set check = ImmutableSet.copyOf(collection);
        checkArgument(collection.size() == check.size(), "Supplied collection %s has duplicate elements", collection);
        return new SetWrapper<>(collection);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy