=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Property.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Property.java 2014-06-06 11:59:40 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/Property.java 2014-06-07 17:40:28 +0000 @@ -40,7 +40,7 @@ /** * @author Morten Olav Hansen */ -@JacksonXmlRootElement( localName = "property", namespace = DxfNamespaces.DXF_2_0 ) +@JacksonXmlRootElement(localName = "property", namespace = DxfNamespaces.DXF_2_0) public class Property { /** @@ -87,7 +87,15 @@ private boolean attribute; /** - * Is this a Collection sub-class. + * This property is true if the type pointed to does not export any properties itself, it is then + * assumed to be a primitive type. If collection is true, this this check is done on the generic type + * of the collection, e.g. List would set simple to be true, but List would set it + * to false. + */ + private boolean simple; + + /** + * This property is true if the type of this property is a sub-class of Collection. * * @see java.util.Collection */ @@ -123,7 +131,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public Class getKlass() { return klass; @@ -137,7 +145,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public Class getItemKlass() { return itemKlass; @@ -154,7 +162,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public String getName() { return name; @@ -166,7 +174,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public String getCollectionName() { return collectionName == null ? name : collectionName; @@ -178,7 +186,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public String getDescription() { return description; @@ -190,7 +198,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public String getNamespaceURI() { return namespaceURI; @@ -202,7 +210,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public boolean isAttribute() { return attribute; @@ -215,6 +223,18 @@ @JsonProperty @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isSimple() + { + return simple; + } + + public void setSimple( boolean simple ) + { + this.simple = simple; + } + + @JsonProperty + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public boolean isCollection() { return collection; @@ -226,7 +246,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public boolean isIdentifiableObject() { return identifiableObject; @@ -238,7 +258,7 @@ } @JsonProperty - @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) public boolean isNameableObject() { return nameableObject; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccess.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccess.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserGroupAccess.java 2014-06-07 17:40:28 +0000 @@ -28,9 +28,15 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import org.hisp.dhis.common.DxfNamespaces; + /** * @author Morten Olav Hansen */ +@JacksonXmlRootElement( localName = "userGroupAccess", namespace = DxfNamespaces.DXF_2_0 ) public class UserGroupAccess { private int id; @@ -53,6 +59,8 @@ this.id = id; } + @JsonProperty + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) public String getAccess() { return access; @@ -63,6 +71,8 @@ this.access = access; } + @JsonProperty + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) public UserGroup getUserGroup() { return userGroup; === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultPropertyIntrospectorService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultPropertyIntrospectorService.java 2014-06-07 13:35:12 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultPropertyIntrospectorService.java 2014-06-07 17:40:28 +0000 @@ -102,109 +102,142 @@ propertyMap.put( "__self__", property ); } + List properties = collectProperties( clazz ); + + for ( Property property : properties ) + { + Method method = property.getGetterMethod(); + JsonProperty jsonProperty = method.getAnnotation( JsonProperty.class ); + + String name = jsonProperty.value(); + + if ( StringUtils.isEmpty( name ) ) + { + String[] getters = new String[]{ + "is", "has", "get" + }; + + name = method.getName(); + + for ( String getter : getters ) + { + if ( name.startsWith( getter ) ) + { + name = name.substring( getter.length() ); + } + } + + name = StringUtils.uncapitalize( name ); + } + + if ( method.isAnnotationPresent( Description.class ) ) + { + Description description = method.getAnnotation( Description.class ); + property.setDescription( description.value() ); + } + + property.setName( name ); + + if ( method.isAnnotationPresent( JacksonXmlProperty.class ) ) + { + JacksonXmlProperty jacksonXmlProperty = method.getAnnotation( JacksonXmlProperty.class ); + + if ( StringUtils.isEmpty( jacksonXmlProperty.localName() ) ) + { + property.setName( name ); + } + else + { + property.setName( jacksonXmlProperty.localName() ); + } + + if ( !StringUtils.isEmpty( jacksonXmlProperty.namespace() ) ) + { + property.setNamespaceURI( jacksonXmlProperty.namespace() ); + } + + property.setAttribute( jacksonXmlProperty.isAttribute() ); + } + + if ( method.isAnnotationPresent( JacksonXmlElementWrapper.class ) ) + { + JacksonXmlElementWrapper jacksonXmlElementWrapper = method.getAnnotation( JacksonXmlElementWrapper.class ); + + // TODO what if element-wrapper have different namespace? + if ( !StringUtils.isEmpty( jacksonXmlElementWrapper.localName() ) ) + { + property.setCollectionName( jacksonXmlElementWrapper.localName() ); + } + } + + propertyMap.put( name, property ); + + Class returnType = method.getReturnType(); + property.setKlass( returnType ); + + if ( Collection.class.isAssignableFrom( returnType ) ) + { + property.setCollection( true ); + + Type type = method.getGenericReturnType(); + + if ( ParameterizedType.class.isInstance( type ) ) + { + ParameterizedType parameterizedType = (ParameterizedType) type; + Class klass = (Class) parameterizedType.getActualTypeArguments()[0]; + property.setItemKlass( klass ); + + if ( collectProperties( klass ).isEmpty() ) + { + property.setSimple( true ); + } + else + { + property.setComplex( true ); + } + + if ( IdentifiableObject.class.isAssignableFrom( klass ) ) + { + property.setIdentifiableObject( true ); + + if ( NameableObject.class.isAssignableFrom( klass ) ) + { + property.setNameableObject( true ); + } + } + } + } + else + { + if ( collectProperties( returnType ).isEmpty() ) + { + property.setSimple( true ); + } + else + { + property.setComplex( true ); + } + } + } + + classMapCache.put( clazz, propertyMap ); + + return propertyMap; + } + + private static List collectProperties( Class clazz ) + { List allMethods = ReflectionUtils.getAllMethods( clazz ); + List properties = Lists.newArrayList(); for ( Method method : allMethods ) { if ( method.isAnnotationPresent( JsonProperty.class ) ) { - JsonProperty jsonProperty = method.getAnnotation( JsonProperty.class ); - Property property = new Property( method ); - - String name = jsonProperty.value(); - - if ( StringUtils.isEmpty( name ) ) - { - String[] getters = new String[]{ - "is", "has", "get" - }; - - name = method.getName(); - - for ( String getter : getters ) - { - if ( name.startsWith( getter ) ) - { - name = name.substring( getter.length() ); - } - } - - name = StringUtils.uncapitalize( name ); - } - - if ( method.isAnnotationPresent( Description.class ) ) - { - Description description = method.getAnnotation( Description.class ); - property.setDescription( description.value() ); - } - - property.setName( name ); - - if ( method.isAnnotationPresent( JacksonXmlProperty.class ) ) - { - JacksonXmlProperty jacksonXmlProperty = method.getAnnotation( JacksonXmlProperty.class ); - - if ( StringUtils.isEmpty( jacksonXmlProperty.localName() ) ) - { - property.setName( name ); - } - else - { - property.setName( jacksonXmlProperty.localName() ); - } - - if ( !StringUtils.isEmpty( jacksonXmlProperty.namespace() ) ) - { - property.setNamespaceURI( jacksonXmlProperty.namespace() ); - } - - property.setAttribute( jacksonXmlProperty.isAttribute() ); - } - - if ( method.isAnnotationPresent( JacksonXmlElementWrapper.class ) ) - { - JacksonXmlElementWrapper jacksonXmlElementWrapper = method.getAnnotation( JacksonXmlElementWrapper.class ); - - // TODO what if element-wrapper have different namespace? - if ( !StringUtils.isEmpty( jacksonXmlElementWrapper.localName() ) ) - { - property.setCollectionName( jacksonXmlElementWrapper.localName() ); - } - } - - propertyMap.put( name, property ); - - Class returnType = method.getReturnType(); - property.setKlass( returnType ); - - if ( Collection.class.isAssignableFrom( returnType ) ) - { - property.setCollection( true ); - - Type type = method.getGenericReturnType(); - - if ( ParameterizedType.class.isInstance( type ) ) - { - ParameterizedType parameterizedType = (ParameterizedType) type; - Class klass = (Class) parameterizedType.getActualTypeArguments()[0]; - property.setItemKlass( klass ); - - if ( IdentifiableObject.class.isAssignableFrom( klass ) ) - { - property.setIdentifiableObject( true ); - - if ( NameableObject.class.isAssignableFrom( klass ) ) - { - property.setNameableObject( true ); - } - } - } - } + properties.add( new Property( method ) ); } } - classMapCache.put( clazz, propertyMap ); - - return propertyMap; + return properties; } }