org.apache.sling.settings.impl.RunModesTransformer Maven / Gradle / Ivy
/*************************************************************************
*
* 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