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

com.kaaprotech.satu.runtime.java.SatuUtil Maven / Gradle / Ivy

/*
 * Copyright 2014 Kaaprotech Ltd.
 *
 * 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.kaaprotech.satu.runtime.java;

import org.apache.commons.lang.ObjectUtils;

import com.gs.collections.api.RichIterable;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.function.Function2;
import com.gs.collections.api.block.procedure.Procedure;
import com.gs.collections.api.list.ImmutableList;
import com.gs.collections.api.map.ImmutableMap;
import com.gs.collections.api.map.MapIterable;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.api.set.MutableSet;
import com.gs.collections.api.set.SetIterable;
import com.gs.collections.api.tuple.Pair;
import com.gs.collections.impl.block.factory.Predicates;
import com.gs.collections.impl.tuple.Tuples;

/**
 * Utility class used by the generated code
 */
@SuppressWarnings("serial")
public final class SatuUtil {

    public static , B extends ModelBuilder> MutableMap toKeyModelBuilderMap(final ImmutableMap models) {
        return models.collect(new Function2>() {
            @Override
            public Pair value(final K key, final M mode2) {
                return Tuples.pair(key, mode2.toBuilder());
            }
        }).toMap();
    }

    public static , B extends ModelBuilder> ImmutableMap toKeyModelMap(final MutableMap builders) {
        return builders.collect(new Function2>() {
            @Override
            public Pair value(final K key, final B bui2der) {
                return Tuples.pair(key, bui2der.build());
            }
        }).toImmutable();
    }

    public static  MutableMap> toKeyValuePairDeltaBuilderMap(final ImmutableList> kvPairs) {
        return kvPairs.toMap(new Function, K>() {
            @Override
            public K valueOf(final KeyValuePairDelta kvPair) {
                return kvPair.getKey();
            }
        }, new Function, KeyValuePairDelta.Builder>() {
            @Override
            public KeyValuePairDelta.Builder valueOf(final KeyValuePairDelta kvPair) {
                return kvPair.toDeltaBuilder();
            }
        });
    }

    public static  MutableMap> toKeyDeltaBuilderMap(final ImmutableList> keyDeltas) {
        return keyDeltas.toMap(new Function, K>() {
            @Override
            public K valueOf(final KeyDelta keyDelta) {
                return keyDelta.getKey();
            }
        }, new Function, KeyDelta.Builder>() {
            @Override
            public KeyDelta.Builder valueOf(final KeyDelta keyDelta) {
                return keyDelta.toDeltaBuilder();
            }
        });
    }

    public static , B extends ModelBuilder, DB extends ModelDeltaBuilder> MutableMap> toKeyModelDeltaBuilderMap(
            final ImmutableList> deltas) {
        return deltas.toMap(new Function, K>() {
            @Override
            public K valueOf(final KeyModelDeltaPairDelta delta) {
                return delta.getKey();
            }
        }, new Function, KeyModelDeltaPairDelta.Builder>() {
            @Override
            public KeyModelDeltaPairDelta.Builder valueOf(final KeyModelDeltaPairDelta delta) {
                return delta.toDeltaBuilder();
            }
        });
    }

    public static  void applyKeyValuePairDeltas(final RichIterable> deltas, final MutableMap pairs) {
        deltas.forEach(new Procedure>() {
            @Override
            public void value(final KeyValuePairDelta delta) {
                switch (delta.getDeltaType()) {
                case ADD:
                case UPDATE:
                    V value = pairs.get(delta.getKey());
                    if (value != null) {
                        if (!ObjectUtils.equals(value, delta.getValue())) {
                            pairs.put(delta.getKey(), delta.getValue());
                        }
                    }
                    else {
                        pairs.put(delta.getKey(), delta.getValue());
                    }
                    break;

                case DELETE:
                    if (pairs.containsKey(delta.getKey())) {
                        pairs.removeKey(delta.getKey());
                    }
                    break;
                }
            }
        });
    }

    public static , MB extends ModelBuilder, DB extends ModelDeltaBuilder> void addKeyModelDeltaPairDelta(
            final MutableMap> deltas, final KeyModelDeltaPairDelta newDelta) {
        KeyModelDeltaPairDelta.Builder builder = deltas.get(newDelta.getKey());
        if (builder == null) {
            builder = newDelta.toDeltaBuilder();
            deltas.put(newDelta.getKey(), builder);
        }
        else {
            builder.addDelta(newDelta);
        }
    }

