2626import org .jboss .jandex .AnnotationValue ;
2727import org .jboss .jandex .ClassInfo ;
2828import org .jboss .jandex .DotName ;
29+ import org .jboss .jandex .FieldInfo ;
2930import org .jboss .jandex .IndexView ;
3031import org .jboss .jandex .MethodInfo ;
3132import org .jboss .jandex .MethodParameterInfo ;
33+ import org .jboss .jandex .ParameterizedType ;
3234import org .jboss .jandex .Type ;
3335import org .jboss .logging .Logger ;
3436import org .objectweb .asm .ClassVisitor ;
@@ -406,11 +408,27 @@ private String generateArgumentMapper(MethodInfo methodInfo, ClassOutput classOu
406408
407409 private Iterable <JsonSchemaProperty > toJsonSchemaProperties (MethodParameterInfo parameter , IndexView index ) {
408410 Type type = parameter .type ();
409- DotName typeName = parameter .type ().name ();
410-
411411 AnnotationInstance pInstance = parameter .annotation (P );
412+
412413 JsonSchemaProperty description = pInstance == null ? null : description (pInstance .value ().asString ());
413414
415+ return toJsonSchemaProperties (type , index , description );
416+ }
417+
418+ private Iterable <JsonSchemaProperty > toJsonSchemaProperties (Type type , IndexView index , JsonSchemaProperty description ) {
419+ DotName typeName = type .name ();
420+
421+ if (type .kind () == Type .Kind .WILDCARD_TYPE ) {
422+ Type boundType = type .asWildcardType ().extendsBound ();
423+ if (boundType == null ) {
424+ boundType = type .asWildcardType ().superBound ();
425+ }
426+ if (boundType != null ) {
427+ return toJsonSchemaProperties (boundType , index , description );
428+ } else {
429+ throw new IllegalArgumentException ("Unsupported wildcard type with no bounds: " + type );
430+ }
431+ }
414432 if (DotNames .STRING .equals (typeName ) || DotNames .CHARACTER .equals (typeName )
415433 || DotNames .PRIMITIVE_CHAR .equals (typeName )) {
416434 return removeNulls (STRING , description );
@@ -435,17 +453,64 @@ private Iterable<JsonSchemaProperty> toJsonSchemaProperties(MethodParameterInfo
435453 return removeNulls (NUMBER , description );
436454 }
437455
438- if ((type .kind () == Type .Kind .ARRAY )
439- || DotNames .LIST .equals (typeName )
440- || DotNames .SET .equals (typeName )) { // TODO something else?
441- return removeNulls (ARRAY , description ); // TODO provide type of array?
456+ // TODO something else?
457+ if (type .kind () == Type .Kind .ARRAY || DotNames .LIST .equals (typeName ) || DotNames .SET .equals (typeName )) {
458+ ParameterizedType parameterizedType = type .kind () == Type .Kind .PARAMETERIZED_TYPE ? type .asParameterizedType ()
459+ : null ;
460+
461+ Type elementType = parameterizedType != null ? parameterizedType .arguments ().get (0 )
462+ : type .asArrayType ().component ();
463+
464+ Iterable <JsonSchemaProperty > elementProperties = toJsonSchemaProperties (elementType , index , null );
465+
466+ JsonSchemaProperty itemsSchema ;
467+ if (isComplexType (elementType )) {
468+ Map <String , Object > fieldDescription = new HashMap <>();
469+
470+ for (JsonSchemaProperty fieldProperty : elementProperties ) {
471+ fieldDescription .put (fieldProperty .key (), fieldProperty .value ());
472+ }
473+ itemsSchema = JsonSchemaProperty .from ("items" , fieldDescription );
474+ } else {
475+ itemsSchema = JsonSchemaProperty .items (elementProperties .iterator ().next ());
476+ }
477+
478+ return removeNulls (ARRAY , itemsSchema , description );
442479 }
443480
444481 if (isEnum (type , index )) {
445482 return removeNulls (STRING , enums (enumConstants (type )), description );
446483 }
447484
448- return removeNulls (OBJECT , description ); // TODO provide internals
485+ if (type .kind () == Type .Kind .CLASS ) {
486+ Map <String , Object > properties = new HashMap <>();
487+ ClassInfo classInfo = index .getClassByName (type .name ());
488+
489+ List <String > required = new ArrayList <>();
490+ if (classInfo != null ) {
491+ for (FieldInfo field : classInfo .fields ()) {
492+ String fieldName = field .name ();
493+
494+ Iterable <JsonSchemaProperty > fieldSchema = toJsonSchemaProperties (field .type (), index , null );
495+ Map <String , Object > fieldDescription = new HashMap <>();
496+
497+ for (JsonSchemaProperty fieldProperty : fieldSchema ) {
498+ fieldDescription .put (fieldProperty .key (), fieldProperty .value ());
499+ }
500+
501+ properties .put (fieldName , fieldDescription );
502+ }
503+ }
504+
505+ JsonSchemaProperty objectSchema = JsonSchemaProperty .from ("properties" , properties );
506+ return removeNulls (OBJECT , objectSchema , JsonSchemaProperty .from ("required" , required ), description );
507+ }
508+
509+ throw new IllegalArgumentException ("Unsupported type: " + type );
510+ }
511+
512+ private boolean isComplexType (Type type ) {
513+ return type .kind () == Type .Kind .CLASS || type .kind () == Type .Kind .PARAMETERIZED_TYPE ;
449514 }
450515
451516 private Iterable <JsonSchemaProperty > removeNulls (JsonSchemaProperty ... properties ) {
0 commit comments