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.transformation; 018 019import io.leangen.geantyref.TypeToken; 020import org.checkerframework.checker.nullness.qual.Nullable; 021import org.spongepowered.configurate.ConfigurateException; 022import org.spongepowered.configurate.ConfigurationNode; 023import org.spongepowered.configurate.NodePath; 024 025import java.util.function.Supplier; 026 027/** 028 * Represents an action to be performed that transforms a node in the 029 * configuration tree. 030 * 031 * @since 4.0.0 032 */ 033@FunctionalInterface 034public interface TransformAction { 035 036 /** 037 * Create a transform action that will remove the node at a specified path. 038 * 039 * @return new action 040 * @since 4.0.0 041 */ 042 static TransformAction remove() { 043 return (path, value) -> { 044 value.raw(null); 045 return null; 046 }; 047 } 048 049 /** 050 * Rename a node 051 * 052 * <p>This transformation cannot be applied to the root node. 053 * 054 * @param newKey the new key 055 * @return new action 056 * @since 4.0.0 057 */ 058 static TransformAction rename(Object newKey) { 059 return (path, value) -> { 060 final Object[] arr = path.array(); 061 if (arr.length == 0) { 062 throw new ConfigurateException(value, "The root node cannot be renamed!"); 063 } 064 arr[arr.length - 1] = newKey; 065 return arr; 066 }; 067 } 068 069 /** 070 * Create a transform action that will change the value of a node to one of 071 * the specified type. 072 * 073 * @param type value type 074 * @param value value 075 * @param <V> value type 076 * @return new transformation action 077 * @since 4.0.0 078 */ 079 static <V> TransformAction set(TypeToken<V> type, @Nullable V value) { 080 return (path, node) -> { 081 node.set(type, value); 082 return null; 083 }; 084 } 085 086 /** 087 * Create a transform action that will change the value of a node to one of 088 * the specified type. 089 * 090 * @param type value type 091 * @param valueSupplier supplier returning a value on each call 092 * @param <V> value type 093 * @return new transformation action 094 * @since 4.0.0 095 */ 096 static <V> TransformAction set(TypeToken<V> type, Supplier<@Nullable V> valueSupplier) { 097 return (path, value) -> { 098 value.set(type, valueSupplier.get()); 099 return null; 100 }; 101 } 102 103 /** 104 * Create a transform action that will change the value of a node to one of 105 * the specified type. 106 * 107 * @param type value type 108 * @param valueSupplier supplier returning a value on each call 109 * @param <V> value type 110 * @return new transformation action 111 * @since 4.0.0 112 */ 113 static <V> TransformAction set(Class<V> type, Supplier<V> valueSupplier) { 114 return (path, value) -> { 115 value.set(type, valueSupplier.get()); 116 return null; 117 }; 118 } 119 120 121 /** 122 * Called at a certain path, with the node at that path. 123 * 124 * <p><strong>Caution:</strong> The state of the <code>path</code> is 125 * only guaranteed to be accurate during a run of the transform function. 126 * Use {@link NodePath#copy()} if the path's state needs to 127 * be stored. 128 * 129 * @param path the path of the given node 130 * @param value the node at the input path. May be modified 131 * @return a modified path, or null if the path is to stay the same 132 * @since 4.0.0 133 */ 134 Object @Nullable[] visitPath(NodePath path, ConfigurationNode value) throws ConfigurateException; 135 136}