    public static  void addKeyValuePairDelta(final MutableMap> deltas, final KeyValuePairDelta newDelta) {
        KeyValuePairDelta.Builder builder = deltas.get(newDelta.getKey());
        if (builder == null) {
            builder = newDelta.toDeltaBuilder();
            deltas.put(builder.getKey(), builder);
        }
        else {
            builder.addDelta(newDelta);
        }
    }

    public static  void addKeyDelta(final MutableMap> deltas, final KeyDelta newDelta) {
        KeyDelta.Builder builder = deltas.get(newDelta.getKey());
        if (builder == null) {
            builder = newDelta.toDeltaBuilder();
            deltas.put(builder.getKey(), builder);
        }
        else {
            builder.addDelta(newDelta);
        }
    }

    public static  void reconcileMap(final MapIterable ref, final MapIterable other, final ReconcileMapNofity notify) {
        reconcileMap(ref, other, notify, new ReconcileMapEquals() {
            @Override
            public boolean equals(V1 value1, V2 value2) {
                return ObjectUtils.equals(value1, value2);
            }
        });
    }

    public static  void reconcileMap(final MapIterable ref, final MapIterable other, final ReconcileMapNofity notify, final ReconcileMapEquals equals) {
        ref.keysView().reject(Predicates.in(other.keysView())).forEach(new Procedure() {
            @Override
            public void value(final K key) {
                notify.delete(key);
            }
        });

        other.keysView().reject(Predicates.in(ref.keysView())).forEach(new Procedure() {
            @Override
            public void value(final K key) {
                notify.add(key, other.get(key));
            }
        });

        ref.keysView().select(Predicates.in(other.keysView())).forEach(new Procedure() {
            @Override
            public void value(final K key) {
                V2 otherValue = other.get(key);
                if (!equals.equals(ref.get(key), otherValue)) {
                    notify.update(key, otherValue);
                }
            }
        });
    }

    public static  void reconcileKeyValuePairs(final MapIterable refTags, final MapIterable modTags, final DeltaAppender> appender) {
        reconcileMap(refTags, modTags, new ReconcileMapNofity() {
            @Override
            public void add(final K key, final V value) {
                appender.append(new KeyValuePairDelta(DeltaType.ADD, key, value));
            }

            @Override
            public void update(final K key, final V value) {
                appender.append(new KeyValuePairDelta(DeltaType.UPDATE, key, value));
            }

            @Override
            public void delete(final K key) {
                appender.append(new KeyValuePairDelta(DeltaType.DELETE, key, null));
            }
        });
    }

    public static  void applyKeyDeltas(final RichIterable> deltas, final MutableSet entries) {
        deltas.forEach(new Procedure>() {
            @Override
            public void value(final KeyDelta delta) {
                final K key = delta.getKey();
                switch (delta.getDeltaType()) {
                case ADD:
                case UPDATE:
                    if (!entries.contains(key)) {
                        entries.add(key);
                    }
                    break;

                case DELETE:
                    if (entries.contains(key)) {
                        entries.remove(key);
                    }
                    break;
                }
            }
        });
    }

    public static , DB extends ModelDeltaBuilder, B extends ModelBuilder> void applyKeyModelPairDeltas(
            final RichIterable> deltas, final MutableMap builders) {
        deltas.forEach(new Procedure>() {
            @Override
            public void value(final KeyModelDeltaPairDelta delta) {
                B builder = builders.get(delta.getKey());
                switch (delta.getDeltaType()) {
                case ADD:
                case UPDATE:
                    if (builder == null || !builder.getKey().equals(delta.getValue().getKey())) {
                        builder = delta.getValue().toBuilder();
                        builders.put(delta.getKey(), builder);
                    }
                    else {
                        builder.applyDelta(delta.getValue());
                    }
                    break;

                case DELETE:
                    if (builder != null) {
                        builders.removeKey(delta.getKey());
                    }
                    break;
                }
            }
        });
    }

    public static  void reconcileSet(final SetIterable ref, final SetIterable other, final ReconcileSetNotify notify) {
        reconcileSet(ref, other, false, notify);
    }

    public static  void reconcileSet(final SetIterable ref, final SetIterable other, final boolean skipIntersect, final ReconcileSetNotify notify) {
        ref.difference(other).forEach(new Procedure() {
            @Override
            public void value(final E element) {
                notify.delete(element);
            }
        });

        other.difference(ref).forEach(new Procedure() {
            @Override
            public void value(final E element) {
                notify.add(element);
            }
        });

        if (!skipIntersect) {
            ref.intersect(other).forEach(new Procedure() {
                @Override
                public void value(final E element) {
                    notify.intersect(element);
                }
            });
        }
    }

