You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/08/21 02:41:46 UTC

[4/6] incubator-tamaya git commit: Implemented, moved experimental modules and added them to non experimental parts: - functions (operators and queries) - model (validation and documentation) - management (jmx bean support)

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/ConfigValidator.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/ConfigValidator.java b/modules/model/src/main/java/org/apache/tamaya/model/ConfigValidator.java
new file mode 100644
index 0000000..a6d231a
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/ConfigValidator.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.model.spi.ConfigDocumentationMBean;
+import org.apache.tamaya.model.spi.ValidationProviderSpi;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Validator accessor to validate the current configuration.
+ */
+public final class ConfigValidator {
+
+    /** The logger used. */
+    private final static Logger LOG = Logger.getLogger(ConfigValidator.class.getName());
+
+    /**
+     * Singleton constructor.
+     */
+    private ConfigValidator() {
+    }
+
+    /**
+     * Get the validations defined.
+     *
+     * @return the sections defined, never null.
+     */
+    public static Collection<Validation> getValidations() {
+        List<Validation> result = new ArrayList<>();
+        for (ValidationProviderSpi model : ServiceContextManager.getServiceContext().getServices(ValidationProviderSpi.class)) {
+            result.addAll(model.getValidations());
+        }
+        return result;
+    }
+
+    /**
+     * Find the validations by checking the validation's name using the given regular expression.
+     * @param type the target ValidationType, not null.
+     * @param namePattern the regular expression to use, not null.
+     * @return the sections defined, never null.
+     */
+    public static Collection<Validation> findValidations(ValidationType type, String namePattern) {
+        List<Validation> result = new ArrayList<>();
+        for (ValidationProviderSpi model : ServiceContextManager.getServiceContext().getServices(ValidationProviderSpi.class)) {
+            for(Validation validation: model.getValidations()) {
+                if(validation.getName().matches(namePattern) && validation.getType()==type) {
+                    result.add(validation);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Find the validations by checking the validation's name using the given regular expression.
+     * @param name the name to use, not null.
+     * @return the sections defined, never null.
+     */
+    public static <T extends Validation> T getValidation(String name, Class<T> validationType) {
+        for (ValidationProviderSpi model : ServiceContextManager.getServiceContext().getServices(ValidationProviderSpi.class)) {
+            for(Validation validation: model.getValidations()) {
+                if(validation.getName().equals(name) && validation.getClass().equals(validationType)) {
+                    return (T)validation;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Find the validations by checking the validation's name using the given regular expression.
+     * @param namePattern the regular expression to use, not null.
+     * @return the sections defined, never null.
+     */
+    public static Collection<Validation> findValidations(String namePattern) {
+        List<Validation> result = new ArrayList<>();
+        for (ValidationProviderSpi model : ServiceContextManager.getServiceContext().getServices(ValidationProviderSpi.class)) {
+            for(Validation validation: model.getValidations()) {
+                if(validation.getName().matches(namePattern)) {
+                    result.add(validation);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Validates the current configuration.
+     *
+     * @return the validation results, never null.
+     */
+    public static Collection<ValidationResult> validate() {
+        return validate(false);
+    }
+
+    /**
+     * Validates the current configuration.
+     * @param showUndefined show any unknown parameters.
+     * @return the validation results, never null.
+     */
+    public static Collection<ValidationResult> validate(boolean showUndefined) {
+        return validate(ConfigurationProvider.getConfiguration(), showUndefined);
+    }
+
+    /**
+     * Validates the given configuration.
+     *
+     * @param config the configuration to be validated against, not null.
+     * @return the validation results, never null.
+     */
+    public static Collection<ValidationResult> validate(Configuration config) {
+        return validate(config, false);
+    }
+
+    /**
+     * Validates the given configuration.
+     *
+     * @param config the configuration to be validated against, not null.
+     * @return the validation results, never null.
+     */
+    public static Collection<ValidationResult> validate(Configuration config, boolean showUndefined) {
+        List<ValidationResult> result = new ArrayList<>();
+        for (Validation defConf : getValidations()) {
+            result.addAll(defConf.validate(config));
+        }
+        if(showUndefined){
+            Map<String,String> map = new HashMap<>(config.getProperties());
+            Set<String> areas = extractTransitiveAreas(map.keySet());
+            for (Validation defConf : getValidations()) {
+                if(ValidationType.Section.equals(defConf.getType())){
+                    for (Iterator<String> iter = areas.iterator();iter.hasNext();){
+                        String area = iter.next();
+                        if(area.matches(defConf.getName())){
+                            iter.remove();
+                        }
+                    }
+                }
+                if(ValidationType.Parameter.equals(defConf.getType())){
+                    map.remove(defConf.getName());
+                }
+            }
+            outer:for(Map.Entry<String,String> entry:map.entrySet()){
+                for (Validation defConf : getValidations()) {
+                    if(ValidationType.Section.equals(defConf.getType())){
+                        if(defConf.getName().endsWith(".*") && entry.getKey().matches(defConf.getName())){
+                            // Ignore parameters that are part of transitive section.
+                            continue outer;
+                        }
+                    }
+                }
+                result.add(ValidationResult.ofUndefined(entry.getKey(), ValidationType.Parameter, null));
+            }
+            for(String area:areas){
+                result.add(ValidationResult.ofUndefined(area, ValidationType.Section, null));
+            }
+        }
+        return result;
+    }
+
+    private static java.util.Set<java.lang.String> extractTransitiveAreas(Set<String> keys) {
+        Set<String> transitiveClosure = new HashSet<>();
+        for(String key:keys){
+            int index = key.lastIndexOf('.');
+            while(index>0){
+                String areaKey = key.substring(0,index);
+                transitiveClosure.add(areaKey);
+                index = areaKey.lastIndexOf('.');
+            }
+        }
+        return transitiveClosure;
+    }
+
+
+    /**
+     * Registers the {@link ConfigDocumentationMBean} mbean for accessing config documentation into the local platform
+     * mbean server.
+     */
+    public static void registerMBean() {
+        registerMBean(null);
+    }
+
+    /**
+     * Registers the {@link ConfigDocumentationMBean} mbean for accessing config documentation into the local platform
+     * mbean server.
+     */
+    public static void registerMBean(String context) {
+        try{
+            ConfigDocumentationMBean configMbean = ServiceContextManager.getServiceContext()
+                    .getService(ConfigDocumentationMBean.class);
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+            ObjectName on = context==null?new ObjectName("org.apache.tamaya.model:type=ConfigDocumentationMBean"):
+                    new ObjectName("org.apache.tamaya.model:type=ConfigDocumentationMBean,context="+context);
+            try{
+                mbs.getMBeanInfo(on);
+                LOG.warning("Cannot register mbean " + on + ": already existing.");
+            } catch(InstanceNotFoundException e) {
+                LOG.info("Registering mbean " + on + "...");
+                mbs.registerMBean(configMbean, on);
+            }
+        } catch(Exception e){
+            LOG.log(Level.WARNING,
+                    "Failed to register ConfigDocumentationMBean.", e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/Validation.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/Validation.java b/modules/model/src/main/java/org/apache/tamaya/model/Validation.java
new file mode 100644
index 0000000..ec5113a
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/Validation.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model;
+
+import org.apache.tamaya.Configuration;
+
+import java.util.Collection;
+
+/**
+ * Basis structure describing a validated item, by default a parameter or a section.
+ */
+public interface Validation {
+
+
+    /**
+     * Get the type of item that is validated by a validation.
+     * @return the validted type, never null.
+     */
+    ValidationType getType();
+
+    /**
+     * Get the item's name, it should minimally describe the validation. Examples are:
+     * <pre>
+     *     Sections: a.b.c
+     *     Params: a.b.c.paramName
+     *     Filter: a.b.c.FilterImplClass
+     *     Dependency: mydepClassname
+     *     CombinationPolicy: a.b.c.MyCombinationPolicyClass
+     * </pre>
+     */
+    String getName();
+
+    /**
+     * CHeck if this validation is a required one.
+     * @return true, if this validation is required.
+     */
+    boolean isRequired();
+
+    /**
+     * Get the provider of this validation.
+     * @return the provider.
+     */
+    String getProvider();
+
+    /**
+     * Get an description of the item, using the default locale. The description is basically optional
+     * though it is higly recommended to provide a description, so the validation issues is well
+     * resolvable.
+     *
+     * @return the description required, or null.
+     */
+    String getDescription();
+
+    /**
+     * Validates the item and all its children against the given configuration.
+     *
+     * @param config the configuration to be validated against, not null.
+     * @return the validation results, never null.
+     */
+    Collection<ValidationResult> validate(Configuration config);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/ValidationResult.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/ValidationResult.java b/modules/model/src/main/java/org/apache/tamaya/model/ValidationResult.java
new file mode 100644
index 0000000..3c86edf
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/ValidationResult.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.model.spi.AbstractValidation;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+
+/**
+ * Models a partial configuration validation result.
+ */
+public final class ValidationResult {
+    /**
+     * the config section.
+     */
+    private Validation validation;
+    /**
+     * The validation result.
+     */
+    private ValidationState result;
+    /**
+     * The validation message.
+     */
+    private String message;
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofValid(Validation validation) {
+        return new ValidationResult(validation, ValidationState.VALID, null);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofMissing(Validation validation) {
+        return new ValidationResult(validation, ValidationState.MISSING, null);
+    }
+
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     *                   @param message Additional message to be shown (optional).
+     */
+    public static ValidationResult ofMissing(Validation validation, String message) {
+        return new ValidationResult(validation, ValidationState.MISSING, message);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofError(Validation validation, String error) {
+        return new ValidationResult(validation, ValidationState.ERROR, error);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofWarning(Validation validation, String warning) {
+        return new ValidationResult(validation, ValidationState.WARNING, warning);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofDeprecated(Validation validation, String alternateUsage) {
+        return new ValidationResult(validation, ValidationState.DEPRECATED, alternateUsage != null ? "Use instead: " + alternateUsage : null);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param validation the validation item, not null.
+     */
+    public static ValidationResult ofDeprecated(Validation validation) {
+        return new ValidationResult(validation, ValidationState.DEPRECATED, null);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param key the name/key
+     * @return a corresponding validation item
+     */
+    public static ValidationResult ofUndefined(final String key, final ValidationType type, String provider) {
+        return new ValidationResult(new AbstractValidation(key, false, "Undefined key: " + key, provider) {
+
+            @Override
+            public ValidationType getType() {
+                return type;
+            }
+
+            @Override
+            public Collection<ValidationResult> validate(Configuration config) {
+                return Collections.emptySet();
+            }
+        }, ValidationState.UNDEFINED, null);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param validation the validation item, not null.
+     * @param result     the validation result, not null.
+     * @param message    the detail message.
+     */
+    public static ValidationResult of(Validation validation, ValidationState result, String message) {
+        return new ValidationResult(validation, result, message);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param validation the validation item, not null.
+     * @param result     the validation result, not null.
+     * @param message    the detail message.
+     */
+    private ValidationResult(Validation validation, ValidationState result, String message) {
+        this.message = message;
+        this.validation = Objects.requireNonNull(validation);
+        this.result = Objects.requireNonNull(result);
+    }
+
+    /**
+     * Get the validation section.
+     *
+     * @return the section, never null.
+     */
+    public Validation getValidation() {
+        return validation;
+    }
+
+    /**
+     * Get the validation result.
+     *
+     * @return the result, never null.
+     */
+    public ValidationState getResult() {
+        return result;
+    }
+
+    /**
+     * Get the detail message.
+     *
+     * @return the detail message, or null.
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    @Override
+    public String toString() {
+        if (message != null) {
+            return result + ": " + validation.getName() + " (" + validation.getType() + ") -> " + message + '\n';
+        }
+        return result + ": " + validation.getName() + " (" + validation.getType() + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/ValidationState.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/ValidationState.java b/modules/model/src/main/java/org/apache/tamaya/model/ValidationState.java
new file mode 100644
index 0000000..0170085
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/ValidationState.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model;
+
+/**
+ * Enum type describing the different validation results supported.
+ */
+public enum ValidationState {
+    /**
+     * The validated item is valid
+     */
+    VALID,
+    /**
+     * The validated item is deprecated.
+     */
+    DEPRECATED,
+    /**
+     * The validated item is correct, but the value is worth a warning.
+     */
+    WARNING,
+    /**
+     * The given section or parameter is not a defined/validated item. It may be still valid, but typically,
+     * when validation is fully implemented, such a parametr or section should be removed.
+     */
+    UNDEFINED,
+    /**
+     * A required parameter or section is missing.
+     */
+    MISSING,
+    /**
+     * The validated item has an invalid value.
+     */
+    ERROR;
+
+    /**
+     * Method to quickly evaluate if the current state is an error state.
+     *
+     * @return true, if the state is not ERROR or MISSING.
+     */
+    boolean isError() {
+        return this.ordinal() == MISSING.ordinal() || this.ordinal() == ERROR.ordinal();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/ValidationType.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/ValidationType.java b/modules/model/src/main/java/org/apache/tamaya/model/ValidationType.java
new file mode 100644
index 0000000..f916032
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/ValidationType.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model;
+
+/**
+ * This enumeration defines the types of supported validations.
+ */
+public enum ValidationType {
+    /**
+     * A configuration section.
+     */
+    Section,
+    /**
+     * A configuration paramter.
+     */
+    Parameter,
+    /**
+     * Validation to ensure a certain configuration filter is installed.
+     */
+    Filter,
+    /**
+     * Validation to ensure a certain combination policy is active.
+     */
+    CombinationPolicy,
+    /**
+     * Validation that is a container of other validations.
+     */
+    Group,
+    /**
+     * Validation to simply check availability for a class on the current classpath.
+     */
+    LoadableClass
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfigDocumentationBean.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfigDocumentationBean.java b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfigDocumentationBean.java
new file mode 100644
index 0000000..1c20bea
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfigDocumentationBean.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.model.ConfigValidator;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.ValidationResult;
+import org.apache.tamaya.model.ValidationType;
+import org.apache.tamaya.model.spi.ConfigDocumentationMBean;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+import javax.json.stream.JsonGenerator;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MBean implementation of {@link ConfigDocumentationMBean}.
+ */
+public class ConfigDocumentationBean implements ConfigDocumentationMBean{
+
+    private final JsonWriterFactory writerFactory;
+
+    private static final Comparator<ValidationResult> COMPARATOR = new Comparator<ValidationResult>() {
+        @Override
+        public int compare(ValidationResult v1, ValidationResult v2) {
+            int compare = VAL_COMPARATOR.compare(v1.getValidation(), v2.getValidation());
+            if(compare==0){
+                compare = v1.getResult().compareTo(v2.getResult());
+            }
+            if(compare==0){
+                return v1.getMessage().compareTo(v2.getMessage());
+            }
+            return compare;
+        }
+    };
+    private static final Comparator<Validation> VAL_COMPARATOR = new Comparator<Validation>() {
+        @Override
+        public int compare(Validation v1, Validation v2) {
+            int compare = v1.getType().compareTo(v2.getType());
+            if(compare==0){
+                compare = v1.getName().compareTo(v2.getName());
+            }
+            return compare;
+        }
+    };
+
+    private Configuration config;
+
+    /**
+     * Default constructor, using the current configuration being available.
+     */
+    public ConfigDocumentationBean(){
+        this(null);
+    }
+
+
+    /**
+     * Creates an mbean bound to the given configuration. This is useful, when multiple mbeans for each
+     * context should be used, e.g. one mbean per ear, app deployment.
+     * @param config the configuration to be used.
+     */
+    public ConfigDocumentationBean(Configuration config){
+        this.config = config;
+        Map<String, Object> writerProperties = new HashMap<>(1);
+        writerProperties.put(JsonGenerator.PRETTY_PRINTING, true);
+        writerFactory = Json.createWriterFactory(writerProperties);
+    }
+
+    /**
+     * Access the configuration.
+     * @return either the configuration bound to this bean, or the current configuration.
+     */
+    private Configuration getConfig(){
+        return config!=null?config: ConfigurationProvider.getConfiguration();
+    }
+
+    @Override
+    public String validate(boolean showUndefined) {
+        List<ValidationResult> validations = new ArrayList<>(ConfigValidator.validate(getConfig(), showUndefined));
+        Collections.sort(validations, COMPARATOR);
+        JsonArrayBuilder builder = Json.createArrayBuilder();
+        for(ValidationResult val:validations){
+            builder.add(toJsonObject(val));
+        }
+        return formatJson(builder.build());
+    }
+
+
+
+    @Override
+    public String getConfigurationModel() {
+        List<Validation> validations = new ArrayList<>(ConfigValidator.getValidations());
+        Collections.sort(validations, VAL_COMPARATOR);
+        JsonArrayBuilder result = Json.createArrayBuilder();
+        for(Validation val:validations){
+            result.add(toJsonObject(val));
+        }
+        return formatJson(result.build());
+    }
+
+    @Override
+    public String getConfigurationModel(ValidationType type) {
+        return findValidationModels(type, ".*");
+    }
+
+    @Override
+    public String findConfigurationModels(String namePattern) {
+        List<Validation> validations = new ArrayList<>(ConfigValidator.findValidations(namePattern));
+        Collections.sort(validations, VAL_COMPARATOR);
+        JsonArrayBuilder result = Json.createArrayBuilder();
+        for(Validation val:validations){
+            result.add(toJsonObject(val));
+        }
+        return formatJson(result.build());
+    }
+
+    @Override
+    public String findValidationModels(ValidationType type, String namePattern) {
+        List<Validation> validations = new ArrayList<>(ConfigValidator.findValidations(type, namePattern));
+        Collections.sort(validations, VAL_COMPARATOR);
+        JsonArrayBuilder result = Json.createArrayBuilder();
+        for(Validation val:validations){
+            result.add(toJsonObject(val));
+        }
+        return formatJson(result.build());
+    }
+
+    @Override
+    public String toString(){
+        return "ConfigDocumentationBean, config: " + (this.config!=null?this.config.toString():"<current>");
+    }
+
+
+    private JsonObject toJsonObject(Validation val) {
+        JsonObjectBuilder valJson = Json.createObjectBuilder().add("type", val.getType().toString())
+                .add("name", val.getName());
+        if(val.getDescription()!=null) {
+            valJson.add("description", val.getDescription());
+        }
+        if(val.isRequired()){
+            valJson.add("required",true);
+        }
+        return valJson.build();
+    }
+
+    private JsonObject toJsonObject(ValidationResult val) {
+        JsonObjectBuilder valJson = Json.createObjectBuilder().add("type", val.getValidation().getType().toString())
+                .add("name", val.getValidation().getName());
+        if(val.getValidation().isRequired()){
+            valJson.add("required",true);
+        }
+        if(val.getValidation().getDescription() != null){
+            valJson.add("description", val.getValidation().getDescription());
+        }
+        valJson.add("result", val.getResult().toString());
+        if( val.getMessage() != null) {
+            valJson.add("message", val.getMessage());
+        }
+        return valJson.build();
+    }
+
+    private String formatJson(JsonArray data) {
+        StringWriter writer = new StringWriter();
+        JsonWriter gen = writerFactory.createWriter(writer);
+        gen.writeArray(data);
+        return writer.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredInlineModelProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredInlineModelProviderSpi.java b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredInlineModelProviderSpi.java
new file mode 100644
index 0000000..1eb7e8c
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredInlineModelProviderSpi.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.internal;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.spi.ConfigValidationsReader;
+import org.apache.tamaya.model.spi.ValidationProviderSpi;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Validation provider that reads model metadata from the current {@link org.apache.tamaya.Configuration}.
+ */
+public class ConfiguredInlineModelProviderSpi implements ValidationProviderSpi {
+
+    /** The logger. */
+    private static final Logger LOG = Logger.getLogger(ConfiguredInlineModelProviderSpi.class.getName());
+    /** parameter to disable this provider. By default the provider is active. */
+    private static final String MODEL_EANABLED_PARAM = "org.apache.tamaya.model.integrated.enabled";
+
+    /** The validations read. */
+    private List<Validation> validations = new ArrayList<>();
+
+
+    /**
+     * Constructor, typically called by the {@link java.util.ServiceLoader}.
+     */
+    public ConfiguredInlineModelProviderSpi() {
+        String enabledVal = ConfigurationProvider.getConfiguration().get(MODEL_EANABLED_PARAM);
+        boolean enabled = enabledVal==null? true: "true".equalsIgnoreCase(enabledVal);
+        if (enabled) {
+            LOG.info("Reading model configuration from config...");
+            Map<String,String> config = ConfigurationProvider.getConfiguration().getProperties();
+            validations.addAll(ConfigValidationsReader.loadValidations(config,
+                    "<Inline Configuration Model>"));
+        }
+        validations = Collections.unmodifiableList(validations);
+    }
+
+
+    @Override
+    public Collection<Validation> getValidations() {
+        return validations;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredPropertiesValidationProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredPropertiesValidationProviderSpi.java b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredPropertiesValidationProviderSpi.java
new file mode 100644
index 0000000..41157ac
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredPropertiesValidationProviderSpi.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.internal;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.spi.ConfigValidationsReader;
+import org.apache.tamaya.model.spi.ValidationProviderSpi;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Validation provider that reads model metadata from property files from
+ * {@code classpath*:META-INF/configmodel.properties} in the following format:
+ * <pre>
+ * ###################################################################################
+ * # Example of a configuration metamodel expressed via properties.
+ * ####################################################################################
+ *
+ * # Metamodel information
+ * [model].provider=ConfigModel Extension
+ *
+ * ####################################################################################
+ * # Description of Configuration Sections (minimal, can be extended by other modules).
+ * # By default its interpreted as a section !
+ * ####################################################################################
+ *
+ * # a (section)
+ * {model}a.class=Section
+ * {model}a.params2.class=Parameter
+ * {model}a.params2.type=String
+ * {model}a.params2.required=true
+ * {model}a.params2.description=a required parameter
+ *
+ * {model}a.paramInt.class=Parameter
+ * {model}a.paramInt.ref=MyNumber
+ * {model}a.paramInt.description=an optional parameter (default)
+ *
+ * {model}a._number.class=Parameter
+ * {model}a._number.type=Integer
+ * {model}a._number.deprecated=true
+ * {model}a._number.mappedTo=a.paramInt
+ *
+ * # a.b.c (section)
+ * {model}a.b.c.class=Section
+ * {model}a.b.c.description=Just a test section
+ *
+ * # a.b.c.aRequiredSection (section)
+ * {model}a.b.c.aRequiredSection.class=Section
+ * {model}a.b.c.aRequiredSection.required=true
+ * {model}a.b.c.aRequiredSection.description=A section containing required parameters is called a required section.\
+ * Sections can also explicitly be defined to be required, but without\
+ * specifying the paramteres to be contained.,
+ *
+ * # a.b.c.aRequiredSection.subsection (section)
+ * {model}a.b.c.aRequiredSection.subsection.class=Section
+ *
+ * {model}a.b.c.aRequiredSection.subsection.param0.class=Parameter
+ * {model}a.b.c.aRequiredSection.subsection.param0.type=String
+ * {model}a.b.c.aRequiredSection.subsection.param0.description=a minmally documented String parameter
+ * # A minmal String parameter
+ * {model}a.b.c.aRequiredSection.subsection.param00.class=Parameter
+ * {model}a.b.c.aRequiredSection.subsection.param00.type=String
+ *
+ * # a.b.c.aRequiredSection.subsection (section)
+ * {model}a.b.c.aRequiredSection.subsection.param1.class=Parameter
+ * {model}a.b.c.aRequiredSection.subsection.param1.type = String
+ * {model}a.b.c.aRequiredSection.subsection.param1.required = true
+ * {model}a.b.c.aRequiredSection.subsection.intParam.class=Parameter
+ * {model}a.b.c.aRequiredSection.subsection.intParam.type = Integer
+ * {model}a.b.c.aRequiredSection.subsection.intParam.description=an optional parameter (default)
+ *
+ * # a.b.c.aRequiredSection.nonempty-subsection (section)
+ * {model}a.b.c.aRequiredSection.nonempty-subsection.class=Section
+ * {model}a.b.c.aRequiredSection.nonempty-subsection.required=true
+ *
+ * # a.b.c.aRequiredSection.optional-subsection (section)
+ * {model}a.b.c.aRequiredSection.optional-subsection.class=Section
+ *
+ * # a.b.c.aValidatedSection (section)
+ * {model}a.b.c.aValidatedSection.class=Section
+ * {model}a.b.c.aValidatedSection.description=A validated section.
+ * {model}a.b.c.aValidatedSection.validations=org.apache.tamaya.model.TestValidator
+ * </pre>
+ */
+public class ConfiguredPropertiesValidationProviderSpi implements ValidationProviderSpi {
+
+    /** The logger. */
+    private static final Logger LOG = Logger.getLogger(ConfiguredPropertiesValidationProviderSpi.class.getName());
+    /** parameter to disable this provider. By default the provider is active. */
+    private static final String MODEL_EANABLED_PARAM = "org.apache.tamaya.model.default.enabled";
+    /** The validations read. */
+    private List<Validation> validations = new ArrayList<>();
+
+    public ConfiguredPropertiesValidationProviderSpi() {
+        String enabledVal = ConfigurationProvider.getConfiguration().get(MODEL_EANABLED_PARAM);
+        boolean enabled = enabledVal==null? true: "true".equalsIgnoreCase(enabledVal);
+        if(!enabled){
+            LOG.info("Reading model data from META-INF/configmodel.properties has been disabled.");
+            return;
+        }
+        try {
+            LOG.info("Reading model data from META-INF/configmodel.properties...");
+            Enumeration<URL> configs = getClass().getClassLoader().getResources("META-INF/configmodel.properties");
+            while (configs.hasMoreElements()) {
+                URL config = configs.nextElement();
+                try (InputStream is = config.openStream()) {
+                    Properties props = new Properties();
+                    props.load(is);
+                    validations.addAll(ConfigValidationsReader.loadValidations(props, config.toString()));
+                } catch (Exception e) {
+                    Logger.getLogger(getClass().getName()).log(Level.SEVERE,
+                            "Error loading config metadata from " + config, e);
+                }
+            }
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE,
+                    "Error loading config metadata from META-INF/configmodel.properties", e);
+        }
+        validations = Collections.unmodifiableList(validations);
+    }
+
+
+    @Override
+    public Collection<Validation> getValidations() {
+        return validations;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredResourcesModelProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredResourcesModelProviderSpi.java b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredResourcesModelProviderSpi.java
new file mode 100644
index 0000000..577ce44
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/internal/ConfiguredResourcesModelProviderSpi.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.internal;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationFormats;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.spi.ConfigValidationsReader;
+import org.apache.tamaya.model.spi.ValidationProviderSpi;
+import org.apache.tamaya.resource.ConfigResources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Validation provider that reads model metadata from property files from
+ * {@code classpath*:META-INF/configmodel.json} in the following format:
+ * <pre>
+ * </pre>
+ */
+public class ConfiguredResourcesModelProviderSpi implements ValidationProviderSpi {
+
+    /** The logger. */
+    private static final Logger LOG = Logger.getLogger(ConfiguredResourcesModelProviderSpi.class.getName());
+    /** The parameter that can be used to configure the location of the configuration model resources. */
+    private static final String MODEL_RESOURCE_PARAM = "org.apache.tamaya.model.resources";
+    /** The resource class to checked for testing the availability of the resources extension module. */
+    private static final String CONFIG_RESOURCE_CLASS = "org.apache.tamaya.resource.ConfigResource";
+    /** The resource class to checked for testing the availability of the formats extension module. */
+    private static final String CONFIGURATION_FORMATS_CLASS = "org.apache.tamaya.format.ConfigurationFormats";
+    /** Initializes the flag showing if the formats module is present (required). */
+    private static boolean available = checkAvailabilityFormats();
+    /** Initializes the flag showing if the resources module is present (optional). */
+    private static boolean resourcesExtensionAvailable = checkAvailabilityResources();
+
+    /** The validations read. */
+    private List<Validation> validations = new ArrayList<>();
+
+    /** Initializes the flag showing if the formats module is present (required). */
+    private static boolean checkAvailabilityFormats() {
+        try {
+            Class.forName(CONFIGURATION_FORMATS_CLASS);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /** Initializes the flag showing if the resources module is present (optional). */
+    private static boolean checkAvailabilityResources() {
+        try {
+            Class.forName(CONFIG_RESOURCE_CLASS);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * Constructor, mostly called from {@link java.util.ServiceLoader}
+     */
+    public ConfiguredResourcesModelProviderSpi() {
+        if (!available) {
+            LOG.info("tamaya-format extension is required to read model configuration, No extended model support available.");
+        } else {
+            String resources = ConfigurationProvider.getConfiguration().get(MODEL_RESOURCE_PARAM);
+            if(resources==null || resources.trim().isEmpty()){
+                LOG.info("Mo model resources location configured in " + MODEL_RESOURCE_PARAM + ".");
+                return;
+            }
+            Collection<URL> urls;
+            if(resourcesExtensionAvailable){
+                LOG.info("Using tamaya-resources extension to read model configuration from " + resources);
+                urls = ConfigResources.getResourceResolver().getResources(resources.split(","));
+            } else{
+                LOG.info("Using default classloader resource location to read model configuration from " + resources);
+                urls = new ArrayList<>();
+                for(String resource:resources.split(",")){
+                    if(!resource.trim().isEmpty()){
+                        Enumeration<URL> configs = null;
+                        try {
+                            configs = getClass().getClassLoader().getResources(resource);
+                            while (configs.hasMoreElements()) {
+                                urls.add(configs.nextElement());
+                            }
+                        } catch (IOException e) {
+                            Logger.getLogger(getClass().getName()).log(Level.SEVERE,
+                                    "Error evaluating config model locations from "+resource, e);
+                        }
+                    }
+                }
+            }
+            // Reading configs
+            for(URL config:urls){
+                try (InputStream is = config.openStream()) {
+                    ConfigurationData data = ConfigurationFormats.readConfigurationData(config);
+                    validations.addAll(ConfigValidationsReader.loadValidations(data.getCombinedProperties(), config.toString()));
+                } catch (Exception e) {
+                    Logger.getLogger(getClass().getName()).log(Level.SEVERE,
+                            "Error loading config model data from " + config, e);
+                }
+            }
+        }
+        validations = Collections.unmodifiableList(validations);
+    }
+
+
+    @Override
+    public Collection<Validation> getValidations() {
+        return validations;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/AbstractValidation.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/AbstractValidation.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/AbstractValidation.java
new file mode 100644
index 0000000..d411198
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/AbstractValidation.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.model.Validation;
+
+import java.util.Objects;
+
+/**
+ * Default configuration Model for a configuration area.
+ */
+public abstract class AbstractValidation implements Validation, Comparable<Validation> {
+
+    private String name;
+    private String provider;
+    private String description;
+    private boolean required = false;
+
+
+    protected AbstractValidation(String name, boolean required, String description, String provider) {
+        this.name = Objects.requireNonNull(name);
+        this.description = description;
+        this.required = required;
+        this.provider = provider;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getProvider() {
+        return provider;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public boolean isRequired() {
+        return required;
+    }
+
+    @Override
+    public int compareTo(Validation validation) {
+        int compare = getType().compareTo(validation.getType());
+        if (compare != 0) {
+            return compare;
+        }
+        return getName().compareTo(validation.getName());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        AbstractValidation that = (AbstractValidation) o;
+        return getType().equals(that.getType()) && name.equals(that.name);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return getType().hashCode() + name.hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/AreaValidation.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/AreaValidation.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/AreaValidation.java
new file mode 100644
index 0000000..efef5a3
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/AreaValidation.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.model.ValidationResult;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.ValidationType;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Default configuration Model for a configuration section.
+ */
+public class AreaValidation extends ValidationGroup {
+
+    /**
+     * Creates a new builder.
+     * @param name the section name.
+     * @return a new builder instance.
+     */
+    public static Builder builder(String name){
+        return new Builder(name);
+    }
+
+    /**
+     * Creates a section validation for the given section.
+     * @param name the fully qualified section name
+     * @param required flag, if the section is required to be present.
+     * @return the Validation instance
+     */
+    public static Validation of(String name, boolean required){
+        return new Builder(name).setRequired(required).build();
+    }
+
+    /**
+     * Creates a section validation for the given section.
+     * @param name the fully qualified section name
+     * @param required flag, if the section is required to be present.
+     * @param validations additional validations
+     * @return
+     */
+    public static Validation of(String name, boolean required, Validation... validations){
+        return new Builder(name).setRequired(required).addValidations(validations).build();
+    }
+
+    /**
+     * Internal constructor.
+     * @param builder the builder, not null.
+     */
+    protected AreaValidation(Builder builder) {
+        super(builder.name, builder.provider, builder.childValidations);
+    }
+
+    @Override
+    public ValidationType getType(){
+        return ValidationType.Section;
+    }
+
+    @Override
+    public Collection<ValidationResult> validate(Configuration config) {
+        Map<String,String> map = config.getProperties();
+        String lookupKey = getName() + '.';
+        boolean present = false;
+        for(String key:map.keySet()){
+            if(key.startsWith(lookupKey)){
+                present = true;
+                break;
+            }
+        }
+        List<ValidationResult> result = new ArrayList<>(1);
+        if(isRequired() && !present) {
+            result.add(ValidationResult.ofMissing(this));
+        }
+        result.addAll(super.validate(config));
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append(getType()).append(": " + getName());
+        if(isRequired()) {
+            b.append(", required: " + isRequired());
+        }
+        for(Validation val:getValidations()){
+             b.append(", ").append(val.toString());
+        }
+        return b.toString();
+    }
+
+    /**
+     * Builder for setting up a AreaValidation instance.
+     */
+    public static class Builder{
+        /** The section name. */
+        private String name;
+        /** The optional provider. */
+        private String provider;
+        /** The optional description. */
+        private String description;
+        /** The required flag. */
+        private boolean required;
+        /** The (optional) custom validations.*/
+        private List<Validation> childValidations = new ArrayList<>();
+
+        /**
+         * Creates a new Builder.
+         * @param sectionName the section name, not null.
+         */
+        public Builder(String sectionName){
+            this.name = Objects.requireNonNull(sectionName);
+        }
+
+        /**
+         * Add validations.
+         * @param validations the validations, not null.
+         * @return the Builder for chaining.
+         */
+        public Builder addValidations(Validation... validations){
+            this.childValidations.addAll(Arrays.asList(validations));
+            return this;
+        }
+
+        /**
+         * Add validations.
+         * @param validations the validations, not null.
+         * @return the Builder for chaining.
+         */
+        public Builder addValidations(Collection<Validation> validations){
+            this.childValidations.addAll(validations);
+            return this;
+        }
+
+        /**
+         * Sets the required flag.
+         * @param required zhe flag.
+         * @return the Builder for chaining.
+         */
+        public Builder setRequired(boolean required){
+            this.required = required;
+            return this;
+        }
+
+        /**
+         * Set the )optional) description.
+         * @param description the description.
+         * @return the Builder for chaining.
+         */
+        public Builder setDescription(String description){
+            this.description = description;
+            return this;
+        }
+
+        /**
+         * Set the )optional) provider.
+         * @param provider the provider.
+         * @return the Builder for chaining.
+         */
+        public Builder setProvider(String provider){
+            this.provider = provider;
+            return this;
+        }
+
+        /**
+         * Set the section name
+         * @param name the section name, not null.
+         * @return the Builder for chaining.
+         */
+        public Builder setName(String name){
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Build a new Validation instance.
+         * @return the new Validation instance, not null.
+         */
+        public Validation build(){
+            return new AreaValidation(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigDocumentationMBean.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigDocumentationMBean.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigDocumentationMBean.java
new file mode 100644
index 0000000..842d0e9
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigDocumentationMBean.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.model.ValidationType;
+
+/**
+ * JMX Management bean for accessing current configuration information
+ */
+public interface ConfigDocumentationMBean {
+    /**
+     * Validates the configuration for the given context.
+     *
+     * @return the validation results, never null.
+     */
+    public String validate(boolean showUndefined);
+
+    public String getConfigurationModel();
+
+    public String getConfigurationModel(ValidationType type);
+
+    /**
+     * Find the validations by checking the validation's name using the given regular expression.
+     * @param namePattern the regular expression to use, not null.
+     * @return the sections defined, never null.
+     */
+    public String findConfigurationModels(String namePattern);
+
+    /**
+     * Find the validations by checking the validation's name using the given regular expression.
+     * @param type the target ValidationType, not null.
+     * @param namePattern the regular expression to use, not null.
+     * @return the sections defined, never null.
+     */
+    public String findValidationModels(ValidationType type, String namePattern);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigValidationsReader.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigValidationsReader.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigValidationsReader.java
new file mode 100644
index 0000000..9a720dc
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/ConfigValidationsReader.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.model.Validation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * Utility class to read metamodel information from properties. Hereby these properties can be part of a
+ * configuration (containing other entriees as well) or be dedicated model definition properties read
+ * from any kind of source.
+ */
+public final class ConfigValidationsReader {
+
+    /** The logger used. */
+    private static final Logger LOGGER =  Logger.getLogger(ConfigValidationsReader.class.getName());
+
+    /** The default model entries selector. */
+    private static final String DEFAULT_META_INFO_SELECTOR = "{model}";
+    /** parameter to change the selector to be used for filtering out the target values to be used. */
+    private static final String META_INFO_SELECTOR_PARAM = "org.apache.tamaya.model.integrated.selector";
+
+    /**
+     * Utility class only.
+     */
+    private ConfigValidationsReader(){}
+
+    /**
+     * Loads validations as configured in the given properties.
+     * @param props the properties to be read
+     * @param defaultProviderName the default provider name used if no explicit provider name is configured.
+     * @return a collection of config validations.
+     */
+    public static Collection<Validation> loadValidations(Properties props,
+                                                         String defaultProviderName) {
+        Map<String,String> map = new HashMap<>();
+        for(Map.Entry<Object,Object> en: props.entrySet()){
+            map.put(en.getKey().toString(), props.getProperty(en.getKey().toString()));
+        }
+        return loadValidations(map, defaultProviderName);
+    }
+
+    /**
+     * Loads validations as configured in the given properties.
+     * @param props the properties to be read
+     * @param defaultProviderName the default provider name used if no explicit provider name is configured.
+     * @return a collection of config validations.
+     */
+    public static Collection<Validation> loadValidations(Map<String,String> props,
+                                                         String defaultProviderName) {
+        String selector = props.get(META_INFO_SELECTOR_PARAM);
+        if(selector==null){
+            selector = DEFAULT_META_INFO_SELECTOR;
+        }
+        return loadValidations(props, selector, defaultProviderName);
+    }
+
+    /**
+     * Loads validations as configured in the given properties.
+     * @param props the properties to be read
+     * @param selector the selector (default is {model}), that identifies the model entries.
+     * @param defaultProviderName the default provider name used if no explicit provider name is configured.
+     * @return a collection of config validations.
+     */
+    public static Collection<Validation> loadValidations(Map<String,String> props, String selector,
+                                                         String defaultProviderName) {
+        List<Validation> result = new ArrayList<>();
+        String provider = props.get(selector + ".__provider");
+        if (provider == null) {
+            provider = defaultProviderName;
+        }
+        Set<String> itemKeys = new HashSet<>();
+        for (Object key : props.keySet()) {
+            if (key.toString().endsWith(".class")) {
+                itemKeys.add(key.toString().substring(0, key.toString().length() - ".class".length()));
+            }
+        }
+        for (String baseKey : itemKeys) {
+            String clazz = props.get(baseKey + ".class");
+            String type = props.get(baseKey + ".type");
+            if (type == null) {
+                type = String.class.getName();
+            }
+            String value = props.get(baseKey + ".transitive");
+            boolean transitive = false;
+            if(value!=null) {
+                transitive = Boolean.parseBoolean(value);
+            }
+            String description = props.get(baseKey + ".description");
+            String regEx = props.get(baseKey + ".expression");
+            String validations = props.get(baseKey + ".validations");
+            String requiredVal = props.get(baseKey + ".required");
+            if ("Parameter".equalsIgnoreCase(clazz)) {
+                result.add(createParameterValidation(baseKey.substring(selector.length() + 1), description, type,
+                            requiredVal, regEx, validations, provider));
+            } else if ("Section".equalsIgnoreCase(clazz)) {
+                if(transitive){
+                    result.add(createSectionValidation(baseKey.substring(selector.length() + 1)+".*", description, requiredVal,
+                            validations, provider));
+                } else {
+                    result.add(createSectionValidation(baseKey.substring(selector.length() + 1), description, requiredVal,
+                            validations, provider));
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Creates a parameter validation.
+     * @param paramName the param name, not null.
+     * @param description the optional description
+     * @param type the param type, default is String.
+     * @param reqVal the required value, default is 'false'.
+     * @param regEx an optional regular expression to be checked for this param
+     * @param validations the optional custom validations to be performed.
+     * @return the new validation for this parameter.
+     */
+    private static Validation createParameterValidation(String paramName, String description, String type, String reqVal,
+                                                       String regEx, String validations, String provider) {
+        boolean required = "true".equalsIgnoreCase(reqVal);
+        ParameterValidation.Builder builder = ParameterValidation.builder(paramName).setRequired(required)
+                .setDescription(description).setExpression(regEx).setType(type).setProvider(provider);
+//        if (validations != null) {
+//            try {
+//                // TODO defined validator API
+////                builder.addValidations(loadValidations(validations));
+//            } catch (Exception e) {
+//                LOGGER.log(Level.WARNING, "Failed to load validations for " + paramName, e);
+//            }
+//        }
+       return builder.build();
+    }
+
+    /**
+     * Creates a section validation.
+     * @param sectionName the section's name, not null.
+     * @param description the optional description
+     * @param reqVal the required value, default is 'false'.
+     * @param validations the optional custom validations to be performed.
+     * @return the new validation for this section.
+     */
+    private static Validation createSectionValidation(String sectionName, String description, String reqVal,
+                                                     String validations, String provider) {
+        boolean required = "true".equalsIgnoreCase(reqVal);
+        AreaValidation.Builder builder = AreaValidation.builder(sectionName).setRequired(required)
+                .setDescription(description).setProvider(provider);
+//        if (validations != null) {
+//            try {
+//                // TODO defined validator API
+////                builder.addValidations(loadValidations(valiadtions));
+//            } catch (Exception e) {
+//                LOGGER.log(Level.WARNING, "Failed to load validations for " + sectionName, e);
+//            }
+//        }
+        return builder.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/ParameterValidation.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/ParameterValidation.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/ParameterValidation.java
new file mode 100644
index 0000000..59444f7
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/ParameterValidation.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.ValidationResult;
+import org.apache.tamaya.model.ValidationType;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Default configuration Model for a configuration parameter.
+ */
+public class ParameterValidation extends AbstractValidation {
+    /** Optional regular expression for validating the value. */
+    private String regEx;
+    /** The target type into which the value must be convertible. */
+    private Class type;
+
+    /**
+     * Internal constructor.
+     * @param builder the builder, not null.
+     */
+    protected ParameterValidation(Builder builder) {
+        super(builder.name, builder.required, builder.description, builder.provider);
+        this.regEx = builder.regEx;
+        this.type = builder.type;
+    }
+
+    @Override
+    public ValidationType getType() {
+        return ValidationType.Parameter;
+    }
+
+    /**
+     * Get the required parameter type.
+     *
+     * @return the type.
+     */
+    public Class getParameterType() {
+        return type;
+    }
+
+    @Override
+    public Collection<ValidationResult> validate(Configuration config) {
+        List<ValidationResult> result = new ArrayList<>(1);
+        String configValue = config.get(getName());
+        if (configValue == null && isRequired()) {
+            result.add(ValidationResult.ofMissing(this));
+        }
+        if (configValue != null && regEx != null) {
+            if (!configValue.matches(regEx)) {
+                result.add(ValidationResult.ofError(this, "Config value not matching expression: " + regEx + ", was " +
+                        configValue));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append(getType()).append(": ").append(getName());
+        if (isRequired()) {
+            b.append(", required: " + isRequired());
+        }
+        if (regEx != null) {
+            b.append(", expression: " + regEx);
+        }
+        return b.toString();
+    }
+
+    /**
+     * Creates a new Builder instance.
+     * @param name the fully qualified parameter name.
+     * @return
+     */
+    public static Builder builder(String name) {
+        return new Builder(name);
+    }
+
+    /**
+     * Creates a new Validation
+     * @param name the fully qualified parameter name.
+     * @param required the required flag.
+     * @param expression an optional regular expression to validate a value.
+     * @return the new Validation instance.
+     */
+    public static Validation of(String name, boolean required, String expression) {
+        return new Builder(name).setRequired(required).setExpression(expression).build();
+    }
+
+    /**
+     * Creates a new Validation
+     * @param name the fully qualified parameter name.
+     * @param required the required flag.
+     * @return the new Validation instance.
+     */
+    public static Validation of(String name, boolean required) {
+        return new Builder(name).setRequired(required).build();
+    }
+
+    /**
+     * Creates a new Validation. The parameter will be defined as optional.
+     * @param name the fully qualified parameter name.
+     * @return the new Validation instance.
+     */
+    public static Validation of(String name) {
+        return new Builder(name).setRequired(false).build();
+    }
+
+
+    /**
+     * A new Builder for creating ParameterValidation instances.
+     */
+    public static class Builder {
+        /** The parameter's target type. */
+        private Class type;
+        /** The fully qualified parameter name. */
+        private String name;
+        /** The optional provider. */
+        private String provider;
+        /** The optional validation expression. */
+        private String regEx;
+        /** The optional description. */
+        private String description;
+        /** The required flag. */
+        private boolean required;
+
+        /**
+         * Creates a new Builder.
+         * @param name the fully qualified parameter name, not null.
+         */
+        public Builder(String name) {
+            this.name = Objects.requireNonNull(name);
+        }
+
+        /**
+         * Sets the target type.
+         * @param type the type, not null.
+         * @return the Builder for chaining
+         */
+        public Builder setType(String type) {
+            try {
+                this.type = Class.forName(type);
+            } catch (ClassNotFoundException e) {
+                try {
+                    this.type = Class.forName("java.lang."+type);
+                } catch (ClassNotFoundException e2) {
+                    Logger.getLogger(getClass().getName()).log(Level.WARNING, "Failed to load parameter type: " + type, e2);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Sets the required flag.
+         * @param required the required flag.
+         * @return the Builder for chaining
+         */
+        public Builder setRequired(boolean required) {
+            this.required = required;
+            return this;
+        }
+
+        /**
+         * Sets the optional description
+         * @param description the description
+         * @return the Builder for chaining
+         */
+        public Builder setDescription(String description) {
+            this.description = description;
+            return this;
+        }
+
+        /**
+         * Sets the optional validation expression
+         * @param expression the validation expression
+         * @return the Builder for chaining
+         */
+        public Builder setExpression(String expression) {
+            this.regEx = expression;
+            return this;
+        }
+
+        /**
+         * Sets the fully qualified parameter name.
+         * @param name the fully qualified parameter name, not null.
+         * @return the Builder for chaining
+         */
+        public Builder setName(String name) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Set the provider.
+         * @param provider the provider.
+         * @return the Builder for chaining
+         */
+        public Builder setProvider(String provider) {
+            this.provider = provider;
+            return this;
+        }
+
+        /**
+         * Creates a new Validation with the given parameters.
+         * @return a new Validation , never null.
+         */
+        public Validation build() {
+            return new ParameterValidation(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationGroup.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationGroup.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationGroup.java
new file mode 100644
index 0000000..baa39bd
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationGroup.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.model.Validation;
+import org.apache.tamaya.model.ValidationResult;
+import org.apache.tamaya.model.ValidationType;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Default configuration Model for a configuration area.
+ */
+public class ValidationGroup implements Validation {
+
+    private String name;
+    private boolean required;
+    private String provider;
+    private List<Validation> childValidations = new ArrayList<>();
+
+    public ValidationGroup(String name, String provider, Validation... validations){
+        this(name, provider, Arrays.asList(validations));
+    }
+
+    public ValidationGroup(String name, String provider, Collection<Validation> validations){
+        this.name = Objects.requireNonNull(name);
+        this.provider = provider;
+        this.childValidations.addAll(validations);
+        this.childValidations = Collections.unmodifiableList(childValidations);
+        for(Validation val:validations) {
+            if(val.isRequired()){
+                this.required = true;
+                break;
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getProvider() {
+        return provider;
+    }
+
+    @Override
+    public boolean isRequired() {
+        return required;
+    }
+
+    @Override
+    public ValidationType getType() {
+        return ValidationType.Group;
+    }
+
+    @Override
+    public String getDescription() {
+        if(childValidations.isEmpty()){
+            return null;
+        }
+        StringBuilder b = new StringBuilder();
+        for(Validation val:childValidations){
+            b.append("  >> " + val);
+        }
+        return b.toString();
+    }
+
+    public Collection<Validation> getValidations(){
+        return childValidations;
+    }
+
+    @Override
+    public Collection<ValidationResult> validate(Configuration config) {
+        List<ValidationResult> result = new ArrayList<>(1);
+        for(Validation child: childValidations){
+            result.addAll(child.validate(config));
+        }
+        return result;
+    }
+
+    @Override
+    public String toString(){
+        StringBuilder b = new StringBuilder();
+        b.append(getType()).append(", size: ").append(childValidations.size()).append(": ").append(getDescription());
+        return b.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationProviderSpi.java b/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationProviderSpi.java
new file mode 100644
index 0000000..edb795c
--- /dev/null
+++ b/modules/model/src/main/java/org/apache/tamaya/model/spi/ValidationProviderSpi.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.model.spi;
+
+import org.apache.tamaya.model.Validation;
+
+import java.util.Collection;
+
+/**
+ * Model of a configuration state. A model can be a full model, or a partial model, validating only
+ * a configuration subset. This allows better user feedback because big configurations can be grouped
+ * and validated by multiple (partial) models.
+ */
+public interface ValidationProviderSpi {
+
+    /**
+     * Get the validation defined.
+     *
+     * @return the sections defined, never null.
+     */
+    Collection<Validation> getValidations();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/resources/META-INF/configmodel.properties
----------------------------------------------------------------------
diff --git a/modules/model/src/main/resources/META-INF/configmodel.properties b/modules/model/src/main/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..7861c9e
--- /dev/null
+++ b/modules/model/src/main/resources/META-INF/configmodel.properties
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Contains definitions for default system property areas.
+{model}.awt.class=Section
+{model}.awt.transitive=true
+{model}.file.class=Section
+{model}.file.transitive=true
+{model}.java.class=Section
+{model}.java.transitive=true
+{model}.line.class=Section
+{model}.line.transitive=true
+{model}.os.class=Section
+{model}.os.transitive=true
+{model}.path.class=Section
+{model}.path.transitive=true
+{model}.sun.class=Section
+{model}.sun.transitive=true
+{model}.user.class=Section
+{model}.user.transitive=true

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c5343410/modules/model/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ConfigDocumentationMBean
----------------------------------------------------------------------
diff --git a/modules/model/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ConfigDocumentationMBean b/modules/model/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ConfigDocumentationMBean
new file mode 100644
index 0000000..05c3d02
--- /dev/null
+++ b/modules/model/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ConfigDocumentationMBean
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.model.internal.ConfigDocumentationBean
\ No newline at end of file