001/* 002 * Configurate 003 * Copyright (C) zml and Configurate 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 org.spongepowered.configurate.extra.dfu.v4; 018 019import static java.util.Objects.requireNonNull; 020 021import com.mojang.serialization.Dynamic; 022import org.spongepowered.configurate.CommentedConfigurationNode; 023import org.spongepowered.configurate.ConfigurationNode; 024import org.spongepowered.configurate.ConfigurationNodeFactory; 025import org.spongepowered.configurate.ConfigurationOptions; 026import org.spongepowered.configurate.serialize.TypeSerializerCollection; 027 028/** 029 * A builder for {@link ConfigurateOps} instances. 030 * 031 * @since 4.0.0 032 */ 033public final class ConfigurateOpsBuilder { 034 035 private ConfigurationNodeFactory<? extends ConfigurationNode> nodeSupplier = CommentedConfigurationNode.factory(); 036 private boolean compressed; 037 private ConfigurateOps.Protection readProtection = ConfigurateOps.Protection.COPY_DEEP; 038 private ConfigurateOps.Protection writeProtection = ConfigurateOps.Protection.COPY_DEEP; 039 040 ConfigurateOpsBuilder() {} 041 042 /** 043 * Set the node factory for the returned ops. 044 * 045 * <p>The default node factory wil create {@link CommentedConfigurationNode} 046 * instances using Confabricate's minecraft serializers. 047 * 048 * @param supplier source for new nodes created to store values in 049 * the {@code create*} methods 050 * @return this builder 051 * @since 4.0.0 052 */ 053 public ConfigurateOpsBuilder factory(final ConfigurationNodeFactory<? extends ConfigurationNode> supplier) { 054 this.nodeSupplier = requireNonNull(supplier, "nodeSupplier"); 055 return this; 056 } 057 058 /** 059 * Set a node factory that will use the provided collection. 060 * 061 * <p>This will replace any set {@link #factory(ConfigurationNodeFactory)}. 062 * 063 * @param collection type serializers to use for nodes. 064 * @return this builder 065 * @since 4.0.0 066 */ 067 public ConfigurateOpsBuilder factoryFromSerializers(final TypeSerializerCollection collection) { 068 requireNonNull(collection, "collection"); 069 return factory(options -> CommentedConfigurationNode.root(options.serializers(collection))); 070 } 071 072 /** 073 * Set the node factory based on the options of the provided node. 074 * 075 * <p>This will replace any set {@link #factory(ConfigurationNodeFactory)}. 076 * 077 * @param node node to use 078 * @return this builder 079 * @since 4.0.0 080 */ 081 public ConfigurateOpsBuilder factoryFromNode(final ConfigurationNode node) { 082 final ConfigurationOptions options = requireNonNull(node, "node").options(); 083 return factory(new ConfigurationNodeFactory<ConfigurationNode>() { 084 @Override 085 public ConfigurationNode createNode(final ConfigurationOptions options) { 086 return CommentedConfigurationNode.root(options); 087 } 088 089 @Override public ConfigurationOptions defaultOptions() { 090 return options; 091 } 092 }); 093 } 094 095 /** 096 * Set whether {@link com.mojang.serialization.Keyable} values should be compressed. 097 * 098 * @param compressed whether to compress values 099 * @return this builder 100 * @see ConfigurateOps#compressMaps() for more about what compression is 101 * @since 4.0.0 102 */ 103 public ConfigurateOpsBuilder compressed(final boolean compressed) { 104 this.compressed = compressed; 105 return this; 106 } 107 108 /** 109 * Set how nodes returned from read methods will be protected 110 * from modification. 111 * 112 * <p>For read protection, the protection level refers to how the attached 113 * node will be affected by modifications made to the nodes returned from 114 * {@code get*} methods. 115 * 116 * @param readProtection protection level 117 * @return this builder 118 * @since 4.0.0 119 */ 120 public ConfigurateOpsBuilder readProtection(final ConfigurateOps.Protection readProtection) { 121 this.readProtection = requireNonNull(readProtection, "readProtection"); 122 return this; 123 } 124 125 /** 126 * Set how nodes provided to mutator methods will be protected 127 * from modification. 128 * 129 * <p>For write protection, the protection level refers to how the provided 130 * {@code prefix} node will be protected from seeing changes to the 131 * operation 132 * 133 * @param writeProtection protection level 134 * @return this builder 135 * @since 4.0.0 136 */ 137 public ConfigurateOpsBuilder writeProtection(final ConfigurateOps.Protection writeProtection) { 138 this.writeProtection = requireNonNull(writeProtection, "writeProtection"); 139 return this; 140 } 141 142 /** 143 * Set how nodes will be protected from both read and write modifications. 144 * 145 * @param protection protection level 146 * @return this builder 147 * @see #readProtection(ConfigurateOps.Protection) for how this level 148 * affects value reads 149 * @see #writeProtection(ConfigurateOps.Protection) for how this level 150 * affects value writes 151 * @since 4.0.0 152 */ 153 public ConfigurateOpsBuilder readWriteProtection(final ConfigurateOps.Protection protection) { 154 requireNonNull(protection, "protection"); 155 this.readProtection = protection; 156 this.writeProtection = protection; 157 return this; 158 } 159 160 /** 161 * Create a new ops instance. 162 * 163 * <p>All options have defaults provided and all setters validate their 164 * input, so by the time this method is reached the builder will be in a 165 * valid state. 166 * 167 * @return the new instance 168 * @since 4.0.0 169 */ 170 public ConfigurateOps build() { 171 return new ConfigurateOps(this.nodeSupplier, this.compressed, this.readProtection, this.writeProtection); 172 } 173 174 /** 175 * Build a new ops instance, returned as part of a {@linkplain Dynamic}. 176 * 177 * <p>Returned ops instances will not take type serializers or other options 178 * from the provided node. For that, use {@link #factoryFromNode(ConfigurationNode)}. 179 * 180 * @param node wrapped node 181 * @return new dynamic 182 * @since 4.0.0 183 */ 184 public Dynamic<ConfigurationNode> buildWrapping(final ConfigurationNode node) { 185 return new Dynamic<>(build(), node); 186 } 187 188}