001package com.mrivanplays.annotationconfig.yaml; 002 003import java.util.Collections; 004import java.util.HashMap; 005import java.util.Map; 006import java.util.Objects; 007 008/** 009 * Represents a section list. A YAML example: 010 * 011 * <pre><code> 012 * foo: 013 * bar: 014 * baz: aa 015 * lorem: ipsum 016 * dolor: sit 017 * amet: lorem 018 * ipsum: 019 * baz: bb 020 * lorem: dolor 021 * dolor: lorem 022 * amet: ipsum 023 * </code></pre> 024 * 025 * <p>How to use: you have to register a {@link SectionObjectListSerializer} with the help of a 026 * {@link com.mrivanplays.annotationconfig.core.utils.TypeToken} in order for this list to properly 027 * (de)serialize. 028 * 029 * @author MrIvanPlays 030 * @since v2.1.1 031 */ 032public final class SectionObjectList<T> { 033 034 /** 035 * Creates a new {@link SectionObjectListBuilder} with pre-defined {@link Class} type. 036 * 037 * @param type type 038 * @param <T> object type 039 * @return new builder 040 */ 041 public static <T> SectionObjectListBuilder<T> newBuilderForType(Class<? extends T> type) { 042 return new SectionObjectListBuilder<>(type); 043 } 044 045 private final Map<String, T> values; 046 private final Class<? extends T> clazz; 047 048 SectionObjectList(Class<? extends T> clazz, Map<String, T> values) { 049 this.clazz = clazz; 050 this.values = values; 051 } 052 053 /** 054 * Returns the {@link Class} type of the value objects held in this section object list. 055 * 056 * @return objects type 057 */ 058 public Class<? extends T> getObjectsType() { 059 return clazz; 060 } 061 062 /** 063 * Returns an unmodifiable representation of this {@code SectionObjectList} as a {@link Map} 064 * 065 * @return as map 066 */ 067 public Map<String, T> getAsMap() { 068 return Collections.unmodifiableMap(values); 069 } 070 071 /** 072 * Represents a builder of {@link SectionObjectList} 073 * 074 * @param <T> object type 075 * @author MrIvanPlays 076 * @since v2.1.1 077 */ 078 public static final class SectionObjectListBuilder<T> { 079 080 private final Map<String, T> values = new HashMap<>(); 081 private final Class<? extends T> type; 082 083 private SectionObjectListBuilder(Class<? extends T> type) { 084 this.type = Objects.requireNonNull(type, "type"); 085 if (SectionObjectList.class.isAssignableFrom(type)) { 086 throw new IllegalArgumentException("SectionObjectList<SectionObjectList>"); 087 } 088 if (SectionObjectListBuilder.class.isAssignableFrom(type)) { 089 throw new IllegalArgumentException("SectionObjectList<SectionObjectListBuilder>"); 090 } 091 } 092 093 /** 094 * Specify a default value held by the created {@link SectionObjectList} 095 * 096 * @param key default value key 097 * @param value default value value 098 * @return this instance for chaining 099 */ 100 public SectionObjectListBuilder<T> defaultValue(String key, T value) { 101 this.values.put(key, value); 102 return this; 103 } 104 105 /** 106 * Builds a new {@link SectionObjectList} from the given parameters. 107 * 108 * @return new section object list 109 */ 110 public SectionObjectList<T> build() { 111 if (values.isEmpty()) { 112 throw new IllegalStateException( 113 "No defaults for SectionObjectList<" + type.getSimpleName() + ">"); 114 } 115 return new SectionObjectList<>(type, values); 116 } 117 } 118}