You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2011/12/29 03:32:07 UTC

git commit: DELTASPIKE-36 ConfigSource - default lookup strategies

Updated Branches:
  refs/heads/master d5b218ce9 -> 81170a8b0


DELTASPIKE-36 ConfigSource - default lookup strategies


Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/81170a8b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/81170a8b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/81170a8b

Branch: refs/heads/master
Commit: 81170a8b0e72eb7d3a45ace61b0443503bce9333
Parents: d5b218c
Author: gpetracek <gp...@apache.org>
Authored: Thu Dec 29 03:30:44 2011 +0100
Committer: gpetracek <gp...@apache.org>
Committed: Thu Dec 29 03:30:44 2011 +0100

----------------------------------------------------------------------
 .../deltaspike/core/api/config/ConfigResolver.java |    7 +-
 .../deltaspike/core/spi/config/ConfigSource.java   |   79 ++++++-
 .../impl/config/DefaultConfigSourceProvider.java   |   59 +++++
 .../config/EnvironmentPropertyConfigSource.java    |   57 +++++
 .../core/impl/config/LocalJndiConfigSource.java    |   81 +++++++
 .../core/impl/config/PropertyFileConfigSource.java |  180 +++++++++++++++
 .../impl/config/SystemPropertyConfigSource.java    |   57 +++++
 .../deltaspike/core/impl/util/JndiUtils.java       |  129 +++++++++++
 ...deltaspike.core.spi.config.ConfigSourceProvider |   20 ++
 .../core/test/api/config/ConfigSourceTest.java     |   84 +++++++
 .../META-INF/apache-deltaspike.properties          |   18 ++
 .../test/resources/apache-deltaspike.properties    |   18 ++
 12 files changed, 779 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index 663fa3c..51a4063 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -129,14 +129,9 @@ public class ConfigResolver
     {
         List<ConfigSource> appConfigSources = new ArrayList<ConfigSource>();
         
-        ServiceLoader<ConfigSource> configSourceServiceLoader = ServiceLoader.load(ConfigSource.class);
-        for (ConfigSource cs : configSourceServiceLoader)
-        {
-            appConfigSources.add(cs);
-        }
-
         ServiceLoader<ConfigSourceProvider> configSourceProviderServiceLoader
                 = ServiceLoader.load(ConfigSourceProvider.class);
+
         for (ConfigSourceProvider csp : configSourceProviderServiceLoader)
         {
             appConfigSources.addAll(csp.getConfigSources());

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java
index 01567fa..1ddf105 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java
@@ -18,6 +18,9 @@
  */
 package org.apache.deltaspike.core.spi.config;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 /**
  * <p>Implement this interfaces to provide a ConfigSource.
  * A ConfigSource provides properties from a specific place, like
@@ -28,21 +31,89 @@ package org.apache.deltaspike.core.spi.config;
  * {@link java.util.ServiceLoader} and therefor must get registered via
  * META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource</p>
  */
-public interface ConfigSource
+public abstract class ConfigSource
 {
+    protected Logger LOG = Logger.getLogger(getClass().getName());
+
+    //X TODO discuss value
+    private static final String ORDINAL_KEY = "org_apache_deltaspike_ORDINAL";
+
+    private int ordinal;
+
+    protected ConfigSource()
+    {
+        init();
+    }
+
     /**
      * @return the 'importance' aka ordinal of the configured values. The higher, the more important.
      */
-    int getOrdinal();
+    public int getOrdinal()
+    {
+        return this.ordinal;
+    }
 
     /**
      * @param key for the property
      * @return configured value or <code>null</code> if this ConfigSource doesn't provide any value for the given key.
      */
-    String getPropertyValue(String key);
+    public abstract String getPropertyValue(String key);
 
     /**
      * @return the 'name' of the configuration source, e.g. 'property-file mylocation/myproperty.properties'
      */
-    String getConfigName();
+    public abstract String getConfigName();
+
+    /**
+     * Provides the default ordinal, if there isn't a custom ordinal for the current
+     * {@link ConfigSource}
+     * @return value for the default ordinal
+     */
+    protected int getDefaultOrdinal()
+    {
+        return 1000;
+    }
+
+    /**
+     * Init method e.g. for initializing the ordinal
+     */
+    protected void init()
+    {
+        this.ordinal = getDefaultOrdinal();
+
+        Integer configuredOrdinal = null;
+
+        String configuredOrdinalString = getPropertyValue(getOrdinalKey());
+        try
+        {
+            if(configuredOrdinalString != null)
+            {
+                configuredOrdinal = new Integer(configuredOrdinalString.trim());
+            }
+        }
+        catch (NumberFormatException e)
+        {
+            LOG.log(Level.WARNING,
+                    "The configured config-ordinal isn't a valid integer. Invalid value: " + configuredOrdinalString);
+        }
+        catch (Exception e)
+        {
+            //do nothing it was just a try
+        }
+
+        if(configuredOrdinal != null)
+        {
+            this.ordinal = configuredOrdinal;
+        }
+    }
+
+    /**
+     * Allows to customize the key which gets used to lookup a customized ordinal for the current
+     * {@link ConfigSource}
+     * @return key which should be used for the ordinal lookup
+     */
+    protected String getOrdinalKey()
+    {
+        return ORDINAL_KEY;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
new file mode 100644
index 0000000..c0ac194
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Default implementation which uses:
+ * <ol>
+ * <li>SystemPropertyConfigSource</li>
+ * <li>EnvironmentPropertyConfigSource</li>
+ * <li>LocalJndiConfigSource</li>
+ * <li>PropertyFileConfigSource</li>
+ * </ol>
+ */
+public class DefaultConfigSourceProvider implements ConfigSourceProvider
+{
+    private List<ConfigSource> configSources = new ArrayList<ConfigSource>();
+
+    /**
+     * Default constructor which adds the {@link ConfigSource} implementations which are supported by default
+     */
+    public DefaultConfigSourceProvider()
+    {
+        this.configSources.add(new SystemPropertyConfigSource());
+        this.configSources.add(new EnvironmentPropertyConfigSource());
+        this.configSources.add(new LocalJndiConfigSource());
+        this.configSources.add(new PropertyFileConfigSource());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<ConfigSource> getConfigSources()
+    {
+        return this.configSources;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSource.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSource.java
new file mode 100644
index 0000000..e2ac370
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSource.java
@@ -0,0 +1,57 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+/**
+ * {@link ConfigSource} which uses System#getenv
+ */
+class EnvironmentPropertyConfigSource extends ConfigSource
+{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected int getDefaultOrdinal()
+    {
+        return 200;
+    }
+
+    /**
+     * The given key gets used for a lookup via System#getenv
+     *
+     * @param key for the property
+     * @return value for the given key or null if there is no configured value
+     */
+    @Override
+    public String getPropertyValue(String key)
+    {
+        return System.getenv(key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getConfigName()
+    {
+        return "environment-properties";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/LocalJndiConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/LocalJndiConfigSource.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/LocalJndiConfigSource.java
new file mode 100644
index 0000000..d2dd192
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/LocalJndiConfigSource.java
@@ -0,0 +1,81 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.impl.util.JndiUtils;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+import javax.enterprise.inject.Typed;
+
+/**
+ * {@link ConfigSource} which uses JNDI for the lookup
+ */
+@Typed()
+class LocalJndiConfigSource extends ConfigSource
+{
+    private static final String BASE_NAME = "java:comp/env/deltaspike/";
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected int getDefaultOrdinal()
+    {
+        return 300;
+    }
+
+    /**
+     * The given key gets used for a lookup via JNDI
+     *
+     * @param key for the property
+     * @return value for the given key or null if there is no configured value
+     */
+    @Override
+    public String getPropertyValue(String key)
+    {
+        try
+        {
+            String jndiKey;
+            if (key.startsWith("java:comp/env"))
+            {
+                jndiKey = key;
+            }
+            else
+            {
+                jndiKey = BASE_NAME + key;
+            }
+
+            return JndiUtils.lookup(jndiKey, String.class);
+        }
+        catch (Exception e)
+        {
+            //do nothing it was just a try
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getConfigName()
+    {
+        return BASE_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
new file mode 100644
index 0000000..c1b91f0
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
@@ -0,0 +1,180 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.api.util.ClassUtils;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+
+/**
+ * {@link ConfigSource} which uses
+ * apache-deltaspike.properties btw. /META-INF/apache-deltaspike.properties for the lookup
+ */
+class PropertyFileConfigSource extends ConfigSource
+{
+    private static Map<ClassLoader, Map<String, String>> propertyCache =
+            new ConcurrentHashMap<ClassLoader, Map<String, String>>();
+
+    private static final String FILE_NAME = "apache-deltaspike";
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected int getDefaultOrdinal()
+    {
+        return 400;
+    }
+
+    /**
+     * The given key gets used for a lookup via a properties file
+     *
+     * @param key for the property
+     * @return value for the given key or null if there is no configured value
+     */
+    @Override
+    public String getPropertyValue(String key)
+    {
+        Map<String, String> cache = getPropertyCache();
+
+        String configuredValue = cache.get(key);
+
+        if ("".equals(configuredValue))
+        {
+            return null;
+        }
+
+        ResourceBundle resourceBundle;
+
+        try
+        {
+            resourceBundle = loadResourceBundleFromClasspath();
+
+            if (resourceBundle.containsKey(key))
+            {
+                configuredValue = resourceBundle.getString(key);
+                cache.put(key, configuredValue);
+            }
+
+            if (configuredValue == null)
+            {
+                Properties properties = loadPropertiesFromMetaInf();
+
+                if (properties != null)
+                {
+                    configuredValue = properties.getProperty(key);
+                    cache.put(key, configuredValue);
+                }
+            }
+
+            if (configuredValue == null)
+            {
+                cache.put(key, "");
+                return null;
+            }
+        }
+        catch (Exception e)
+        {
+            cache.put(key, "");
+            return null;
+        }
+        return configuredValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getConfigName()
+    {
+        //X TODO should we split the impl. to have a better name?
+        return FILE_NAME + ".properties";
+    }
+
+    private ResourceBundle loadResourceBundleFromClasspath()
+    {
+        try
+        {
+            return ResourceBundle.getBundle(FILE_NAME, Locale.getDefault(), ClassUtils.getClassLoader(null));
+        }
+        catch (MissingResourceException e)
+        {
+            //it was just a try
+            return null;
+        }
+    }
+
+    private Map<String, String> getPropertyCache()
+    {
+        ClassLoader classLoader = ClassUtils.getClassLoader(null);
+        Map<String, String> cache = propertyCache.get(classLoader);
+
+        if (cache == null)
+        {
+            cache = new ConcurrentHashMap<String, String>();
+            propertyCache.put(classLoader, cache);
+        }
+        return cache;
+    }
+
+    private Properties loadPropertiesFromMetaInf()
+    {
+        String resourceName = "META-INF/" + FILE_NAME + ".properties";
+        Properties properties = null;
+
+        ClassLoader classLoader = ClassUtils.getClassLoader(resourceName);
+        InputStream inputStream = classLoader.getResourceAsStream(resourceName);
+
+        if (inputStream != null)
+        {
+            properties = new Properties();
+
+            try
+            {
+                properties.load(inputStream);
+            }
+            catch (IOException e)
+            {
+                return null;
+            }
+            finally
+            {
+                try
+                {
+                    inputStream.close();
+                }
+                catch (IOException e)
+                {
+                    LOG.log(Level.WARNING, "Failed to close " + resourceName, e);
+                }
+            }
+        }
+
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/SystemPropertyConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/SystemPropertyConfigSource.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/SystemPropertyConfigSource.java
new file mode 100644
index 0000000..f652f85
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/SystemPropertyConfigSource.java
@@ -0,0 +1,57 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+/**
+ * {@link ConfigSource} which uses System#getProperty
+ */
+class SystemPropertyConfigSource extends ConfigSource
+{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected int getDefaultOrdinal()
+    {
+        return 100;
+    }
+
+    /**
+     * The given key gets used for a lookup via System#getProperty
+     *
+     * @param key for the property
+     * @return value for the given key or null if there is no configured value
+     */
+    @Override
+    public String getPropertyValue(String key)
+    {
+        return System.getProperty(key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getConfigName()
+    {
+        return "system-properties";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java
new file mode 100644
index 0000000..b72c7d9
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java
@@ -0,0 +1,129 @@
+/*
+ * 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.deltaspike.core.impl.util;
+
+import org.apache.deltaspike.core.api.util.ClassUtils;
+
+import javax.enterprise.inject.Typed;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This is the internal helper class for low level access to JNDI
+ */
+@Typed()
+public class JndiUtils
+{
+    private static final Logger LOG = Logger.getLogger(JndiUtils.class.getName());
+
+    private static InitialContext initialContext = null;
+
+    static
+    {
+        try
+        {
+            initialContext = new InitialContext();
+        }
+        catch (Exception e)
+        {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    private JndiUtils()
+    {
+        // prevent instantiation
+    }
+
+    /**
+     * Resolves an instance for the given name.
+     *
+     * @param name       current name
+     * @param targetType target type
+     * @param <T>        type
+     * @return the found instance, null otherwise
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T lookup(String name, Class<? extends T> targetType)
+    {
+        try
+        {
+            Object result = initialContext.lookup(name);
+
+            if (result != null)
+            {
+                if (targetType.isAssignableFrom(result.getClass()))
+                {
+                    // we have a value and the type fits
+                    return (T) result;
+                }
+                else if (result instanceof String) //but the target type != String
+                {
+                    // lookedUp might be a class name
+                    try
+                    {
+                        Class<?> classOfResult = ClassUtils.loadClassForName((String) result);
+                        if (targetType.isAssignableFrom(classOfResult))
+                        {
+                            try
+                            {
+                                return (T) classOfResult.newInstance();
+                            }
+                            catch (Exception e)
+                            {
+                                // could not create instance
+                                LOG.log(Level.SEVERE, "Class " + classOfResult + " from JNDI lookup for name "
+                                        + name + " could not be instantiated", e);
+                            }
+                        }
+                        else
+                        {
+                            // lookedUpClass does not extend/implement expectedClass
+                            LOG.log(Level.SEVERE, "JNDI lookup for key " + name
+                                    + " returned class " + classOfResult.getName()
+                                    + " which does not implement/extend the expected class"
+                                    + targetType.getName());
+                        }
+                    }
+                    catch (ClassNotFoundException cnfe)
+                    {
+                        // could not find class
+                        LOG.log(Level.SEVERE, "Could not find Class " + result
+                                + " from JNDI lookup for name " + name, cnfe);
+                    }
+                }
+                else
+                {
+                    // we have a value, but the value does not fit
+                    LOG.log(Level.SEVERE, "JNDI lookup for key " + name + " should return a value of "
+                            + targetType + ", but returned " + result);
+                }
+            }
+
+            return null;
+        }
+        catch (NamingException e)
+        {
+            //X TODO custom exception type needed - see UnhandledException
+            throw new IllegalStateException("Could not get " + name + " from JNDI", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
new file mode 100644
index 0000000..c03e1e4
--- /dev/null
+++ b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
@@ -0,0 +1,20 @@
+#####################################################################################
+# 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.
+#####################################################################################
+
+org.apache.deltaspike.core.impl.config.DefaultConfigSourceProvider

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/core/test/api/config/ConfigSourceTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/core/test/api/config/ConfigSourceTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/core/test/api/config/ConfigSourceTest.java
new file mode 100644
index 0000000..425700d
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/core/test/api/config/ConfigSourceTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.deltaspike.core.test.api.config;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link org.apache.deltaspike.core.spi.config.ConfigSource}
+ */
+public class ConfigSourceTest
+{
+    @Test
+    public void testConfigViaSystemProperty()
+    {
+        String key = "testProperty01";
+        String value = "test_value_01";
+        System.setProperty(key, value);
+        
+        String configuredValue = ConfigResolver.getPropertyValue(key);
+        
+        Assert.assertEquals(value, configuredValue);
+
+        System.setProperty(key, "");
+
+        configuredValue = ConfigResolver.getPropertyValue(key);
+
+        Assert.assertEquals("", configuredValue);
+    }
+
+    @Test
+    public void testConfigViaClasspathPropertyFile()
+    {
+        String key = "testProperty02";
+        String value = "test_value_02";
+
+        String configuredValue = ConfigResolver.getPropertyValue(key);
+
+        Assert.assertEquals(value, configuredValue);
+    }
+
+    @Test
+    public void testConfigViaMetaInfPropertyFile()
+    {
+        String key = "testProperty03";
+        String value = "test_value_03";
+
+        String configuredValue = ConfigResolver.getPropertyValue(key);
+
+        Assert.assertEquals(value, configuredValue);
+    }
+
+    /*
+    //X TODO discuss marker
+    @Test
+    public void testConfigViaSystemPropertyAndMarker()
+    {
+        String key = "testProperty01";
+        String value = "test_value";
+        System.setProperty("org.apache.deltaspike." + key, value);
+
+        String configuredValue = ConfigResolver.getPropertyValue("@@deltaspike@@" + key);
+
+        Assert.assertEquals(value, configuredValue);
+    }
+    */
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
new file mode 100644
index 0000000..48b9ad8
--- /dev/null
+++ b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
@@ -0,0 +1,18 @@
+#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.
+
+testProperty03=test_value_03
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/81170a8b/deltaspike/core/impl/src/test/resources/apache-deltaspike.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/apache-deltaspike.properties b/deltaspike/core/impl/src/test/resources/apache-deltaspike.properties
new file mode 100644
index 0000000..e90dcb2
--- /dev/null
+++ b/deltaspike/core/impl/src/test/resources/apache-deltaspike.properties
@@ -0,0 +1,18 @@
+#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.
+
+testProperty02=test_value_02
\ No newline at end of file