Java tutorial
/** * 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.extrabackends.groupmanager; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.loader.ConfigurationLoader; import ninja.leaping.configurate.objectmapping.Setting; import ninja.leaping.configurate.yaml.YAMLConfigurationLoader; import ninja.leaping.permissionsex.data.ContextInheritance; import ninja.leaping.permissionsex.data.ImmutableSubjectData; import ninja.leaping.permissionsex.exception.PermissionsLoadingException; import ninja.leaping.permissionsex.extrabackends.ReadOnlyDataStore; import ninja.leaping.permissionsex.rank.FixedRankLadder; import ninja.leaping.permissionsex.rank.RankLadder; import org.yaml.snakeyaml.DumperOptions; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import static ninja.leaping.permissionsex.PermissionsEx.SUBJECTS_GROUP; import static ninja.leaping.permissionsex.PermissionsEx.SUBJECTS_USER; import static ninja.leaping.permissionsex.util.Translations.t; /** * Backend implementing GroupManager data storage format */ public class GroupManagerDataStore extends ReadOnlyDataStore { public static final Factory FACTORY = new Factory("groupmanager", GroupManagerDataStore.class); @Setting("group-manager-root") private String groupManagerRoot = "plugins/GroupManager"; private ConfigurationNode config; private ConfigurationNode globalGroups; private Map<String, Map.Entry<ConfigurationNode, ConfigurationNode>> worldUserGroups; private GroupManagerContextInheritance contextInheritance; protected GroupManagerDataStore() { super(FACTORY); } private ConfigurationLoader<ConfigurationNode> getLoader(Path file) { return YAMLConfigurationLoader.builder().setFlowStyle(DumperOptions.FlowStyle.BLOCK).setPath(file).build(); } ConfigurationNode getGlobalGroups() { return globalGroups; } Map.Entry<ConfigurationNode, ConfigurationNode> getUserGroupsConfigForWorld(String world) { return worldUserGroups.get(world); } @Override protected void initializeInternal() throws PermissionsLoadingException { final Path rootFile = Paths.get(groupManagerRoot); if (!Files.isDirectory(rootFile)) { throw new PermissionsLoadingException(t("GroupManager directory %s does not exist", rootFile)); // TODO: Actual translations } try { config = getLoader(rootFile.resolve("config.yml")).load(); globalGroups = getLoader(rootFile.resolve("globalgroups.yml")).load(); worldUserGroups = new HashMap<>(); Files.list(rootFile.resolve("worlds")).filter(Files::isDirectory).forEach(world -> { try { worldUserGroups.put(world.getFileName().toString(), Maps.immutableEntry(getLoader(world.resolve("users.yml")).load(), getLoader(world.resolve("groups.yml")).load())); } catch (IOException e) { throw new RuntimeException(e); // TODO } }); contextInheritance = new GroupManagerContextInheritance(config.getNode("settings", "mirrors")); } catch (IOException e) { throw new PermissionsLoadingException(e); } } @Override protected CompletableFuture<ImmutableSubjectData> getDataInternal(String type, String identifier) { return CompletableFuture .completedFuture(new GroupManagerSubjectData(identifier, this, EntityType.forTypeString(type))); } @Override protected CompletableFuture<RankLadder> getRankLadderInternal(String ladder) { return CompletableFuture .completedFuture(new FixedRankLadder(ladder, ImmutableList.<Map.Entry<String, String>>of())); // GM does not have a concept of rank ladders } @Override protected CompletableFuture<ContextInheritance> getContextInheritanceInternal() { return CompletableFuture.completedFuture(contextInheritance); } @Override public void close() { } @Override public CompletableFuture<Boolean> isRegistered(String type, String identifier) { if (type.equals(SUBJECTS_USER)) { for (Map.Entry<String, Map.Entry<ConfigurationNode, ConfigurationNode>> ent : this.worldUserGroups .entrySet()) { if (!ent.getValue().getKey().getNode("users", identifier).isVirtual()) { return CompletableFuture.completedFuture(true); } } } else if (type.equals(SUBJECTS_GROUP)) { if (!globalGroups.getNode("groups", "g:" + identifier).isVirtual()) { return CompletableFuture.completedFuture(true); } for (Map.Entry<String, Map.Entry<ConfigurationNode, ConfigurationNode>> ent : this.worldUserGroups .entrySet()) { if (!ent.getValue().getValue().getNode("groups", identifier).isVirtual()) { return CompletableFuture.completedFuture(true); } } } return CompletableFuture.completedFuture(false); } @Override public Set<String> getAllIdentifiers(String type) { if (type.equals(SUBJECTS_USER)) { return this.worldUserGroups.values().stream() .map(input -> input.getKey().getNode("users").getChildrenMap().keySet()).flatMap(Set::stream) .map(Object::toString).collect(Collectors.toSet()); } else if (type.equals(SUBJECTS_GROUP)) { return Sets .newHashSet( Iterables .transform(Iterables.concat( Iterables.concat(Iterables.transform(this.worldUserGroups.values(), input -> input.getValue().getNode("groups").getChildrenMap() .keySet())), Iterables.transform( globalGroups.getNode("groups").getChildrenMap().keySet(), input -> { if (input instanceof String && ((String) input).startsWith("g:")) { input = ((String) input).substring(2); } return input; })), Object::toString)); } else { return ImmutableSet.of(); } } @Override public Set<String> getRegisteredTypes() { return ImmutableSet.of(SUBJECTS_USER, SUBJECTS_GROUP); } @Override public Iterable<Map.Entry<Map.Entry<String, String>, ImmutableSubjectData>> getAll() { return Iterables.transform( Iterables.concat( Iterables.transform(getAllIdentifiers(SUBJECTS_USER), name -> Maps.immutableEntry(SUBJECTS_USER, name)), Iterables.transform(getAllIdentifiers(SUBJECTS_GROUP), name -> Maps.immutableEntry(SUBJECTS_GROUP, name))), input -> Maps.immutableEntry(input, Futures.getUnchecked(getData(input.getKey(), input.getValue(), null)))); } @Override public Iterable<String> getAllRankLadders() { return ImmutableList.of(); } @Override public CompletableFuture<Boolean> hasRankLadder(String ladder) { return CompletableFuture.completedFuture(false); } public Collection<String> getKnownWorlds() { return this.worldUserGroups.keySet(); } }