You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2016/09/06 17:18:42 UTC
[46/50] [abbrv] incubator-tamaya-sandbox git commit: TAMAYA-145:
Implemented big parts of the new meta-configuration DSL mechanism.
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 <an...@apache.org>
Authored: Thu May 5 18:44:48 2016 +0200
Committer: anatole <an...@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