    public static  void reconcileKeys(final SetIterable refValues, final SetIterable modValues, final DeltaAppender> appender) {
        reconcileSet(refValues, modValues, true, new ReconcileSetNotify() {
            @Override
            public void add(final K value) {
                appender.append(new KeyDelta(DeltaType.ADD, value));
            }

            @Override
            public void delete(final K value) {
                appender.append(new KeyDelta(DeltaType.DELETE, value));
            }

            @SuppressWarnings("unused")
            @Override
            public void intersect(final K value) {
                // Noop
            }
        });
    }

    public static  ImmutableList> buildKeyDelta(final RichIterable> builders) {
        return builders.collect(new Function, KeyDelta>() {
            @Override
            public KeyDelta valueOf(final KeyDelta.Builder builder) {
                return builder.buildDelta();
            }
        }).select(Predicates.notNull()).toList().toImmutable();
    }

    public static  ImmutableList> buildKeyValuePairDelta(RichIterable> builders) {
        return builders.collect(new Function, KeyValuePairDelta>() {
            @Override
            public KeyValuePairDelta valueOf(final KeyValuePairDelta.Builder builder) {
                return builder.buildDelta();
            }
        }).select(Predicates.notNull()).toList().toImmutable();
    }

    public static , B extends ModelBuilder, DB extends ModelDeltaBuilder> ImmutableList> buildKeyModelDeltaPairDelta(
            final RichIterable> builders) {
        return builders.collect(new Function, KeyModelDeltaPairDelta>() {
            @Override
            public KeyModelDeltaPairDelta valueOf(final KeyModelDeltaPairDelta.Builder builder) {
                return builder.buildDelta();
            }
        }).select(Predicates.notNull()).toList().toImmutable();
    }

