2121import java .io .IOException ;
2222import java .lang .reflect .Constructor ;
2323import java .lang .reflect .Field ;
24+ import java .lang .reflect .InvocationTargetException ;
2425import java .lang .reflect .ParameterizedType ;
2526import java .lang .reflect .Type ;
2627import java .util .ArrayDeque ;
28+ import java .util .ArrayList ;
2729import java .util .Collection ;
2830import java .util .Deque ;
31+ import java .util .HashSet ;
2932import java .util .List ;
3033import java .util .Map ;
3134import java .util .Queue ;
3437import java .util .logging .Logger ;
3538import javax .annotation .Nullable ;
3639import net .elytrium .serializer .SerializerConfig ;
40+ import net .elytrium .serializer .annotations .CollectionType ;
3741import net .elytrium .serializer .annotations .Serializer ;
3842import net .elytrium .serializer .custom .ClassSerializer ;
3943import net .elytrium .serializer .exceptions .ReflectionException ;
@@ -203,13 +207,37 @@ public Object readByType(@Nullable Field owner, @Nullable Object holder, Type ty
203207 GenericUtils .getParameterType (Map .class , parameterizedType , 0 ),
204208 GenericUtils .getParameterType (Map .class , parameterizedType , 1 ));
205209 } else if (Collection .class .isAssignableFrom (clazz )) {
206- Type collectionType = GenericUtils .getParameterType (Collection .class , parameterizedType , 0 );
210+ Type collectionEntryType = GenericUtils .getParameterType (Collection .class , parameterizedType , 0 );
211+ if (owner != null ) {
212+ CollectionType collectionType = owner .getAnnotation (CollectionType .class );
213+ if (collectionType != null ) {
214+ try {
215+ //noinspection unchecked
216+ return this .readCollection (owner ,
217+ (Collection <Object >) collectionType .value ().getDeclaredConstructor ().newInstance (),
218+ collectionEntryType );
219+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e ) {
220+ throw new SerializableReadException (e );
221+ }
222+ } else {
223+ try {
224+ //noinspection unchecked
225+ return this .readCollection (owner ,
226+ (Collection <Object >) owner .getType ().getDeclaredConstructor ().newInstance (),
227+ collectionEntryType );
228+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e ) {
229+ throw new SerializableReadException (e );
230+ } catch (NoSuchMethodException e ) {
231+ // Ignoring NoSuchMethod.
232+ }
233+ }
234+ }
207235 if (Set .class .isAssignableFrom (clazz )) {
208- return this .readSet (collectionType );
236+ return this .readSet (collectionEntryType );
209237 } else if (Queue .class .isAssignableFrom (clazz )) {
210- return this .readDeque (collectionType );
238+ return this .readDeque (collectionEntryType );
211239 } else {
212- return this .readList (collectionType );
240+ return this .readList (collectionEntryType );
213241 }
214242 } else {
215243 return this .readGuessingType (owner );
@@ -274,6 +302,16 @@ public Map<Object, Object> readMap(Type keyType, Type valueType) {
274302
275303 public abstract Map <Object , Object > readMap (@ Nullable Field owner , Type keyType , Type valueType );
276304
305+ public <C extends Collection <Object >> C readCollection (@ Nullable Field owner , C result ) {
306+ return this .readCollection (owner , result , Object .class );
307+ }
308+
309+ public <C extends Collection <Object >> C readCollection (C result , Type type ) {
310+ return this .readCollection (null , result , type );
311+ }
312+
313+ public abstract <C extends Collection <Object >> C readCollection (@ Nullable Field owner , C result , Type type );
314+
277315 public List <Object > readList (@ Nullable Field owner ) {
278316 return this .readList (owner , Object .class );
279317 }
@@ -282,7 +320,9 @@ public List<Object> readList(Type type) {
282320 return this .readList (null , type );
283321 }
284322
285- public abstract List <Object > readList (@ Nullable Field owner , Type type );
323+ public List <Object > readList (@ Nullable Field owner , Type type ) {
324+ return this .readCollection (owner , new ArrayList <>(), type );
325+ }
286326
287327 public Set <Object > readSet (@ Nullable Field owner ) {
288328 return this .readSet (owner , Object .class );
@@ -292,7 +332,9 @@ public Set<Object> readSet(Type type) {
292332 return this .readSet (null , type );
293333 }
294334
295- public abstract Set <Object > readSet (@ Nullable Field owner , Type type );
335+ public Set <Object > readSet (@ Nullable Field owner , Type type ) {
336+ return this .readCollection (owner , new HashSet <>(), type );
337+ }
296338
297339 public Deque <Object > readDeque (@ Nullable Field owner ) {
298340 return this .readDeque (owner , Object .class );
@@ -302,7 +344,9 @@ public Deque<Object> readDeque(Type type) {
302344 return this .readDeque (null , type );
303345 }
304346
305- public abstract Deque <Object > readDeque (@ Nullable Field owner , Type type );
347+ public Deque <Object > readDeque (@ Nullable Field owner , Type type ) {
348+ return this .readCollection (owner , new ArrayDeque <>(), type );
349+ }
306350
307351 public String readString () {
308352 return this .readString (null );
0 commit comments