You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by st...@apache.org on 2014/12/27 14:57:54 UTC
[10/34] incubator-tamaya git commit: first step: move all sources to
a 'dormant' directory
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
new file mode 100644
index 0000000..6290706
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
@@ -0,0 +1,142 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+/**
+ * Created by Anatole on 12.04.2014.
+ */
+class ContextualPropertySource implements PropertySource {
+
+ private volatile Map<String,PropertySource> cachedMaps = new ConcurrentHashMap<>();
+
+ private Supplier<PropertySource> mapSupplier;
+ private Supplier<String> isolationKeySupplier;
+ private String name;
+
+
+ /**
+ * Creates a new contextual PropertyMap. Contextual maps delegate to different instances current PropertyMap depending
+ * on the keys returned fromMap the isolationP
+ *
+ * @param mapSupplier
+ * @param isolationKeySupplier
+ */
+ public ContextualPropertySource(String name, Supplier<PropertySource> mapSupplier, Supplier<String> isolationKeySupplier){
+ this.name = Optional.ofNullable(name).orElse("<noname>");
+ Objects.requireNonNull(mapSupplier);
+ Objects.requireNonNull(isolationKeySupplier);
+ this.mapSupplier = mapSupplier;
+ this.isolationKeySupplier = isolationKeySupplier;
+ }
+
+ /**
+ * This method provides the contextual Map for the current environment. Hereby, ba default, for each different
+ * key returned by the #isolationKeySupplier a separate PropertyMap instance is acquired fromMap the #mapSupplier.
+ * If the map supplier returns an instance it is cached in the local #cachedMaps.
+ *
+ * @return the current contextual PropertyMap.
+ */
+ protected PropertySource getContextualMap(){
+ String environmentKey = this.isolationKeySupplier.get();
+ if(environmentKey == null){
+ return PropertySource.EMPTY_PROPERTYSOURCE;
+ }
+ PropertySource map = this.cachedMaps.get(environmentKey);
+ if(map == null){
+ synchronized(cachedMaps){
+ map = this.cachedMaps.get(environmentKey);
+ if(map == null){
+ map = this.mapSupplier.get();
+ if(map == null){
+ return PropertySource.EMPTY_PROPERTYSOURCE;
+ }
+ this.cachedMaps.put(environmentKey, map);
+ }
+ }
+ }
+ return map;
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ return getContextualMap().getProperties();
+ }
+
+ @Override
+ public String getName(){
+ return this.name;
+ }
+
+ @Override
+ public Optional<String> get(String key){
+ return getContextualMap().get(key);
+ }
+
+ /**
+ * Access a cached PropertyMap.
+ *
+ * @param key the target environment key as returned by the environment key supplier, not null.
+ * @return the corresponding PropertyMap, or null.
+ */
+ public PropertySource getCachedMap(String key){
+ return this.cachedMaps.get(key);
+ }
+
+ /**
+ * Access the set current currently loaded/cached maps.
+ *
+ * @return the set current cached map keys, never null.
+ */
+ public Set<String> getCachedMapKeys(){
+ return this.cachedMaps.keySet();
+ }
+
+ /**
+ * Access the supplier for environment key, determining map isolation.
+ *
+ * @return the environment key supplier instance, not null.
+ */
+ public Supplier<String> getIsolationKeySupplier(){
+ return this.isolationKeySupplier;
+ }
+
+ /**
+ * Access the supplier for new PropertyMap instances.
+ *
+ * @return the PropertyMap supplier instance, not null.
+ */
+ public Supplier<PropertySource> getMapSupplier(){
+ return this.mapSupplier;
+ }
+
+ @Override
+ public String toString(){
+ return "ContextualMap{" +
+ "cachedMaps(key)=" + cachedMaps.keySet() +
+ ", mapSupplier=" + mapSupplier +
+ ", isolationKeySupplier=" + isolationKeySupplier +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
new file mode 100644
index 0000000..c4bfc92
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
@@ -0,0 +1,79 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertySource} that is an aggregate current
+ * multiple child instances. Controlled by an {@link org.apache.tamaya.AggregationPolicy} the
+ * following aggregations are supported:
+ * <ul>
+ * <li><b>IGNORE_DUPLICATES: </b>Ignore all overrides.</li>
+ * <li><b>: </b></li>
+ * <li><b>: </b></li>
+ * <li><b>: </b></li>
+ * </ul>
+ */
+class DelegatingPropertySource implements PropertySource {
+
+ private PropertySource mainMap;
+ private Map<String,String> parentMap;
+ private String name;
+
+
+ /**
+ * Creates a mew instance, with aggregation polilcy
+ * {@code AggregationPolicy.OVERRIDE}.
+ *
+ * @param mainMap The main ConfigMap.
+ * @param parentMap The delegated parent ConfigMap.
+ */
+ public DelegatingPropertySource(String name, PropertySource mainMap, Map<String, String> parentMap){
+ this.name = Optional.of(name).orElse("<noname>");
+ this.parentMap = Objects.requireNonNull(parentMap);
+ this.parentMap = Objects.requireNonNull(parentMap);
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ return null;
+ }
+
+ @Override
+ public String getName(){
+ return this.name;
+ }
+
+ @Override
+ public Optional<String> get(String key){
+ Optional<String> val = mainMap.get(key);
+ if(!val.isPresent()){
+ return Optional.ofNullable(parentMap.get(key));
+ }
+ return val;
+ }
+
+ @Override
+ public String toString(){
+ return super.toString() + "(mainMap=" + mainMap + ", delegate=" + parentMap + ")";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
new file mode 100644
index 0000000..d0b2172
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
@@ -0,0 +1,40 @@
+/*
+ * 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.properties;
+
+import java.util.Map;
+
+class EnvironmentPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 4753258482658331010L;
+
+ public Map<String,String> getProperties(){
+ return System.getenv();
+ }
+
+ public EnvironmentPropertySource(){
+ super("<System.getenv()>");
+ }
+
+ @Override
+ public String toString(){
+ return "EnvironmentPropertyProvider[" + System.getenv().size() + " environment properties]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
new file mode 100644
index 0000000..b3aca71
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
@@ -0,0 +1,97 @@
+/*
+ * 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.properties;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class FileSystemPropertySource extends AbstractClasspathAwarePropertySource {
+
+ private static final Logger LOG = Logger.getLogger(FileSystemPropertySource.class.getName());
+ private static final long serialVersionUID = -2016119697552480056L;
+ private Map<String, Map<String, String>> propMetaInfo = new HashMap<>();
+
+ public FileSystemPropertySource(String resourcePath, ClassLoader classLoader,
+ AbstractClasspathAwarePropertySource parentConfig) {
+ super(classLoader, parentConfig, resourcePath);
+ }
+
+ public FileSystemPropertySource(String resourcePath, AbstractClasspathAwarePropertySource parentConfig) {
+ super(getCurrentClassLoader(), parentConfig, resourcePath);
+ }
+
+ public FileSystemPropertySource(String resourcePath) {
+ super(getCurrentClassLoader(), null, resourcePath);
+ }
+
+
+ @Override
+ protected void readSource(Map<String, String> targetMap, String src) {
+ try (InputStream is = getClassLoader().getResource(
+ src).openStream()) {
+ Properties props = new Properties();
+ URL resource = getClassLoader().getResource(
+ src);
+// if (isSourceRead(resource.toString())) {
+// // continue;
+// return;
+// }
+ addSource(resource.toString());
+ Map<String, String> mi = new HashMap<>();
+ mi.put("source", resource.toString());
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ mi.put("classloader", Thread.currentThread()
+ .getContextClassLoader().toString());
+ }
+ props.load(is);
+ for (Map.Entry<Object, Object> en : props.entrySet()) {
+ targetMap.put(en.getKey().toString(),
+ en.getValue().toString());
+ propMetaInfo.put(en.getKey().toString(),
+ mi);
+ }
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error loading config unit.", e);
+ }
+ }
+
+ protected Map<String, String> getMetaInfo(String key, String value) {
+ Map<String, String> mi = propMetaInfo.get(key);
+ if (mi != null) {
+ return mi;
+ }
+ return Collections.emptyMap();
+ }
+
+ private static ClassLoader getCurrentClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ return FileSystemPropertySource.class.getClassLoader();
+ }
+ return cl;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
new file mode 100644
index 0000000..a0c1a53
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
@@ -0,0 +1,51 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+class FilteredPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 4301042530074932562L;
+ private PropertySource unit;
+ private Predicate<String> filter;
+
+ public FilteredPropertySource(String name, PropertySource configuration, Predicate<String> filter){
+ super(name==null?Objects.requireNonNull(configuration).getName():name);
+ this.unit = configuration;
+ this.filter = filter;
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ final Map<String,String> result = new HashMap<>();
+ this.unit.getProperties().entrySet().forEach(e -> {
+ if(filter.test(e.getKey())){
+ result.put(e.getKey(), e.getValue());
+ }
+ });
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java
new file mode 100644
index 0000000..f0e5eec
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java
@@ -0,0 +1,74 @@
+/*
+ * 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.properties;
+
+import java.io.Serializable;
+import java.util.*;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+ * This class models a freezed instance current an {@link org.apache.tamaya.PropertySource}.
+ * Created by Anatole on 28.03.14.
+ */
+final class FreezedPropertySource implements PropertySource, Serializable{
+
+ private static final long serialVersionUID = 3365413090311267088L;
+ private String name;
+ private Map<String,String> properties = new HashMap<>();
+
+ private FreezedPropertySource(String name, PropertySource propertyMap) {
+ Map<String, String> map = propertyMap.getProperties();
+ this.properties.putAll(map);
+ this.properties = Collections.unmodifiableMap(this.properties);
+ this.name = Optional.ofNullable(name).orElse(propertyMap.getName()+"(freezed)");
+ }
+
+ public static PropertySource of(String name, PropertySource propertyProvider){
+ if(propertyProvider instanceof FreezedPropertySource){
+ return propertyProvider;
+ }
+ return new FreezedPropertySource(name, propertyProvider);
+ }
+
+ public int size(){
+ return properties.size();
+ }
+
+ public boolean isEmpty(){
+ return properties.isEmpty();
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ return Collections.unmodifiableMap(this.properties);
+ }
+
+ @Override
+ public String getName(){
+ return this.name;
+ }
+
+ @Override
+ public Optional<String> get(String key){
+ return Optional.ofNullable(properties.get(key));
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
new file mode 100644
index 0000000..d7c46d2
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
@@ -0,0 +1,55 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Provider implementation that combines multiple other config by intersecting
+ * the key/values common to all config, conflicting keys are resolved using an
+ * {@link org.apache.tamaya.AggregationPolicy}.
+ */
+class IntersectingPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = -1492990130201110889L;
+ private List<PropertySource> providers;
+ private PropertySource aggregatedDelegate;
+
+ public IntersectingPropertySource(String name, AggregationPolicy policy, List<PropertySource> providers) {
+ super(name);
+ this.providers = new ArrayList<>(providers);
+ aggregatedDelegate = PropertySourceBuilder.of(name).withAggregationPolicy(policy)
+ .addProviders(this.providers).build();
+ }
+
+ @Override
+ public Optional<String> get(String key) {
+ return aggregatedDelegate.get(key);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return aggregatedDelegate.getProperties().entrySet().stream().filter(en -> get(en.getKey()).isPresent()).collect(
+ Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
new file mode 100644
index 0000000..41b730e
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.properties;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Models a {@link org.apache.tamaya.PropertySource} that can be build using a builder pattern.
+ */
+class MapBasedPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 7601389831472839249L;
+
+ private static final Logger LOG = Logger.getLogger(MapBasedPropertySource.class.getName());
+ /**
+ * The unit's entries.
+ */
+ private Map<String,String> entries = new ConcurrentHashMap<>();
+
+ /**
+ * Constructor.
+ *
+ * @param entries the config entries, not null.
+ */
+ MapBasedPropertySource(String name, Map<String, String> entries){
+ super(name);
+ Objects.requireNonNull(entries, "entries required.");
+ this.entries.putAll(entries);
+ }
+
+
+ /**
+ * Constructor.
+ *
+ * @param entries the entries
+ * @param sources the sources
+ * @param errors the errors
+ */
+ MapBasedPropertySource(String name, Map<String, String> entries, Set<String> sources,
+ Collection<Throwable> errors){
+ super(name);
+ Objects.requireNonNull(entries, "entries required.");
+ this.entries.putAll(entries);
+ addSources(sources);
+ }
+
+ MapBasedPropertySource(String name, Set<String> sources){
+ super(name);
+ addSources(sources);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return new HashMap<>(this.entries);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
new file mode 100644
index 0000000..80184d1
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
@@ -0,0 +1,83 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.core.resource.ResourceLoader;
+
+import java.util.*;
+
+/**
+ * Implementation of a PropertySource that reads configuration from some given resource paths.
+ */
+final class PathBasedPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 5147019699905042582L;
+ private List<String> paths = new ArrayList<>();
+ private Map<String, String> properties = new HashMap<>();
+ private AggregationPolicy aggregationPolicy;
+
+ public PathBasedPropertySource(String name, Collection<String> paths, AggregationPolicy aggregationPolicy) {
+ super(name);
+ this.paths.addAll(Objects.requireNonNull(paths));
+ this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+ init();
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return this.properties;
+ }
+
+ private void init() {
+ List<String> sources = new ArrayList<>();
+ List<String> effectivePaths = new ArrayList<>();
+ paths.forEach((path) -> {
+ effectivePaths.add(path);
+ for (Resource res : ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(path)) {
+ ConfigurationFormat format = ConfigurationFormat.from(res);
+ if (format != null) {
+ try {
+ Map<String, String> read = format.readConfiguration(res);
+ sources.add(res.toString());
+ read.forEach((k, v) -> {
+ String valueToAdd = aggregationPolicy.aggregate(k,properties.get(k),v);
+ if(valueToAdd==null) {
+ properties.remove(k);
+ }
+ else{
+ properties.put(k, valueToAdd);
+ }
+ });
+ }
+ catch(ConfigException e){
+ throw e;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+// metaInfo = MetaInfoBuilder.of(getMetaInfo())
+// .setSourceExpressions(new String[effectivePaths.size()])
+// .set("sources", sources.toString()).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
new file mode 100644
index 0000000..b099230
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
@@ -0,0 +1,477 @@
+/*
+* 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.properties;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+* Builder for assembling non trivial property providers.
+*/
+public final class PropertySourceBuilder {
+
+ /**
+ * Name used for the final result.
+ */
+ private String name;
+
+ /**
+ * Name used for the next operation.
+ */
+ private String currentName;
+
+ /**
+ * the current property provider, or null.
+ */
+ private PropertySource current;
+ /**
+ * The current aggregation policy used, when aggregating providers.
+ */
+ private AggregationPolicy aggregationPolicy = AggregationPolicy.OVERRIDE;
+
+ /**
+ * Private singleton constructor.
+ */
+ private PropertySourceBuilder(String name) {
+ this.name = Objects.requireNonNull(name);
+ }
+
+ /**
+ * Private singleton constructor.
+ */
+ private PropertySourceBuilder(String name, PropertySource propertySource) {
+ this.name = Objects.requireNonNull(name);
+ this.current = propertySource;
+ }
+
+ /**
+ * Creates a new builder instance.
+ *
+ * @param name the provider name, not null.
+ * @param provider the base provider to be used, not null.
+ * @return a new builder instance, never null.
+ */
+ public static PropertySourceBuilder of(String name, PropertySource provider) {
+ return new PropertySourceBuilder(name, provider);
+ }
+
+ /**
+ * Creates a new builder instance.
+ *
+ * @param provider the base provider to be used, not null.
+ * @return a new builder instance, never null.
+ */
+ public static PropertySourceBuilder of(PropertySource provider) {
+ return new PropertySourceBuilder(provider.getName(), provider);
+ }
+
+
+ /**
+ * Creates a new builder instance.
+ *
+ * @param name the provider name, not null.
+ * @return a new builder instance, never null.
+ */
+ public static PropertySourceBuilder of(String name) {
+ return new PropertySourceBuilder(Objects.requireNonNull(name));
+ }
+
+ /**
+ * Creates a new builder instance.
+ *
+ * @return a new builder instance, never null.
+ */
+ public static PropertySourceBuilder of() {
+ return new PropertySourceBuilder("<noname>");
+ }
+
+
+
+
+ /**
+ * Sets the aggregation policy to be used, when adding additional property sets. The policy will
+ * be active a slong as the builder is used or it is reset to another keys.
+ *
+ * @param aggregationPolicy the aggregation policy, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder withAggregationPolicy(AggregationPolicy aggregationPolicy) {
+ this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+ return this;
+ }
+
+ /**
+ * Adds the given providers with the current active {@link AggregationPolicy}. By
+ * default {@link AggregationPolicy#OVERRIDE} is used.
+ * @see #withAggregationPolicy(AggregationPolicy)
+ * @param providers providers to be added, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addProviders(PropertySource... providers) {
+ if(providers.length==0){
+ return this;
+ }
+ return addProviders(Arrays.asList(providers));
+ }
+
+ /**
+ * Adds the given providers with the current active {@link AggregationPolicy}. By
+ * default {@link AggregationPolicy#OVERRIDE} is used.
+ * @see #withAggregationPolicy(AggregationPolicy)
+ * @param providers providers to be added, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addProviders(List<PropertySource> providers) {
+ if(providers.isEmpty()){
+ return this;
+ }
+ List<PropertySource> allProviders = new ArrayList<>(providers);
+ if (this.current != null) {
+ allProviders.add(0, this.current);
+ }
+ StringBuilder b = new StringBuilder();
+ providers.forEach(p -> b.append(p.getName()).append(','));
+ b.setLength(b.length()-1);
+ String source = b.toString();
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<aggregate> -> source=" + source;
+ }
+ this.current = PropertySourceFactory.aggregate(name, this.aggregationPolicy, allProviders);
+ this.currentName = null;
+ return this;
+ }
+
+ /**
+ * Creates a new {@link PropertySource} using the given command line arguments and adds it
+ * using the current aggregation policy in place.
+ *
+ * @param args the command line arguments, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addArgs(String... args) {
+ if(args.length==0){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<CLI-args>";
+ }
+ PropertySource argProvider = PropertySourceFactory.fromArgs(name, args);
+ return addProviders(argProvider);
+ }
+
+ /**
+ * Creates a new read-only {@link PropertySource} by reading the according path resources. The effective resources read
+ * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+ * Properties read are aggregated using the current aggregation policy active.
+ *
+ * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addPaths(String... paths) {
+ if(paths.length==0){
+ return this;
+ }
+ return addPaths(Arrays.asList(paths));
+ }
+
+
+ /**
+ * Creates a new read-only {@link PropertySource} by reading the according path resources. The effective resources read
+ * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+ * Properties read are aggregated using the current aggregation policy active.
+ *
+ * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addPaths(List<String> paths) {
+ if(paths.isEmpty()){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<aggregate> -> paths=" + paths.toString();
+ }
+ return addProviders(PropertySourceFactory.fromPaths(name, aggregationPolicy, paths));
+ }
+
+ /**
+ * Creates a new read-only {@link PropertySource} by reading the according URL resources.
+ * Properties read are aggregated using the current aggregation policy active.
+ *
+ * @param urls the urls to be read, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addURLs(URL... urls) {
+ if(urls.length==0){
+ return this;
+ }
+ return addURLs(Arrays.asList(urls));
+ }
+
+ /**
+ * Creates a new read-only {@link PropertySource} by reading the according URL resources.
+ * Properties read are aggregated using the current aggregation policy active.
+ *
+ * @param urls the urls to be read, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addURLs(List<URL> urls) {
+ if(urls.isEmpty()){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<aggregate> -> urls=" + urls;
+ }
+ return addProviders(PropertySourceFactory.fromURLs(name, this.aggregationPolicy, urls));
+ }
+
+
+ /**
+ * Creates a new read-only {@link PropertySource} based on the given map.
+ * Properties read are aggregated using the current aggregation policy active.
+ *
+ * @param map the map to be added, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addMap(Map<String, String> map) {
+ if(map.isEmpty()){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<Map> -> map=" + map;
+ }
+ return addProviders(PropertySourceFactory.fromMap(name, map));
+ }
+
+
+ /**
+ * Add the current environment properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+ *
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addEnvironmentProperties() {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<System.getenv()>";
+ }
+ return addProviders(PropertySourceFactory.fromEnvironmentProperties());
+ }
+
+ /**
+ * Add the current system properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+ *
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder addSystemProperties() {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<System.getProperties()>";
+ }
+ return addProviders(PropertySourceFactory.fromSystemProperties());
+ }
+
+ /**
+ * Add the name used for the next aggregation/adding operation on this builder.
+ * @param name the name to be used, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder withName(String name) {
+ this. currentName = Objects.requireNonNull(name);
+ return this;
+ }
+
+ /**
+ * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+ * active.
+ *
+ * @param providers the maps to be included, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder aggregate(PropertySource... providers) {
+ if(providers.length==0){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<aggregate> -> " + Arrays.toString(providers);
+ }
+ return addProviders(PropertySourceFactory.aggregate(name, aggregationPolicy, Arrays.asList(providers)));
+ }
+
+
+ /**
+ * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+ * active.
+ *
+ * @param providers the maps to be included, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder aggregate(List<PropertySource> providers) {
+ if(providers.isEmpty()){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<aggregate> -> " + providers;
+ }
+ return addProviders(PropertySourceFactory.aggregate(name, aggregationPolicy, providers));
+ }
+
+
+ /**
+ * Filters the current {@link org.apache.tamaya.PropertySource} with the given valueFilter.
+ * @param valueFilter the value filter, not null.
+ * @return the (dynamically) filtered source instance, never null.
+ */
+ public PropertySourceBuilder filterValues(BiFunction<String, String, String> valueFilter){
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<filteredValues> -> " + valueFilter;
+ }
+ this.current = PropertySourceFactory.filterValues(name, valueFilter, this.current);
+ return this;
+ }
+
+
+ /**
+ * Intersetcs the current properties with the given {@link org.apache.tamaya.PropertySource} instance.
+ *
+ * @param providers the maps to be intersected, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder intersect(PropertySource... providers) {
+ if(providers.length==0){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<intersection> -> " + Arrays.toString(providers);
+ }
+ return addProviders(PropertySourceFactory.intersected(name, aggregationPolicy, Arrays.asList(providers)));
+ }
+
+
+ /**
+ * Subtracts with the given {@link org.apache.tamaya.PropertySource} instance from the current properties.
+ *
+ * @param providers the maps to be subtracted, not null.
+ * @return the builder for chaining.
+ */
+ public PropertySourceBuilder subtract(PropertySource... providers) {
+ if(providers.length==0){
+ return this;
+ }
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<subtraction> -> " + Arrays.toString(providers);
+ }
+ current = PropertySourceFactory.subtracted(name, current, Arrays.asList(providers));
+ return this;
+ }
+
+
+ /**
+ * Filters the current properties based on the given predicate..
+ *
+ * @param filter the filter to be applied, not null.
+ * @return the new filtering instance.
+ */
+ public PropertySourceBuilder filter(Predicate<String> filter) {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<filtered> -> " + filter;
+ }
+ current = PropertySourceFactory.filtered(name, filter, current);
+ this.currentName = null;
+ return this;
+ }
+
+ /**
+ * Creates a new contextual {@link org.apache.tamaya.PropertySource}. Contextual maps delegate to different instances current PropertyMap depending
+ * on the keys returned fromMap the isolationP
+ *
+ * @param mapSupplier the supplier creating new provider instances
+ * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
+ */
+ public PropertySourceBuilder addContextual(Supplier<PropertySource> mapSupplier,
+ Supplier<String> isolationKeySupplier) {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<contextual> -> map="+mapSupplier+",isolationKeySupplier="+isolationKeySupplier;
+ }
+ return addProviders(PropertySourceFactory.contextual(name, mapSupplier, isolationKeySupplier));
+ }
+
+ /**
+ * Replaces all keys in the current provider by the given map.
+ *
+ * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
+ * @return the new delegating instance.
+ */
+ public PropertySourceBuilder replace(Map<String, String> replacementMap) {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<replacement> -> current="+current.getName()+" with ="+replacementMap;
+ }
+ current = PropertySourceFactory.replacing(name, current, replacementMap);
+ this.currentName = null;
+ return this;
+ }
+
+ /**
+ * Build a new property provider based on the input.
+ * @return a new property provider, or null.
+ */
+ public PropertySource build(){
+ if (current != null) {
+ return PropertySourceFactory.build(name, current);
+ }
+ return PropertySourceFactory.empty(name);
+ }
+
+ /**
+ * Creates a {@link PropertySource} instance that is serializable and immutable,
+ * so it can be sent over a network connection.
+ *
+ * @return the freezed instance, never null.
+ */
+ public PropertySource buildFrozen() {
+ String name = this.currentName;
+ if (currentName == null) {
+ name = "<freezed> -> source="+current.getName();
+ }
+ PropertySource prov = PropertySourceFactory.freezed(name, current);
+ this.currentName = null;
+ return prov;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
new file mode 100644
index 0000000..3f8a0b1
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
@@ -0,0 +1,287 @@
+/*
+ * 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.properties;
+
+import java.net.URL;
+import java.time.Instant;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+ * Default implementation current the singleton backing bean for the {@link org.apache.tamaya.core.properties.PropertySourceBuilder}.
+ */
+public final class PropertySourceFactory {
+
+ private static final PropertySource EMPTY_PROPERTYSOURCE = fromMap("<empty>", Collections.emptyMap());
+ private static final PropertySource ENV_PROPERTYSOURCE = new EnvironmentPropertySource();
+
+
+ /**
+ * Singleton constructor.
+ */
+ private PropertySourceFactory(){}
+
+ public static PropertySource fromArgs(String name, String... args) {
+ if(name==null){
+ name ="<CLI> " + Arrays.toString(args);
+ }
+ // TODO read the CLI with some better library, e.g. move parsing service to ext. service SPI
+ Map<String, String> properties = new HashMap<>();
+ for (int base = 0; base < args.length; base++) {
+ if (args[base].startsWith("--")) {
+ String argKey = args[base].substring(2);
+ String value = "true"; // flag only
+ if (base != args.length - 1) {
+ if (args[base + 1].startsWith("-")) {
+ base++;
+ int eqIndex = argKey.indexOf('=');
+ if (eqIndex > 0) {
+ value = argKey.substring(eqIndex + 1);
+ argKey = argKey.substring(0, eqIndex);
+ }
+ } else {
+ value = args[base + 1];
+ base += 2;
+ }
+ }
+ properties.put(argKey, value);
+ } else if (args[base].startsWith("-")) {
+ String argKey = args[base].substring(1);
+ String value = "true"; // flag only
+ if (base != args.length - 1) {
+ if (args[base + 1].startsWith("-")) {
+ base++;
+ int eqIndex = argKey.indexOf('=');
+ if (eqIndex > 0) {
+ value = argKey.substring(eqIndex + 1);
+ argKey = argKey.substring(0, eqIndex);
+ }
+ } else {
+ value = args[base + 1];
+ base += 2;
+ }
+ }
+ properties.put(argKey, value);
+ }
+ }
+ return fromMap(name, properties);
+ }
+
+ public static PropertySource fromPaths(String name, AggregationPolicy aggregationPolicy, List<String> paths) {
+ if(name==null){
+ name ="<Paths> " + paths.toString();
+ }
+ return new PathBasedPropertySource(name, paths, aggregationPolicy);
+ }
+
+ public static PropertySource fromURLs(String name, AggregationPolicy aggregationPolicy, List<URL> urls) {
+ if(name==null){
+ name ="<URLs> " + urls.toString();
+ }
+ return new URLBasedPropertySource(name, urls, aggregationPolicy);
+ }
+
+ public static PropertySource fromMap(String name, Map<String, String> map) {
+ if(name==null){
+ name ="<Map> " + map.toString();
+ }
+ return new MapBasedPropertySource(name, map);
+ }
+
+ public static PropertySource empty(String name) {
+ if(name==null) {
+ return EMPTY_PROPERTYSOURCE;
+ }
+ return fromMap(name, Collections.emptyMap());
+ }
+
+ /**
+ * Returns a read-only {@link org.apache.tamaya.PropertySource} reflecting the current runtime environment properties.
+ *
+ * @return a new read-only {@link org.apache.tamaya.PropertySource} instance based on the current runtime environment properties.
+ */
+ public static PropertySource fromEnvironmentProperties() {
+ return ENV_PROPERTYSOURCE;
+ }
+
+ /**
+ * Creates a new read-only {@link org.apache.tamaya.PropertySource} reflecting the current system properties.
+ *
+ * @return a new read-only {@link org.apache.tamaya.PropertySource} instance based on the current system properties.
+ */
+ public static PropertySource fromSystemProperties() {
+ return new SystemPropertiesPropertySource();
+ }
+
+ public static PropertySource freezed(String name, PropertySource source) {
+ if(name==null){
+ name ="<Freezed> source=" + source.toString()+", at="+Instant.now().toString();
+ }
+ return FreezedPropertySource.of(name, source);
+ }
+
+ /**
+ * Creates a new {@link org.apache.tamaya.PropertySource} containing all property maps given, hereby using the given AggregationPolicy.
+ *
+ * @param policy the AggregationPolicy to be used, not null.
+ * @param providers the maps to be included, not null.
+ * @return the aggregated instance containing all given maps.
+ */
+ public static PropertySource aggregate(String name, AggregationPolicy policy, List<PropertySource> providers) {
+ if(name==null){
+ name ="<Aggregate> policy=" + policy.toString()+", providers="+providers.toString();
+ }
+ return new AggregatedPropertySource(name, null, policy, providers);
+ }
+
+ /**
+ * Creates a new {@link org.apache.tamaya.PropertySource} that is mutable by adding a map based instance that overrides
+ * values fromMap the original map.
+ * @param provider the provider to be made mutable, not null.
+ * @return the mutable instance.
+ */
+ public static PropertySource mutable(String name, PropertySource provider) {
+ if(name==null){
+ name ="<Mutable> provider="+provider.getName();
+ }
+ PropertySource mutableProvider = fromMap(name,new HashMap<>());
+ List<PropertySource> providers = new ArrayList<>(2);
+ providers.add(provider);
+ providers.add(mutableProvider);
+ return new AggregatedPropertySource(name, mutableProvider, AggregationPolicy.OVERRIDE, providers);
+ }
+
+ /**
+ * Creates a new {@link org.apache.tamaya.PropertySource} containing only properties that are shared by all given maps,
+ * hereby later maps in the array override properties fromMap previous instances.
+ * @param aggregationPolicy the policy to resolve aggregation conflicts.
+ * @param providers the maps to be included, not null.
+ * @return the intersecting instance containing all given maps.
+ */
+ public static PropertySource intersected(String name, AggregationPolicy aggregationPolicy, List<PropertySource> providers) {
+ return new IntersectingPropertySource(name, aggregationPolicy, providers);
+ }
+
+ /**
+ * Creates a new {@link org.apache.tamaya.PropertySource} containing only properties fromMap the target instance, that are not contained
+ * in one current the other maps passed.
+ *
+ * @param target the base map, not null.
+ * @param subtrahendSets the maps to be subtracted, not null.
+ * @return the intersecting instance containing all given maps.
+ */
+ public static PropertySource subtracted(String name, PropertySource target, List<PropertySource> subtrahendSets) {
+ return new SubtractingPropertySource(name, target,subtrahendSets);
+ }
+
+
+ /**
+ * Creates a filtered {@link org.apache.tamaya.PropertySource} (a view) current a given base {@link }PropertyMap}. The filter hereby is
+ * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
+ *
+ * @param name the base map instance, not null.
+ * @param filter the filtger to be applied, not null.
+ * @return the new filtering instance.
+ */
+ public static PropertySource filtered(String name, Predicate<String> filter, PropertySource source) {
+ if(name==null){
+ name ="<Filtered> filter="+filter+", source="+source.getName();
+ }
+ return new FilteredPropertySource(name, source, filter);
+ }
+
+ /**
+ * Creates a new contextual {@link org.apache.tamaya.PropertySource}. Contextual maps delegate to different instances current PropertyMap depending
+ * on the keys returned fromMap the isolationP
+ *
+ * @param name the base name instance, not null.
+ * @param mapSupplier the supplier creating new provider instances
+ * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
+ */
+ public static PropertySource contextual(String name, Supplier<PropertySource> mapSupplier,
+ Supplier<String> isolationKeySupplier) {
+ if(name==null){
+ name ="<Contextual> mapSupplier="+mapSupplier+", isolationKeyProvider="+isolationKeySupplier;
+ }
+ return new ContextualPropertySource(name, mapSupplier, isolationKeySupplier);
+ }
+
+
+ /**
+ * Creates a filtered {@link org.apache.tamaya.PropertySource} (a view) current a given base {@link }PropertyMap}. The filter hereby is
+ * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
+ *
+ * @param name the base name instance, not null.
+ * @param source the main map instance, not null.
+ * @param parentMap the delegated parent map instance, not null.
+ * @return the new delegating instance.
+ */
+ public static PropertySource delegating(String name, PropertySource source, Map<String, String> parentMap) {
+ if(name==null){
+ name ="<Delegating> source="+source+", delegates="+parentMap;
+ }
+ return new DelegatingPropertySource(name, source, parentMap);
+ }
+
+ /**
+ * Creates a {@link org.apache.tamaya.PropertySource} where all keys current a current map,
+ * existing in another map are replaced
+ * with the ones fromMap the other {@link org.apache.tamaya.PropertySource}. The filter hereby is
+ * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
+ * Keys not existing in the {@code mainMap}, but present in {@code replacementMao} will be hidden.
+ *
+ * @param name the base name instance, not null.
+ * @param source the main source instance, which keys, present in {@code replacementMap} will be replaced
+ * with the ones
+ * in {@code replacementMap}, not null.
+ * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
+ * @return the new delegating instance.
+ */
+ public static PropertySource replacing(String name, PropertySource source, Map<String, String> replacementMap) {
+ if(name==null){
+ name ="<Replacement> source="+source+", replacements="+replacementMap;
+ }
+ return new ReplacingPropertySource(name, source, replacementMap);
+ }
+
+ /**
+ * Creates a new {@link org.apache.tamaya.PropertySource} given an existing one, and an alternate
+ * meta-info.
+ * @param name the new meta-information, not null.
+ * @param baseProvider the property source, not null.
+ * @return the new property source.never null.
+ */
+ public static PropertySource build(String name, PropertySource baseProvider) {
+ return new BuildablePropertySource(name, baseProvider);
+ }
+
+ /**
+ * Creates a new filtered {@link org.apache.tamaya.PropertySource} using the given filter.
+ * @param name the base name instance, not null.
+ * @param valueFilter the value filter function, null result will remove the given entries.
+ * @param current the source to be filtered
+ */
+ public static PropertySource filterValues(String name, BiFunction<String, String, String> valueFilter, PropertySource current) {
+ return new ValueFilteredPropertySource(name, valueFilter, current);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
new file mode 100644
index 0000000..85100e3
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertySource} that is an aggregate current
+ * multiple child instances, where all existing key/values in a replacementMap will
+ * replace values in a main map, if present there.
+ */
+class ReplacingPropertySource implements PropertySource {
+
+ private PropertySource mainMap;
+ private Map<String,String> replacingMap;
+ private String name;
+
+ /**
+ * Creates a mew instance, with aggregation polilcy
+ * {@code AggregationPolicy.OVERRIDE}.
+ *
+ * @param mainMap The main ConfigMap.
+ * @param replacingMap The replacing ConfigMap.
+ */
+ public ReplacingPropertySource(String name, PropertySource mainMap, Map<String, String> replacingMap){
+ this.replacingMap = Objects.requireNonNull(replacingMap);
+ this.mainMap = Objects.requireNonNull(mainMap);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ Map<String,String> result = new HashMap<>(replacingMap);
+ mainMap.getProperties().entrySet().stream().filter(en -> !replacingMap.containsKey(en.getKey())).forEach(en ->
+ result.put(en.getKey(), en.getValue()));
+ return result;
+ }
+
+ @Override
+ public String getName(){
+ return this.name;
+ }
+
+ @Override
+ public Optional<String> get(String key){
+ String val = replacingMap.get(key);
+ if(val == null){
+ return mainMap.get(key);
+ }
+ return Optional.ofNullable(val);
+ }
+
+ @Override
+ public String toString(){
+ return super.toString() + "(mainMap=" + mainMap + ", replacingMap=" + replacingMap + ")";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
new file mode 100644
index 0000000..f78ceb9
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
@@ -0,0 +1,56 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+class SubtractingPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 4301042530074932562L;
+ private PropertySource unit;
+ private List<PropertySource> subtrahends;
+
+ public SubtractingPropertySource(String name, PropertySource configuration, List<PropertySource> subtrahends){
+ super(name);
+ Objects.requireNonNull(configuration);
+ this.unit = configuration;
+ this.subtrahends = new ArrayList<>(subtrahends);
+ }
+
+ private boolean filter(Map.Entry<String,String> entry){
+ for(PropertySource prov: subtrahends){
+ if(prov.get(entry.getKey()).isPresent()){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ return this.unit.getProperties().entrySet().stream().filter(this::filter).collect(Collectors.toMap(
+ Map.Entry::getKey,
+ Map.Entry::getValue
+ ));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
new file mode 100644
index 0000000..f66c4f8
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
@@ -0,0 +1,56 @@
+/*
+ * 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.properties;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+class SystemPropertiesPropertySource extends AbstractPropertySource {
+
+
+ private static final long serialVersionUID = -5935940312707001199L;
+
+ /**
+ * Constructor.
+ */
+ protected SystemPropertiesPropertySource() {
+ super("<System.getProperties()>");
+ }
+
+ @Override
+ public Map<String,String> getProperties(){
+ Properties sysProps = System.getProperties();
+// if(sysProps instanceof ConfiguredSystemProperties){
+// sysProps = ((ConfiguredSystemProperties)sysProps).getInitialProperties();
+// }
+ Map<String,String> props = new HashMap<>();
+ for (Map.Entry<Object,Object> en : sysProps.entrySet()) {
+ props.put(en.getKey().toString(), en.getValue().toString());
+ }
+ return Collections.unmodifiableMap(props);
+ }
+
+ @Override
+ public String toString(){
+ return "SystemPropertiesPropertyProvider[" + System.getProperties().size() + " system properties]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java
new file mode 100644
index 0000000..f690ef9
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.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.tamaya.core.properties;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.core.internal.resources.io.UrlResource;
+import org.apache.tamaya.core.resource.Resource;
+
+import java.net.URL;
+import java.util.*;
+
+/**
+ * Created by Anatole on 16.10.2014.
+ */
+final class URLBasedPropertySource extends AbstractPropertySource {
+
+ private static final long serialVersionUID = 648272283683183532L;
+ private List<URL> resources = new ArrayList<>();
+ private Map<String,String> properties = new HashMap<>();
+ private AggregationPolicy aggregationPolicy;
+
+ public URLBasedPropertySource(String name, List<URL> resources, AggregationPolicy aggregationPolicy) {
+ super(name);
+ this.resources.addAll(Objects.requireNonNull(resources));
+ this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+ init();
+ }
+
+ private void init(){
+ List<String> sources = new ArrayList<>();
+ for(URL url : resources){
+ Resource res = new UrlResource(url);
+ ConfigurationFormat format = ConfigurationFormat.from(res);
+ if(format != null){
+ try{
+ Map<String, String> read = format.readConfiguration(res);
+ sources.add(res.toString());
+ read.forEach((k, v) -> {
+ String newValue = aggregationPolicy.aggregate(k, properties.get(k), v);
+ if(newValue==null) {
+ properties.remove(k);
+ }
+ else {
+ properties.put(k, newValue);
+ }
+ });
+ }
+ catch(ConfigException e){
+ throw e;
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+// MetaInfoBuilder metaInfoBuilder = MetaInfoBuilder.of(getMetaInfo());
+// metaInfo = metaInfoBuilder
+// .setSources(sources.toString()).build();
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
new file mode 100644
index 0000000..db17d21
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
@@ -0,0 +1,51 @@
+package org.apache.tamaya.core.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+
+/**
+ * Property source which filters any key/values dynamically.
+ */
+class ValueFilteredPropertySource implements PropertySource{
+
+ private String name;
+ private BiFunction<String, String, String> valueFilter;
+ private PropertySource source;
+
+ public ValueFilteredPropertySource(String name, BiFunction<String, String, String> valueFilter, PropertySource current) {
+ this.name = Optional.ofNullable(name).orElse("<valueFiltered> -> name="+current.getName()+", valueFilter="+valueFilter.toString());
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Optional<String> get(String key) {
+ String value = this.source.get(key).orElse(null);
+ value = valueFilter.apply(key, value);
+ return Optional.ofNullable(value);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ Map<String, String> map = new HashMap<>(source.getProperties());
+ map.replaceAll(valueFilter);
+ return map;
+ }
+
+ @Override
+ public String toString() {
+ return "ValueFilteredPropertySource{" +
+ "source=" + source.getName() +
+ ", name='" + name + '\'' +
+ ", valueFilter=" + valueFilter +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
new file mode 100644
index 0000000..102337d
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
@@ -0,0 +1,55 @@
+/*
+* Copyright 2002-2012 the original author or authors.
+*
+* Licensed 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.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+* Simple interface for objects that are sources for an {@link InputStream}.
+*
+* <p>This is the base interface for Spring's more extensive {@link Resource} interface.
+*
+* <p>For single-use streams, {@link org.apache.tamaya.core.internal.resources.io.InputStreamResource} can be used for any
+* given {@code InputStream}. Spring's {@code ByteArrayResource} or any
+* file-based {@code Resource} implementation can be used as a concrete
+* instance, allowing one to read the underlying content stream multiple times.
+* This makes this interface useful as an abstract content source for mail
+* attachments, for example.
+*
+* @author Juergen Hoeller
+* @since 20.01.2004
+* @see java.io.InputStream
+* @see Resource
+* @see org.apache.tamaya.core.internal.resources.io.InputStreamResource
+*/
+@FunctionalInterface
+public interface InputStreamSource {
+
+ /**
+ * Return an {@link InputStream}.
+ * <p>It is expected that each call creates a <i>fresh</i> stream.
+ * <p>This requirement is particularly important when you consider an API such
+ * as JavaMail, which needs to be able to read the stream multiple times when
+ * creating mail attachments. For such a use case, it is <i>required</i>
+ * that each {@code getInputStreamSupplier()} call returns a fresh stream.
+ * @return the input stream for the underlying resource (must not be {@code null})
+ * @throws IOException if the stream could not be opened
+ */
+ InputStream getInputStream() throws IOException;
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
new file mode 100644
index 0000000..ca76974
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed 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.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * Interface for a resource descriptor that abstracts from the actual
+ * type current underlying resource, such as a file or class path resource.
+ *
+ * <p>An InputStream can be opened for every resource if it exists in
+ * physical form, but a URL or File handle can just be returned for
+ * certain resources. The actual behavior is implementation-specific.
+ *
+ * @author Juergen Hoeller
+ * @since 28.12.2003
+ * @see #getInputStream()
+ * @see #getURL()
+ * @see #getURI()
+ * @see #getFile()
+ */
+public interface Resource extends InputStreamSource {
+
+ /**
+ * Return whether this resource actually exists in physical form.
+ * <p>This method performs a definitive existence check, whereas the
+ * existence current a {@code Resource} handle only guarantees a
+ * valid descriptor handle.
+ */
+ boolean exists();
+
+ /**
+ * Return whether the contents current this resource can be read,
+ * e.g. via {@link #getInputStream()} or {@link #getFile()}.
+ * <p>Will be {@code true} for typical resource descriptors;
+ * note that actual content reading may still fail when attempted.
+ * However, a keys current {@code false} is a definitive indication
+ * that the resource content cannot be read.
+ * @see #getInputStream()
+ */
+ boolean isReadable();
+
+ /**
+ * Return whether this resource represents a handle with an open
+ * stream. If true, the InputStream cannot be read multiple times,
+ * and must be read and closed to avoid resource leaks.
+ * <p>Will be {@code false} for typical resource descriptors.
+ */
+ boolean isOpen();
+
+ /**
+ * Return a URL handle for this resource.
+ * @throws IOException if the resource cannot be resolved as URL,
+ * i.e. if the resource is not available as descriptor
+ */
+ URL getURL() throws IOException;
+
+ /**
+ * Return a URI handle for this resource.
+ * @throws IOException if the resource cannot be resolved as URI,
+ * i.e. if the resource is not available as descriptor
+ */
+ URI getURI() throws IOException;
+
+ /**
+ * Return a File handle for this resource.
+ * @throws IOException if the resource cannot be resolved as absolute
+ * file path, i.e. if the resource is not available in a file system
+ */
+ File getFile() throws IOException;
+
+ /**
+ * Determine the content length for this resource.
+ * @throws IOException if the resource cannot be resolved
+ * (in the file system or as some other known physical resource type)
+ */
+ long contentLength() throws IOException;
+
+ /**
+ * Determine the last-modified timestamp for this resource.
+ * @throws IOException if the resource cannot be resolved
+ * (in the file system or as some other known physical resource type)
+ */
+ long lastModified() throws IOException;
+
+ /**
+ * Create a resource relative to this resource.
+ * @param relativePath the relative path (relative to this resource)
+ * @return the resource handle for the relative resource
+ * @throws IOException if the relative resource cannot be determined
+ */
+ Resource createRelative(String relativePath) throws IOException;
+
+ /**
+ * Determine a filename for this resource, i.e. typically the last
+ * part current the path: for example, "myfile.txt".
+ * <p>Returns {@code null} if this type current resource does not
+ * have a filename.
+ */
+ String getFilename();
+
+ /**
+ * Get a description of the resource.
+ * @return the description.
+ */
+ String getDescription();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java
new file mode 100644
index 0000000..1c55e55
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.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.tamaya.core.resource;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Interface to be implemented by containers that decouples loading current classpath resources fromMap the effective
+ * classloader architecture current a runtime environment. Implementations current this class encapsulate the mechanism current
+ * determining the
+ * concrete resources available base on an expression defining the configuration
+ * locations. A an example the expression {@code cfg/global/*.xml} defines a
+ * location for reading global configuration in the classpath. A resources
+ * interprets this expression and evaluates the concrete resources to be read,
+ * e.g. {@code cfg/global/default.xml, cfg/global/myApp.xml}.
+ * Created by Anatole on 16.06.2014.
+ */
+public interface ResourceLoader{
+
+ /**
+ * Get the prefixes supportedby this loader.
+ *
+ * @return the supported prefixes, not empty.
+ */
+ Collection<String> getResolverIds();
+
+ /**
+ * Called, when a given expression has to be resolved.
+ *
+ * @param expressions the expressions to be resolved, not empty.
+ * @return the corresponding collection current {@link java.net.URI}s defining the
+ * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+ * .
+ */
+ List<Resource> getResources(String... expressions);
+
+ /**
+ * Called, when a given expression has to be resolved.
+ *
+ * @param expressions the expressions to be resolved, not empty.
+ * @return the corresponding collection current {@link java.net.URI}s defining the
+ * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+ * .
+ */
+ List<Resource> getResources(Collection<String> expressions);
+
+ /**
+ * Called, when a given expression has to be resolved.
+ *
+ * @param expressions the expressions to be resolved, not empty.
+ * @return the corresponding collection current {@link java.net.URI}s defining the
+ * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+ * .
+ */
+ List<Resource> getResources(ClassLoader classLoader, String... expressions);
+
+ /**
+ * Called, when a given expression has to be resolved.
+ *
+ * @param expressions the expressions to be resolved, not empty.
+ * @return the corresponding collection current {@link java.net.URI}s defining the
+ * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+ * .
+ */
+ List<Resource> getResources(ClassLoader classLoader, Collection<String> expressions);
+
+}