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