2626
2727import de .bluecolored .bluenbt .*;
2828import lombok .RequiredArgsConstructor ;
29+ import lombok .SneakyThrows ;
2930import org .jetbrains .annotations .Nullable ;
3031
3132import java .io .IOException ;
33+ import java .lang .reflect .Constructor ;
3234import java .lang .reflect .Field ;
3335import java .lang .reflect .Modifier ;
3436import java .lang .reflect .Type ;
@@ -73,8 +75,7 @@ static class DefaultAdapter<T> implements TypeSerializer<T> {
7375 public DefaultAdapter (TypeToken <T > type , BlueNBT blueNBT ) {
7476 this .type = type ;
7577
76- Map <Class <? extends TypeSerializer <?>>, TypeSerializer <?>> typeSerializerCache =
77- new HashMap <>();
78+ Map <Class <? extends TypeSerializer <?>>, TypeSerializer <?>> typeSerializerCache = new HashMap <>();
7879
7980 TypeToken <?> typeToken = type ;
8081 Class <?> raw ;
@@ -95,19 +96,10 @@ public DefaultAdapter(TypeToken<T> type, BlueNBT blueNBT) {
9596 TypeSerializer <?> typeSerializer ;
9697 Class <? extends TypeSerializer <?>> serializerType = findSerializerType (field , fieldType .getRawType ());
9798 if (serializerType != null ) {
98- typeSerializer = typeSerializerCache .computeIfAbsent (serializerType , t -> {
99- try {
100- // try BlueNBT constructor
101- try {
102- return t .getDeclaredConstructor (BlueNBT .class ).newInstance (blueNBT );
103- } catch (NoSuchMethodException ignore ) {}
104-
105- // use no-args constructor
106- return t .getDeclaredConstructor ().newInstance ();
107- } catch (Exception ex ) {
108- throw new RuntimeException ("Failed to create Instance of TypeSerializer!" , ex );
109- }
110- });
99+ typeSerializer = typeSerializerCache .computeIfAbsent (
100+ serializerType ,
101+ t -> createTypeSerializerInstance (t , fieldType , blueNBT )
102+ );
111103 } else if (SPECIAL_ACCESSORS .containsKey (fieldType .getType ())) {
112104 FieldWriter accessor = SPECIAL_ACCESSORS .get (fieldType .getType ()).apply (field );
113105 fields .put (name , accessor );
@@ -156,6 +148,41 @@ public void write(T value, NBTWriter writer) throws IOException {
156148 return null ;
157149 }
158150
151+ private TypeSerializer <?> createTypeSerializerInstance (
152+ Class <? extends TypeSerializer <?>> serializerType ,
153+ TypeToken <?> fieldType ,
154+ BlueNBT blueNBT
155+ ) {
156+ try {
157+
158+ // try TypeToken & BlueNBT constructor
159+ try {
160+ return callConstructor (serializerType .getDeclaredConstructor (TypeToken .class , BlueNBT .class ), fieldType , blueNBT );
161+ } catch (NoSuchMethodException ignore ) {}
162+
163+ // try TypeToken constructor
164+ try {
165+ return callConstructor (serializerType .getDeclaredConstructor (TypeToken .class ), fieldType );
166+ } catch (NoSuchMethodException ignore ) {}
167+
168+ // try BlueNBT constructor
169+ try {
170+ return callConstructor (serializerType .getDeclaredConstructor (BlueNBT .class ), blueNBT );
171+ } catch (NoSuchMethodException ignore ) {}
172+
173+ // use no-args constructor
174+ return callConstructor (serializerType .getDeclaredConstructor ());
175+
176+ } catch (ReflectiveOperationException ex ) {
177+ throw new IllegalStateException ("Failed to create instance of TypeSerializer: " + serializerType , ex );
178+ }
179+ }
180+
181+ private <U > U callConstructor (Constructor <U > constructor , Object ... args ) throws ReflectiveOperationException {
182+ constructor .setAccessible (true );
183+ return constructor .newInstance (args );
184+ }
185+
159186 }
160187
161188 private interface FieldWriter {
0 commit comments