/** * PermissionsEx * Copyright (C) zml and PermissionsEx contributors * * 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 ninja.leaping.permissionsex.rank; import com.google.common.collect.ImmutableList; import ninja.leaping.permissionsex.data.ImmutableSubjectData; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.Set; import static java.util.Map.Entry; public abstract class AbstractRankLadder implements RankLadder { private final String name; public AbstractRankLadder(String name) { this.name = name; } @Override public String getName() { return this.name; } @Override public final ImmutableSubjectData promote(Set<Entry<String, String>> contexts, ImmutableSubjectData input) { if (getRanks().isEmpty()) { return input; } List<Entry<String, String>> parents = input.getParents(contexts); if (parents.isEmpty()) { return input.addParent(contexts, getRanks().get(0).getKey(), getRanks().get(0).getValue()); } else { int index; parents = new ArrayList<>(parents); boolean found = false; for (ListIterator<Entry<String, String>> it = parents.listIterator(); it.hasNext();) { Entry<String, String> parent = it.next(); if ((index = getRanks().indexOf(parent)) > -1) { if (index == getRanks().size() - 1) { return input; } else { it.set(getRanks().get(index + 1)); found = true; } } } if (found) { return input.setParents(contexts, parents); // Promotion happened } else { return input.addParent(contexts, getRanks().get(0).getKey(), getRanks().get(0).getValue()); } } } @Override public final ImmutableSubjectData demote(Set<Entry<String, String>> contexts, ImmutableSubjectData input) { if (getRanks().isEmpty()) { return input; } List<Entry<String, String>> parents = input.getParents(contexts); if (parents.isEmpty()) { return input; } else { int index; parents = new ArrayList<>(parents); boolean found = false; for (ListIterator<Entry<String, String>> it = parents.listIterator(); it.hasNext();) { Entry<String, String> parent = it.next(); if ((index = getRanks().indexOf(parent)) > -1) { if (index == 0) { // At bottom of rank ladder, remove the rank entirely it.remove(); } else { it.set(getRanks().get(index - 1)); } found = true; } } if (found) { return input.setParents(contexts, parents); } else { return input; } } } @Override public final boolean isOnLadder(Set<Entry<String, String>> contexts, ImmutableSubjectData subject) { if (getRanks().isEmpty()) { return false; } for (Entry<String, String> par : subject.getParents(contexts)) { if (getRanks().indexOf(par) != -1) { return true; } } return false; } @Override public final int indexOfRank(Entry<String, String> subject) { return getRanks().indexOf(subject); } @Override public final RankLadder addRank(Entry<String, String> subject) { int indexOf = getRanks().indexOf(subject); if (indexOf != -1) { List<Entry<String, String>> ents = new ArrayList<>(this.getRanks()); ents.remove(indexOf); ents.add(subject); return newWithRanks(ents); } else { return newWithRanks(ImmutableList.<Entry<String, String>>builder().addAll(this.getRanks()).add(subject).build()); } } @Override public final RankLadder addRankAt(Entry<String, String> subject, int index) { if (index > getRanks().size() || index < 0) { return this; } int indexOf = getRanks().indexOf(subject); final List<Entry<String, String>> newEnts = new ArrayList<>(getRanks()); newEnts.add(index, subject); if (indexOf != -1) { if (indexOf >= index) { ++indexOf; } newEnts.remove(indexOf); } return newWithRanks(newEnts); } @Override public final RankLadder removeRank(Entry<String, String> subject) { int indexOf = getRanks().indexOf(subject); if (indexOf == -1) { return this; } else { List<Entry<String, String>> newRanks = new ArrayList<>(getRanks()); newRanks.remove(indexOf); return newWithRanks(newRanks); } } @Override public abstract List<? extends Entry<String, String>> getRanks(); protected abstract RankLadder newWithRanks(List<Entry<String,String>> ents); }