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

com.speedment.runtime.compute.internal.expression.ComposedUtil 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.

The 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.
 */
package com.speedment.runtime.compute.internal.expression;

import com.speedment.common.function.ToBooleanFunction;
import com.speedment.common.function.ToByteFunction;
import com.speedment.common.function.ToCharFunction;
import com.speedment.common.function.ToFloatFunction;
import com.speedment.common.function.ToShortFunction;
import com.speedment.runtime.compute.*;
import com.speedment.runtime.compute.expression.ComposedExpression;
import com.speedment.runtime.compute.expression.Expression;

import java.math.BigDecimal;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

import static java.util.Objects.requireNonNull;

/**
 * Utility class used to produce types instances of {@link ComposedExpression}.
 *
 * @author Emil Forslund
 * @since  3.1.0
 */
public final class ComposedUtil {

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToByteNullable composeToByte(Function before, ToByte after) {
        return new ComposeToByte<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToByteNullable composeToByteNullable(Function before, ToByteNullable after) {
        return new ComposeToByte<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToByte & Expression>
        implements ComposedExpression, ToByteNullable {

        private final Function before;
        private final AFTER after;

        ComposeToByte(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public byte applyAsByte(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsByte(intermediate);
        }

        @Override
        public Byte apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsByte(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToShortNullable composeToShort(Function before, ToShort after) {
        return new ComposeToShort<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToShortNullable composeToShortNullable(Function before, ToShortNullable after) {
        return new ComposeToShort<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToShort & Expression>
        implements ComposedExpression, ToShortNullable {

        private final Function before;
        private final AFTER after;

        ComposeToShort(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public short applyAsShort(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsShort(intermediate);
        }

        @Override
        public Short apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsShort(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToIntNullable composeToInt(Function before, ToInt after) {
        return new ComposeToInt<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToIntNullable composeToIntNullable(Function before, ToIntNullable after) {
        return new ComposeToInt<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToInt & Expression>
        implements ComposedExpression, ToIntNullable {

        private final Function before;
        private final AFTER after;

        ComposeToInt(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public int applyAsInt(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsInt(intermediate);
        }

        @Override
        public Integer apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsInt(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToLongNullable composeToLong(Function before, ToLong after) {
        return new ComposeToLong<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToLongNullable composeToLongNullable(Function before, ToLongNullable after) {
        return new ComposeToLong<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToLong & Expression>
        implements ComposedExpression, ToLongNullable {

        private final Function before;
        private final AFTER after;

        ComposeToLong(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public long applyAsLong(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsLong(intermediate);
        }

        @Override
        public Long apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsLong(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToFloatNullable composeToFloat(Function before, ToFloat after) {
        return new ComposeToFloat<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToFloatNullable composeToFloatNullable(Function before, ToFloatNullable after) {
        return new ComposeToFloat<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToFloat & Expression>
        implements ComposedExpression, ToFloatNullable {

        private final Function before;
        private final AFTER after;

        ComposeToFloat(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public float applyAsFloat(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsFloat(intermediate);
        }

        @Override
        public Float apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsFloat(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToDoubleNullable composeToDouble(Function before, ToDouble after) {
        return new ComposeToDouble<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToDoubleNullable composeToDoubleNullable(Function before, ToDoubleNullable after) {
        return new ComposeToDouble<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToDouble & Expression>
        implements ComposedExpression, ToDoubleNullable {

        private final Function before;
        private final AFTER after;

        ComposeToDouble(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public double applyAsDouble(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsDouble(intermediate);
        }

        @Override
        public Double apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsDouble(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToBoolean composeToBoolean(Function before, ToBoolean after) {
        return new ComposeToBoolean<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToBooleanNullable composeToBooleanAsNullable(Function before, ToBoolean after) {
        return new ComposeToBooleanNullable<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToBooleanNullable composeToBooleanNullable(Function before, ToBooleanNullable after) {
        return new ComposeToBooleanNullable<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}. Booleans are
     * handled a bit differently when it comes to {@code null}-values. If the
     * {@code before}-function returns {@code null}, then the expression will
     * always evaluate to {@code false}. This is to stay compatible with how
     * Speedment handles predicates in streams.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToBoolean & Expression>
        implements ComposedExpression, ToBoolean {

        private final Function before;
        private final AFTER after;

        ComposeToBoolean(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public boolean applyAsBoolean(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return intermediate != null && after.applyAsBoolean(intermediate);
        }
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToBooleanNullable & Expression>
        implements ComposedExpression, ToBooleanNullable {

        private final Function before;
        private final AFTER after;

        ComposeToBooleanNullable(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public boolean applyAsBoolean(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsBoolean(intermediate);
        }

        @Override
        public Boolean apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsBoolean(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToCharNullable composeToChar(Function before, ToChar after) {
        return new ComposeToChar<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToCharNullable composeToCharNullable(Function before, ToCharNullable after) {
        return new ComposeToChar<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToChar & Expression>
    implements ComposedExpression, ToCharNullable {

        private final Function before;
        private final AFTER after;

        ComposeToChar(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public char applyAsChar(T object) throws NullPointerException {
            final A intermediate = before.apply(object);
            return after.applyAsChar(intermediate);
        }

        @Override
        public Character apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.applyAsChar(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToStringNullable composeToString(Function before, ToString after) {
        return new ComposeToString<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToStringNullable composeToStringNullable(Function before, ToStringNullable after) {
        return new ComposeToString<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToString & Expression>
    implements ComposedExpression, ToStringNullable {

        private final Function before;
        private final AFTER after;

        ComposeToString(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public String apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.apply(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToBigDecimalNullable composeToBigDecimal(Function before, ToBigDecimal after) {
        return new ComposeToBigDecimal<>(before, after);
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static  ToBigDecimalNullable composeToBigDecimalNullable(Function before, ToBigDecimalNullable after) {
        return new ComposeToBigDecimal<>(before, after);
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToBigDecimal & Expression>
        implements ComposedExpression, ToBigDecimalNullable {

        private final Function before;
        private final AFTER after;

        ComposeToBigDecimal(Function before, AFTER after) {
            this.before = requireNonNull(before);
            this.after  = requireNonNull(after);
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public BigDecimal apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.apply(intermediate);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static > ToEnumNullable composeToEnum(Function before, ToEnum after) {
        return new ComposeToEnum<>(before, after, after.enumClass());
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param before the first function to apply
     * @param after  the expression to apply to the result
     * @param   the type of the initial input
     * @param   the type returned by {@code first}
     * @return  the composed expression
     */
    public static > ToEnumNullable composeToEnumNullable(Function before, ToEnumNullable after) {
        return new ComposeToEnum<>(before, after, after.enumClass());
    }

    /**
     * Internal implementation of the {@link ComposedExpression}.
     *
     * @param       the outer input type
     * @param       the inner input type
     * @param   the expression type of the {@code after} operation
     */
    private final static class ComposeToEnum, AFTER extends Function & Expression>
    implements ComposedExpression, ToEnumNullable {

        private final Function before;
        private final AFTER after;
        private final Class enumClass;

        ComposeToEnum(Function before, AFTER after, Class enumClass) {
            this.before    = requireNonNull(before);
            this.after     = requireNonNull(after);
            this.enumClass = requireNonNull(enumClass);
        }

        @Override
        public Class enumClass() {
            return enumClass;
        }

        @Override
        public Function firstStep() {
            return before;
        }

        @Override
        public AFTER secondStep() {
            return after;
        }

        @Override
        public E apply(T object) {
            final A intermediate = before.apply(object);
            if (intermediate == null) return null;
            return after.apply(intermediate);
        }
    }

    /**
     * Utility classes should not be instantiated.
     */
    private ComposedUtil() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy