tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ple...@apache.org
Subject [46/50] [abbrv] incubator-tamaya-sandbox git commit: TAMAYA-145: Implemented big parts of the new meta-configuration DSL mechanism.
Date Tue, 06 Sep 2016 17:18:42 GMT
TAMAYA-145: Implemented big parts of the new meta-configuration DSL mechanism.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/877d10e8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/877d10e8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/877d10e8

Branch: refs/heads/master
Commit: 877d10e8dc434b10d7733258a0a1f563435f6f13
Parents: 4397008
Author: anatole <anatole@apache.org>
Authored: Thu May 5 18:44:48 2016 +0200
Committer: anatole <anatole@apache.org>
Committed: Thu May 5 18:44:48 2016 +0200

----------------------------------------------------------------------
 metamodels/staged/pom.xml                       |  20 +++
 .../tamaya/dsl/ConfigurationContextManager.java | 163 +++++++++++++++++
 .../java/org/apache/tamaya/dsl/EnvConfig.java   | 102 +++++++++++
 .../org/apache/tamaya/dsl/FormatManager.java    | 168 +++++++++++++++++
 .../org/apache/tamaya/dsl/ProfileManager.java   | 179 +++++++++++++++++++
 .../org/apache/tamaya/dsl/package-info.java     |  23 +++
 .../tamaya/staged/spi/DSLSourceResolver.java    |  54 ++++++
 .../apache/tamaya/dsl/ProfileManagerTest.java   |  78 ++++++++
 .../src/test/resources/tamaya-config.yaml       |  85 +++++++++
 9 files changed, 872 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/pom.xml
----------------------------------------------------------------------
diff --git a/metamodels/staged/pom.xml b/metamodels/staged/pom.xml
index 52a1e73..b5c96a2 100644
--- a/metamodels/staged/pom.xml
+++ b/metamodels/staged/pom.xml
@@ -51,6 +51,11 @@ under the License.
         </dependency>
         <dependency>
             <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-resolver</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
             <artifactId>tamaya-spisupport</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -60,9 +65,24 @@ under the License.
             <version>${project.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-formats</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-yaml</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ConfigurationContextManager.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ConfigurationContextManager.java
b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ConfigurationContextManager.java
new file mode 100644
index 0000000..67a79a6
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ConfigurationContextManager.java
@@ -0,0 +1,163 @@
+/*
+ * 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.dsl;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.spi.*;
+import org.apache.tamaya.staged.spi.DSLSourceResolver;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * Created by atsticks on 05.05.16.
+ */
+public class ConfigurationContextManager {
+
+    private static final Logger LOGGER = Logger.getLogger(EnvConfig.class.getName());
+
+    private ConfigurationContext configurationContext;
+    private Set<String> formats = new HashSet<>();
+    private Set<String> suffixes = new HashSet<>();
+    private Map<String,DSLSourceResolver> dslResolvers = new HashMap<>();
+
+
+    public ConfigurationContextManager(){
+        loadDSLSourceResolvers();
+        Configuration metaConfig = EnvConfig.getMetaConfiguration();
+        Configuration profilesConfig = metaConfig.with(
+                ConfigurationFunctions.section("TAMAYA.PROFILES", true));
+        Configuration metaProfile = profilesConfig.with(
+                ConfigurationFunctions.section("<COMMON>", true));
+        String[] values = metaProfile.getOrDefault("formats","yaml, properties, xml-properties").split(",");
+        for(String fmt:values){
+            fmt = fmt.trim();
+            if(fmt.isEmpty()){
+                continue;
+            }
+            this.formats.add(fmt);
+        }
+        values = metaProfile.getOrDefault("suffixes", "yml, yaml, properties, xml").split(",");
+        for(String sfx:values){
+            sfx = sfx.trim();
+            if(sfx.isEmpty()){
+                continue;
+            }
+            this.suffixes.add(sfx);
+        }
+        ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder();
+        Map<String, PropertySource> loadedPropertySources = loadDefaultPropertySources();
+        int defaultOrdinal = loadSources(builder, "<COMMON>", metaProfile, loadedPropertySources,
0) + 20;
+        // Load current profiles
+        for(String profile:ProfileManager.getInstance().getActiveProfiles()){
+            metaProfile = profilesConfig.with(
+                    ConfigurationFunctions.section(profile, true));
+            defaultOrdinal = loadSources(builder, profile, metaProfile, loadedPropertySources,
defaultOrdinal) + 20;
+        }
+//         formats:  yaml, properties, xml-properties
+//    - SUFFIX:   yaml, yml, properties, xml
+//    - sources:
+//      - "named:env-properties"   # provider name, or class name
+//      - "named:main-args"
+//      - "named:sys-properties"
+//      - "resource:classpath:META-INF/config/**/*.SUFFIX"
+
+}
+
+    /**
+     * Loads all default registered property sources and providers.
+     * @return the default property sources available on the system.
+     */
+    private Map<String, PropertySource> loadDefaultPropertySources() {
+        Map<String, PropertySource> loadedPropertySources = new HashMap<>();
+        for(PropertySource ps: ServiceContextManager.getServiceContext().getServices(PropertySource.class)){
+            loadedPropertySources.put(ps.getName(), ps);
+        }
+        for(PropertySourceProvider prov: ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){
+            for(PropertySource ps: prov.getPropertySources()){
+                loadedPropertySources.put(ps.getName(), ps);
+            }
+        }
+        return loadedPropertySources;
+    }
+
+    private int loadSources(ConfigurationContextBuilder builder, String profileId, Configuration
metaProfile, Map<String,
+            PropertySource> defaultPropertySources, int defaultOrdinal) {
+        String[] values;
+        values = metaProfile.getOrDefault("sources","<default>").split(",");
+        if(values.length==1 && "<default>".equals(values[0])){
+            // load default property sources and providers from config as default.
+            // additional providers may be added depending on the active profile...
+            LOGGER.info("Using default configuration setup for "+profileId);
+            builder.addPropertySources(defaultPropertySources.values());
+        }else {
+            int newMaxOrdinal = defaultOrdinal;
+            LOGGER.info("Loading DSL based "+profileId+" configuration context...");
+            int count = 0;
+            for (String source : values) {
+                source = source.trim();
+                if (source.isEmpty()) {
+                    continue;
+                }
+                String sourceKey = getSourceKey(source);
+                LOGGER.info("Loading "+profileId+" configuration source: " + source);
+                // evaluate DSLSourceResolver and resolve PropertySources, register thm into
context
+                // apply newMaxOrdinal...
+                DSLSourceResolver resolver = dslResolvers.get(sourceKey);
+                if(resolver==null){
+                    LOGGER.warning("DSL error: unresolvable source expression: "+ source);
+                    continue;
+                }
+                List<PropertySource> sources = resolver.resolve(source.substring(sourceKey.length()),
defaultPropertySources, defaultOrdinal);
+                count += sources.size();
+                for(PropertySource ps:sources){
+                    if(ps.getOrdinal()>newMaxOrdinal){
+                        newMaxOrdinal = ps.getOrdinal();
+                    }
+                }
+                builder.addPropertySources(sources);
+            }
+            LOGGER.info("Loaded "+count+" DSL based "+profileId+" configuration contexts.");
+            return newMaxOrdinal;
+        }
+        return defaultOrdinal;
+    }
+
+    private String getSourceKey(String source) {
+        int index = source.indexOf(':');
+        if(index>0){
+            return source.substring(0,index);
+        }
+        return source;
+    }
+
+    private void loadDSLSourceResolvers() {
+        // Load the ConfigurationDSLSourceResolvers on the system
+        for(DSLSourceResolver res:ServiceContextManager.getServiceContext().getServices(DSLSourceResolver.class)){
+            this.dslResolvers.put(res.getKey(), res);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/dsl/EnvConfig.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/dsl/EnvConfig.java b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/EnvConfig.java
new file mode 100644
index 0000000..aa5aa62
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/EnvConfig.java
@@ -0,0 +1,102 @@
+/*
+ * 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.dsl;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationFormat;
+import org.apache.tamaya.format.ConfigurationFormats;
+import org.apache.tamaya.json.YAMLFormat;
+import org.apache.tamaya.resource.ConfigResources;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+import org.apache.tamaya.spisupport.MapPropertySource;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Meta environment configuration builder and accessor. Normally this class shoulds never
be accessed
+ * by client code. But it could be useful for extensions that extend the meta-configuration
capabilities
+ * of tamaya having access to the meta-configuration, so they can read their own meta-entries
to
+ * setup whatever features they implement.
+ */
+public final class EnvConfig {
+
+    private static final Logger LOGGER = Logger.getLogger(EnvConfig.class.getName());
+    private static EnvConfig INSTANCE = new EnvConfig();
+
+    private Configuration config;
+
+    private EnvConfig(){
+        ConfigurationFormat[] formats = loadFormats();
+        ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder();
+        for(URL url:ConfigResources.getResourceResolver().getResources("tamaya-config.*"))
{
+            for(ConfigurationFormat format:formats) {
+                if(format.accepts(url)){
+                    try(InputStream is = url.openStream()){
+                        ConfigurationData data = format.readConfiguration(url.toString(),
is);
+                        builder.addPropertySources(new MapPropertySource(
+                                url.toString(), data.getCombinedProperties()));
+                    }catch(Exception e){
+                        LOGGER.log(Level.INFO, "Failed to read " + url + " with format "
+ format, e);
+                    }
+                }
+            }
+        }
+        this.config = new DefaultConfiguration(builder.build());
+        LOGGER.info("Meta-Configuration read: " + this.config.getProperties().size() + "
entries.");
+    }
+
+    private ConfigurationFormat[] loadFormats() {
+        List<ConfigurationFormat> formats = new ArrayList<>();
+        String metaFormats = System.getProperty("tamaya.meta-formats");
+        if(metaFormats!=null){
+            String[] formatNames = metaFormats.split(",");
+            for(String formatName:formatNames){
+                formats.addAll(ConfigurationFormats.getFormats(formatName));
+            }
+        }
+        if(formats.isEmpty()){
+            formats.addAll(ConfigurationFormats.getFormats("yaml"));
+        }
+        if(formats.isEmpty()){
+            formats.add(new YAMLFormat());
+        }
+        return formats.toArray(new ConfigurationFormat[formats.size()]);
+    }
+
+    /**
+     * Access the system's meta-configuration. Normally this class shoulds never be accessed
+     * by client code. But it could be useful for extensions that extend the meta-configuration
capabilities
+     * of tamaya having access to the meta-configuration, so they can read their own meta-entries
to
+     * setup whatever features they implement.
+     * @return the meta-configuration instance used for setting up the Tamaya's application
configuration
+     * model.
+     */
+    public static Configuration getMetaConfiguration(){
+        return INSTANCE.config;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/dsl/FormatManager.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/dsl/FormatManager.java b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/FormatManager.java
new file mode 100644
index 0000000..52c4c48
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/FormatManager.java
@@ -0,0 +1,168 @@
+/*
+ * 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.dsl;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.resolver.Resolver;
+
+import java.util.*;
+
+/**
+ * Component that manages the current supported formats:
+ * <pre>
+ * TAMAYA:
+ *   FORMAT-DEF:
+ *     - formats: yaml, properties, xml-properties
+ * </pre>
+ * Hereby:
+ * <ul>
+ *     <li><b>profiles</b> defines the available profiles, including implicit
default profiles.</li>
+ * </ul>
+ */
+public class FormatManager {
+
+    private static final FormatManager INSTANCE = new FormatManager();
+
+    /** The currently active profiles, in order of precedence, the most significant are the
last ones. */
+    private List<String> activeProfiles = new ArrayList<>();
+    /** A set of all defined profiles. */
+    private Set<String> profiles = new HashSet<>();
+    /** The current used default profiles, loaded initially, before all other profiles are
loaded. */
+    private List<String> defaultProfiles = new ArrayList<>();
+
+    /**
+     * Get the current instance.
+     * @return the current profile manager, never null.
+     */
+    public static FormatManager getInstance(){
+        return INSTANCE;
+    }
+
+    private FormatManager(){
+        Configuration metaConfig = EnvConfig.getMetaConfiguration();
+        Configuration profileConfig = metaConfig.with(
+                ConfigurationFunctions.section("TAMAYA.ENV-DEF"));
+        String[] selectables = profileConfig.getOrDefault("profiles","DEFAULT,DEV,TEST,PROD").split(",");
+        for(String sel:selectables){
+            sel = sel.trim();
+            if(sel.isEmpty()){
+                continue;
+            }
+            this.profiles.add(sel);
+        }
+        String[] defaults = profileConfig.getOrDefault("defaults","DEFAULT").split(",");
+        for(String def:defaults){
+            def = def.trim();
+            if(def.isEmpty()){
+                continue;
+            }
+            if(!isProfileDefined(def)){
+                throw new ConfigException("Invalid profile encountered: " +def + ", valid
are: " + profiles);
+            }
+            this.defaultProfiles.add(def);
+        }
+        String[] expressions = profileConfig.getOrDefault("evaluation","${sys:ENV}, ${env:ENV}").split(",");
+        String currentEnvironment = null;
+        for(String exp:expressions){
+            exp = exp.trim();
+            if(exp.isEmpty()){
+                continue;
+            }
+            currentEnvironment = Resolver.evaluateExpression(exp, false);
+            if(currentEnvironment!=null){
+                currentEnvironment = currentEnvironment.trim();
+                if(!currentEnvironment.isEmpty()){
+                    break;
+                }
+            }
+        }
+        if(currentEnvironment==null|| currentEnvironment.isEmpty()){
+            currentEnvironment = profileConfig.getOrDefault("default-active", "DEV");
+        }
+        this.activeProfiles.addAll(defaultProfiles);
+        String[] profilesActive = currentEnvironment.split(",");
+        for(String prof:profilesActive){
+            prof = prof.trim();
+            if(prof.isEmpty()){
+                continue;
+            }
+            if(!isProfileDefined(prof)){
+                throw new ConfigException("Invalid profile encountered: " +prof + ", valid
are: " + profiles);
+            }
+            this.activeProfiles.add(prof);
+        }
+    }
+
+    /**
+     * Allows to check if a profile is currently active.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is active.
+     */
+    public boolean isProfileActive(String profileName){
+        return this.activeProfiles.contains(profileName);
+    }
+
+    /**
+     * Allows to check if a profile is currently defined.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is defined.
+     */
+    public boolean isProfileDefined(String profileName){
+        return this.profiles.contains(profileName);
+    }
+
+    /**
+     * Allows to check if a profile is a default profile.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is a default profile.
+     */
+    public boolean isProfileDefault(String profileName){
+        return this.defaultProfiles.contains(profileName);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public List<String> getActiveProfiles(){
+        return Collections.unmodifiableList(activeProfiles);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public List<String> getDefaultProfiles(){
+        return Collections.unmodifiableList(defaultProfiles);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public Set<String> getAllProfiles(){
+        return Collections.unmodifiableSet(profiles);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ProfileManager.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ProfileManager.java b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ProfileManager.java
new file mode 100644
index 0000000..6dba2f2
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/ProfileManager.java
@@ -0,0 +1,179 @@
+/*
+ * 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.dsl;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.resolver.Resolver;
+
+import java.util.*;
+
+/**
+ * Component that manages the current setup profiles for this environment/runtime. The profile
manager
+ * reads the profile meta configuration that looks as follows:
+ * <pre>
+ * TAMAYA:
+ *   PROFILES-DEF:
+ *     - profiles:          DEFAULTS,DEV,TEST,PTA,PROD
+ *     - defaults:          DEFAULTS
+ *     - default-active:    DEV
+ *     - evaluation:        ${sys:ENV}, ${env:ENV}
+ * </pre>
+ * Hereby:
+ * <ul>
+ *     <li><b>profiles</b> defines the available profiles, including implicit
default profiles.</li>
+ *     <li><b>defaults</b> defines the profiles that are loaded implicitly
first as defaults.</li>
+ *     <li><b>default-active</b> defines the profile(s) activated by default,
when no profile setting could be evaluated.
+ *     <li><b>evaluation</b> defines the resolution expressions to be used
to evaluate the current profiles active.
+ *       By default {@code ${sys:ENV}, ${env:ENV}} is used, which tries to evaluate {@code
ENV} using system and
+ *       environment properties. Refere to the {@code tamaya-resolver} module for further
details on resolvers and
+ *       expressions and see {@link Resolver#evaluateExpression(String, boolean)}.
+ * </ul>
+ */
+public final class ProfileManager {
+
+    private static final ProfileManager INSTANCE = new ProfileManager();
+
+    /** The currently active profiles, in order of precedence, the most significant are the
last ones. */
+    private List<String> activeProfiles = new ArrayList<>();
+    /** A set of all defined profiles. */
+    private Set<String> profiles = new HashSet<>();
+    /** The current used default profiles, loaded initially, before all other profiles are
loaded. */
+    private List<String> defaultProfiles = new ArrayList<>();
+
+
+    /**
+     * Get the current instance.
+     * @return the current profile manager, never null.
+     */
+    public static ProfileManager getInstance(){
+        return INSTANCE;
+    }
+
+    private ProfileManager(){
+        Configuration metaConfig = EnvConfig.getMetaConfiguration();
+        Configuration profileConfig = metaConfig.with(
+                ConfigurationFunctions.section("TAMAYA.PROFILES-DEF"));
+        String[] selectables = profileConfig.getOrDefault("profiles","DEFAULT,DEV,TEST,PROD").split(",");
+        for(String sel:selectables){
+            sel = sel.trim();
+            if(sel.isEmpty()){
+                continue;
+            }
+            this.profiles.add(sel);
+        }
+        String[] defaults = profileConfig.getOrDefault("defaults","DEFAULT").split(",");
+        for(String def:defaults){
+            def = def.trim();
+            if(def.isEmpty()){
+                continue;
+            }
+            if(!isProfileDefined(def)){
+                throw new ConfigException("Invalid profile encountered: " +def + ", valid
are: " + profiles);
+            }
+            this.defaultProfiles.add(def);
+        }
+        String[] expressions = profileConfig.getOrDefault("evaluation","${sys:ENV}, ${env:ENV}").split(",");
+        String currentEnvironment = null;
+        for(String exp:expressions){
+            exp = exp.trim();
+            if(exp.isEmpty()){
+                continue;
+            }
+            currentEnvironment = Resolver.evaluateExpression(exp, false);
+            if(currentEnvironment!=null){
+                currentEnvironment = currentEnvironment.trim();
+                if(!currentEnvironment.isEmpty()){
+                    break;
+                }
+            }
+        }
+        if(currentEnvironment==null|| currentEnvironment.isEmpty()){
+            currentEnvironment = profileConfig.getOrDefault("default-active", "DEV");
+        }
+        this.activeProfiles.addAll(defaultProfiles);
+        String[] profilesActive = currentEnvironment.split(",");
+        for(String prof:profilesActive){
+            prof = prof.trim();
+            if(prof.isEmpty()){
+                continue;
+            }
+            if(!isProfileDefined(prof)){
+                throw new ConfigException("Invalid profile encountered: " +prof + ", valid
are: " + profiles);
+            }
+            this.activeProfiles.add(prof);
+        }
+    }
+
+    /**
+     * Allows to check if a profile is currently active.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is active.
+     */
+    public boolean isProfileActive(String profileName){
+        return this.activeProfiles.contains(profileName);
+    }
+
+    /**
+     * Allows to check if a profile is currently defined.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is defined.
+     */
+    public boolean isProfileDefined(String profileName){
+        return this.profiles.contains(profileName);
+    }
+
+    /**
+     * Allows to check if a profile is a default profile.
+     * @param profileName the profile name, not null.
+     * @return true, if the profile is a default profile.
+     */
+    public boolean isProfileDefault(String profileName){
+        return this.defaultProfiles.contains(profileName);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public List<String> getActiveProfiles(){
+        return Collections.unmodifiableList(activeProfiles);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public List<String> getDefaultProfiles(){
+        return Collections.unmodifiableList(defaultProfiles);
+    }
+
+    /**
+     * Get the list of currently active profiles.
+     * @return the list of currently active profiles, in order of precedence, the most significant
+     * are the last ones, never null.
+     */
+    public Set<String> getAllProfiles(){
+        return Collections.unmodifiableSet(profiles);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/dsl/package-info.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/dsl/package-info.java b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/package-info.java
new file mode 100644
index 0000000..0b89d0d
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/dsl/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * Main package of the DSL module. Normally client code does not need access this package.
+ * But extensions also relying on the meta-data configuration mechanism may use it.
+ */
+package org.apache.tamaya.dsl;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/main/java/org/apache/tamaya/staged/spi/DSLSourceResolver.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/main/java/org/apache/tamaya/staged/spi/DSLSourceResolver.java
b/metamodels/staged/src/main/java/org/apache/tamaya/staged/spi/DSLSourceResolver.java
new file mode 100644
index 0000000..e7e0168
--- /dev/null
+++ b/metamodels/staged/src/main/java/org/apache/tamaya/staged/spi/DSLSourceResolver.java
@@ -0,0 +1,54 @@
+/*
+ * 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.staged.spi;
+
+import org.apache.tamaya.spi.PropertySource;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Resolver to resolve/map DSL related source expressions into PropertySources
+ * loadable by a ConfigurationContext. Hereby the ordering of loaded property sources must
be
+ * honored if possible by implicitly adapting/Overriding the default ordinal for the sources
+ * added.
+ */
+public interface DSLSourceResolver {
+
+    /**
+     * Resolve the given expression (without the key part).
+     * @param sourceExpression the source expression, not null.
+     * @param defaultPropertySources the default property sources that can be used as defined
by the functionality by
+     *                               a resolver.
+     * @param latestMaxOrdinal the latest ordinal. Newly added property sources should have
incresed ordinal values
+     *                         so the overall ordering is preserved as defined by the DSL
user.
+     * @return the list of loaded Property sources, never null.
+     */
+    List<PropertySource> resolve(String sourceExpression,
+                                 Map<String, PropertySource> defaultPropertySources,
+                                 int latestMaxOrdinal);
+
+    /**
+     * Get the resolver key, which identifiesan expression to be resolved by a resolver instance.
+     * As an example {@code "named:"} is the key for an expression {@code "named:sys-properties"}.
+     * The method {@link #resolve(String, Map, int)} will onyl receive the secoind part of
the expression.
+     * @return identifying key.
+     */
+    String getKey();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/test/java/org/apache/tamaya/dsl/ProfileManagerTest.java
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/test/java/org/apache/tamaya/dsl/ProfileManagerTest.java
b/metamodels/staged/src/test/java/org/apache/tamaya/dsl/ProfileManagerTest.java
new file mode 100644
index 0000000..73a9a59
--- /dev/null
+++ b/metamodels/staged/src/test/java/org/apache/tamaya/dsl/ProfileManagerTest.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.dsl;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 05.05.16.
+ */
+public class ProfileManagerTest {
+
+    private ProfileManager profileManager = new ProfileManager();
+
+    @org.junit.Test
+    public void isProfileActive() throws Exception {
+        assertTrue(profileManager.isProfileActive("DEV"));
+        assertTrue(profileManager.isProfileActive("DEFAULT"));
+        assertFalse(profileManager.isProfileActive("PROD"));
+    }
+
+    @org.junit.Test
+    public void isProfileDefined() throws Exception {
+        assertTrue(profileManager.isProfileDefined("DEV"));
+        assertTrue(profileManager.isProfileDefined("DEFAULT"));
+        assertFalse(profileManager.isProfileDefined("foo"));
+    }
+
+    @org.junit.Test
+    public void isProfileDefault() throws Exception {
+        assertFalse(profileManager.isProfileDefault("DEV"));
+        assertTrue(profileManager.isProfileDefault("DEFAULT"));
+    }
+
+    @org.junit.Test
+    public void getActiveProfiles() throws Exception {
+        List<String> profiles = profileManager.getActiveProfiles();
+        assertTrue(profiles.contains("DEV"));
+        assertTrue(profiles.contains("DEFAULT"));
+        assertFalse(profiles.contains("TEST"));
+        assertFalse(profiles.contains("PROD"));
+    }
+
+    @org.junit.Test
+    public void getDefaultProfiles() throws Exception {
+        List<String> profiles = profileManager.getDefaultProfiles();
+        assertTrue(profiles.contains("DEFAULT"));
+        assertFalse(profiles.contains("TEST"));
+    }
+
+    @org.junit.Test
+    public void getAllProfiles() throws Exception {
+        Set<String> profiles = profileManager.getAllProfiles();
+        assertTrue(profiles.contains("DEFAULT"));
+        assertTrue(profiles.contains("DEV"));
+        assertTrue(profiles.contains("TEST"));
+        assertTrue(profiles.contains("PROD"));
+        assertFalse(profiles.contains("foo"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/877d10e8/metamodels/staged/src/test/resources/tamaya-config.yaml
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/test/resources/tamaya-config.yaml b/metamodels/staged/src/test/resources/tamaya-config.yaml
new file mode 100644
index 0000000..a99eda9
--- /dev/null
+++ b/metamodels/staged/src/test/resources/tamaya-config.yaml
@@ -0,0 +1,85 @@
+#
+# 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.
+#
+TAMAYA:
+  PROFILES-DEF:
+   - selectable:          DEFAULT,DEV,TEST,PTA,PROD
+   - supports-multi:      false
+   - defaults:            DEFAULT
+   - default-active:      DEV
+   - defined-by:          sys-property:ENV, env-property:ENV
+
+  PROFILES:
+    <COMMON>:
+    - formats:  yaml, properties, xml-properties
+    - suffixes:   yaml, yml, properties, xml
+    - sources:
+      - "named:env-properties"   # provider name, or class name
+      - "named:main-args"
+      - "named:sys-properties"
+      - "resource:classpath:META-INF/config/**/*.SUFFIX"
+    DEFAULT:
+      - prio:       0   # optional
+      - sources:
+        - "resource:classpath:META-INF/defaults/**/*.SUFFIX"
+        - "resource:file:${config.dir}/defaults/**/*.SUFFIX"
+      - filters:
+        - "section:DEFAULTS\.*"
+        - "section:defaults\.*"
+        - "exclude:_\.*"   # removes all meta-entries
+    TEST:
+      - prio:        100   # optional
+      - filters:
+        - "section:TEST\.*"
+        - "section:test\.*"
+    PROD:
+      - prio:        1000   # optional
+      - filters:
+        - "section:PROD\.*"
+        - "section:prod\.*"
+
+  MODEL:
+      a.b.c:        "Section"
+      - owner:      "Test Model"
+      - children:   false
+      - required:   true
+      - validation: "my.abc.ValidatorClass"
+
+      java.version: "Parameter"
+      - owner:      "Expression Test"
+      - expression: ".*v1.7.*"
+      - required:   true
+
+      ch.trivadis:  "Section"       # Declaration only
+
+  USAGE:
+      track:        true
+
+#  FORMAT-DEF:
+#   - formats: yaml, properties, xml-properties
+#   - mappings:
+#      yaml            -> CustomMapping1Classname,
+#      xml-properties  -> Mapping2Classname
+#   - suffixes:
+#      yml, yaml, xml, properties
+
+#  FUNCTIONS:
+#    - default-map:  map(DEFAULTS,.)
+#    - env-map:      map(${ENV},.)
+#    - omit:         omit(!DEFAULTS,!${ENV})
+#    - config-map:   omit,default-map,env-map
\ No newline at end of file



Mime
View raw message