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

com.speedment.runtime.compute.internal.expression.ComposedUtil Maven / Gradle / Ivy

/**
 *
 * Copyright (c) 2006-2018, 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.runtime.compute.*;
import com.speedment.runtime.compute.expression.ComposedExpression;
import com.speedment.runtime.compute.expression.ComposedPredicate;
import com.speedment.runtime.compute.expression.Expression;
import com.speedment.runtime.compute.trait.ToNullable;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;

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 first   the first function to apply
     * @param second  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  ToByte
    composeToByte(Function first, ToByte second) {
        return new ComposedToByte<>(first, second);
    }

    private final static class ComposedToByte
    extends AbstractComposedExpression>
    implements ToByte {
        ComposedToByte(Function first, ToByte aToByte) {
            super(first, aToByte);
        }

        @Override
        public byte applyAsByte(T object) {
            return second.applyAsByte(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToShort
    composeToShort(Function first, ToShort second) {
        return new ComposedToShort<>(first, second);
    }

    private final static class ComposedToShort
    extends AbstractComposedExpression>
    implements ToShort {
        ComposedToShort(Function first, ToShort aToShort) {
            super(first, aToShort);
        }

        @Override
        public short applyAsShort(T object) {
            return second.applyAsShort(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToInt
    composeToInt(Function first, ToInt second) {
        return new ComposedToInt<>(first, second);
    }

    private final static class ComposedToInt
    extends AbstractComposedExpression>
    implements ToInt {
        ComposedToInt(Function first, ToInt aToInt) {
            super(first, aToInt);
        }

        @Override
        public int applyAsInt(T object) {
            return second.applyAsInt(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToLong
    composeToLong(Function first, ToLong second) {
        return new ComposedToLong<>(first, second);
    }

    private final static class ComposedToLong
    extends AbstractComposedExpression>
    implements ToLong {
        ComposedToLong(Function first, ToLong aToLong) {
            super(first, aToLong);
        }

        @Override
        public long applyAsLong(T object) {
            return second.applyAsLong(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToFloat
    composeToFloat(Function first, ToFloat second) {
        return new ComposedToFloat<>(first, second);
    }

    private final static class ComposedToFloat
    extends AbstractComposedExpression>
    implements ToFloat {
        ComposedToFloat(Function first, ToFloat aToFloat) {
            super(first, aToFloat);
        }

        @Override
        public float applyAsFloat(T object) {
            return second.applyAsFloat(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToDouble
    composeToDouble(Function first, ToDouble second) {
        return new ComposedToDouble<>(first, second);
    }

    private final static class ComposedToDouble
    extends AbstractComposedExpression>
    implements ToDouble {
        ComposedToDouble(Function first, ToDouble aToDouble) {
            super(first, aToDouble);
        }

        @Override
        public double applyAsDouble(T object) {
            return second.applyAsDouble(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToChar
    composeToChar(Function first, ToChar second) {
        return new ComposedToChar<>(first, second);
    }

    private final static class ComposedToChar
    extends AbstractComposedExpression>
    implements ToChar {
        ComposedToChar(Function first, ToChar aToChar) {
            super(first, aToChar);
        }

        @Override
        public char applyAsChar(T object) {
            return second.applyAsChar(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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 first, ToBoolean second) {
        return new ComposedToBoolean<>(first, second);
    }

    private final static class ComposedToBoolean
    extends AbstractComposedExpression>
    implements ToBoolean {
        ComposedToBoolean(Function first, ToBoolean aToBoolean) {
            super(first, aToBoolean);
        }

        @Override
        public boolean applyAsBoolean(T object) {
            return second.applyAsBoolean(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToString
    composeToString(Function first, ToString second) {
        return new ComposedToString<>(first, second);
    }

    private final static class ComposedToString
    extends AbstractComposedExpression>
    implements ToString {
        ComposedToString(Function first, ToString aToString) {
            super(first, aToString);
        }

        @Override
        public String apply(T object) {
            return second.apply(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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  ToBigDecimal
    composeToBigDecimal(Function first, ToBigDecimal second) {
        return new ComposedToBigDecimal<>(first, second);
    }

    private final static class ComposedToBigDecimal
    extends AbstractComposedExpression>
    implements ToBigDecimal {
        ComposedToBigDecimal(Function first, ToBigDecimal aToBigDecimal) {
            super(first, aToBigDecimal);
        }

        @Override
        public BigDecimal apply(T object) {
            return second.apply(first.apply(object));
        }
    }

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

    private final static class ComposedToEnum>
    extends AbstractComposedExpression>
    implements ToEnum {
        ComposedToEnum(Function first, ToEnum aToEnum) {
            super(first, aToEnum);
        }

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

        @Override
        public E apply(T object) {
            return second.apply(first.apply(object));
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToByteNullable second) {
        return new ComposedToByteNullable<>(first, second);
    }

    private final static class ComposedToByteNullable
    extends AbstractComposedNullableExpression, ToByte, ToByteNullable>
    implements ToByteNullable {
        ComposedToByteNullable(Function first, ToByteNullable aToByte) {
            super(first, aToByte);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToShortNullable second) {
        return new ComposedToShortNullable<>(first, second);
    }

    private final static class ComposedToShortNullable
    extends AbstractComposedNullableExpression, ToShort, ToShortNullable>
    implements ToShortNullable {
        ComposedToShortNullable(Function first, ToShortNullable aToShort) {
            super(first, aToShort);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToIntNullable second) {
        return new ComposedToIntNullable<>(first, second);
    }

    private final static class ComposedToIntNullable
    extends AbstractComposedNullableExpression, ToInt, ToIntNullable>
    implements ToIntNullable {
        ComposedToIntNullable(Function first, ToIntNullable aToInt) {
            super(first, aToInt);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToLongNullable second) {
        return new ComposedToLongNullable<>(first, second);
    }

    private final static class ComposedToLongNullable
    extends AbstractComposedNullableExpression, ToLong, ToLongNullable>
    implements ToLongNullable {
        ComposedToLongNullable(Function first, ToLongNullable aToLong) {
            super(first, aToLong);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToFloatNullable second) {
        return new ComposedToFloatNullable<>(first, second);
    }

    private final static class ComposedToFloatNullable
    extends AbstractComposedNullableExpression, ToFloat, ToFloatNullable>
    implements ToFloatNullable {
        ComposedToFloatNullable(Function first, ToFloatNullable aToFloat) {
            super(first, aToFloat);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToDoubleNullable second) {
        return new ComposedToDoubleNullable<>(first, second);
    }

    private final static class ComposedToDoubleNullable
    extends AbstractComposedNullableExpression, ToDouble, ToDoubleNullable>
    implements ToDoubleNullable {
        ComposedToDoubleNullable(Function first, ToDoubleNullable aToDouble) {
            super(first, aToDouble);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToCharNullable second) {
        return new ComposedToCharNullable<>(first, second);
    }

    private final static class ComposedToCharNullable
        extends AbstractComposedNullableExpression, ToChar, ToCharNullable>
        implements ToCharNullable {
        ComposedToCharNullable(Function first, ToCharNullable aToChar) {
            super(first, aToChar);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToBooleanNullable second) {
        return new ComposedToBooleanNullable<>(first, second);
    }

    private final static class ComposedToBooleanNullable
    extends AbstractComposedNullableExpression, ToBoolean, ToBooleanNullable>
    implements ToBooleanNullable {
        ComposedToBooleanNullable(Function first, ToBooleanNullable aToBoolean) {
            super(first, aToBoolean);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToStringNullable second) {
        return new ComposedToStringNullable<>(first, second);
    }

    private final static class ComposedToStringNullable
    extends AbstractComposedNullableExpression, ToString, ToStringNullable>
    implements ToStringNullable {
        ComposedToStringNullable(Function first, ToStringNullable aToString) {
            super(first, aToString);
        }
    }

    /**
     * Returns a new expression that first applies the {@code first} function
     * and then passes the result to the {@code second} expression.
     *
     * @param first   the first function to apply
     * @param second  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
    composeNullable(Function first, ToBigDecimalNullable second) {
        return new ComposedToBigDecimalNullable<>(first, second);
    }

    private final static class ComposedToBigDecimalNullable
    extends AbstractComposedNullableExpression, ToBigDecimal, ToBigDecimalNullable>
    implements ToBigDecimalNullable {
        ComposedToBigDecimalNullable(Function first, ToBigDecimalNullable aToBigDecimal) {
            super(first, aToBigDecimal);
        }
    }

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

    private final static class ComposedToEnumNullable>
    extends AbstractComposedNullableExpression, ToEnum, ToEnumNullable>
    implements ToEnumNullable {
        ComposedToEnumNullable(Function first, ToEnumNullable aToEnum) {
            super(first, aToEnum);
        }

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

    private abstract static class AbstractComposedNullableExpression
        ,
            A_EXPR extends Expression,
            SECOND extends ToNullable>
    implements ComposedExpression, ToNullable {

        protected final Function first;
        protected final SECOND second;

        AbstractComposedNullableExpression(Function first, SECOND second) {
            this.first  = requireNonNull(first);
            this.second = requireNonNull(second);
        }

        @Override
        public final R apply(T t) {
            return second.apply(first.apply(t));
        }

        @Override
        public final ComposedPredicate isNull() {
            return new IsNull<>(first);
        }

        @Override
        public final ComposedPredicate isNotNull() {
            return new IsNotNull<>(first);
        }

        @Override
        public final boolean isNull(T object) {
            return second.isNull(first.apply(object));
        }

        @Override
        public final boolean isNotNull(T object) {
            return second.isNotNull(first.apply(object));
        }

        @Override
        public final Function firstStep() {
            return first;
        }

        @Override
        public final Expression secondStep() {
            return second;
        }
    }

    private abstract static class AbstractComposedExpression>
    implements ComposedExpression {

        protected final Function first;
        protected final SECOND second;

        AbstractComposedExpression(Function first, SECOND second) {
            this.first  = requireNonNull(first);
            this.second = requireNonNull(second);
        }

        @Override
        public final Function firstStep() {
            return first;
        }

        @Override
        public final Expression secondStep() {
            return second;
        }
    }

    private final static class IsNull
    implements ComposedPredicate {

        private final Function innerMapper;
        private final Predicate innerPredicate;

        IsNull(Function innerMapper) {
            this.innerMapper    = requireNonNull(innerMapper);
            this.innerPredicate = Objects::isNull;
        }

        @Override
        public SpecialTypes specialType() {
            return SpecialTypes.IS_NULL;
        }

        @Override
        public boolean test(T t) {
            return innerMapper.apply(t) == null;
        }

        @Override
        public Function innerMapper() {
            return innerMapper;
        }

        @Override
        public Predicate innerPredicate() {
            return innerPredicate;
        }
    }

    private final static class IsNotNull
    implements ComposedPredicate {

        private final Function innerMapper;
        private final Predicate innerPredicate;

        IsNotNull(Function innerMapper) {
            this.innerMapper    = requireNonNull(innerMapper);
            this.innerPredicate = Objects::nonNull;
        }

        @Override
        public SpecialTypes specialType() {
            return SpecialTypes.IS_NOT_NULL;
        }

        @Override
        public boolean test(T t) {
            return innerMapper.apply(t) != null;
        }

        @Override
        public Function innerMapper() {
            return innerMapper;
        }

        @Override
        public Predicate innerPredicate() {
            return innerPredicate;
        }
    }

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy