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

org.hibernate.query.spi.StreamDecorator Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.query.spi;

import java.lang.reflect.InvocationTargetException;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.internal.util.ReflectHelper;

/**
 * The {@link StreamDecorator} wraps a Java {@link Stream} and registers a {@code closeHandler}
 * which is passed further to any resulting {@link Stream}.
 *
 * The goal of the {@link StreamDecorator} is to close the underlying {@link Stream} upon
 * calling a terminal operation.
 *
 * @author Vlad Mihalcea
 * @since 5.4
 */
@Incubating
public class StreamDecorator implements Stream {

	private final Stream delegate;

	private Runnable closeHandler;

	public StreamDecorator(
			Stream delegate,
			Runnable closeHandler) {
		this.delegate = delegate;
		this.closeHandler = closeHandler;
		this.delegate.onClose( closeHandler );
	}

	@Override
	public Stream filter(Predicate predicate) {
		return new StreamDecorator( delegate.filter( predicate ), closeHandler );
	}

	@Override
	public  Stream map(Function mapper) {
		return new StreamDecorator<>( delegate.map( mapper ), closeHandler );
	}

	@Override
	public IntStream mapToInt(ToIntFunction mapper) {
		return new IntStreamDecorator(
				delegate.mapToInt( mapper ),
				closeHandler
		);
	}

	@Override
	public LongStream mapToLong(ToLongFunction mapper) {
		return new LongStreamDecorator(
				delegate.mapToLong( mapper ),
				closeHandler
		);
	}

	@Override
	public DoubleStream mapToDouble(ToDoubleFunction mapper) {
		return new DoubleStreamDecorator(
				delegate.mapToDouble( mapper ),
				closeHandler
		);
	}

	@Override
	public  Stream flatMap(Function> mapper) {
		return new StreamDecorator<>( delegate.flatMap( mapper ), closeHandler );
	}

	@Override
	public IntStream flatMapToInt(Function mapper) {
		return new IntStreamDecorator(
				delegate.flatMapToInt( mapper ),
				closeHandler
		);
	}

	@Override
	public LongStream flatMapToLong(Function mapper) {
		return new LongStreamDecorator(
				delegate.flatMapToLong( mapper ),
				closeHandler
		);
	}

	@Override
	public DoubleStream flatMapToDouble(Function mapper) {
		return new DoubleStreamDecorator(
				delegate.flatMapToDouble( mapper ),
				closeHandler
		);
	}

	@Override
	public Stream distinct() {
		return new StreamDecorator<>( delegate.distinct(), closeHandler );
	}

	@Override
	public Stream sorted() {
		return new StreamDecorator<>( delegate.sorted(), closeHandler );
	}

	@Override
	public Stream sorted(Comparator comparator) {
		return new StreamDecorator<>( delegate.sorted( comparator ), closeHandler );
	}

	@Override
	public Stream peek(Consumer action) {
		return new StreamDecorator<>( delegate.peek( action ), closeHandler );
	}

	@Override
	public Stream limit(long maxSize) {
		return new StreamDecorator<>( delegate.limit( maxSize ), closeHandler );
	}

	@Override
	public Stream skip(long n) {
		return new StreamDecorator<>( delegate.skip( n ), closeHandler );
	}

	@Override
	public void forEach(Consumer action) {
		delegate.forEach( action );
		close();
	}

	@Override
	public void forEachOrdered(Consumer action) {
		delegate.forEachOrdered( action );
		close();
	}

	@Override
	public Object[] toArray() {
		Object[] result = delegate.toArray();
		close();
		return result;
	}

	@Override
	public  A[] toArray(IntFunction generator) {
		A[] result = delegate.toArray( generator );
		close();
		return result;
	}

	@Override
	public R reduce(R identity, BinaryOperator accumulator) {
		R result = delegate.reduce( identity, accumulator );
		close();
		return result;
	}

	@Override
	public Optional reduce(BinaryOperator accumulator) {
		Optional result = delegate.reduce( accumulator );
		close();
		return result;
	}

	@Override
	public  U reduce(
			U identity, BiFunction accumulator, BinaryOperator combiner) {
		U result = delegate.reduce( identity, accumulator, combiner );
		close();
		return result;
	}

	@Override
	public  R1 collect(
			Supplier supplier, BiConsumer accumulator, BiConsumer combiner) {
		R1 result = delegate.collect( supplier, accumulator, combiner );
		close();
		return result;
	}

	@Override
	public  R1 collect(Collector collector) {
		R1 result = delegate.collect( collector );
		close();
		return result;
	}

	@Override
	public Optional min(Comparator comparator) {
		Optional result = delegate.min( comparator );
		close();
		return result;
	}

	@Override
	public Optional max(Comparator comparator) {
		Optional result = delegate.max( comparator );
		close();
		return result;
	}

	@Override
	public long count() {
		long result = delegate.count();
		close();
		return result;
	}

	@Override
	public boolean anyMatch(Predicate predicate) {
		boolean result = delegate.anyMatch( predicate );
		close();
		return result;
	}

	@Override
	public boolean allMatch(Predicate predicate) {
		boolean result = delegate.allMatch( predicate );
		close();
		return result;
	}

	@Override
	public boolean noneMatch(Predicate predicate) {
		boolean result = delegate.noneMatch( predicate );
		close();
		return result;
	}

	@Override
	public Optional findFirst() {
		Optional result = delegate.findFirst();
		close();
		return result;
	}

	@Override
	public Optional findAny() {
		Optional result = delegate.findAny();
		close();
		return result;
	}

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

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

	@Override
	public boolean isParallel() {
		return delegate.isParallel();
	}

	@Override
	public Stream sequential() {
		return new StreamDecorator<>( delegate.sequential(), closeHandler );
	}

	@Override
	public Stream parallel() {
		return new StreamDecorator<>( delegate.parallel(), closeHandler );
	}

	@Override
	public Stream unordered() {
		return new StreamDecorator<>( delegate.unordered(), closeHandler );
	}

	@Override
	public Stream onClose(Runnable closeHandler) {
		this.closeHandler = closeHandler;
		return this;
	}

	@Override
	public void close() {
		delegate.close();
	}

	//Methods added to JDK 9

	public Stream takeWhile(Predicate predicate) {
		try {
			@SuppressWarnings("unchecked")
			Stream result = (Stream)
					ReflectHelper.getMethod( Stream.class, "takeWhile", Predicate.class )
							.invoke( delegate, predicate );
			return new StreamDecorator<>( result, closeHandler );
		}
		catch (IllegalAccessException | InvocationTargetException e) {
			throw new HibernateException( e );
		}
	}

	public Stream dropWhile(Predicate predicate) {
		try {
			@SuppressWarnings("unchecked")
			Stream result = (Stream)
					ReflectHelper.getMethod( Stream.class, "dropWhile", Predicate.class )
							.invoke( delegate, predicate );
			return new StreamDecorator<>( result, closeHandler );
		}
		catch (IllegalAccessException | InvocationTargetException e) {
			throw new HibernateException( e );
		}
	}
}