001/* 002 * PermissionsEx 003 * Copyright (C) zml and PermissionsEx contributors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package ca.stellardrift.permissionsex.impl.backend.file; 018 019import ca.stellardrift.permissionsex.impl.backend.memory.MemorySubjectData; 020import ca.stellardrift.permissionsex.context.ContextValue; 021import ca.stellardrift.permissionsex.exception.PermissionsLoadingException; 022import ca.stellardrift.permissionsex.impl.util.PCollections; 023import org.pcollections.PMap; 024import org.pcollections.PSet; 025import org.spongepowered.configurate.ConfigurationNode; 026import org.spongepowered.configurate.serialize.SerializationException; 027 028import java.util.HashMap; 029import java.util.Map; 030import java.util.Set; 031 032public final class FileSubjectData extends MemorySubjectData { 033 static final String KEY_CONTEXTS = "contexts"; 034 035 static FileSubjectData fromNode(ConfigurationNode node) throws SerializationException, PermissionsLoadingException { 036 PMap<PSet<ContextValue<?>>, MemorySegment> map = PCollections.map(); 037 if (node.isList()) { 038 for (ConfigurationNode child : node.childrenList()) { 039 if (!child.isMap()) { 040 throw new PermissionsLoadingException(Messages.FILE_LOAD_CONTEXT.tr()); 041 } 042 final PSet<ContextValue<?>> contexts = contextsFrom(child); 043 MemorySegment value = MAPPER.load(child); 044 map = map.plus(contexts, value); 045 } 046 } 047 return new FileSubjectData(map); 048 } 049 050 FileSubjectData() { 051 super(); 052 } 053 054 FileSubjectData(final PMap<PSet<ContextValue<?>>, MemorySegment> contexts) { 055 super(contexts); 056 } 057 058 @Override 059 protected MemorySubjectData newData(final PMap<PSet<ContextValue<?>>, MemorySegment> contexts) { 060 return new FileSubjectData(contexts); 061 } 062 063 private static PSet<ContextValue<?>> contextsFrom(final ConfigurationNode node) { 064 PSet<ContextValue<?>> contexts = PCollections.set(); 065 final ConfigurationNode contextsNode = node.node(KEY_CONTEXTS); 066 if (contextsNode.isMap()) { 067 contexts = contextsNode.childrenMap().entrySet().stream() 068 .map(ent -> new ContextValue<>(ent.getKey().toString(), ent.getValue().getString())) 069 .collect(PCollections.toPSet()); 070 } 071 return contexts; 072 } 073 074 void serialize(final ConfigurationNode node) throws SerializationException { 075 if (!node.isList()) { 076 node.raw(null); 077 } 078 final Map<Set<ContextValue<?>>, ConfigurationNode> existingSections = new HashMap<>(); 079 for (final ConfigurationNode child : node.childrenList()) { 080 existingSections.put(contextsFrom(child), child); 081 } 082 for (final Map.Entry<PSet<ContextValue<?>>, MemorySegment> ent : this.segments.entrySet()) { 083 ConfigurationNode contextSection = existingSections.remove(ent.getKey()); 084 if (contextSection == null) { 085 contextSection = node.appendListNode(); 086 final ConfigurationNode contextsNode = contextSection.node(KEY_CONTEXTS); 087 for (final ContextValue<?> context : ent.getKey()) { 088 contextsNode.node(context.key()).set(context.rawValue()); 089 } 090 } 091 MAPPER.save(ent.getValue(), contextSection); 092 } 093 for (final ConfigurationNode unused : existingSections.values()) { 094 unused.raw(null); 095 } 096 } 097 098 @Override 099 public String toString() { 100 return "FileSubjectData{" + 101 "segments=" + segments + 102 '}'; 103 } 104}