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

com.speedment.runtime.core.internal.stream.StreamUtil Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

There is a newer version: 3.1.18
Show newest version
/**
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * 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:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.speedment.runtime.core.internal.stream;

import com.speedment.runtime.core.db.SqlFunction;
import com.speedment.runtime.core.exception.SpeedmentException;
import com.speedment.runtime.core.stream.parallel.ParallelStrategy;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static com.speedment.runtime.core.util.StaticClassUtil.instanceNotAllowed;
import static java.util.Objects.requireNonNull;

/**
 *
 * @author Emil Forslund
 */
public final class StreamUtil {
    
    public static  Stream streamOfOptional(@SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional element) {
        return Stream.of(element.orElse(null)).filter(Objects::nonNull);
    }

    public static  Stream streamOfNullable(T element) {
        // Needless to say, element is nullable...
        if (element == null) {
            return Stream.empty();
        } else {
            return Stream.of(element);
        }
    }

    public static  Stream asStream(Iterator iterator) {
        requireNonNull(iterator);
        return asStream(iterator, false);
    }

    public static  Stream asStream(Iterator iterator, boolean parallel) {
        requireNonNull(iterator);
        final Iterable iterable = () -> iterator;
        return StreamSupport.stream(iterable.spliterator(), parallel);
    }

    public static  Stream asStream(ResultSet resultSet, SqlFunction mapper) {
         return asStream(resultSet, mapper, ParallelStrategy.computeIntensityDefault());
    }
    
    public static  Stream asStream(ResultSet resultSet, SqlFunction mapper, ParallelStrategy parallelStrategy) {
        requireNonNull(resultSet);
        requireNonNull(mapper);
        final Iterator iterator = new ResultSetIterator<>(resultSet, mapper);
        return StreamSupport.stream(parallelStrategy.spliteratorUnknownSize(iterator, Spliterator.IMMUTABLE + Spliterator.NONNULL), false);
    }

    public static  Stream from(@SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional optional) {
        requireNonNull(optional);
        return optional.map(Stream::of).orElseGet(Stream::empty);
    }

    /**
     * Specialized read-only {@link Iterator} for consuming
     * {@link ResultSet ResultSets} by mapping them to an entity using an
     * adapter. This implementation is not thread safe.
     *
     * @param   the type of the entity
     */
    static class ResultSetIterator implements Iterator {

        /**
         * The current state of the {@code ResultSetIterator}.
         */
        private enum State {
            /**
             * There is a row in the ResultSet that has not yet been consumed.
             */
            NEXT,

            /**
             * There are no more rows in the ResultSet.
             */
            NO_NEXT,

            /**
             * The current row has already been consumed and we don't know if
             * there are any more yet. Call {@link #hasNext()} to find out.
             */
            NOT_DETERMINED
        }

        private final ResultSet resultSet;
        private final SqlFunction mapper;

        private State state = State.NOT_DETERMINED;

        ResultSetIterator(final ResultSet resultSet,
                          final SqlFunction mapper) {

            this.resultSet = requireNonNull(resultSet);
            this.mapper    = requireNonNull(mapper);
        }

        /**
         * {@inheritDoc}
         * 

* After the termination of this method, the state will be either * {@link State#NEXT} or {@link State#NO_NEXT}. Calling this method * multiple times in a row has no effect. The state will remain the * same. * * @return if there are more rows */ @Override public boolean hasNext() { switch (state) { case NEXT : return true; case NO_NEXT : return false; case NOT_DETERMINED : { try { if (!resultSet.next()) { state = State.NO_NEXT; return false; } } catch (final SQLException ex) { state = State.NO_NEXT; return false; } state = State.NEXT; return true; } default : throw new IllegalStateException( "Unknown state '" + state + "'." ); } } @Override public T next() { if (state == State.NOT_DETERMINED) { if (!hasNext()) { throwNoSuchElementException(); }; } if (state == State.NO_NEXT) { throwNoSuchElementException(); } state = State.NOT_DETERMINED; try { return mapper.apply(resultSet); } catch (final SQLException ex) { throw new SpeedmentException(ex); } } @Override public void forEachRemaining(Consumer action) { if (state == State.NOT_DETERMINED) { if (!hasNext()) { return; }; } if (state == State.NO_NEXT) { return; } try { do { try { action.accept(mapper.apply(resultSet)); } catch (final SQLException ex) { throw new SpeedmentException(ex); } } while (resultSet.next()); } catch (final SQLException ex) { // Do nothing. } finally { state = State.NO_NEXT; } } private void throwNoSuchElementException() { throw new NoSuchElementException( "Next was called even though hasNext() returned false." ); } } /** * Utility classes should not be instantiated. */ private StreamUtil() { instanceNotAllowed(getClass()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy