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

com.speedment.runtime.field.internal.EnumFieldImpl 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.field.internal;

import com.speedment.runtime.config.identifier.ColumnIdentifier;
import com.speedment.runtime.field.EnumField;
import com.speedment.runtime.field.Field;
import com.speedment.runtime.field.comparator.FieldComparator;
import com.speedment.runtime.field.comparator.NullOrder;
import com.speedment.runtime.field.internal.comparator.ReferenceFieldComparatorImpl;
import com.speedment.runtime.field.internal.predicate.AlwaysFalsePredicate;
import com.speedment.runtime.field.internal.predicate.enums.EnumIsNotNullPredicate;
import com.speedment.runtime.field.internal.predicate.enums.EnumIsNullPredicate;
import com.speedment.runtime.field.internal.predicate.reference.ReferenceEqualPredicate;
import com.speedment.runtime.field.internal.predicate.reference.ReferenceInPredicate;
import com.speedment.runtime.field.method.ReferenceGetter;
import com.speedment.runtime.field.method.ReferenceSetter;
import com.speedment.runtime.field.predicate.Inclusion;
import com.speedment.runtime.field.predicate.SpeedmentPredicate;
import com.speedment.runtime.typemapper.TypeMapper;

import java.util.Collection;
import java.util.EnumSet;
import java.util.function.Function;
import java.util.function.Predicate;

import static java.util.Objects.requireNonNull;

/**
 * Default implementation of the {@link EnumField}-interface.
 *
 * @author Emil Forslund
 * @since  3.0.10
 */
