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

cdc.util.enums.AbstractSynthesisMask Maven / Gradle / Ivy

package cdc.util.enums;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import cdc.util.lang.Checks;

public abstract class AbstractSynthesisMask, V> implements SynthesisMask {
    protected final SynthesisMaskSupport support;
    protected final Map map;

    protected AbstractSynthesisMask(SynthesisMaskSupport support,
                                    Map map) {
        Checks.isNotNull(support, "support");
        this.support = support;
        this.map = Collections.unmodifiableMap(map);
    }

    @FunctionalInterface
    protected static interface Creator, V> {
        public M create(SynthesisMaskSupport support,
                        Map map);
    }

    public static , V> SynthesisMaskSupport support(Class maskClass,
                                                                                                Creator creator,
                                                                                                ListType type,
                                                                                                Nullable nullable) {
        Checks.isNotNull(maskClass, "maskClass");
        Checks.isNotNull(creator, "creator");
        Checks.isNotNull(type, "type");
        Checks.isNotNull(nullable, "nullable");
        return new SupportImpl<>(maskClass, creator, type, nullable);
    }

    protected static , V extends Enum> SynthesisMaskSupport support(Class maskClass,
                                                                                                                   Creator creator,
                                                                                                                   Class enumClass,
                                                                                                                   Nullable nullable) {
        Checks.isNotNull(maskClass, "maskClass");
        Checks.isNotNull(creator, "creator");
        Checks.isNotNull(enumClass, "enumClass");
        Checks.isNotNull(nullable, "nullable");
        return support(maskClass, creator, EnumTypes.getEnumType(enumClass), nullable);
    }

    @Override
    public final SynthesisMaskSupport getSupport() {
        return support;
    }

    @Override
    public ListType getType() {
        return support.getType();
    }

    @Override
    public boolean isNullable() {
        return support.isNullable();
    }

    @Override
    public M set(V value,
                 SynthesisStatus status) {
        final Map tmp = new HashMap<>();
        tmp.putAll(map);
        if (status == SynthesisStatus.UNDEFINED) {
            tmp.remove(value);
        } else {
            tmp.put(value, status);
        }
        return support.create(tmp);
    }

    @Override
    public M setAll(SynthesisStatus status) {
        final Map tmp = new HashMap<>();
        if (status != SynthesisStatus.UNDEFINED) {
            for (final V value : getType().getValues()) {
                tmp.put(value, status);
            }
            if (isNullable()) {
                tmp.put(null, status);
            }
        }
        return support.create(tmp);
    }

    @Override
    public SynthesisStatus get(V value) {
        return map.getOrDefault(value, SynthesisStatus.UNDEFINED);
    }

    @Override
    public M merge(M other) {
        final Map tmp = new HashMap<>();
        for (final V value : getType().getValues()) {
            final SynthesisStatus status = get(value).merge(other.get(value));
            if (status != SynthesisStatus.UNDEFINED) {
                tmp.put(value, status);
            }
        }
        if (isNullable()) {
            final SynthesisStatus status = get(null).merge(other.get(null));
            if (status != SynthesisStatus.UNDEFINED) {
                tmp.put(null, status);
            }
        }
        return support.create(tmp);
    }

    @Override
    public M merge(Mask mask) {
        return merge(support.create(mask));
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (!(support.getSynthesisMaskClass().isInstance(other))) {
            return false;
        }
        final M o = support.getSynthesisMaskClass().cast(other);
        return support.getType().equals(o.support.getType())
                && support.isNullable() == o.support.isNullable()
                && this.map.equals(o.map);
    }

    @Override
    public int hashCode() {
        return support.getType().hashCode()
                + (support.isNullable() ? 1 : 0)
                + map.hashCode();
    }

    @Override
    public String toString(Function statusToString,
                           String separator) {
        final StringBuilder builder = new StringBuilder();
        boolean first = true;
        for (final V value : getSupport().getType().getValues()) {
            if (first) {
                first = false;
            } else {
                builder.append(separator);
            }
            builder.append(statusToString.apply(get(value)));
        }
        if (isNullable()) {
            if (!first) {
                builder.append(separator);
            }
            builder.append(statusToString.apply(get(null)));
        }
        return builder.toString();
    }

    @Override
    public String toString() {
        return toString(SynthesisStatus::name, "|");
    }

    private static final class SupportImpl, V> implements SynthesisMaskSupport {
        public final Class cls;
        private final Creator creator;
        private final ListType type;
        private final Nullable nullable;

        public SupportImpl(Class cls,
                           Creator creator,
                           ListType type,
                           Nullable nullable) {
            this.cls = cls;
            this.creator = creator;
            this.type = type;
            this.nullable = nullable;
        }

        @Override
        public Class getSynthesisMaskClass() {
            return cls;
        }

        @Override
        public ListType getType() {
            return type;
        }

        @Override
        public boolean isNullable() {
            return nullable == Nullable.TRUE;
        }

        @Override
        public M create() {
            return creator.create(this, Collections.emptyMap());
        }

        @Override
        public M create(Map map) {
            return creator.create(this, map);
        }

        @Override
        public M create(SynthesisStatus status) {
            final Map tmp = new HashMap<>();
            if (status != SynthesisStatus.UNDEFINED) {
                for (final V value : getType().getValues()) {
                    tmp.put(value, status);
                }
                if (isNullable()) {
                    tmp.put(null, status);
                }
            }
            return creator.create(this, tmp);
        }

        @Override
        public M create(Mask mask) {
            final Map tmp = new HashMap<>();
            for (final V value : getType().getValues()) {
                tmp.put(value, SynthesisStatus.NONE);
            }
            if (isNullable()) {
                tmp.put(null, SynthesisStatus.NONE);
            }
            for (final V value : mask.getValues()) {
                tmp.put(value, SynthesisStatus.ALL);
            }
            return creator.create(this, tmp);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy