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.objectmapping.meta; 018 019import org.spongepowered.configurate.CommentedConfigurationNodeIntermediary; 020import org.spongepowered.configurate.ConfigurationNode; 021 022import java.lang.annotation.Annotation; 023import java.lang.reflect.Type; 024import java.util.ResourceBundle; 025 026/** 027 * Performs a transformation on a value annotated with a specific type. 028 * 029 * @since 4.0.0 030 */ 031@FunctionalInterface 032public interface Processor<V> { 033 034 /** 035 * Transform the output node on write. 036 * 037 * @param value source value 038 * @param destination destination node 039 * @since 4.0.0 040 */ 041 void process(V value, ConfigurationNode destination); 042 043 /** 044 * Provider to, given an annotation instance and the type it's on, 045 * create a {@link Processor}. 046 * 047 * @param <A> annotation type 048 * @param <T> handled value type 049 * @since 4.0.0 050 */ 051 @FunctionalInterface 052 interface Factory<A extends Annotation, T> { 053 054 /** 055 * Create a new processor given the annotation and data type. 056 * 057 * @param data annotation type on record field 058 * @param value declared field type 059 * @return new processor 060 * @since 4.0.0 061 */ 062 Processor<T> make(A data, Type value); 063 064 } 065 066 /** 067 * Apply comments from {@link Comment} annotation on save. 068 * 069 * @return a new processor factory 070 * @since 4.0.0 071 */ 072 static Processor.Factory<Comment, Object> comments() { 073 return (data, fieldType) -> (value, destination) -> { 074 if (destination instanceof CommentedConfigurationNodeIntermediary<?>) { 075 final CommentedConfigurationNodeIntermediary<?> commented = (CommentedConfigurationNodeIntermediary<?>) destination; 076 if (data.override()) { 077 commented.comment(data.value()); 078 } else { 079 commented.commentIfAbsent(data.value()); 080 } 081 } 082 }; 083 } 084 085 /** 086 * Apply localized comments from {@link Comment} annotation on save. 087 * 088 * <p>The {@link Comment#value() comment's value} will be treated as a key 089 * into {@code source}, resolved to the system default locale. Missing keys 090 * will be written literally to node.</p> 091 * 092 * @param source source bundle for comments 093 * @return a new processor factory 094 * @since 4.0.0 095 */ 096 static Processor.Factory<Comment, Object> localizedComments(final ResourceBundle source) { 097 return (data, fieldType) -> { 098 final String translated = Localization.key(source, data.value()); 099 return (value, destination) -> { 100 if (destination instanceof CommentedConfigurationNodeIntermediary<?>) { 101 final CommentedConfigurationNodeIntermediary<?> commented = (CommentedConfigurationNodeIntermediary<?>) destination; 102 if (data.override()) { 103 commented.comment(translated); 104 } else { 105 commented.commentIfAbsent(translated); 106 } 107 } 108 }; 109 }; 110 } 111 112}