private static JaxInfo [ ] buildFields ( Class < ? > clazz , String defaultNS ) throws SecurityException , NoSuchFieldException , ClassNotFoundException { ArrayList < JaxInfo > fields = null ; // allow for lazy instantiation, because many structures won't have XmlType Class < ? > cls = clazz ; // Build up Method names from JAXB Annotations XmlType xt ; while ( ( xt = cls . getAnnotation ( XmlType . class ) ) != null ) { if ( fields == null ) fields = new ArrayList < JaxInfo > ( ) ; for ( String field : xt . propOrder ( ) ) { if ( "" . equals ( field ) ) break ; // odd bug. "" returned when no fields exist, rather than empty array Field rf = cls . getDeclaredField ( field ) ; Class < ? > ft = rf . getType ( ) ; boolean required = false ; boolean nillable = false ; String xmlName = field ; String namespace = defaultNS ; XmlElement xe = rf . getAnnotation ( XmlElement . class ) ; if ( xe != null ) { xmlName = xe . name ( ) ; required = xe . required ( ) ; nillable = false ; if ( DEFAULT . equals ( xmlName ) ) { xmlName = field ; } namespace = xe . namespace ( ) ; if ( DEFAULT . equals ( namespace ) ) { namespace = defaultNS ; } } // If object is a List, then it is possible multiple, per XML/JAXB evaluation if ( ft . isAssignableFrom ( List . class ) ) { Type t = rf . getGenericType ( ) ; String classname = t . toString ( ) ; int start = classname . indexOf ( ' ' ) ; int end = classname . indexOf ( ' ' ) ; Class < ? > genClass = Class . forName ( classname . substring ( start + 1 , end ) ) ; xe = genClass . getAnnotation ( XmlElement . class ) ; if ( xe != null && ! DEFAULT . equals ( xe . namespace ( ) ) ) { namespace = xe . namespace ( ) ; } // add recursed recursed member, marked as array fields . add ( new JaxInfo ( xmlName , namespace , genClass , buildFields ( genClass , namespace ) , genClass . equals ( String . class ) , true , required , nillable ) ) ; } else { boolean isString = ft . equals ( String . class ) || ft . equals ( XMLGregorianCalendar . class ) ; // add recursed member fields . add ( new JaxInfo ( xmlName , namespace , ft , buildFields ( ft , namespace ) , isString , false , required , nillable ) ) ; } } cls = cls . getSuperclass ( ) ; } ; if ( fields != null ) { JaxInfo [ ] rv = new JaxInfo [ fields . size ( ) ] ; fields . toArray ( rv ) ; return rv ; } else { return null ; } }
This is recursive if a member is a JAXB Object as well .