You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2016/11/28 22:42:33 UTC

svn commit: r1771825 - in /sling/trunk/contrib/extensions/contextaware-config: impl/src/main/java/org/apache/sling/caconfig/impl/ impl/src/main/java/org/apache/sling/caconfig/impl/metadata/ impl/src/test/java/org/apache/sling/caconfig/example/ impl/src...

Author: sseifert
Date: Mon Nov 28 22:42:33 2016
New Revision: 1771825

URL: http://svn.apache.org/viewvc?rev=1771825&view=rev
Log:
SLING-6338 support nested configuration classes when detecting configuration metadata

Modified:
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationProxy.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParser.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/example/NestedConfig.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationProxyTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParserTest.java
    sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadata.java
    sling/trunk/contrib/extensions/contextaware-config/spi/src/test/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadataTest.java

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationProxy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationProxy.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationProxy.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationProxy.java Mon Nov 28 22:42:33 2016
@@ -58,8 +58,8 @@ final class ConfigurationProxy {
     public @Nonnull static <T> T get(@Nullable Resource resource, @Nonnull Class<T> clazz, ChildResolver childResolver) {
 
         // only annotation interface classes are supported
-        if (!AnnotationClassParser.isContextAwareConfig(clazz)) {
-            throw new ConfigurationResolveException("Annotation interface class with @Configuration annotation expected: " + clazz.getName());
+        if (!clazz.isAnnotation()) {
+            throw new ConfigurationResolveException("Annotation interface class expected: " + clazz.getName());
         }
 
         // create dynamic proxy for annotation class accessing underlying resource properties
@@ -101,7 +101,7 @@ final class ConfigurationProxy {
             if (isArray) {
                 componentType = targetType.getComponentType();
             }
-            if (AnnotationClassParser.isContextAwareConfig(componentType)) {
+            if (componentType.isAnnotation()) {
                 if (isArray) {
                     Collection<?> listItems = childResolver.getChildren(propName, componentType);
                     return listItems.toArray((Object[])Array.newInstance(componentType, listItems.size()));

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParser.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParser.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParser.java Mon Nov 28 22:42:33 2016
@@ -128,22 +128,54 @@ public final class AnnotationClassParser
         configMetadata.setCollection(configAnnotation.collection());
 
         // property metadata
+        configMetadata.setPropertyMetadata(buildConfigurationMetadata_PropertyMetadata(clazz));
+        
+        return configMetadata;
+    }
+    
+    /**
+     * Build configuration metadata by parsing the given annotation interface class which is used for nested configurations.
+     * @param clazz Configuration annotation class
+     * @return Configuration metadata
+     */
+    private static ConfigurationMetadata buildConfigurationMetadata_Nested(Class<?> clazz) {
+        ConfigurationMetadata configMetadata = new ConfigurationMetadata("{" + clazz.getName() + "}");
+
+        // property metadata
+        configMetadata.setPropertyMetadata(buildConfigurationMetadata_PropertyMetadata(clazz));
+        
+        return configMetadata;
+    }
+    
+    private static Map<String,PropertyMetadata<?>> buildConfigurationMetadata_PropertyMetadata(Class<?> clazz) {
         Map<String,PropertyMetadata<?>> propertyMetadataList = new HashMap<>();
         Method[] propertyMethods = clazz.getDeclaredMethods();
         for (Method propertyMethod : propertyMethods) {
             PropertyMetadata<?> propertyMetadata = buildPropertyMetadata(propertyMethod, propertyMethod.getReturnType());
             propertyMetadataList.put(propertyMetadata.getName(), propertyMetadata);
         }
-        configMetadata.setPropertyMetadata(propertyMetadataList);
-        
-        return configMetadata;
+        return propertyMetadataList;
     }
     
     @SuppressWarnings("unchecked")
     private static <T> PropertyMetadata<T> buildPropertyMetadata(Method propertyMethod, Class<T> type) {
         String propertyName = getPropertyName(propertyMethod.getName());
-        PropertyMetadata<T> propertyMetadata = new PropertyMetadata<>(propertyName, type);
-        propertyMetadata.setDefaultValue((T)propertyMethod.getDefaultValue());
+        
+        PropertyMetadata propertyMetadata;
+        if (type.isArray() && type.getComponentType().isAnnotation()) {
+            ConfigurationMetadata nestedConfigMetadata = buildConfigurationMetadata_Nested(type.getComponentType());
+            propertyMetadata = new PropertyMetadata<>(propertyName, ConfigurationMetadata[].class);
+            propertyMetadata.setConfigurationMetadata(nestedConfigMetadata);
+        }
+        else if (type.isAnnotation()) {
+            ConfigurationMetadata nestedConfigMetadata = buildConfigurationMetadata_Nested(type);
+            propertyMetadata = new PropertyMetadata<>(propertyName, ConfigurationMetadata.class);
+            propertyMetadata.setConfigurationMetadata(nestedConfigMetadata);
+        }
+        else {
+            propertyMetadata = new PropertyMetadata<>(propertyName, type);            
+            propertyMetadata.setDefaultValue((T)propertyMethod.getDefaultValue());
+        }
         
         Property propertyAnnotation = propertyMethod.getAnnotation(Property.class);
         if (propertyAnnotation != null) {            

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/example/NestedConfig.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/example/NestedConfig.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/example/NestedConfig.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/example/NestedConfig.java Mon Nov 28 22:42:33 2016
@@ -28,5 +28,7 @@ public @interface NestedConfig {
     SimpleConfig subConfig();
     
     ListConfig[] subListConfig();
+
+    WithoutAnnotationConfig subConfigWithoutAnnotation();    
     
 }

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationProxyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationProxyTest.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationProxyTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationProxyTest.java Mon Nov 28 22:42:33 2016
@@ -46,6 +46,7 @@ import org.apache.sling.caconfig.example
 import org.apache.sling.caconfig.example.NestedConfig;
 import org.apache.sling.caconfig.example.SimpleConfig;
 import org.apache.sling.caconfig.example.SpecialNamesConfig;
+import org.apache.sling.caconfig.example.WithoutAnnotationConfig;
 import org.apache.sling.caconfig.impl.ConfigurationProxy.ChildResolver;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Rule;
@@ -154,7 +155,8 @@ public class ConfigurationProxyTest {
             .resource("/test/subConfig", "stringParam", "v2", "intParam", 444, "boolParam", true)
             .resource("/test/subListConfig/1", "stringParam", "v3.1")
             .resource("/test/subListConfig/2", "stringParam", "v3.2")
-            .resource("/test/subListConfig/3", "stringParam", "v3.3");
+            .resource("/test/subListConfig/3", "stringParam", "v3.3")
+            .resource("/test/subConfigWithoutAnnotation", "stringParam", "v4");
 
         Resource resource = context.resourceResolver().getResource("/test");
         
@@ -172,6 +174,9 @@ public class ConfigurationProxyTest {
         assertEquals("v3.1", listConfig[0].stringParam());
         assertEquals("v3.2", listConfig[1].stringParam());
         assertEquals("v3.3", listConfig[2].stringParam());
+
+        WithoutAnnotationConfig subConfigWithoutAnnotation = cfg.subConfigWithoutAnnotation();
+        assertEquals("v4", subConfigWithoutAnnotation.stringParam());
     }
 
     @Test(expected=ConfigurationResolveException.class)

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParserTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParserTest.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParserTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/metadata/AnnotationClassParserTest.java Mon Nov 28 22:42:33 2016
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.util.Collection;
 
@@ -33,6 +34,7 @@ import org.apache.commons.lang3.StringUt
 import org.apache.sling.caconfig.example.AllTypesConfig;
 import org.apache.sling.caconfig.example.ListConfig;
 import org.apache.sling.caconfig.example.MetadataSimpleConfig;
+import org.apache.sling.caconfig.example.NestedConfig;
 import org.apache.sling.caconfig.example.SimpleConfig;
 import org.apache.sling.caconfig.example.WithoutAnnotationConfig;
 import org.apache.sling.caconfig.spi.metadata.ConfigurationMetadata;
@@ -98,11 +100,14 @@ public class AnnotationClassParserTest {
                 assertTrue(propertyMetadata.getProperties().isEmpty());
                 assertEquals(5, propertyMetadata.getDefaultValue());
             }
-            else if (StringUtils.equals(propertyMetadata.getName(), "booleanParam")) {
+            else if (StringUtils.equals(propertyMetadata.getName(), "boolParam")) {
                 assertNull(propertyMetadata.getLabel());
                 assertNull(propertyMetadata.getDescription());
                 assertTrue(propertyMetadata.getProperties().isEmpty());
-                assertFalse((Boolean)propertyMetadata.getDefaultValue());
+                assertNull(propertyMetadata.getDefaultValue());
+            }
+            else {
+                fail("Unexpected property name: " + propertyMetadata.getName());
             }
         }
     }
@@ -126,6 +131,43 @@ public class AnnotationClassParserTest {
         assertEquals(20, metadata.getPropertyMetadata().size());
     }
     
+    @Test
+    public void testBuildConfigurationMetadata_Nested() {
+        ConfigurationMetadata metadata = buildConfigurationMetadata(NestedConfig.class);
+        
+        assertEquals(NestedConfig.class.getName(), metadata.getName());
+
+        Collection<PropertyMetadata<?>> propertyMetadataList = metadata.getPropertyMetadata().values();
+        assertEquals(4, propertyMetadataList.size());
+        
+        for (PropertyMetadata<?> propertyMetadata : propertyMetadataList) {
+            if (StringUtils.equals(propertyMetadata.getName(), "stringParam")) {
+                assertEquals(String.class, propertyMetadata.getType());
+            }
+            else if (StringUtils.equals(propertyMetadata.getName(), "subConfig")) {
+                assertEquals(ConfigurationMetadata.class, propertyMetadata.getType());
+                
+                ConfigurationMetadata subConfigMetadata = propertyMetadata.getConfigurationMetadata();
+                assertEquals(3, subConfigMetadata.getPropertyMetadata().size());
+            }
+            else if (StringUtils.equals(propertyMetadata.getName(), "subListConfig")) {
+                assertEquals(ConfigurationMetadata[].class, propertyMetadata.getType());
+
+                ConfigurationMetadata subListConfigMetadata = propertyMetadata.getConfigurationMetadata(); 
+                assertEquals(2, subListConfigMetadata.getPropertyMetadata().size());
+            }
+            else if (StringUtils.equals(propertyMetadata.getName(), "subConfigWithoutAnnotation")) {
+                assertEquals(ConfigurationMetadata.class, propertyMetadata.getType());
+
+                ConfigurationMetadata subConfigWithoutAnnotationMetadata = propertyMetadata.getConfigurationMetadata(); 
+                assertEquals(1, subConfigWithoutAnnotationMetadata.getPropertyMetadata().size());
+            }
+            else {
+                fail("Unexpected property name: " + propertyMetadata.getName());
+            }
+        }
+    }
+    
     @Test(expected = IllegalArgumentException.class)
     public void testBuildConfigurationMetadata_IllegalClass() {
         buildConfigurationMetadata(WithoutAnnotationConfig.class);

Modified: sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadata.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadata.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadata.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadata.java Mon Nov 28 22:42:33 2016
@@ -52,6 +52,7 @@ public final class PropertyMetadata<T> e
     
     private final Class<T> type;
     private T defaultValue;
+    private ConfigurationMetadata configurationMetadata;
 
     /**
      * @param name Property name
@@ -122,6 +123,20 @@ public final class PropertyMetadata<T> e
     public void setDefaultValue(T value) {
         this.defaultValue = value;
     }
+    
+    /**
+     * @return Metadata for nested configuration
+     */
+    public ConfigurationMetadata getConfigurationMetadata() {
+        return configurationMetadata;
+    }
+
+    /**
+     * @param configurationMetadata Metadata for nested configuration
+     */
+    public void setConfigurationMetadata(ConfigurationMetadata configurationMetadata) {
+        this.configurationMetadata = configurationMetadata;
+    }
 
     @Override
     public String toString() {

Modified: sling/trunk/contrib/extensions/contextaware-config/spi/src/test/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadataTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/spi/src/test/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadataTest.java?rev=1771825&r1=1771824&r2=1771825&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/spi/src/test/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadataTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/spi/src/test/java/org/apache/sling/caconfig/spi/metadata/PropertyMetadataTest.java Mon Nov 28 22:42:33 2016
@@ -19,6 +19,7 @@
 package org.apache.sling.caconfig.spi.metadata;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 
 import java.util.Map;
 
@@ -40,10 +41,14 @@ public class PropertyMetadataTest {
         Map<String,String> props = ImmutableMap.of("p1", "v1");
         underTest.setProperties(props);
         
+        ConfigurationMetadata configMetadata = new ConfigurationMetadata("test");
+        underTest.setConfigurationMetadata(configMetadata);
+        
         assertEquals("label1", underTest.getLabel());
         assertEquals("desc1", underTest.getDescription());
         assertEquals("value1", underTest.getDefaultValue());
         assertEquals(props, underTest.getProperties());
+        assertSame(configMetadata, underTest.getConfigurationMetadata());
     }
 
     @Test