    public static , B extends ModelBuilder, D extends ModelDelta, DB extends ModelDeltaBuilder> void reconcileKeyModelBuilderPairs(
            final MapIterable refModels, final MapIterable builders, final DeltaAppender> deltaAppender) {
        reconcileSet(refModels.keysView().toSet(), builders.keysView().toSet(), new ReconcileSetNotify() {
            @Override
            public void add(final K key) {
                final B builder = builders.get(key);
                final D delta = builder.toDelta(DeltaType.ADD);
                if (delta != null) {
                    deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.ADD, key, delta));
                }
                else {
                    // Create a blank delta
                    final D d = builder.toDelta(DeltaType.DELETE).toDeltaBuilder().setDeltaType(DeltaType.ADD).buildDelta();
                    deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.ADD, key, d));
                }
            }

            @Override
            public void intersect(final K key) {
                final M refModel = refModels.get(key);
                final B builder = builders.get(key);
                if (refModel.getKey().equals(builder.getKey())) {
                    final D delta = builder.reconcile(DeltaType.UPDATE, refModel);
                    if (delta != null) {
                        deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.UPDATE, key, delta));
                    }
                }
                else {
                    final M emptyModel = builder.buildEmpty();
                    final D delta = builder.reconcile(DeltaType.ADD, emptyModel);
                    if (delta != null) {
                        deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.UPDATE, key, delta));
                    }
                }
            }

            @Override
            public void delete(final K key) {
                final M refModel = refModels.get(key);
                final B emptyBuilder = refModel.toBuilderEmpty();
                final D delta = emptyBuilder.reconcile(DeltaType.DELETE, refModel);
                if (delta != null) {
                    deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.DELETE, key, delta));
                }
            }
        });
    }

    public static , B extends ModelBuilder, D extends ModelDelta, DB extends ModelDeltaBuilder> void reconcileKeyModelPairs(
            final ImmutableMap refModels, final ImmutableMap models, final DeltaAppender> deltaAppender) {
        reconcileSet(refModels.keysView().toSet(), models.keysView().toSet(), new ReconcileSetNotify() {
            @Override
            public void add(final K key) {
                final M model = models.get(key);
                final B builder = model.toBuilder();
                final M emptyModel = builder.buildEmpty();
                final D delta = builder.reconcile(DeltaType.ADD, emptyModel);
                if (delta != null) {
                    deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.ADD, key, delta));
                }
            }

            @Override
            public void intersect(final K key) {
                final M refModel = refModels.get(key);
                final M model = models.get(key);
                if (refModel.getKey().equals(model.getKey())) {
                    final D delta = model.toBuilder().reconcile(DeltaType.UPDATE, refModel);
                    if (delta != null) {
                        deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.UPDATE, key, delta));
                    }
                }
                else {
                    final B builder = model.toBuilder();
                    final M emptyModel = builder.buildEmpty();
                    final D delta = builder.reconcile(DeltaType.ADD, emptyModel);
                    if (delta != null) {
                        deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.UPDATE, key, delta));
                    }
                }
            }

            @Override
            public void delete(final K key) {
                final M refModel = refModels.get(key);
                final B emptyBuilder = refModel.toBuilderEmpty();
                final D delta = emptyBuilder.reconcile(DeltaType.DELETE, refModel);
                if (delta != null) {
                    deltaAppender.append(new KeyModelDeltaPairDelta(DeltaType.DELETE, key, delta));
                }
            }
        });
    }

    public static , B extends ModelBuilder, D extends ModelDelta, DB extends ModelDeltaBuilder> B applyModelDelta(final D delta,
            final B builder) {
        if (builder == null || !builder.getKey().equals(delta.getKey())) {
            return delta.toBuilder();
        }
        builder.applyDelta(delta);
        return builder;
    }

    public static , B extends ModelBuilder, D extends ModelDelta, DB extends ModelDeltaBuilder> void reconcileModelBuilderField(final M refModel,
            final B builder, final DB deltaBuilder, final DeltaBuilderSetter setter) {
        if (refModel == null && builder == null) {
            setter.set(null);
            return;
        }

        final D delta;

        if (refModel == null && builder != null) {
            final M emptyModel = builder.buildEmpty();
            delta = builder.reconcile(DeltaType.ADD, emptyModel);
        }
        else if (refModel != null && builder != null) {
            if (refModel.getKey().equals(builder.getKey())) {
                delta = builder.reconcile(DeltaType.UPDATE, refModel);
            }
            else {
                final M emptyModel = builder.buildEmpty();
                delta = builder.reconcile(DeltaType.ADD, emptyModel);
            }
        }
        else {
            final B emptyBuilder = refModel.toBuilderEmpty();
            delta = emptyBuilder.reconcile(DeltaType.DELETE, refModel);
        }

        if (deltaBuilder != null && delta != null && deltaBuilder.getKey().equals(delta.getKey())) {
            deltaBuilder.addDelta(delta);
            setter.set(deltaBuilder);
        }
        else if (delta != null) {
            setter.set(delta.toDeltaBuilder());
        }
        else {
            setter.set(null);
        }
    }

    public static , B extends ModelBuilder, D extends ModelDelta, DB extends ModelDeltaBuilder> void reconcileModelField(final M refModel,
            final M model, final DB deltaBuilder, final DeltaBuilderSetter setter) {
        if (refModel == null && model == null) {
            setter.set(null);
            return;
        }

        final D delta;

        if (refModel == null && model != null) {
            final B builder = model.toBuilder();
            final M emptyModel = builder.buildEmpty();
            delta = builder.reconcile(DeltaType.ADD, emptyModel);
        }

        else if (refModel != null && model != null) {
            if (refModel.getKey().equals(model.getKey())) {
                delta = model.toBuilder().reconcile(DeltaType.UPDATE, refModel);
            }
            else {
                final B builder = model.toBuilder();
                final M emptyModel = builder.buildEmpty();
                delta = builder.reconcile(DeltaType.ADD, emptyModel);
            }
        }
        else {
            final B emptyBuilder = refModel.toBuilderEmpty();
            delta = emptyBuilder.reconcile(DeltaType.DELETE, refModel);
        }

        if (deltaBuilder != null && delta != null && deltaBuilder.getKey().equals(delta.getKey())) {
            deltaBuilder.addDelta(delta);
            setter.set(deltaBuilder);
        }
        else if (delta != null) {
            setter.set(delta.toDeltaBuilder());
        }
        else {
            setter.set(null);
        }
    }

    public interface ReconcileMapNofity {

        void add(K key, V value);

        void update(K key, V value);

        void delete(K key);
    }

    public interface ReconcileMapEquals {

        boolean equals(V1 value1, V2 value2);
    }

    public interface ReconcileSetNotify {

        void add(E element);

        void intersect(E element);

        void delete(E element);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy