33import org .jetbrains .annotations .NotNull ;
44import org .jetbrains .annotations .Nullable ;
55
6+ import java .util .ArrayList ;
7+ import java .util .HashMap ;
68import java .util .Iterator ;
79import java .util .List ;
810import java .util .Map ;
@@ -35,6 +37,16 @@ default boolean isType(@Nullable Object object) {
3537 return true ;
3638 }
3739
40+ /**
41+ * Create a tag object from its value represented as java object.
42+ *
43+ * @param object the object value to convert.
44+ * @return a tag object containing the object value.
45+ */
46+ default T build (@ Nullable Object object ) {
47+ return build (TagType .getType (object ), object );
48+ }
49+
3850 /**
3951 * Create a tag object from its value represented as java object.
4052 *
@@ -44,6 +56,18 @@ default boolean isType(@Nullable Object object) {
4456 */
4557 T build (@ NotNull TagType <?> type , @ Nullable Object object );
4658
59+ /**
60+ * Create an unchecked tag object from its value represented as java object.<br>
61+ * This method assumes that the required object is the type of that is returned.
62+ *
63+ * @param object the object value to convert.
64+ * @return an unchecked tag object containing the object value.
65+ * @param <A> the implementation of tag object.
66+ */
67+ default <A extends T > A buildAny (@ Nullable Object object ) {
68+ return buildAny (TagType .getType (object ), object );
69+ }
70+
4771 /**
4872 * Create an unchecked tag object from its value represented as java object.<br>
4973 * This method assumes that the required object is the type of that is returned.
@@ -58,6 +82,104 @@ default <A extends T> A buildAny(@NotNull TagType<?> type, @Nullable Object obje
5882 return (A ) build (type , object );
5983 }
6084
85+ /**
86+ * Convert the provided value and any inner element to tag object if it isn't a tag type.<br>
87+ * This method safely convert any unmodifiable list or map into a required one.
88+ *
89+ * @param object the object value to convert.
90+ * @return a tag object containing the object value.
91+ */
92+ @ SuppressWarnings ("unchecked" )
93+ default T parse (@ Nullable Object object ) {
94+ if (isType (object )) {
95+ return (T ) object ;
96+ }
97+ return parse (TagType .getType (object ), object );
98+ }
99+
100+ /**
101+ * Convert the provided list and any inner element to tag object.<br>
102+ * This method safely convert any unmodifiable list into a required one.
103+ *
104+ * @param list the list to convert.
105+ * @return a list tag object containing the list value or elements.
106+ */
107+ default T parse (@ NotNull List <?> list ) {
108+ if (!list .isEmpty () && !isType (list .get (0 ))) {
109+ final List <T > tagList = new ArrayList <>();
110+ for (Object element : list ) {
111+ tagList .add (parse (element ));
112+ }
113+ return build (TagType .LIST , tagList );
114+ }
115+ return build (TagType .LIST , list );
116+ }
117+
118+ /**
119+ * Convert the provided map and any inner value to tag object.<br>
120+ * This method safely convert any unmodifiable map into a required one.
121+ *
122+ * @param map the map to convert.
123+ * @return a compound tag object containing the map value or entries.
124+ */
125+ default T parse (@ NotNull Map <String , ?> map ) {
126+ if (!map .isEmpty () && !isType (map .values ().iterator ().next ())) {
127+ final Map <String , T > compound = new HashMap <>();
128+ for (Map .Entry <String , ?> entry : map .entrySet ()) {
129+ compound .put (entry .getKey (), parse (entry .getValue ()));
130+ }
131+ return build (TagType .COMPOUND , compound );
132+ }
133+ return build (TagType .COMPOUND , map );
134+ }
135+
136+ /**
137+ * Convert the provided value and any inner element to tag object.<br>
138+ * This method safely convert any unmodifiable list or map into a required one.
139+ *
140+ * @param type the type of tag that will be converted.
141+ * @param object the object value to convert.
142+ * @return a tag object containing the object value.
143+ */
144+ @ SuppressWarnings ("unchecked" )
145+ default T parse (@ NotNull TagType <?> type , @ Nullable Object object ) {
146+ if (type == TagType .LIST ) {
147+ return parse ((List <?>) object );
148+ } else if (type == TagType .COMPOUND ) {
149+ return parse ((Map <String , ?>) object );
150+ }
151+ return build (type , object );
152+ }
153+
154+ /**
155+ * Create an unchecked tag object from the provided value and any inner element if it isn't a tag type.<br>
156+ * This method assumes that the required object is the type of that is returned
157+ * and also safely convert any unmodifiable list or map into a required one.
158+ *
159+ * @param object the object value to convert.
160+ * @return a tag object containing the object value.
161+ * @param <A> the implementation of tag object.
162+ */
163+ @ SuppressWarnings ("unchecked" )
164+ default <A extends T > A parseAny (@ Nullable Object object ) {
165+ return (A ) parse (object );
166+ }
167+
168+ /**
169+ * Create an unchecked tag object from the provided value and any inner element.<br>
170+ * This method assumes that the required object is the type of that is returned
171+ * and also safely convert any unmodifiable list or map into a required one.
172+ *
173+ * @param type the type of tag that will be converted.
174+ * @param object the object value to convert.
175+ * @return a tag object containing the object value.
176+ * @param <A> the implementation of tag object.
177+ */
178+ @ SuppressWarnings ("unchecked" )
179+ default <A extends T > A parseAny (@ NotNull TagType <?> type , @ Nullable Object object ) {
180+ return (A ) parse (type , object );
181+ }
182+
61183 /**
62184 * Extracts the inner value that tag object implementation contains.
63185 *
@@ -77,6 +199,33 @@ default Object extract(@Nullable T t) {
77199 return t ;
78200 }
79201
202+ /**
203+ * Deeply extract the inner value that tag object implementation
204+ * contains and it's elements if inner value it is a List or Map.
205+ *
206+ * @param t the tag object.
207+ * @return a java value any inner element as java value that was represented from tag object.
208+ */
209+ @ SuppressWarnings ("unchecked" )
210+ default Object deepExtract (@ Nullable T t ) {
211+ final Object value = extract (t );
212+ if (value instanceof List ) {
213+ final List <Object > list = new ArrayList <>();
214+ for (T element : (List <T >) value ) {
215+ list .add (deepExtract (element ));
216+ }
217+ return list ;
218+ } else if (value instanceof Map ) {
219+ final Map <String , Object > map = new HashMap <>();
220+ for (Map .Entry <String , T > entry : ((Map <String , T >) value ).entrySet ()) {
221+ map .put (entry .getKey (), deepExtract (entry .getValue ()));
222+ }
223+ return map ;
224+ } else {
225+ return value ;
226+ }
227+ }
228+
80229 /**
81230 * Get the size of bytes from tag object implementation.
82231 *
0 commit comments