tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [06/11] incubator-tamaya git commit: Initial import from GitHub. Added PGP public key.
Date Wed, 26 Nov 2014 18:07:11 GMT
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/WeakConfigListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/WeakConfigListenerManager.java b/core/src/main/java/org/apache/tamaya/core/internal/WeakConfigListenerManager.java
new file mode 100644
index 0000000..461e1a4
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/WeakConfigListenerManager.java
@@ -0,0 +1,104 @@
+/*
+ * 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.core.internal;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.core.properties.Store;
+
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by Anatole on 29.03.14.
+ */
+public class WeakConfigListenerManager{
+
+    private static final Logger LOG = LogManager.getLogger(WeakConfigListenerManager.class);
+    private Map<String,Store<PropertyChangeListener>> changeListeners = new ConcurrentHashMap<>();
+
+
+    private void addPropertyChangeListener(PropertyChangeListener l, String... configIds){
+        for(String configId : configIds){
+            Store<PropertyChangeListener> items = changeListeners.get(configId);
+            if(items != null){
+                synchronized(items){
+                    items.add(l);
+                }
+            }
+        }
+    }
+
+    private void removePropertyChangeListener(PropertyChangeListener l, String... configIds){
+        for(String configId : configIds){
+            Store<PropertyChangeListener> items = changeListeners.get(configId);
+            if(items != null){
+                items.remove(l);
+            }
+        }
+    }
+
+    private void publishPropertyChangeEventToGlobalListeners(PropertyChangeEvent evt){
+        Store<PropertyChangeListener> items = changeListeners.get("_globalConfigChangeListeners");
+        if(items != null){
+            synchronized(items){
+                for(PropertyChangeListener l : items){
+                    try{
+                        l.propertyChange(evt);
+                    }
+                    catch(Exception e){
+                        LOG.error("Error thrown by PropertyChangeListener: " + l, e);
+                    }
+                }
+
+            }
+        }
+    }
+
+
+    public void publishPropertyChangeEvent(PropertyChangeEvent evt, String configId){
+        Store<PropertyChangeListener> items = changeListeners.get(configId);
+        if(items != null){
+            synchronized(items){
+                for(PropertyChangeListener l : items){
+                    try{
+                        l.propertyChange(evt);
+                    }
+                    catch(Exception e){
+                        LOG.error("Error thrown by ConfigChangeListener: " + l, e);
+                    }
+                }
+
+            }
+        }
+        publishPropertyChangeEventToGlobalListeners(evt);
+    }
+
+
+    @Override
+    public String toString(){
+        return "WeakConfigListenerManager{" +
+                "changeListeners=" + changeListeners +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/el/ELResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/el/ELResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/el/ELResolver.java
new file mode 100644
index 0000000..fc439d3
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/el/ELResolver.java
@@ -0,0 +1,159 @@
+/*
+ * 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.core.internal.el;
+//
+//import org.apache.tamaya.Configuration;
+//import org.apache.tamaya.Environment;
+//import org.apache.tamaya.core.spi.ExpressionResolver;
+//
+//import javax.el.*;
+//import java.lang.reflect.Method;
+//import java.util.HashMap;
+//import java.util.Map;
+//import java.util.Objects;
+//import java.util.Properties;
+//
+///**
+// * Created by Anatole on 28.09.2014.
+// */
+//public final class ELResolver implements ExpressionResolver{
+//
+//    private ExpressionFactory factory;
+//
+//
+//    @Override
+//    public String getResolverId() {
+//        return "el";
+//    }
+//
+//    @Override
+//    public String resolve(String expression){
+//        if(factory==null){
+//            Properties props = new Properties();
+//            props.setProperty("javax.el.ExpressionFactory", "org.apache.el.ExpressionFactoryImpl");
+//            ExpressionFactory tmpFactory = null;
+//            try {
+//                tmpFactory = ExpressionFactory.newInstance(props);
+//            } catch ( RuntimeException e ) {
+//                System.err.println("Error creating EL expression factory.");
+//            }
+//            factory = tmpFactory;
+//        }
+//        ConfigurationContext context = new ConfigurationContext();
+//        Configuration config = Configuration.of();
+//        Objects.requireNonNull(config);
+//        context.bind("config", config);
+//        context.bind("env", Environment.of());
+//        context.bind("system.env", System.getenv());
+//        context.bind("system.prop", System.getProperties());
+//        ValueExpression converted = factory.createValueExpression(context, expression, Object.class );
+//        return String.valueOf(converted.getValue(context));
+//
+//    }
+//
+//    private class ConfigurationContext extends ELContext{
+//
+//        private final BeanELResolver resolver = new BeanELResolver();
+//        private final FunctionMapper functionMapper = new NoopFunctionMapper();
+//        private final VariableMapper variableMapper = new VariableMapperImpl();
+//        private final Map<String,ValueExpression> variables = new HashMap<>();
+//
+//        @Override
+//        public javax.el.ELResolver getELResolver(){
+//            return resolver;
+//        }
+//
+//        @Override
+//        public FunctionMapper getFunctionMapper(){
+//            return functionMapper;
+//        }
+//
+//        @Override
+//        public VariableMapper getVariableMapper(){
+//            return variableMapper;
+//        }
+//
+//        public void bind(final String variable, final Object obj){
+//            variables.put(variable, new ValueExpression(){
+//                @Override
+//                public Object getValue(ELContext elContext){
+//                    return obj;
+//                }
+//
+//                @Override
+//                public void setValue(ELContext elContext, Object o){
+//                    // ignore
+//                }
+//
+//                @Override
+//                public boolean isReadOnly(ELContext elContext){
+//                    return true;
+//                }
+//
+//                @Override
+//                public Class<?> getType(ELContext elContext){
+//                    return variable.getClass();
+//                }
+//
+//                @Override
+//                public Class<?> getExpectedType(){
+//                    return variable.getClass();
+//                }
+//
+//                @Override
+//                public String getExpressionString(){
+//                    return null;
+//                }
+//
+//                @Override
+//                public boolean equals(Object o){
+//                    return false;
+//                }
+//
+//                @Override
+//                public int hashCode(){
+//                    return 0;
+//                }
+//
+//                @Override
+//                public boolean isLiteralText(){
+//                    return false;
+//                }
+//            });
+//        }
+//
+//        private class VariableMapperImpl extends VariableMapper{
+//            public ValueExpression resolveVariable(String s){
+//                return variables.get(s);
+//            }
+//
+//            public ValueExpression setVariable(String s, ValueExpression valueExpression){
+//                return (variables.put(s, valueExpression));
+//            }
+//        }
+//
+//        private class NoopFunctionMapper extends FunctionMapper{
+//            public Method resolveFunction(String s, String s1){
+//                return null;
+//            }
+//        }
+//
+//    }
+//
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
new file mode 100644
index 0000000..4aa41ab
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
@@ -0,0 +1,43 @@
+/*
+ * 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.core.internal.el;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.core.spi.ExpressionResolver;
+
+import java.util.Optional;
+
+/**
+ * Created by Anatole on 28.09.2014.
+ */
+public final class EnvironmentPropertyResolver implements ExpressionResolver{
+
+    @Override
+    public String getResolverId() {
+        return "env";
+    }
+
+    @Override
+    public String resolve(String expression){
+        return Optional.ofNullable(System.getenv(expression)).orElseThrow(
+                () -> new ConfigException("No such environment property: " + expression)
+        );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
new file mode 100644
index 0000000..450504e
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
@@ -0,0 +1,44 @@
+/*
+ * 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.core.internal.el;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.spi.ExpressionResolver;
+
+import java.util.*;
+
+/**
+ * Created by Anatole on 28.09.2014.
+ */
+public final class SystemPropertyResolver implements ExpressionResolver{
+
+    @Override
+    public String getResolverId() {
+        return "sys";
+    }
+
+    @Override
+    public String resolve(String expression){
+        return Optional.ofNullable(System.getProperty(expression)).orElseThrow(
+                () -> new ConfigException("No such system property: " + expression)
+        );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
new file mode 100644
index 0000000..9b2dc95
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
@@ -0,0 +1,109 @@
+/*
+ * 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.core.internal.env;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.Environment;
+import org.apache.tamaya.core.config.ConfigurationFormats;
+import org.apache.tamaya.core.env.EnvironmentBuilder;
+import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+import org.apache.tamaya.core.spi.EnvironmentProvider;
+import org.apache.tamaya.core.spi.ResourceLoader;
+
+
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by Anatole on 17.10.2014.
+ */
+public class ClassLoaderDependentApplicationEnvironmentProvider implements EnvironmentProvider {
+
+    private static  final Logger LOG = LogManager.getLogger(ClassLoaderDependentApplicationEnvironmentProvider.class);
+
+    private static final String WARID_PROP = "org.apache.tamaya.env.applicationId";
+
+    private Map<ClassLoader, Environment> environments = new ConcurrentHashMap<>();
+    private Map<String, Environment> environmentsByAppId = new ConcurrentHashMap<>();
+
+    @Override
+    public String getEnvironmentType() {
+        return "application";
+    }
+
+    @Override
+    public boolean isEnvironmentActive() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if(cl==null){
+            return false;
+        }
+        List<URI> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+                "classpath*:META-INF/env/application.properties", "classpath*:META-INF/env/application.xml", "classpath*:META-INF/env/application.ini");
+        return !propertyUris.isEmpty();
+    }
+
+    @Override
+    public Environment getEnvironment(Environment parentEnvironment) {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if(cl==null){
+            return null;
+        }
+        Environment environment = this.environments.get(cl);
+        if(environment!=null){
+            return environment;
+        }
+        List<URI> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+                "classpath*:META-INF/env/application.properties", "classpath*:META-INF/env/application.xml", "classpath*:META-INF/env/application.ini");
+        Map<String,String> data = new HashMap<>();
+
+        for(URI uri:propertyUris){
+            try{
+                ConfigurationFormat format = ConfigurationFormats.getFormat(uri);
+                Map<String,String> read = format.readConfiguration(uri);
+                data.putAll(read);
+            }
+            catch(Exception e){
+                LOG.error("Error reading application environment data from " + uri, e);
+            }
+        }
+        String applicationId = data.getOrDefault(WARID_PROP, cl.toString());
+        EnvironmentBuilder builder = EnvironmentBuilder.of(applicationId, getEnvironmentType());
+        builder.setParent(parentEnvironment);
+        builder.set("classloader.type", cl.getClass().getName());
+        builder.set("classloader.info", cl.toString());
+        Set<URI> uris = new HashSet<>();
+        uris.addAll(propertyUris);
+        builder.set("environment.sources", uris.toString());
+        builder.setAll(data);
+        environment = builder.build();
+        this.environments.put(cl, environment);
+        if(applicationId!=null) {
+            this.environmentsByAppId.put(applicationId, environment);
+        }
+        return environment;
+    }
+
+    @Override
+    public Set<String> getEnvironmentContexts() {
+        return environmentsByAppId.keySet();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
new file mode 100644
index 0000000..38b7728
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
@@ -0,0 +1,115 @@
+/*
+ * 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.core.internal.env;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.Environment;
+import org.apache.tamaya.Stage;
+import org.apache.tamaya.core.config.ConfigurationFormats;
+import org.apache.tamaya.core.env.EnvironmentBuilder;
+import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+import org.apache.tamaya.core.spi.EnvironmentProvider;
+import org.apache.tamaya.core.spi.ResourceLoader;
+
+
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by Anatole on 17.10.2014.
+ */
+public class ClassLoaderDependentEarEnvironmentProvider implements EnvironmentProvider {
+
+    private static  final Logger LOG = LogManager.getLogger(ClassLoaderDependentEarEnvironmentProvider.class);
+
+    private static final String EARID_PROP = "org.apache.tamaya.core.env.earId";
+
+    private Map<ClassLoader, Environment> environments = new ConcurrentHashMap<>();
+    private Map<String, Environment> environmentsByEarId = new ConcurrentHashMap<>();
+
+    @Override
+    public String getEnvironmentType() {
+        return "ear";
+    }
+
+    @Override
+    public boolean isEnvironmentActive() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if(cl==null){
+            return false;
+        }
+        List<URI> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+                "classpath*:META-INF/env/ear.properties", "classpath*:META-INF/env/ear.xml", "classpath*:META-INF/env/ear.ini");
+        return !propertyUris.isEmpty();
+    }
+
+    @Override
+    public Environment getEnvironment(Environment parentEnvironment) {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if(cl==null){
+            return null;
+        }
+        Environment environment = this.environments.get(cl);
+        if(environment!=null){
+            return environment;
+        }
+        List<URI> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+                "classpath*:META-INF/env/ear.properties", "classpath*:META-INF/env/ear.xml", "classpath*:META-INF/env/ear.ini");
+        Map<String,String> data = new HashMap<>();
+
+        for(URI uri:propertyUris){
+            try{
+                ConfigurationFormat format = ConfigurationFormats.getFormat(uri);
+                Map<String,String> read = format.readConfiguration(uri);
+                data.putAll(read);
+            }
+            catch(Exception e){
+                LOG.error("Error reading ear environment data from " + uri, e);
+            }
+        }
+        String earId = data.getOrDefault(EARID_PROP, cl.toString());
+        EnvironmentBuilder builder = EnvironmentBuilder.of(earId, getEnvironmentType());
+        builder.setParent(parentEnvironment);
+        String stageValue =  data.get(InitialEnvironmentProvider.STAGE_PROP);
+        if (stageValue != null) {
+            Stage stage = Stage.of(stageValue);
+            builder.setStage(stage);
+        }
+        builder.set("classloader.type", cl.getClass().getName());
+        builder.set("classloader.info", cl.toString());
+        Set<URI> uris = new HashSet<>();
+        uris.addAll(propertyUris);
+        builder.set("environment.sources", uris.toString());
+        builder.setAll(data);
+        environment = builder.build();
+        this.environments.put(cl, environment);
+        if(earId!=null) {
+            this.environmentsByEarId.put(earId, environment);
+        }
+        return environment;
+    }
+
+    @Override
+    public Set<String> getEnvironmentContexts() {
+        return environmentsByEarId.keySet();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/env/InitialEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/InitialEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/InitialEnvironmentProvider.java
new file mode 100644
index 0000000..894e0b2
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/InitialEnvironmentProvider.java
@@ -0,0 +1,92 @@
+/*
+ * 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.core.internal.env;
+
+import org.apache.tamaya.core.env.ConfiguredSystemProperties;
+import org.apache.tamaya.core.env.EnvironmentBuilder;
+
+import java.net.InetAddress;
+import java.util.*;
+import java.util.Map.Entry;
+
+import org.apache.tamaya.Environment;
+import org.apache.tamaya.Stage;
+import org.apache.tamaya.core.spi.EnvironmentProvider;
+
+/**
+ * Default {@link org.apache.tamaya.Environment}.
+ */
+public final class InitialEnvironmentProvider implements EnvironmentProvider{
+
+	public static final String STAGE_PROP = "org.apache.tamaya.stage";
+    public static final Stage DEFAULT_STAGE = Stage.development();
+    private Map<String,Environment> environments = new HashMap<>();
+
+	public InitialEnvironmentProvider() {
+        EnvironmentBuilder builder = EnvironmentBuilder.of(getEnvironmentType(), getEnvironmentType());
+        Properties props = System.getProperties();
+        if(props instanceof ConfiguredSystemProperties){
+            props = ((ConfiguredSystemProperties)props).getInitialProperties();
+        }
+        String stageValue =  props.getProperty(STAGE_PROP);
+        Stage stage = DEFAULT_STAGE;
+        if (stageValue != null) {
+            stage = Stage.of(stageValue);
+        }
+        builder.setStage(stage);
+        // Copy system properties....
+        // TODO filter properties
+        for (Entry<Object, Object> en : props.entrySet()) {
+            builder.set(en.getKey().toString(), en.getValue().toString());
+        }
+        builder.set("timezone", TimeZone.getDefault().getID());
+        builder.set("locale", Locale.getDefault().toString());
+        try {
+            builder.set("host", InetAddress.getLocalHost().toString());
+        } catch (Exception e) {
+// log warning
+        }
+        // Copy env properties....
+        for (Entry<String, String> en : System.getenv().entrySet()) {
+            builder.set(en.getKey(), en.getValue());
+        }
+        environments.put("root", builder.build());
+	}
+
+    @Override
+	public Environment getEnvironment(Environment env) {
+        return environments.get("root");
+	}
+
+    @Override
+    public Set<String> getEnvironmentContexts() {
+        return new HashSet<>(environments.keySet());
+    }
+
+    @Override
+    public String getEnvironmentType() {
+        return "root";
+    }
+
+    @Override
+    public boolean isEnvironmentActive() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java b/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
new file mode 100644
index 0000000..5c3d52a
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
@@ -0,0 +1,101 @@
+/*
+ * 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.core.internal.env;
+
+import org.apache.tamaya.Environment;
+
+import org.apache.tamaya.core.internal.MetaConfig;
+import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.EnvironmentManagerSingletonSpi;
+import org.apache.tamaya.core.spi.EnvironmentProvider;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Service for accessing {@link org.apache.tamaya.Environment}. Environments are used to
+ * access/determine configurations.<br/>
+ * <h3>Implementation PropertyMapSpec</h3> This class is
+ * <ul>
+ * <li>thread safe,
+ * <li>and behaves contextual.
+ * </ul>
+ */
+public class SingleEnvironmentManager implements EnvironmentManagerSingletonSpi{
+
+    private static final String ENVIRONMENT_ORDER_KEY = "org.apache.tamaya.environmentOrder";
+    private static final String DEFAULT_ENVIRONMENT_ORDER = "root,system,ear,application";
+
+    private final Map<String,EnvironmentProvider> providerMap = new HashMap<>();
+    private final List<EnvironmentProvider> environmentProviders = loadEnvironmentProviders();
+
+    private List<EnvironmentProvider> loadEnvironmentProviders() {
+        for(EnvironmentProvider prov: Bootstrap.getServices(EnvironmentProvider.class)){
+            providerMap.put(prov.getEnvironmentType(), prov);
+        }
+        String providerOrdering = MetaConfig.getOrDefault(ENVIRONMENT_ORDER_KEY, DEFAULT_ENVIRONMENT_ORDER);
+        String[] ids = providerOrdering.split(",");
+        List<EnvironmentProvider> providerList = new ArrayList<>();
+        for(String id: ids) {
+            providerList.add(Optional.of(providerMap.get(id.trim())).get());
+        }
+        return providerList;
+    }
+
+    @Override
+    public Environment getEnvironment(){
+        Environment env = null;
+        for(EnvironmentProvider prov: environmentProviders){
+            if(prov.isEnvironmentActive()){
+                env = prov.getEnvironment(env);
+            }
+        }
+        if(env==null){
+            throw new IllegalStateException("No current environment present.");
+        }
+        return env;
+    }
+
+    @Override
+    public Environment getRootEnvironment(){
+        for(EnvironmentProvider prov: environmentProviders){
+            if(prov.isEnvironmentActive()){
+                return prov.getEnvironment(null);
+            }
+        }
+        throw new IllegalStateException("No root environment present.");
+    }
+
+    @Override
+    public Optional<Environment> getEnvironment(String environmentType, String contextId) {
+        return null;
+    }
+
+    @Override
+    public Set<String> getEnvironmentContexts(String environmentType) {
+        return Optional.ofNullable(providerMap.get(environmentType))
+                .orElseThrow(() -> new IllegalArgumentException("No such environment type: " + environmentType))
+                .getEnvironmentContexts();
+    }
+
+    @Override
+    public List<String> getEnvironmentTypeOrder() {
+        return environmentProviders.stream().map(EnvironmentProvider::getEnvironmentType).collect(Collectors.toList());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/env/SystemClassLoaderEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/SystemClassLoaderEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/SystemClassLoaderEnvironmentProvider.java
new file mode 100644
index 0000000..9ea5c38
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/SystemClassLoaderEnvironmentProvider.java
@@ -0,0 +1,96 @@
+/*
+ * 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.core.internal.env;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.Environment;
+import org.apache.tamaya.Stage;
+import org.apache.tamaya.core.config.ConfigurationFormats;
+import org.apache.tamaya.core.env.EnvironmentBuilder;
+import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+import org.apache.tamaya.core.spi.EnvironmentProvider;
+import org.apache.tamaya.core.spi.ResourceLoader;
+
+
+import java.net.URI;
+import java.util.*;
+
+/**
+ * Created by Anatole on 17.10.2014.
+ */
+public class SystemClassLoaderEnvironmentProvider implements EnvironmentProvider {
+
+    private static  final Logger LOG = LogManager.getLogger(SystemClassLoaderEnvironmentProvider.class);
+
+    private Map<String,Environment> environments = new HashMap<>();
+
+    @Override
+    public String getEnvironmentType() {
+        return "system";
+    }
+
+    @Override
+    public boolean isEnvironmentActive() {
+        return true;
+    }
+
+    @Override
+    public Environment getEnvironment(Environment parentEnvironment) {
+        Environment env = this.environments.get("system");
+        if(env!=null){
+            return env;
+        }
+        List<URI> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(ClassLoader.getSystemClassLoader(),
+                "classpath*:META-INF/env/system.properties", "classpath*:META-INF/env/system.xml", "classpath*:META-INF/env/system.ini");
+        EnvironmentBuilder builder = EnvironmentBuilder.of("system", getEnvironmentType());
+        for(URI uri:propertyUris){
+            try{
+                ConfigurationFormat format = ConfigurationFormats.getFormat(uri);
+                Map<String,String> data = format.readConfiguration(uri);
+                builder.setAll(data);
+            }
+            catch(Exception e){
+                LOG.error("Error readong environment data from " + uri, e);
+            }
+        }
+        builder.setParent(parentEnvironment);
+        String stageValue =  builder.getProperty(InitialEnvironmentProvider.STAGE_PROP);
+        Stage stage = InitialEnvironmentProvider.DEFAULT_STAGE;
+        if (stageValue != null) {
+            stage = Stage.of(stageValue);
+        }
+        builder.setStage(stage);
+        builder.set("classloader.type", ClassLoader.getSystemClassLoader().getClass().getName());
+        builder.set("classloader.info", ClassLoader.getSystemClassLoader().toString());
+        Set<URI> uris = new HashSet<>();
+        uris.addAll(propertyUris);
+        builder.set("environment.sources", uris.toString());
+        env = builder.build();
+        this.environments.put("system", env);
+        return env;
+    }
+
+    @Override
+    public Set<String> getEnvironmentContexts() {
+        return this.environments.keySet();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigFormatsSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigFormatsSingletonSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigFormatsSingletonSpi.java
new file mode 100644
index 0000000..124b4fd
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigFormatsSingletonSpi.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.core.internal.format;
+
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+import org.apache.tamaya.core.spi.ConfigurationFormatsSingletonSpi;
+
+import java.net.URI;
+import java.util.*;
+
+import org.apache.tamaya.spi.Bootstrap;
+
+/**
+ * Singleton accessor to access registered reader mechanism.
+ */
+public final class DefaultConfigFormatsSingletonSpi implements ConfigurationFormatsSingletonSpi{
+
+    public ConfigurationFormat getFormat(String formatName){
+        Objects.requireNonNull(formatName);
+        try {
+            for (ConfigurationFormat configFormat : Bootstrap.getServices(ConfigurationFormat.class)) {
+                if(formatName.equals(configFormat.getFormatName())){
+                    return configFormat;
+                }
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public Collection<String> getFormatNames(){
+        Set<String> result = new HashSet<>();
+        try {
+            for (ConfigurationFormat configFormat : Bootstrap.getServices(ConfigurationFormat.class)) {
+                result.add(configFormat.getFormatName());
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+	public ConfigurationFormat getFormat(URI resource) {
+        Objects.requireNonNull(resource);
+        try {
+            for (ConfigurationFormat configFormat : Bootstrap.getServices(ConfigurationFormat.class)) {
+                if(configFormat.isAccepted(resource)){
+                    return configFormat;
+                }
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return null;
+	}
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java b/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
new file mode 100644
index 0000000..b297f7e
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
@@ -0,0 +1,94 @@
+/*
+ * 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.core.internal.format;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+
+
+import org.apache.tamaya.ConfigException;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+public class IniFormat implements ConfigurationFormat{
+
+    private static final Logger LOG = LogManager.getLogger(IniFormat.class);
+
+
+    @Override
+    public String getFormatName(){
+        return "ini";
+    }
+
+    @Override
+    public boolean isAccepted(URI resource){
+        String path = resource.getPath();
+        return path != null && path.endsWith(".ini");
+    }
+
+    @Override
+    public Map<String,String> readConfiguration(URI resource){
+        Map<String,String> result = new HashMap<>();
+        if(isAccepted(resource)){
+            try(InputStream is = resource.toURL().openStream()){
+                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+                String line = reader.readLine();
+                int lineNum = 0;
+                String section = null;
+                while(line != null){
+                    lineNum++;
+                    line = line.trim();
+                    if(line.isEmpty()){
+                        continue;
+                    }
+                    if(line.startsWith("[")){
+                        int end = line.indexOf(']');
+                        if(end < 0){
+                            throw new ConfigException(
+                                    "Invalid INI-Format, ']' expected, at " + lineNum + " in " + resource);
+                        }
+                        section = line.substring(1, end);
+                    }
+                    else{
+                        int sep = line.indexOf('=');
+                        String key = line.substring(0,sep);
+                        String value = line.substring(sep+1);
+                        if(section!=null){
+                            result.put(section + '.' + key, value);
+                        }
+                        else{
+                            result.put(key, value);
+                        }
+                    }
+                    line = reader.readLine();
+                }
+            }
+            catch(Exception e){
+                LOG.error("Error reading configuration: " + resource, e);
+            }
+        }
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesFormat.java b/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesFormat.java
new file mode 100644
index 0000000..3496476
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesFormat.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.tamaya.core.internal.format;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+
+public class PropertiesFormat implements ConfigurationFormat{
+
+    @Override
+    public String getFormatName(){
+        return "properties";
+    }
+
+    @Override
+	public boolean isAccepted(URI resource) {
+		String path = resource.getPath();
+		return path != null && path.endsWith(".properties");
+	}
+
+	@Override
+	public Map<String,String> readConfiguration(URI resource) {
+		if (isAccepted(resource)) {
+			try (InputStream is = resource.toURL().openStream()) {
+				Properties p = new Properties();
+				p.load(is);
+				return Map.class.cast(p);
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		return Collections.emptyMap();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesXmlFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesXmlFormat.java b/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesXmlFormat.java
new file mode 100644
index 0000000..c1d3fbd
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/format/PropertiesXmlFormat.java
@@ -0,0 +1,58 @@
+/*
+ * 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.core.internal.format;
+
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+
+
+public class PropertiesXmlFormat implements ConfigurationFormat{
+
+    @Override
+    public String getFormatName(){
+        return "xml-properties";
+    }
+
+    @Override
+    public boolean isAccepted(URI resource){
+        String path = resource.getPath();
+        return path != null && path.endsWith(".xml");
+    }
+
+    @Override
+    public Map<String,String> readConfiguration(URI resource) {
+        if (isAccepted(resource)) {
+            try (InputStream is = resource.toURL().openStream()) {
+                Properties p = new Properties();
+                p.loadFromXML(is);
+                return Map.class.cast(p);
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        return Collections.emptyMap();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
new file mode 100644
index 0000000..c89250b
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.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.core.internal.inject;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.beans.PropertyChangeEvent;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Created by Anatole on 03.10.2014.
+ */
+public final class ConfigChangeCallbackMethod {
+
+    private static final Logger LOG = LogManager.getLogger(ConfigChangeCallbackMethod.class);
+
+    private Method callbackMethod;
+
+    public ConfigChangeCallbackMethod(Method callbackMethod) {
+        Objects.requireNonNull(callbackMethod);
+        this.callbackMethod = Optional.of(callbackMethod).filter(
+                (m) -> void.class.equals(m.getReturnType()) &&
+                        m.getParameterCount() == 1 &&
+                        m.getParameterTypes()[0].equals(PropertyChangeEvent.class)).get();
+    }
+
+    public void call(Object instance, PropertyChangeEvent configChangeEvent) {
+        try {
+            callbackMethod.setAccessible(true);
+            callbackMethod.invoke(instance, configChangeEvent);
+        } catch (Exception e) {
+            LOG.error("Error calling ConfigChange callback method " + callbackMethod.getDeclaringClass().getName() + '.' + callbackMethod.getName() + " on " + instance, e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
new file mode 100644
index 0000000..53fa163
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
@@ -0,0 +1,223 @@
+/*
+ * 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.core.internal.inject;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertyAdapter;
+import org.apache.tamaya.PropertyAdapters;
+import org.apache.tamaya.annot.*;
+import org.apache.tamaya.core.internal.Utils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Small class that contains and manages all information anc access to a configured field and a concrete instance of
+ * it (referenced by a weak reference). It also implements all aspects of value filtering, conversiong any applying the
+ * final value by reflection.
+ * Created by Anatole on 01.10.2014.
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class ConfiguredField {
+
+    private Logger LOG = LogManager.getLogger(ConfiguredField.class);
+
+    /**
+     * The configured field instance.
+     */
+    private Field annotatedField;
+
+    /**
+     * Models a configured field and provides mechanisms for injection.
+     *
+     * @param field the field instance.
+     */
+    public ConfiguredField(Field field) {
+        Objects.requireNonNull(field);
+        this.annotatedField = field;
+    }
+
+    /**
+     * Evaluate the initial value from the configuration and apply it to the field.
+     *
+     * @param target the target instance.
+     * @throws ConfigException if evaluation or conversion failed.
+     */
+    public void applyInitialValue(Object target) throws ConfigException {
+        Collection<ConfiguredProperty> configuredProperties = Utils.getAnnotations(
+                annotatedField, ConfiguredProperty.class, ConfiguredProperties.class);
+        DefaultAreas areasAnnot = this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        WithLoadPolicy loadPolicy = Utils.getAnnotation(WithLoadPolicy.class, this.annotatedField, this.annotatedField.getDeclaringClass());
+        DefaultValue defaultValue = this.annotatedField.getAnnotation(DefaultValue.class);
+        String configValue = getConfigValue(loadPolicy, areasAnnot, configuredProperties, defaultValue);
+        applyValue(target, configValue, false);
+    }
+
+    /**
+     * Internally evaluated the current vaslid configuration value based on the given annotations present.
+     *
+     * @param loadPolicyAnnot The load policy, determining any explicit listeners to be informed.
+     * @param areasAnnot      Any default areas to be looked up.
+     * @param propertiesAnnot The configured property keys (qualified or relative).
+     * @param defaultAnnot    any configured default value.
+     * @return the value to be applied, or null.
+     */
+    private String getConfigValue(WithLoadPolicy loadPolicyAnnot, DefaultAreas areasAnnot, Collection<ConfiguredProperty> propertiesAnnot, DefaultValue defaultAnnot) {
+        String[] areas = null;
+        if (areasAnnot != null) {
+            areas = areasAnnot.value();
+        }
+        List<String> keys = evaluateKeys(areasAnnot, propertiesAnnot);
+        annotatedField.setAccessible(true);
+        Configuration config = getConfiguration();
+        String configValue = null;
+        for (String key : keys) {
+            if (config.containsKey(key)) {
+                configValue = config.get(key).orElse(null);
+            }
+            if (configValue != null) {
+                break;
+            }
+        }
+        if (configValue == null && defaultAnnot != null) {
+            configValue = defaultAnnot.value();
+        }
+        if (configValue != null) {
+            // net step perform expression resolution, if any
+            return Configuration.evaluateValue(configValue);
+        }
+        return null;
+    }
+
+    /**
+     * This method reapplies a changed configuration value to the field.
+     *
+     * @param target      the target instance, not null.
+     * @param configValue the new value to be applied, null will trigger the evaluation of the configured default value.
+     * @param resolve     set to true, if expression resolution should be applied on the value passed.
+     * @throws ConfigException if the configuration required could not be resolved or converted.
+     */
+    public void applyValue(Object target, String configValue, boolean resolve) throws ConfigException {
+        Objects.requireNonNull(target);
+        try {
+            if (resolve && configValue != null) {
+                // net step perform exression resolution, if any
+                configValue = Configuration.evaluateValue(configValue);
+            }
+            // Check for adapter/filter
+            WithPropertyAdapter adapterAnnot = this.annotatedField.getAnnotation(WithPropertyAdapter.class);
+            Class<? extends PropertyAdapter> propertyAdapterType = null;
+            if (adapterAnnot != null) {
+                propertyAdapterType = adapterAnnot.value();
+                if (!propertyAdapterType.equals(PropertyAdapter.class)) {
+                    // TODO cache here...
+                    PropertyAdapter<String> filter = propertyAdapterType.newInstance();
+                    configValue = filter.adapt(configValue);
+                }
+            }
+            if (configValue == null) {
+                // TODO Check for optional injection!
+                // annotatedField.set(target, null);
+                LOG.info("No config found for " +
+                        this.annotatedField.getDeclaringClass().getName() + '#' +
+                        this.annotatedField.getName());
+            } else {
+                Class baseType = annotatedField.getType();
+                if (String.class.equals(baseType) || baseType.isAssignableFrom(configValue.getClass())) {
+                    annotatedField.set(target, configValue);
+                } else {
+                    PropertyAdapter<?> adapter = PropertyAdapters.getAdapter(baseType);
+                    annotatedField.set(target, adapter.adapt(configValue));
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigException("Failed to inject configured field: " + this.annotatedField.getDeclaringClass()
+                    .getName() + '.' + annotatedField.getName(), e);
+        }
+    }
+
+    /**
+     * Evaluates all absolute configuration key based on the annotations found on a class.
+     *
+     * @param areasAnnot          the (optional) annotation definining areas to be looked up.
+     * @param propertyAnnotations the annotation on field/method level that may defined the
+     *                            exact key to be looked up (in absolute or relative form).
+     * @return the list of keys in order how they should be processed/looked up.
+     */
+    private List<String> evaluateKeys(DefaultAreas areasAnnot,Collection<ConfiguredProperty> propertyAnnotations) {
+        Objects.requireNonNull(propertyAnnotations);
+        List<String> keys = propertyAnnotations.stream().map(s -> s.value()).filter(s -> !s.isEmpty())
+                .collect(Collectors.toList());
+        if (keys.isEmpty()) //noinspection UnusedAssignment
+            keys.add(annotatedField.getName());
+        ListIterator<String> iterator = keys.listIterator();
+        while (iterator.hasNext()) {
+            String next = iterator.next();
+            if (next.startsWith("[") && next.endsWith("]")) {
+                // absolute key, strip away brackets, take key as is
+                iterator.set(next.substring(1, next.length() - 1));
+            } else {
+                if (areasAnnot != null) {
+                    // Remove original entry, since it will be replaced with prefixed entries
+                    iterator.remove();
+                    // Add prefixed entries, including absolute (root) entry for "" area value.
+                    for (String area : areasAnnot.value()) {
+                        iterator.add(area.isEmpty() ? next : area + '.' + next);
+                    }
+                }
+            }
+        }
+        return keys;
+    }
+
+    /**
+     * This method checks if the given (qualified) configuration key is referenced from this field.
+     * This is useful to determine, if a key changed in a configuration should trigger any change events
+     * on the related instances.
+     *
+     * @param key the (qualified) configuration key, not null.
+     * @return true, if the key is referenced.
+     */
+    public boolean matchesKey(String key) {
+        DefaultAreas areasAnnot = this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        Collection<ConfiguredProperty> configuredProperties = Utils.getAnnotations(this.annotatedField, ConfiguredProperty.class,
+                ConfiguredProperties.class );
+        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
+        return keys.contains(key);
+    }
+
+    /**
+     * This method evaluates the {@link Configuration} that currently is valid for the given target field/method.
+     *
+     * @return the {@link Configuration} instance to be used, never null.
+     */
+    public Configuration getConfiguration() {
+        WithConfig name = annotatedField.getAnnotation(WithConfig.class);
+        if(name!=null) {
+            return Configuration.of(name.value());
+        }
+        return Configuration.of();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
new file mode 100644
index 0000000..c037c41
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
@@ -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 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.core.internal.inject;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertyProvider;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.WeakReference;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This service class manages the configured instances that are currently attached to the configuration
+ * system. References to instances are rest as WeakReference instances, and cleanup of internal structures
+ * is performed implictly during event triggering for configuration changes.
+ * Created by Anatole on 03.10.2014.
+ */
+public final class ConfiguredInstancesManager implements PropertyChangeListener{
+
+    private static final ConfiguredInstancesManager INSTANCE = new ConfiguredInstancesManager();
+    private Map<ConfiguredType,List<WeakReference<Object>>> configuredInstances = new ConcurrentHashMap<>();
+    private final Object LOCK = new Object();
+
+    private ConfiguredInstancesManager(){
+//        Configuration.addGlobalPropertyChangeListener(this);
+    }
+
+    public static <T> void register(ConfiguredType configuredType, Object instance) {
+        List<WeakReference<Object>> instances = INSTANCE.configuredInstances.get(configuredType);
+        if(instances==null){
+            synchronized(INSTANCE.configuredInstances){
+                instances = INSTANCE.configuredInstances.get(configuredType);
+                if(instances==null){
+                    instances = Collections.synchronizedList(new ArrayList<>());
+                    INSTANCE.configuredInstances.put(configuredType, instances);
+                }
+            }
+        }
+        synchronized(instances) {
+            instances.add(new WeakReference<>(instance));
+        }
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
+        for(Map.Entry<ConfiguredType,List<WeakReference<Object>>> en: configuredInstances.entrySet()){
+            PropertyProvider propertyProvider = (PropertyProvider)propertyChangeEvent.getSource();
+            if((propertyProvider instanceof Configuration) && en.getKey().isConfiguredBy((Configuration)propertyProvider)){
+                List<WeakReference<Object>> instances = en.getValue();
+                synchronized (instances){
+                    Iterator<WeakReference<Object>> iterator = instances.iterator();
+                    while (iterator.hasNext()) {
+                        WeakReference<Object> ref = iterator.next();
+                        Object instance = ref.get();
+                        if(instance==null){
+                            iterator.remove();
+                        }
+                        else{
+                            en.getKey().triggerConfigUpdate(propertyChangeEvent, instance);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
new file mode 100644
index 0000000..2d65c79
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
@@ -0,0 +1,198 @@
+/*
+ * 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.core.internal.inject;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertyAdapter;
+import org.apache.tamaya.PropertyAdapters;
+import org.apache.tamaya.annot.*;
+import org.apache.tamaya.core.internal.Utils;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Small class that contains and manages all information anc access to a configured field and a concrete instance of
+ * it (referenced by a weak reference). It also implements all aspects of value filtering, conversiong any applying the
+ * final value by reflection.
+ * Created by Anatole on 01.10.2014.
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class ConfiguredMethod {
+
+    private static final Logger LOG = LogManager.getLogger(ConfiguredMethod.class);
+
+    /**
+     * The configured field instance.
+     */
+    private Method annotatedMethod;
+
+    /**
+     * Models a configured field and provides mechanisms for injection.
+     *
+     * @param method the method instance.
+     */
+    public ConfiguredMethod(Method method) {
+        this.annotatedMethod = Objects.requireNonNull(method);
+    }
+
+
+    /**
+     * Internally evaluated the current valid configuration value based on the given annotations present.
+     *
+     * @return the value to be returned, or null.
+     */
+    private String getConfigValue() {
+        DefaultAreas areasAnnot = this.annotatedMethod.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        DefaultValue defaultAnnot = this.annotatedMethod.getAnnotation(DefaultValue.class);
+        Collection<ConfiguredProperty> configuredProperties =
+                Utils.getAnnotations(this.annotatedMethod, ConfiguredProperty.class, ConfiguredProperties.class);
+        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
+        Configuration config = getConfiguration();
+        String configValue = null;
+        for (String key : keys) {
+            if (config.containsKey(key)) {
+                configValue = config.get(key).orElse(null);
+            }
+            if (configValue != null) {
+                break;
+            }
+        }
+        if (configValue == null && defaultAnnot != null) {
+            configValue = defaultAnnot.value();
+        }
+        if (configValue != null) {
+            // net step perform expression resolution, if any
+            return Configuration.evaluateValue(configValue);
+        }
+        return null;
+    }
+
+    /**
+     * Evaluates all absolute configuration key based on the annotations found on a class.
+     *
+     * @param areasAnnot          the (optional) annotation definining areas to be looked up.
+     * @param propertyAnnotations the annotation on field/method level that may defined the
+     *                            exact key to be looked up (in absolute or relative form).
+     * @return the list of keys in order how they should be processed/looked up.
+     */
+    private List<String> evaluateKeys(DefaultAreas areasAnnot, Collection<ConfiguredProperty> propertyAnnotations) {
+        List<String> keys = new ArrayList<>();
+        Objects.requireNonNull(propertyAnnotations);
+        for (ConfiguredProperty property : propertyAnnotations) {
+            if (!property.value().isEmpty()) {
+                keys.add(property.value());
+            }
+        }
+        if (keys.isEmpty()) //noinspection UnusedAssignment
+            keys.add(annotatedMethod.getName());
+        ListIterator<String> iterator = keys.listIterator();
+        while (iterator.hasNext()) {
+            String next = iterator.next();
+            if (next.startsWith("[") && next.endsWith("]")) {
+                // absolute key, strip away brackets, take key as is
+                iterator.set(next.substring(1, next.length() - 1));
+            } else {
+                if (areasAnnot != null) {
+                    // Remove original entry, since it will be replaced with prefixed entries
+                    iterator.remove();
+                    // Add prefixed entries, including absolute (root) entry for "" area value.
+                    for (String area : areasAnnot.value()) {
+                        iterator.add(area.isEmpty() ? next : area + '.' + next);
+                    }
+                }
+            }
+        }
+        return keys;
+    }
+
+    /**
+     * This method checks if the given (qualified) configuration key is referenced from this field.
+     * This is useful to determine, if a key changed in a configuration should trigger any change events
+     * on the related instances.
+     *
+     * @param key the (qualified) configuration key, not null.
+     * @return true, if the key is referenced.
+     */
+    public boolean matchesKey(String key) {
+        DefaultAreas areasAnnot = this.annotatedMethod.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        Collection<ConfiguredProperty> configuredProperties =
+                Utils.getAnnotations(this.annotatedMethod, ConfiguredProperty.class, ConfiguredProperties.class);
+        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
+        return keys.contains(key);
+    }
+
+    /**
+     * This method evaluates the {@link org.apache.tamaya.Configuration} that currently is valid for the given target field/method.
+     *
+     * @return the {@link org.apache.tamaya.Configuration} instance to be used, never null.
+     */
+    public Configuration getConfiguration() {
+        WithConfig name = annotatedMethod.getAnnotation(WithConfig.class);
+        if(name!=null) {
+            return Configuration.of(name.value());
+        }
+        return Configuration.of();
+    }
+
+    /**
+     * This method reapplies a changed configuration value to the field.
+     *
+     * @throws org.apache.tamaya.ConfigException if the configuration required could not be resolved or converted.
+     */
+    public Object getValue(Object[] args) throws ConfigException {
+        // TODO do something with additional args?
+        String configValue = getConfigValue();
+        try {
+            // Check for adapter/filter
+            WithPropertyAdapter adapterAnnot = this.annotatedMethod.getAnnotation(WithPropertyAdapter.class);
+            Class<? extends PropertyAdapter> propertyAdapterType = null;
+            if (adapterAnnot != null) {
+                propertyAdapterType = adapterAnnot.value();
+                if (!propertyAdapterType.equals(PropertyAdapter.class)) {
+                    // TODO cache here...
+                    PropertyAdapter<String> filter = propertyAdapterType.newInstance();
+                    configValue = filter.adapt(configValue);
+                }
+            }
+            if (configValue == null) {
+                // TODO optionally return null...
+                LOG.info("No config value found for " +
+                        this.annotatedMethod.getDeclaringClass().getName() + '#' +
+                        this.annotatedMethod.getName());
+                return null;
+            } else {
+                Class baseType = annotatedMethod.getReturnType();
+                if (String.class.equals(baseType) || baseType.isAssignableFrom(configValue.getClass())) {
+                    return configValue;
+                } else {
+                    PropertyAdapter<?> adapter = PropertyAdapters.getAdapter(baseType);
+                    return adapter.adapt(configValue);
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigException("Failed to inject configured field: " + this.annotatedMethod.getDeclaringClass()
+                    .getName() + '.' + annotatedMethod.getName(), e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
new file mode 100644
index 0000000..798e5a6
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
@@ -0,0 +1,159 @@
+/*
+ * 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.core.internal.inject;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.annot.*;
+
+import java.beans.PropertyChangeEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Structure that contains and manages configuration related things for a configured type registered.
+ * Created by Anatole on 03.10.2014.
+ */
+public class ConfiguredType {
+
+    private List<ConfiguredField> configuredFields = new ArrayList<>();
+    private Map<Method, ConfiguredMethod> configuredMethods = new HashMap<>();
+    private List<ConfigChangeCallbackMethod> callbackMethods = new ArrayList<>();
+    private Class type;
+
+    public ConfiguredType(Class type) {
+        this.type = Objects.requireNonNull(type);
+        for (Field f : type.getDeclaredFields()) {
+            ConfiguredProperties propertiesAnnot = f.getAnnotation(ConfiguredProperties.class);
+            if (propertiesAnnot != null) {
+                try {
+                    ConfiguredField configuredField = new ConfiguredField(f);
+                    configuredFields.add(configuredField);
+                } catch (Exception e) {
+                    throw new ConfigException("Failed to initialized configured field: " +
+                            f.getDeclaringClass().getName() + '.' + f.getName(), e);
+                }
+            }
+            else{
+                ConfiguredProperty propertyAnnot = f.getAnnotation(ConfiguredProperty.class);
+                if (propertyAnnot != null) {
+                    try {
+                        ConfiguredField configuredField = new ConfiguredField(f);
+                        configuredFields.add(configuredField);
+                    } catch (Exception e) {
+                        throw new ConfigException("Failed to initialized configured field: " +
+                                f.getDeclaringClass().getName() + '.' + f.getName(), e);
+                    }
+                }
+            }
+        }
+        for (Method m : type.getDeclaredMethods()) {
+            ConfigChanged mAnnot = m.getAnnotation(ConfigChanged.class);
+            if(mAnnot!=null) {
+                if (m.getParameterTypes().length != 1) {
+                    continue;
+                }
+                if (!m.getParameterTypes()[0].equals(PropertyChangeEvent.class)) {
+                    continue;
+                }
+                if (!void.class.equals(m.getReturnType())) {
+                    continue;
+                }
+                try {
+                    this.callbackMethods.add(new ConfigChangeCallbackMethod(m));
+                } catch (Exception e) {
+                    throw new ConfigException("Failed to initialized configured callback method: " +
+                            m.getDeclaringClass().getName() + '.' + m.getName(), e);
+                }
+            }
+            else{
+                ConfiguredProperties propertiesAnnot = m.getAnnotation(ConfiguredProperties.class);
+                if (propertiesAnnot != null) {
+                    try {
+                        ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
+                        configuredMethods.put(m, configuredMethod);
+                    } catch (Exception e) {
+                        throw new ConfigException("Failed to initialized configured method: " +
+                                m.getDeclaringClass().getName() + '.' + m.getName(), e);
+                    }
+                }
+                else{
+                    ConfiguredProperty propertyAnnot = m.getAnnotation(ConfiguredProperty.class);
+                    if (propertyAnnot != null) {
+                        try {
+                            ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
+                            configuredMethods.put(m, configuredMethod);
+                        } catch (Exception e) {
+                            throw new ConfigException("Failed to initialized configured method: " +
+                                    m.getDeclaringClass().getName() + '.' + m.getName(), e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public Object getConfiguredValue(Method method, Object[] args) {
+        ConfiguredMethod m = this.configuredMethods.get(method);
+        return m.getValue(args);
+    }
+
+    public void configure(Object instance) {
+        for (ConfiguredField field : configuredFields) {
+            field.applyInitialValue(instance);
+        }
+    }
+
+    public void triggerConfigUpdate(PropertyChangeEvent configChangeEvent, Object instance) {
+        // TODO do check for right config ;)
+        configuredFields.stream().filter(field -> field.matchesKey(configChangeEvent.getPropertyName())).forEach(field -> field.applyValue(instance, (String) configChangeEvent.getNewValue(), false));
+        for (ConfigChangeCallbackMethod callBack : this.callbackMethods) {
+            callBack.call(instance, configChangeEvent);
+        }
+    }
+
+    public boolean isConfiguredBy(Configuration configuration) {
+        // TODO implement this
+        return true;
+    }
+
+    public static boolean isConfigured(Class type) {
+        if(type.getAnnotation(DefaultAreas.class)!=null){
+            return true;
+        }
+        // if no class level annotation is there we might have field level annotations only
+        for (Field field : type.getDeclaredFields()) {
+            if (field.isAnnotationPresent(ConfiguredProperties.class)) {
+                return true;
+            }
+        }
+        // if no class level annotation is there we might have method level annotations only
+        for (Method method : type.getDeclaredMethods()) {
+            if (method.isAnnotationPresent(ConfiguredProperties.class)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Class getType() {
+        return this.type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
new file mode 100644
index 0000000..a7f09ef
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.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.core.internal.resources;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Stream;
+
+public class AntPathClasspathResolver implements PathResolver{
+
+    @Override
+    public String getResolverId(){
+        return "classpath";
+    }
+
+    @Override
+    public Collection<URI> resolve(ClassLoader classLoader, Stream<String> expressions){
+        List<URI> result = new ArrayList<>();
+        expressions.forEach((expression) -> {
+            if(expression.startsWith("classpath:")){
+                String exp = expression.substring("classpath:".length());
+                URL url = classLoader.getResource(exp);
+                if(url != null){
+                    try{
+                        result.add(url.toURI());
+                    }
+                    catch(URISyntaxException e){
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cf59ebbd/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
new file mode 100644
index 0000000..4f3a898
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
@@ -0,0 +1,64 @@
+/*
+ * 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.core.internal.resources;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Stream;
+
+public class AntPathClasspathsResolver implements PathResolver{
+
+    @Override
+    public String getResolverId(){
+        return "classpath*";
+    }
+
+    @Override
+    public Collection<URI> resolve(ClassLoader classLoader, Stream<String> expressions){
+        List<URI> result = new ArrayList<>();
+        Objects.requireNonNull(classLoader);
+        expressions.forEach((expression) -> {
+            if(expression.startsWith("classpath*:")){
+                String exp = expression.substring("classpath*:".length());
+                Enumeration<URL> urls;
+                try{
+                    urls = classLoader.getResources(exp);
+                    while(urls.hasMoreElements()){
+                        URL url = (URL) urls.nextElement();
+                        try{
+                            result.add(url.toURI());
+                        }
+                        catch(URISyntaxException e){
+                            // TODO Auto-generated catch block
+                            e.printStackTrace();
+                        }
+                    }
+                }
+                catch(IOException e1){
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+            }
+        });
+        return result;
+    }
+}


Mime
View raw message