public final class EnumFieldImpl>
    implements
    EnumField,
    FieldComparator {

    private final ColumnIdentifier identifier;
    private final ReferenceGetter getter;
    private final ReferenceSetter setter;
    private final TypeMapper typeMapper;
    private final Function enumToString;
    private final Function stringToEnum;
    private final Class enumClass;
    private final EnumSet constants;
    private final String tableAlias;

    public EnumFieldImpl(
        final ColumnIdentifier identifier,
        final ReferenceGetter getter,
        final ReferenceSetter setter,
        final TypeMapper typeMapper,
        final Function enumToString,
        final Function stringToEnum,
        final Class enumClass
    ) {
        this.identifier   = requireNonNull(identifier);
        this.getter       = requireNonNull(getter);
        this.setter       = requireNonNull(setter);
        this.typeMapper   = requireNonNull(typeMapper);
        this.enumToString = requireNonNull(enumToString);
        this.stringToEnum = requireNonNull(stringToEnum);
        this.enumClass    = requireNonNull(enumClass);
        this.constants    = EnumSet.allOf(enumClass);
        this.tableAlias   = identifier.getTableId();
    }

    private EnumFieldImpl(
        final ColumnIdentifier identifier,
        final ReferenceGetter getter,
        final ReferenceSetter setter,
        final TypeMapper typeMapper,
        final Function enumToString,
        final Function stringToEnum,
        final Class enumClass,
        final String tableAlias
    ) {
        this.identifier   = requireNonNull(identifier);
        this.getter       = requireNonNull(getter);
        this.setter       = requireNonNull(setter);
        this.typeMapper   = requireNonNull(typeMapper);
        this.enumToString = requireNonNull(enumToString);
        this.stringToEnum = requireNonNull(stringToEnum);
        this.enumClass    = requireNonNull(enumClass);
        this.constants    = EnumSet.allOf(enumClass);
        this.tableAlias   = requireNonNull(tableAlias);
    }


    ////////////////////////////////////////////////////////////////////////////
    //                                Getters                                 //
    ////////////////////////////////////////////////////////////////////////////

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

    @Override
    public EnumSet constants() {
        return EnumSet.allOf(enumClass);
    }

    @Override
    public ColumnIdentifier identifier() {
        return identifier;
    }

    @Override
    public ReferenceSetter setter() {
        return setter;
    }

    @Override
    public ReferenceGetter getter() {
        return getter;
    }

    @Override
    public TypeMapper typeMapper() {
        return typeMapper;
    }

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

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

    @Override
    public boolean isUnique() {
        return false;
    }

    @Override
    public String tableAlias() {
        return tableAlias;
    }

    @Override
    public EnumField tableAlias(String tableAlias) {
        return new EnumFieldImpl<>(identifier, getter, setter, typeMapper, enumToString, stringToEnum, enumClass, tableAlias);
    }

    ////////////////////////////////////////////////////////////////////////////
    //                              Comparators                               //
    ////////////////////////////////////////////////////////////////////////////

    @Override
    public FieldComparator comparator() {
        return new ReferenceFieldComparatorImpl<>(this, NullOrder.LAST);
    }

    @Override
    public FieldComparator comparatorNullFieldsFirst() {
        return new ReferenceFieldComparatorImpl<>(this, NullOrder.FIRST);
    }

    @Override
    public Field getField() {
        return this;
    }

    @Override
    public NullOrder getNullOrder() {
        return NullOrder.LAST;
    }

    @Override
    public boolean isReversed() {
        return false;
    }

    @Override
    public FieldComparator reversed() {
        return comparator().reversed();
    }

    @Override
    public int compare(ENTITY first, ENTITY second) {
        final E f = get(first);
        final E s = get(second);
        if (f == null && s == null) return 0;
        else if (f == null) return 1;
        else if (s == null) return -1;
        else return f.compareTo(s);
    }

    ////////////////////////////////////////////////////////////////////////////
    //                              Predicates                                //
    ////////////////////////////////////////////////////////////////////////////

    @Override
    public EnumIsNullPredicate isNull() {
        return new EnumIsNullPredicate<>(this);
    }

    @Override
    public EnumIsNotNullPredicate isNotNull() {
        return new EnumIsNotNullPredicate<>(this);
    }

    @Override
    public SpeedmentPredicate equal(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) == 0);
    }

    @Override
    public SpeedmentPredicate notEqual(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) != 0);
    }

    @Override
    public SpeedmentPredicate lessThan(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) < 0);
    }

    @Override
    public SpeedmentPredicate lessOrEqual(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) <= 0);
    }

    @Override
    public SpeedmentPredicate greaterThan(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) > 0);
    }

    @Override
    public SpeedmentPredicate greaterOrEqual(E value) {
        return toEntityPredicate(e -> e != null && e.compareTo(value) >= 0);
    }

    @Override
    public SpeedmentPredicate between(E start, E end, Inclusion inclusion) {
        return toEntityPredicate(e -> {
            switch (inclusion) {
                case START_EXCLUSIVE_END_EXCLUSIVE:
                    return e.compareTo(start) >  0 && e.compareTo(end) <  0;
                case START_EXCLUSIVE_END_INCLUSIVE:
                    return e.compareTo(start) >  0 && e.compareTo(end) <= 0;
                case START_INCLUSIVE_END_EXCLUSIVE:
                    return e.compareTo(start) >= 0 && e.compareTo(end) <  0;
                case START_INCLUSIVE_END_INCLUSIVE:
                    return e.compareTo(start) >= 0 && e.compareTo(end) <= 0;
                default : throw new UnsupportedOperationException(
                    "Unknown inclusion '" + inclusion + "'."
                );
            }
        });
    }

    @Override
    public SpeedmentPredicate notBetween(E start, E end, Inclusion inclusion) {
        return toEntityPredicate(e -> {
            switch (inclusion) {
                case START_EXCLUSIVE_END_EXCLUSIVE:
                    return e.compareTo(start) <= 0 || e.compareTo(end) >= 0;
                case START_EXCLUSIVE_END_INCLUSIVE:
                    return e.compareTo(start) <= 0 || e.compareTo(end) >  0;
                case START_INCLUSIVE_END_EXCLUSIVE:
                    return e.compareTo(start) <  0 || e.compareTo(end) >= 0;
                case START_INCLUSIVE_END_INCLUSIVE:
                    return e.compareTo(start) <  0 || e.compareTo(end) >  0;
                default : throw new UnsupportedOperationException(
                    "Unknown inclusion '" + inclusion + "'."
                );
            }
        });
    }

    @Override
    public SpeedmentPredicate in(Collection values) {
        return toEntityPredicate(values::contains);
    }

    @Override
    public SpeedmentPredicate notIn(Collection values) {
        return toEntityPredicate(e -> !values.contains(e));
    }

    ////////////////////////////////////////////////////////////////////////////
    //                           String Predicates                            //
    ////////////////////////////////////////////////////////////////////////////

    @Override
    public SpeedmentPredicate equal(String value) {
        return toEntityPredicate(e -> value.equals(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate notEqual(String value) {
        return toEntityPredicate(e -> !value.equals(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate lessThan(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.compareTo(value) < 0;
        });
    }

    @Override
    public SpeedmentPredicate lessOrEqual(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.compareTo(value) <= 0;
        });
    }

    @Override
    public SpeedmentPredicate greaterThan(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.compareTo(value) > 0;
        });
    }

    @Override
    public SpeedmentPredicate greaterOrEqual(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.compareTo(value) >= 0;
        });
    }

    @Override
    public SpeedmentPredicate between(String start, String end, Inclusion inclusion) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            if (str == null) return false;

            switch (inclusion) {
                case START_EXCLUSIVE_END_EXCLUSIVE:
                    return str.compareTo(start) >  0 && str.compareTo(end) <  0;
                case START_EXCLUSIVE_END_INCLUSIVE:
                    return str.compareTo(start) >  0 && str.compareTo(end) <= 0;
                case START_INCLUSIVE_END_EXCLUSIVE:
                    return str.compareTo(start) >= 0 && str.compareTo(end) <  0;
                case START_INCLUSIVE_END_INCLUSIVE:
                    return str.compareTo(start) >= 0 && str.compareTo(end) <= 0;
                default : throw new UnsupportedOperationException(
                    "Unknown inclusion '" + inclusion + "'."
                );
            }
        });
    }

    @Override
    public SpeedmentPredicate notBetween(String start, String end, Inclusion inclusion) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            if (str == null) return false;

            switch (inclusion) {
                case START_EXCLUSIVE_END_EXCLUSIVE:
                    return str.compareTo(start) <= 0 || str.compareTo(end) >= 0;
                case START_EXCLUSIVE_END_INCLUSIVE:
                    return str.compareTo(start) <= 0 || str.compareTo(end) >  0;
                case START_INCLUSIVE_END_EXCLUSIVE:
                    return str.compareTo(start) <  0 || str.compareTo(end) >= 0;
                case START_INCLUSIVE_END_INCLUSIVE:
                    return str.compareTo(start) <  0 || str.compareTo(end) >  0;
                default : throw new UnsupportedOperationException(
                    "Unknown inclusion '" + inclusion + "'."
                );
            }
        });
    }

    @Override
    public SpeedmentPredicate isEmpty() {
        return toEntityPredicate(e -> "".equals(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate equalIgnoreCase(String value) {
        return toEntityPredicate(e -> value.equalsIgnoreCase(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate startsWith(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.startsWith(value);
        });
    }

    @Override
    public SpeedmentPredicate startsWithIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.toLowerCase()
                .startsWith(value.toLowerCase());
        });
    }

    @Override
    public SpeedmentPredicate endsWith(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.endsWith(value);
        });
    }

    @Override
    public SpeedmentPredicate endsWithIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.toLowerCase()
                .endsWith(value.toLowerCase());
        });
    }

    @Override
    public SpeedmentPredicate contains(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.contains(value);
        });
    }

    @Override
    public SpeedmentPredicate containsIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && str.toLowerCase()
                .contains(value.toLowerCase());
        });
    }

    @Override
    public SpeedmentPredicate isNotEmpty() {
        return toEntityPredicate(e -> !"".equals(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate notEqualIgnoreCase(String value) {
        return toEntityPredicate(e -> !value.equalsIgnoreCase(enumToString.apply(e)));
    }

    @Override
    public SpeedmentPredicate notStartsWith(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.startsWith(value);
        });
    }

    @Override
    public SpeedmentPredicate notEndsWith(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.endsWith(value);
        });
    }

    @Override
    public SpeedmentPredicate notContains(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.contains(value);
        });
    }

    @Override
    public SpeedmentPredicate notStartsWithIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.toLowerCase()
                .startsWith(value.toLowerCase());
        });
    }

    @Override
    public SpeedmentPredicate notEndsWithIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.toLowerCase()
                .endsWith(value.toLowerCase());
        });
    }

    @Override
    public SpeedmentPredicate notContainsIgnoreCase(String value) {
        return toEntityPredicate(e -> {
            final String str = enumToString.apply(e);
            return str != null && !str.toLowerCase()
                .contains(value.toLowerCase());
        });
    }

    ////////////////////////////////////////////////////////////////////////////
    //                            Internal Methods                            //
    ////////////////////////////////////////////////////////////////////////////

    private SpeedmentPredicate toEntityPredicate(Predicate predicate) {
        final EnumSet valid = evaluate(predicate);
        switch (valid.size()) {
            case 0  : return new AlwaysFalsePredicate<>(this);
            case 1  : return new ReferenceEqualPredicate<>(this, valid.iterator().next());
            default : return new ReferenceInPredicate<>(this, valid);
        }
    }

    private EnumSet evaluate(Predicate predicate) {
        final EnumSet result = EnumSet.noneOf(enumClass);
        constants.stream().filter(predicate).forEach(result::add);
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy