This is an automated email from the ASF dual-hosted git repository.

anatole pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-tamaya-sandbox.git

commit ef3d76279f46d8fdd280f14c9ac0cb97379d7396
Author: Anatole Tresch <[email protected]>
AuthorDate: Thu Feb 21 19:09:45 2019 +0100

    Initial experiments with config documentation.
---
 .../org/apache/tamaya/doc/ConfigDocumenter.java    | 24 ++++--
 ...ration.java => ConfigurationDocumentation.java} | 73 ++++++++++++-----
 .../main/java/org/apache/tamaya/doc/DocFormat.java |  2 +-
 .../java/org/apache/tamaya/doc/DocumentedArea.java | 93 ++++++----------------
 .../org/apache/tamaya/doc/DocumentedProperty.java  | 58 ++++++++++----
 .../apache/tamaya/doc/annot/ConfigAreaSpec.java    |  8 +-
 .../tamaya/doc/annot/ConfigPropertySpec.java       |  4 +-
 .../tamaya/doc/annot/ConfigPropertySpecs.java      |  2 +-
 .../org/apache/tamaya/doc/annot/ConfigSpec.java    | 14 +++-
 .../apache/tamaya/doc/formats/HtmlDocFormat.java   | 27 +++----
 .../apache/tamaya/doc/formats/TextDocFormat.java   | 22 ++---
 .../AnnotBasedStandaloneConfigDocumentation.java   | 60 +++++++-------
 .../apache/tamaya/doc/AnnotatedDocConfigBean.java  | 20 +++--
 .../apache/tamaya/doc/ConfigDocumenterTest.java    |  8 +-
 14 files changed, 213 insertions(+), 202 deletions(-)

diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java 
b/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java
index c726101..595d5d4 100644
--- a/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java
@@ -33,8 +33,6 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -42,7 +40,7 @@ import java.util.List;
  */
 public class ConfigDocumenter {
 
-    private DocumentedConfiguration docs = new DocumentedConfiguration();
+    private ConfigurationDocumentation docs = new ConfigurationDocumentation();
 
 
     public static ConfigDocumenter getInstance(){
@@ -99,7 +97,8 @@ public class ConfigDocumenter {
         }
         configBuilder.filterInputsBy(filterBuilder);
         configBuilder.setUrls(ClasspathHelper.forJavaClassPath());
-        configBuilder.setScanners(new TypeAnnotationsScanner(), new 
MethodAnnotationsScanner(), new FieldAnnotationsScanner());
+        configBuilder.setScanners(new TypeAnnotationsScanner(),
+                new MethodAnnotationsScanner(), new FieldAnnotationsScanner());
         Reflections reflections = new Reflections(configBuilder);
         readSpecs(reflections);
     }
@@ -108,7 +107,7 @@ public class ConfigDocumenter {
      * Access the collected configuration documentation.
      * @return the documentation, not null.
      */
-    public DocumentedConfiguration getDocumentation(){
+    public ConfigurationDocumentation getDocumentation(){
         return docs;
     }
 
@@ -158,13 +157,24 @@ public class ConfigDocumenter {
     }
 
     private void readConfigSpec(Class type){
-        docs.init((ConfigSpec)type.getAnnotation(ConfigSpec.class), type);
+        ConfigSpec configAnnot = 
(ConfigSpec)type.getAnnotation(ConfigSpec.class);
+        docs.init(configAnnot, type);
+        for (ConfigAreaSpec areaSpec:configAnnot.areas()){
+            for(String basePath:areaSpec.basePaths()) {
+                docs.addGroup(new DocumentedArea(areaSpec, type));
+            }
+        }
+        for (ConfigPropertySpec propertySpec:configAnnot.properties()){
+            docs.addProperty(new DocumentedProperty(propertySpec, type));
+        }
     }
 
     private void readAreaSpecs(AnnotatedElement elem){
         ConfigAreaSpecs areaSpecs = elem.getAnnotation(ConfigAreaSpecs.class);
         for (ConfigAreaSpec areaSpec:areaSpecs.value()){
-            docs.addGroup(new DocumentedArea(areaSpec, elem));
+            for(String basePath:areaSpec.basePaths()) {
+                docs.addGroup(new DocumentedArea(areaSpec, elem));
+            }
         }
     }
 
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java
 
b/documentation/src/main/java/org/apache/tamaya/doc/ConfigurationDocumentation.java
similarity index 65%
rename from 
documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java
rename to 
documentation/src/main/java/org/apache/tamaya/doc/ConfigurationDocumentation.java
index 62aa446..7b68d62 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/ConfigurationDocumentation.java
@@ -25,25 +25,27 @@ import java.util.*;
 /**
  * Documentation of an application configuration.
  */
-public final class DocumentedConfiguration {
+public final class ConfigurationDocumentation {
 
     private String name;
     private String version;
     private Class ownerClass;
 
     private Map<String, DocumentedProperty> properties = new TreeMap<>();
+    private Map<String, DocumentedProperty> allProperties = new TreeMap<>();
     private Map<String, DocumentedArea> groups = new TreeMap<>();
+    private Map<String, DocumentedArea> allGroups = new TreeMap<>();
 
     /**
      * Creates a new empty configuration documentation.
      */
-    public DocumentedConfiguration(){}
+    public ConfigurationDocumentation(){}
 
     /**
      * Creates a new configuration documentation and initializes it with the 
values from the annotation given.
      * @param annotation the spec annotation, not null.
      */
-    public DocumentedConfiguration(ConfigSpec annotation){
+    public ConfigurationDocumentation(ConfigSpec annotation){
         init(annotation, null);
     }
 
@@ -58,6 +60,38 @@ public final class DocumentedConfiguration {
         this.ownerClass = ownerClass;
     }
 
+    public void resolveReferences(){
+        DocumentedArea currentArea = null;
+        for(DocumentedProperty prop:getAllPropertiesSorted()){
+            String[] parentCandidates = getCandidates(prop.getMainKey());
+            for(String candidateId:parentCandidates){
+                currentArea = getArea(candidateId);
+                if(currentArea!=null){
+                    prop.parentArea(currentArea);
+                }
+            }
+        }
+    }
+
+    private String[] getCandidates(String mainKey) {
+        List<String> candidates = new ArrayList<>();
+        String[] parts = mainKey.split("\\.");
+        if(parts.length==1){
+            candidates.add("");
+        }else {
+            for (int max = parts.length-1; max >= 0; max--) {
+                StringBuilder b = new StringBuilder();
+                for (int i = 0; i < max; i++) {
+                    b.append(parts[i]).append(".");
+                }
+                b.setLength(b.length() - 1);
+                candidates.add(b.toString());
+            }
+            candidates.add("");
+        }
+        return candidates.toArray(new String[candidates.size()]);
+    }
+
     /**
      * Get the current configuration name.
      * @return the name, or {@code <undefined>}.
@@ -108,7 +142,7 @@ public final class DocumentedConfiguration {
     }
 
     private int compareAreas(DocumentedArea area1, DocumentedArea area2) {
-        return area1.getPath().compareTo(area2.getPath());
+        return area1.getMainBasePath().compareTo(area2.getMainBasePath());
     }
 
     /**
@@ -118,15 +152,12 @@ public final class DocumentedConfiguration {
     public List<DocumentedProperty> getAllPropertiesSorted() {
         List<DocumentedProperty> props = new ArrayList<>();
         props.addAll(getProperties().values());
-        for(DocumentedArea area:getAreas().values()) {
-            props.addAll(area.getProperties().values());
-        }
         props.sort(this::compareProperties);
         return props;
     }
 
     private int compareProperties(DocumentedProperty property, 
DocumentedProperty property1) {
-        return property.getName().compareTo(property1.getName());
+        return property.getMainKey().compareTo(property1.getMainKey());
     }
 
     /**
@@ -137,30 +168,36 @@ public final class DocumentedConfiguration {
         return groups;
     }
 
-    public DocumentedArea getGroup(String path) {
-        return null;
+    public DocumentedArea getArea(String path) {
+        return allGroups.get(path);
     }
 
     public DocumentedProperty getProperty(String path) {
-        return null;
+        return allProperties.get(path);
     }
 
-    public DocumentedConfiguration addProperty(DocumentedProperty property){
-        this.properties.put(property.getName(), property);
+    public ConfigurationDocumentation addProperty(DocumentedProperty property){
+        for(String key:property.getKeys()) {
+            this.allProperties.put(key, property);
+        }
+        this.properties.put(property.getMainKey(), property);
         return this;
     }
 
-    public DocumentedConfiguration addGroup(DocumentedArea group){
-        this.groups.put(group.getPath(), group);
+    public ConfigurationDocumentation addGroup(DocumentedArea group){
+        for(String basePath:group.getBasePaths()) {
+            this.allGroups.put(basePath, group);
+        }
+        this.groups.put(group.getMainBasePath(), group);
         return this;
     }
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (!(o instanceof DocumentedConfiguration)) return false;
+        if (!(o instanceof ConfigurationDocumentation)) return false;
 
-        DocumentedConfiguration that = (DocumentedConfiguration) o;
+        ConfigurationDocumentation that = (ConfigurationDocumentation) o;
 
         if (!name.equals(that.name)) return false;
         return version.equals(that.version);
@@ -179,7 +216,7 @@ public final class DocumentedConfiguration {
                 "name='" + name + '\'' +
                 ", version='" + version + '\'' +
                 ", properties=" + properties +
-                ", groups=" + groups +
+                ", areas=" + groups +
                 '}';
     }
 
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java 
b/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
index 0f5e14a..0d93272 100644
--- a/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
@@ -20,6 +20,6 @@ package org.apache.tamaya.doc;
 
 import java.util.function.Function;
 
-public interface DocFormat<T> extends Function<DocumentedConfiguration, T> {
+public interface DocFormat<T> extends Function<ConfigurationDocumentation, T> {
 
 }
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java 
b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java
index e2215b4..b455a35 100644
--- a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java
@@ -19,8 +19,7 @@
 package org.apache.tamaya.doc;
 
 import org.apache.tamaya.doc.annot.ConfigAreaSpec;
-import org.apache.tamaya.doc.annot.ConfigPropertySpec;
-import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.api.ConfigSection;
 import org.apache.tamaya.inject.spi.InjectionUtils;
 import org.apache.tamaya.spi.PropertyValue;
 
@@ -31,11 +30,10 @@ public final class DocumentedArea {
 
     private final AnnotatedElement owner;
     private ConfigAreaSpec configArea;
-    private String path;
+    private String mainBasePath;
+    private Set<String> basePaths = new TreeSet<>();
     private String description;
     private PropertyValue.ValueType groupType;
-    private Map<String, DocumentedProperty> properties = new HashMap<>();
-    private Map<String, DocumentedArea> areas = new HashMap<>();
     private Class<?> valueType;
 
     private int minCardinality;
@@ -46,10 +44,12 @@ public final class DocumentedArea {
     public DocumentedArea(ConfigAreaSpec areaSpec, AnnotatedElement owner){
         this.owner = owner;
         this.configArea = areaSpec;
-        if(!areaSpec.path().isEmpty()) {
-            this.path = areaSpec.path();
+        if(!(areaSpec.basePaths().length==0)) {
+            this.mainBasePath = areaSpec.basePaths()[0];
+            this.basePaths.addAll(Arrays.asList(areaSpec.basePaths()));
         }else{
-           this.path = evaluatePath(owner);
+           this.mainBasePath = evaluatePath(owner);
+           this.basePaths.add(mainBasePath);
         }
         if(!areaSpec.description().isEmpty()) {
             this.description = areaSpec.description();
@@ -68,9 +68,6 @@ public final class DocumentedArea {
                 this.valueType = ((Class)owner);
             }
         }
-        for(ConfigPropertySpec ps:areaSpec.properties()) {
-            this.properties.put(ps.name(), new DocumentedProperty(ps, owner));
-        }
     }
 
     private String evaluatePath(AnnotatedElement owner) {
@@ -79,7 +76,7 @@ public final class DocumentedArea {
         }else if(owner instanceof Method) {
             return String.join(", ", InjectionUtils.getKeys((Method) owner));
         }else if(owner instanceof Class) {
-            ConfigDefaultSections sectionsAnnot = 
owner.getAnnotation(ConfigDefaultSections.class);
+            ConfigSection sectionsAnnot = 
owner.getAnnotation(ConfigSection.class);
             if(sectionsAnnot!=null){
                 return String.join(", ", sectionsAnnot.value());
             }
@@ -88,10 +85,10 @@ public final class DocumentedArea {
         return "<root>";
     }
 
-    void resolve(DocumentedConfiguration documentation){
+    void resolve(ConfigurationDocumentation documentation){
         if(configArea !=null){
             for(String key: configArea.dependsOnAreas()){
-                this.dependsOnGroups.add(documentation.getGroup(key));
+                this.dependsOnGroups.add(documentation.getArea(key));
             }
             for(String key: configArea.dependsOnProperties()){
                 this.dependsOnProperties.add(documentation.getProperty(key));
@@ -99,22 +96,12 @@ public final class DocumentedArea {
         }
     }
 
-    public DocumentedArea addGroup(DocumentedArea group){
-        this.areas.put(group.path, group);
-        return this;
-    }
-
-    public DocumentedArea addProperty(DocumentedProperty property){
-        this.properties.put(property.getName(), property);
-        return this;
-    }
-
     public AnnotatedElement getOwner() {
         return owner;
     }
 
-    public String getPath() {
-        return path;
+    public Set<String> getBasePaths() {
+        return Collections.unmodifiableSet(basePaths);
     }
 
     public String getDescription() {
@@ -125,26 +112,6 @@ public final class DocumentedArea {
         return groupType;
     }
 
-    public Map<String, DocumentedProperty> getProperties() {
-        return properties;
-    }
-
-    public List<DocumentedProperty> getPropertiesSorted() {
-        List<DocumentedProperty> result = new ArrayList<>(properties.values());
-        result.sort(Comparator.comparing(DocumentedProperty::getName));
-        return result;
-    }
-
-    public Map<String, DocumentedArea> getAreas() {
-        return areas;
-    }
-
-    public List<DocumentedArea> getAreasSorted() {
-        List<DocumentedArea> result = new ArrayList<>(areas.values());
-        result.sort(Comparator.comparing(DocumentedArea::getPath));
-        return result;
-    }
-
     public Class<?> getValueType() {
         return valueType;
     }
@@ -159,18 +126,22 @@ public final class DocumentedArea {
 
     public List<DocumentedArea> getDependsOnAreas() {
         List<DocumentedArea> result = new ArrayList<>(dependsOnGroups);
-        result.sort(Comparator.comparing(DocumentedArea::getPath));
+        result.sort(Comparator.comparing(DocumentedArea::getMainBasePath));
         return result;
     }
 
+    public String getMainBasePath() {
+        return this.mainBasePath;
+    }
+
     public List<DocumentedProperty> getDependsOnProperties() {
         List<DocumentedProperty> result = new ArrayList<>(dependsOnProperties);
-        result.sort(Comparator.comparing(DocumentedProperty::getName));
+        result.sort(Comparator.comparing(DocumentedProperty::getMainKey));
         return result;
     }
 
-    public DocumentedArea path(String path) {
-        this.path = path;
+    public DocumentedArea addBasePath(String path) {
+        this.basePaths.add(path);
         return this;
     }
 
@@ -184,16 +155,6 @@ public final class DocumentedArea {
         return this;
     }
 
-    public DocumentedArea properties(Map<String, DocumentedProperty> 
properties) {
-        this.properties = properties;
-        return this;
-    }
-
-    public DocumentedArea groups(Map<String, DocumentedArea> groups) {
-        this.areas = groups;
-        return this;
-    }
-
     public DocumentedArea valueType(Class<?> valueType) {
         this.valueType = valueType;
         return this;
@@ -229,29 +190,25 @@ public final class DocumentedArea {
         return Objects.equals(this.dependsOnGroups, that.dependsOnGroups) &&
                 Objects.equals(this.dependsOnProperties, 
that.dependsOnProperties) &&
                 Objects.equals(this.description, that.description) &&
-                Objects.equals(this.areas, that.areas) &&
                 Objects.equals(this.groupType, that.groupType) &&
                 Objects.equals(this.maxCardinality, that.maxCardinality) &&
                 Objects.equals(this.minCardinality, that.minCardinality) &&
-                Objects.equals(this.path, that.path) &&
-                Objects.equals(this.properties, that.properties) &&
+                Objects.equals(this.basePaths, that.basePaths) &&
                 Objects.equals(this.valueType, that.valueType);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(dependsOnGroups, dependsOnProperties, description, 
areas, groupType, maxCardinality,
-                minCardinality, path, properties, valueType);
+        return Objects.hash(dependsOnGroups, dependsOnProperties, description, 
groupType, maxCardinality,
+                minCardinality, basePaths, valueType);
     }
 
     @Override
     public String toString() {
         return "ConfigGroup{" +
-                "path='" + path + '\'' +
+                "basePaths='" + basePaths + '\'' +
                 ", description='" + description + '\'' +
                 ", areaType=" + groupType +
-                ", properties=" + properties +
-                ", areas=" + areas +
                 ", valueType=" + valueType +
                 ", minCardinality=" + minCardinality +
                 ", maxCardinality=" + maxCardinality +
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java 
b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java
index b270aea..66e499e 100644
--- a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java
@@ -31,11 +31,13 @@ public final class DocumentedProperty {
 
     private final AnnotatedElement owner;
     private ConfigPropertySpec propertySpec;
-    private String name;
+    private String mainKey;
+    private Set<String> keys = new TreeSet<>();
     private String defaultValue;
     private boolean required;
     private String description;
     private Class<?> valueType;
+    private DocumentedArea parentArea;
 
     private Set<DocumentedArea> dependsOnGroups = new TreeSet<>();
     private Set<DocumentedProperty> dependsOnProperties = new TreeSet<>();
@@ -44,13 +46,18 @@ public final class DocumentedProperty {
     public DocumentedProperty(ConfigPropertySpec annot, AnnotatedElement 
owner){
         this.owner = owner;
         this.propertySpec = annot;
-        if(!annot.name().isEmpty()) {
-            this.name = annot.name();
+        if(!(annot.keys().length==0)) {
+            this.mainKey = annot.keys()[0];
+            this.keys.addAll(Arrays.asList(annot.keys()));
         }else{
             if(owner instanceof Field) {
-                this.name = String.join(", ", InjectionUtils.getKeys((Field) 
owner));
+                List<String> evalKeys = InjectionUtils.getKeys((Field) owner);
+                this.mainKey = evalKeys.get(0);
+                this.keys.addAll(evalKeys);
             }else if(owner instanceof Method) {
-                this.name = String.join(", ", InjectionUtils.getKeys((Method) 
owner));
+                List<String> evalKeys = InjectionUtils.getKeys((Method) owner);
+                this.mainKey = evalKeys.get(0);
+                this.keys.addAll(evalKeys);
             }
         }
         this.description = annot.description();
@@ -67,14 +74,16 @@ public final class DocumentedProperty {
         Config configAnnot = owner.getAnnotation(Config.class);
         if(configAnnot!=null){
             this.required = configAnnot.required();
-            this.defaultValue = configAnnot.defaultValue();
+            if(!Config.UNCONFIGURED_VALUE.equals(configAnnot.defaultValue())) {
+                this.defaultValue = configAnnot.defaultValue();
+            }
         }
     }
 
-    void resolve(DocumentedConfiguration documentation){
+    void resolve(ConfigurationDocumentation documentation){
         if(propertySpec !=null){
             for(String key: propertySpec.dependsOnAreas()){
-                this.dependsOnGroups.add(documentation.getGroup(key));
+                this.dependsOnGroups.add(documentation.getArea(key));
             }
             for(String key: propertySpec.dependsOnProperties()){
                 this.dependsOnProperties.add(documentation.getProperty(key));
@@ -97,8 +106,18 @@ public final class DocumentedProperty {
         return required;
     }
 
-    public String getName() {
-        return name;
+    public Set<String> getKeys() {
+        return Collections.unmodifiableSet(keys);
+    }
+
+    public Set<String> getBackupKeys() {
+        Set<String> result = new TreeSet<>(keys);
+        result.remove(getMainKey());
+        return result;
+    }
+
+    public String getMainKey() {
+        return this.mainKey;
     }
 
     public String getDescription() {
@@ -108,6 +127,10 @@ public final class DocumentedProperty {
         return description;
     }
 
+    public DocumentedArea getParentArea(){
+        return parentArea;
+    }
+
     public Class<?> getValueType() {
         return valueType;
     }
@@ -120,8 +143,13 @@ public final class DocumentedProperty {
         return dependsOnProperties;
     }
 
-    public DocumentedProperty path(String path) {
-        this.name = path;
+    public DocumentedProperty addKey(String key) {
+        this.keys.add(key);
+        return this;
+    }
+
+    public DocumentedProperty parentArea(DocumentedArea parentArea) {
+        this.parentArea = parentArea;
         return this;
     }
 
@@ -165,19 +193,19 @@ public final class DocumentedProperty {
         return Objects.equals(this.dependsOnGroups, that.dependsOnGroups) &&
                 Objects.equals(this.dependsOnProperties, 
that.dependsOnProperties) &&
                 Objects.equals(this.description, that.description) &&
-                Objects.equals(this.name, that.name) &&
+                Objects.equals(this.keys, that.keys) &&
                 Objects.equals(this.valueType, that.valueType);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(dependsOnGroups, dependsOnProperties, description, 
name, valueType);
+        return Objects.hash(dependsOnGroups, dependsOnProperties, description, 
keys, valueType);
     }
 
     @Override
     public String toString() {
         return "ConfigGroup{" +
-                "name='" + name + '\'' +
+                "keys='" + keys + '\'' +
                 ", description='" + description + '\'' +
                 ", valueType=" + valueType +
                 ", dependsOnAreas=" + dependsOnGroups +
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java
index 27c27fa..d87b100 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java
@@ -34,7 +34,7 @@ public @interface ConfigAreaSpec {
      * of the configuration tree.
      * @return the path, not null.
      */
-    String path()default"";
+    String[] basePaths() default {};
 
     /**
      * Define a description of the area.
@@ -75,12 +75,6 @@ public @interface ConfigAreaSpec {
     int max() default 0;
 
     /**
-     * The properties managed in this area.
-     * @return the properties managed within this area.
-     */
-    ConfigPropertySpec[] properties() default {};
-
-    /**
      * Allows to define that this area is only required, if any of these 
configured areas are present in your config.
      * @return the area dependencies. This can be ensured/checked by a 
configuration validation
      */
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
index 49ee6df..103690d 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
@@ -28,13 +28,11 @@ import java.lang.annotation.Target;
 @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
 public @interface ConfigPropertySpec {
 
-//    boolean id() default false;
-
     /**
      * The property name. The full property key is a combination of the parent
      * @return the name of the property, taken from the default resolution, if 
empty.
      */
-    String name() default "";
+    String[] keys() default {};
 
     /**
      * Define a description of the property.
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
index a8fd4f0..b30ff71 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
@@ -34,5 +34,5 @@ public @interface ConfigPropertySpecs {
      * The contained child annotations.
      * @return the contained annotations.
      */
-    ConfigPropertySpec[] value()default{};
+    ConfigPropertySpec[] value() default{};
 }
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java 
b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java
index 5f0c798..8f42f6b 100644
--- a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java
@@ -40,9 +40,15 @@ public @interface ConfigSpec {
     String description() default "";
 
     /**
-     * Should loading of the configuration fail, if a validation failed, 
default is {@code false}, where
-     * a warning is logged only.
-     * @return true to fail config load on configuration validation failures.
+     * The contained child annotations.
+     * @return the contained annotations.
      */
-    boolean failOnErrors() default false;
+    ConfigAreaSpec[] areas() default{};
+
+    /**
+     * The contained child annotations.
+     * @return the contained annotations.
+     */
+    ConfigPropertySpec[] properties()default{};
+
 }
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java 
b/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java
index b37bf80..f28224d 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java
@@ -21,7 +21,7 @@ package org.apache.tamaya.doc.formats;
 import j2html.tags.ContainerTag;
 import org.apache.tamaya.doc.DocFormat;
 import org.apache.tamaya.doc.DocumentedArea;
-import org.apache.tamaya.doc.DocumentedConfiguration;
+import org.apache.tamaya.doc.ConfigurationDocumentation;
 import org.apache.tamaya.doc.DocumentedProperty;
 
 import java.io.File;
@@ -34,7 +34,7 @@ import static j2html.TagCreator.*;
 
 public class HtmlDocFormat implements DocFormat<String> {
     @Override
-    public String apply(DocumentedConfiguration documentedConfiguration) {
+    public String apply(ConfigurationDocumentation documentedConfiguration) {
         List<ContainerTag> areaTags = new ArrayList<>();
         for(DocumentedArea area:documentedConfiguration.getAllAreasSorted()) {
             areaTags.addAll(createAreaEntries(area, null));
@@ -68,7 +68,7 @@ public class HtmlDocFormat implements DocFormat<String> {
         }
     }
 
-    private ContainerTag createHead(DocumentedConfiguration config) {
+    private ContainerTag createHead(ConfigurationDocumentation config) {
         return head(title("Tamaya Configuration - " + config.getName() + " " +
                         config.getVersion()),
                 meta().withCharset("utf-8"),
@@ -83,15 +83,17 @@ public class HtmlDocFormat implements DocFormat<String> {
         List<ContainerTag> propertyRows = new ArrayList<>();
         for (DocumentedProperty prop : properties) {
             propertyRows.add(tr(
-                    td(pre(prop.getName().replace(", ", 
"\n"))).attr("scope","row"),
+                    td(pre(prop.getMainKey())).attr("scope","row"),
+                    td(pre(String.join("\n", 
prop.getBackupKeys())).attr("scope","row"),
                     
td(Object.class==prop.getValueType()?"":prop.getValueType().getName()),
                     td(prop.getDescription()),
                     td(i(prop.getDefaultValue()))
-            ));
+            )));
         }
         ContainerTag propertiesTable = table(
                 thead(tr(
-                        th("Key(s)").attr("scope","col"),
+                        th("Main Key").attr("scope","col"),
+                        th("Alternate Keys").attr("scope","col"),
                         th("Valuetype").attr("scope","col"),
                         th("Description").attr("width", 
"75%").attr("scope","col"),
                         th("Default").attr("scope","col").attr("width", "15%")
@@ -104,23 +106,14 @@ public class HtmlDocFormat implements DocFormat<String> {
 
     private List<ContainerTag> createAreaEntries(DocumentedArea area, String 
parentArea) {
         List<ContainerTag> result = new ArrayList<>();
-        if(parentArea==null){
-            result.add(h4(area.getPath()));
-        }else{
-            result.add(h4(parentArea + "."+ area.getPath()));
-        }
+        result.add(h4(area.getMainBasePath()));
         result.add(ul(
                 li(b("Group Type: "), text(area.getGroupType().toString()),
                 li(b("Valuetype: "), text(area.getValueType().getName()))
                         .withCondHidden(Object.class==area.getValueType()),
                 li(b("Description: "), text(area.getDescription()))
-                        .withCondHidden(area.getDescription()==null),
-                li(b("Properties: 
")).with(createPropertiesTable(area.getPropertiesSorted(), area.getPath()))
-                        .withCondHidden(area.getProperties().isEmpty())
+                        .withCondHidden(area.getDescription()==null)
         )));
-        for(DocumentedArea subArea:area.getAreasSorted()){
-            result.addAll(createAreaEntries(subArea, area.getPath()));
-        }
         return result;
     }
 
diff --git 
a/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java 
b/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java
index 4172cb9..aa07cc0 100644
--- 
a/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java
+++ 
b/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java
@@ -19,7 +19,7 @@
 package org.apache.tamaya.doc.formats;
 
 import org.apache.tamaya.doc.DocFormat;
-import org.apache.tamaya.doc.DocumentedConfiguration;
+import org.apache.tamaya.doc.ConfigurationDocumentation;
 import org.apache.tamaya.doc.DocumentedArea;
 import org.apache.tamaya.doc.DocumentedProperty;
 
@@ -32,7 +32,7 @@ import java.util.stream.Stream;
 
 public class TextDocFormat implements DocFormat<String> {
     @Override
-    public String apply(DocumentedConfiguration documentedConfiguration) {
+    public String apply(ConfigurationDocumentation documentedConfiguration) {
         StringBuilder b = new StringBuilder();
         b.append("Configuration:\n");
         b.append("  Spec    : 
").append(documentedConfiguration.getName()).append('\n');
@@ -56,8 +56,8 @@ public class TextDocFormat implements DocFormat<String> {
     }
 
     private void printArea(String inset, DocumentedArea area, StringBuilder b) 
{
-        if(!area.getPath().isEmpty()) {
-            b.append(inset).append("- name     : 
").append(area.getPath()).append("\n");
+        if(!area.getMainBasePath().isEmpty()) {
+            b.append(inset).append("- name     : 
").append(area.getMainBasePath()).append("\n");
         }else{
             b.append(inset).append("- name     : NONE\n");
         }
@@ -78,22 +78,10 @@ public class TextDocFormat implements DocFormat<String> {
         if(area.getValueType()!=Object.class) {
             b.append(inset).append("  Value    : 
").append(area.getValueType().getName()).append('\n');
         }
-        if(!area.getProperties().isEmpty()) {
-            b.append(inset).append("  Properties : ").append('\n');
-            for (DocumentedProperty prop : area.getProperties().values()) {
-                printProperty(inset + "    ", prop, b);
-            }
-        }
-        if(!area.getAreas().isEmpty()) {
-            b.append(inset).append("  Areas   : ").append('\n');
-            for (DocumentedArea childArea : area.getAreas().values()) {
-                printArea(inset + "  ", childArea, b);
-            }
-        }
     }
 
     private void printProperty(String inset, DocumentedProperty prop, 
StringBuilder b) {
-        b.append(inset).append("- Name     : 
").append(prop.getName()).append("\n");
+        b.append(inset).append("- Name     : 
").append(prop.getKeys()).append("\n");
 //        b.append(inset).append("  Type     : property\n");
         if(prop.getOwner()!=null){
             b.append(inset).append("  Owner    : 
").append(printOwner(prop.getOwner())).append('\n');
diff --git 
a/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
 
b/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
index e6bc60f..fe7c242 100644
--- 
a/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
+++ 
b/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
@@ -22,7 +22,7 @@ import org.apache.tamaya.doc.annot.ConfigAreaSpec;
 import org.apache.tamaya.doc.annot.ConfigPropertySpec;
 import org.apache.tamaya.doc.annot.ConfigSpec;
 import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.api.ConfigSection;
 import org.apache.tamaya.spi.PropertyValue;
 
 import java.net.URL;
@@ -30,35 +30,37 @@ import java.net.URL;
 @ConfigSpec(
         name="Test",
         version="0.1.0",
-        description = "Tomcat Configuration based on Tamaya"
-)
-@ConfigAreaSpec(
-        path = "kubernetes",
-        description = "Kubernetes Settings",
-        areaType = PropertyValue.ValueType.MAP,
-        max = 1
-)
-@ConfigAreaSpec(
-        path = "kubernetes.security",
-        description = "Kubernetes Security Settings",
-        areaType = PropertyValue.ValueType.MAP,
-        max = 1
-)
-@ConfigAreaSpec(
-        path = "kubernetes.cluster",
-        description = "Kubernetes Cluster Options",
-        areaType = PropertyValue.ValueType.MAP,
-        max = 1
-)
-@ConfigAreaSpec(
-        path = "<root>",
-        description = "Main Options",
-        areaType = PropertyValue.ValueType.MAP,
+        description = "Tomcat Configuration based on Tamaya",
+        areas = {
+                @ConfigAreaSpec(
+                        basePaths = "kubernetes",
+                        description = "Kubernetes Settings",
+                        areaType = PropertyValue.ValueType.MAP,
+                        max = 1
+                ),
+                @ConfigAreaSpec(
+                        basePaths = "kubernetes.security",
+                        description = "Kubernetes Security Settings",
+                        areaType = PropertyValue.ValueType.MAP,
+                        max = 1
+                ),
+                @ConfigAreaSpec(
+                        basePaths = "kubernetes.cluster",
+                        description = "Kubernetes Cluster Options",
+                        areaType = PropertyValue.ValueType.MAP,
+                        max = 1
+                ),
+                @ConfigAreaSpec(
+                        basePaths = "<root>",
+                        description = "Main Options",
+                        areaType = PropertyValue.ValueType.MAP
+                )
+        },
         properties = {
-                @ConfigPropertySpec(name="log", description ="Log the server 
startup in detail, default: false.",
+                @ConfigPropertySpec(keys ="log", description ="Log the server 
startup in detail, default: false.",
                         valueType = Boolean.class),
-                @ConfigPropertySpec(name="refresh", description = "Refresh 
interval in millis, default: 1000ms",
-                        valueType = Long.class),
+                @ConfigPropertySpec(keys ="refresh", description = "Refresh 
interval in millis, default: 1000ms",
+                        valueType = Long.class)
         }
 )
 public interface AnnotBasedStandaloneConfigDocumentation {
@@ -67,7 +69,7 @@ public interface AnnotBasedStandaloneConfigDocumentation {
             description = "Tomcat Server Endpoints",
             min = 1,
             areaType = PropertyValue.ValueType.ARRAY)
-    @ConfigDefaultSections("servers")
+    @ConfigSection("servers")
     class Server{
         @ConfigPropertySpec(description = "The server name.")
         @Config(required = true)
diff --git 
a/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java 
b/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java
index 184c4ce..a47358a 100644
--- 
a/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java
+++ 
b/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java
@@ -21,9 +21,7 @@ package org.apache.tamaya.doc;
 import org.apache.tamaya.doc.annot.ConfigAreaSpec;
 import org.apache.tamaya.doc.annot.ConfigPropertySpec;
 import org.apache.tamaya.doc.annot.ConfigSpec;
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.NoConfig;
+import org.apache.tamaya.inject.api.*;
 import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.ArrayList;
@@ -39,18 +37,18 @@ import java.util.List;
         version="0.1.0"
 )
 @ConfigAreaSpec(
-        path="",
-        description = "Default root configuration",
-        areaType = PropertyValue.ValueType.MAP
+        description = "Server configuration options",
+        areaType = PropertyValue.ValueType.ARRAY
 )
+@ConfigSection("servers")
 public class AnnotatedDocConfigBean {
 
     @ConfigPropertySpec(description = "Tests a multi key resolution")
-    @Config(value = {"foo.bar.myprop", "mp", "common.testdata.myProperty"}, 
defaultValue = "ET")
+    @Config(key = "myProperty", alternateKeys = {"foo.bar.myprop", "mp"}, 
defaultValue = "ET")
     public String myParameter;
 
     @ConfigPropertySpec(description = "Tests a simple String description")
-    @Config("simple_value")
+    @Config(key = "simple_value")
     public String simpleValue;
 
     @ConfigPropertySpec(description = "Another test value without any explicit 
definition")
@@ -58,11 +56,11 @@ public class AnnotatedDocConfigBean {
     String anotherValue;
 
     @ConfigPropertySpec(description = "An explicit config parameter value.")
-    @Config("[host.name]")
+    @Config(key = "host.name", keyResolver = KeyResolution.ABSOLUTE)
     private String hostName;
 
     @ConfigPropertySpec(description = "An non String typed instance.")
-    @Config("host.name")
+    @Config(key = "[servers.dynamic.name]")
     private DynamicValue<String> dynamicHostname;
 
     @NoConfig
@@ -87,7 +85,7 @@ public class AnnotatedDocConfigBean {
     public static final String CONSTANT = "a constant";
 
 
-    @Config("java.version")
+    @Config(key = "java.version")
     void setJavaVersion(String version){
         this.javaVersion = version;
     }
diff --git 
a/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java 
b/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java
index 1979e74..6d90861 100644
--- 
a/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java
+++ 
b/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java
@@ -30,7 +30,7 @@ public class ConfigDocumenterTest {
     public void getDocumentationAndPrint_ConfigBean() {
         ConfigDocumenter reader = new ConfigDocumenter();
         reader.readClasses(AnnotatedDocConfigBean.class);
-        DocumentedConfiguration documentation = reader.getDocumentation();
+        ConfigurationDocumentation documentation = reader.getDocumentation();
         assertNotNull(documentation);
         System.out.println(new TextDocFormat().apply(documentation));
     }
@@ -39,7 +39,7 @@ public class ConfigDocumenterTest {
     public void getDocumentationAndPrint_AnnotationType() {
         ConfigDocumenter reader = new ConfigDocumenter();
         reader.readClasses(AnnotBasedStandaloneConfigDocumentation.class);
-        DocumentedConfiguration documentation = reader.getDocumentation();
+        ConfigurationDocumentation documentation = reader.getDocumentation();
         assertNotNull(documentation);
         System.out.println(new TextDocFormat().apply(documentation));
     }
@@ -48,7 +48,7 @@ public class ConfigDocumenterTest {
     public void getDocumentationAndPrint_Package() {
         ConfigDocumenter reader = new ConfigDocumenter();
         reader.readPackages("org.apache.tamaya.doc");
-        DocumentedConfiguration documentation = reader.getDocumentation();
+        ConfigurationDocumentation documentation = reader.getDocumentation();
         assertNotNull(documentation);
         System.out.println(new TextDocFormat().apply(documentation));
     }
@@ -57,7 +57,7 @@ public class ConfigDocumenterTest {
     public void getDocumentationAndPrint_Package_html() {
         ConfigDocumenter reader = new ConfigDocumenter();
         reader.readPackages("org.apache.tamaya.doc");
-        DocumentedConfiguration documentation = reader.getDocumentation();
+        ConfigurationDocumentation documentation = reader.getDocumentation();
         assertNotNull(documentation);
         System.out.println(new HtmlDocFormat().apply(documentation));
     }

Reply via email to