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

org.apache.sling.settings.impl.RunModesTransformer Maven / Gradle / Ivy

There is a newer version: 1.68.0
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * ___________________
 *
 * Copyright 2016 Adobe Systems Incorporated
 * All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package org.apache.sling.settings.impl;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.sling.settings.impl.RunModes.Group;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;

import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.singletonList;
import static java.util.Collections.min;

public final class RunModesTransformer {

    private RunModes currentRunModes;

    private RunModesTransformer(final RunModes runModes) {
        this.currentRunModes = Objects.requireNonNull(runModes);
    }

    public static RunModesTransformer transform(final RunModes runModes) {
        return new RunModesTransformer(runModes);
    }

    public RunModesTransformer activate(final String runMode) {
        transformRunModes(getActivateFunction(runMode));
        return this;
    }

    private static Function getActivateFunction(final String runMode) {
        return new Function() {
            @Nullable
            @Override
            public Group apply(@Nullable final Group group) {
                assert group != null;
                return group.getAvailableModes().contains(runMode)
                        ? new Group(group.getAvailableModes(), runMode)
                        : group;
            }
        };
    }

    public RunModesTransformer deactivate(final String runMode) {
        transformRunModes(getDeactivateFunction(runMode));
        return this;
    }

    private static Function getDeactivateFunction(final String runMode) {
        return new Function() {
            @Nullable
            @Override
            public Group apply(@Nullable final Group group) {
                assert group != null;
                return Objects.equals(group.getSelectedMode(), runMode)
                        ? transformGroup(group)
                        : group;
            }

            private Group transformGroup(final Group group) {
                final String firstNotEqual = getFirstNotEqual(runMode, group.getAvailableModes());
                return new Group(group.getAvailableModes(), getElectedOrPreviousRunMode(group, firstNotEqual));
            }

            private String getElectedOrPreviousRunMode(final Group group, final String firstNotEqual) {
                return firstNotEqual != null ? firstNotEqual : group.getSelectedMode();
            }

            private String getFirstNotEqual(final String runModeToDeactivate, final List availableModes) {
                return Iterables.find(availableModes, new Predicate() {
                    @Override
                    public boolean apply(@Nullable final String runMode) {
                        return !Objects.equals(runMode, runModeToDeactivate);
                    }
                });
            }
        };
    }

    private void transformRunModes(final Function transformFunction) {
        update(Iterables.transform(currentRunModes.getGroups(), transformFunction));
    }

    private void update(final Iterable newGroups) {
        currentRunModes = new RunModes(newArrayList(newGroups));
    }

    public RunModes toSlingRunMode() {
        return currentRunModes;
    }


    /**
     * Install a new run mode in a group characterized by examples in the order they appear
     * on the list. If the examples aren't characterizing any existing group the run mode won't be
     * added.
     *
     * @param newRunMode the new run mode to be added
     * @param runModeGroupExamples the examples that characterizes the one group
     * @return the instance of this transformer
     */
    public RunModesTransformer install(final String newRunMode, final List runModeGroupExamples) {
        final Iterable> rankedGroups = getGroupsWithRanksMatchingToExamples(runModeGroupExamples);
        final Integer bestRankPosition = selectBestRank(rankedGroups);
        if (bestRankPosition < Integer.MAX_VALUE) {
            update(installRunModeForSelectedGroup(newRunMode, rankedGroups, bestRankPosition));
        }
        return this;
    }

    private Iterable installRunModeForSelectedGroup(final String newRunMode,
                                                           final Iterable> rankedGroups,
                                                           final Integer rank) {
        return Iterables.transform(rankedGroups, getSelectedInstallFunction(rank, newRunMode));
    }

    private Integer selectBestRank(final Iterable> rankedGroups) {
        return min(newArrayList(getRanksOfGroups(rankedGroups)));
    }

    private Iterable> getGroupsWithRanksMatchingToExamples(final List runModeGroupExamples) {
        return Iterables.transform(currentRunModes.getGroups(), getGroupRankInstallFunction(runModeGroupExamples));
    }

    private Iterable getRanksOfGroups(final Iterable> newGroupsWithRank) {
        return Iterables.transform(newGroupsWithRank, new Function, Integer>() {
            @Nullable
            @Override
            public Integer apply(@Nullable final Pair groupWithRank) {
                assert groupWithRank != null;
                return groupWithRank.getValue();
            }
        });
    }

    private static Function, Group> getSelectedInstallFunction(final Integer selectedRank,
                                                                           final String newRunMode) {
        return new Function, Group>() {
            @Nullable
            @Override
            public Group apply(@Nullable final Pair groupWithRank) {
                assert groupWithRank != null;
                return Objects.equals(groupWithRank.getValue(), selectedRank)
                        ? transformGroup(groupWithRank.getKey(), newRunMode)
                        : groupWithRank.getKey();
            }

            private Group transformGroup(final Group group, String newRunMode) {
                return new Group(getNewRunModeGroup(group, newRunMode),
                        newRunMode);
            }

            private List getNewRunModeGroup(final Group group, final String newRunMode) {
                return group.getAvailableModes().contains(newRunMode)
                        ? group.getAvailableModes()
                        : newArrayList(concat(group.getAvailableModes(), singletonList(newRunMode)));
            }
        };
    }

    private static Function> getGroupRankInstallFunction(final List runModeGroupExamples) {
        return new Function>() {
            @Nullable
            @Override
            public Pair apply(@Nullable final Group group) {
                assert group != null;
                return Pair.of(group, calculateRank(group));
            }

            private Integer calculateRank(final @Nonnull Group group) {
                return min(calculateDestinationGroupRank(runModeGroupExamples,
                        getModeListOfGroup(group)));
            }

            private List calculateDestinationGroupRank(final List runModeGroupExamples,
                                                                final List currentModes) {
                return newArrayList(Iterables.transform(currentModes, new Function() {
                    @Nullable
                    @Override
                    public Integer apply(@Nullable final String runModeToFind) {
                        return normalizeRank(runModeGroupExamples.indexOf(runModeToFind));
                    }

                    private Integer normalizeRank(final int index) {
                        return index < 0 ? Integer.MAX_VALUE : index;
                    }
                }));
            }

            private List getModeListOfGroup(final @Nonnull Group group) {
                return newArrayList(concat(
                        singletonList(group.getSelectedMode()),
                        group.getAvailableModes()
                ));
            }

        };
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy