Reworked format API.

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

Branch: refs/heads/master
Commit: 1e871d87a02458c84e9798b37bdaf7237eab65be
Parents: 120fbd4
Author: anatole <anat...@apache.org>
Authored: Thu Feb 12 22:23:02 2015 +0100
Committer: anatole <anat...@apache.org>
Committed: Thu Feb 12 22:32:23 2015 +0100

----------------------------------------------------------------------
 ...hBasedMultiFormatPropertySourceProvider.java |  24 +---
 .../BaseSimpleFormatPropertySourceProvider.java |  35 +----
 .../tamaya/format/ConfigurationDataBuilder.java | 140 +++++++++++++++++++
 .../tamaya/format/ConfigurationFormat.java      |  58 ++------
 .../tamaya/format/IniConfigurationFormat.java   |  23 +--
 .../apache/tamaya/format/PropertiesFormat.java  |  15 +-
 .../tamaya/format/PropertiesXmlFormat.java      |  16 +--
 7 files changed, 172 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/BasePathBasedMultiFormatPropertySourceProvider.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/BasePathBasedMultiFormatPropertySourceProvider.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/BasePathBasedMultiFormatPropertySourceProvider.java
index ed59f39..cb60d6e 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/BasePathBasedMultiFormatPropertySourceProvider.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/BasePathBasedMultiFormatPropertySourceProvider.java
@@ -28,7 +28,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.logging.Level;
@@ -89,14 +88,10 @@ public abstract class 
BasePathBasedMultiFormatPropertySourceProvider implements
     /**
      * Method to create a {@link org.apache.tamaya.spi.PropertySource} based 
on the given entries read.
      *
-     * @param entryTypeName the entry type of the entries read, not null.
-     * @param entries       the entries read by the {@link 
org.apache.tamaya.format.ConfigurationFormat}
-     * @param formatUsed    the format instance used to read the entries.
+     * @param data the configuration data, not null.
      * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready 
to be registered.
-     * @see org.apache.tamaya.format.ConfigurationFormat#getEntryTypes()
      */
-    protected abstract PropertySource getPropertySource(String entryTypeName, 
Map<String, String> entries,
-                                                        ConfigurationFormat 
formatUsed);
+    protected abstract Collection<PropertySource> 
getPropertySources(ConfigurationData data);
 
     /**
      * This method does dynamically resolve the paths using the current 
ClassLoader set. If no ClassLoader was
@@ -107,23 +102,16 @@ public abstract class 
BasePathBasedMultiFormatPropertySourceProvider implements
      */
     @Override
     public Collection<PropertySource> getPropertySources() {
+        ResourceResolver resourceResolver = 
ServiceContext.getInstance().getService(ResourceResolver.class).get();
         List<PropertySource> propertySources = new ArrayList<>();
         paths.forEach((path) -> {
-            for (URL res : 
ServiceContext.getInstance().getService(ResourceResolver.class).get().getResources(
+            for (URL res : resourceResolver.getResources(
                     
this.classLoader.orElse(Thread.currentThread().getContextClassLoader()),
                     path)) {
                 try {
                     for (ConfigurationFormat format : configFormats) {
-                        Map<String, Map<String, String>> entries = 
format.readConfiguration(res);
-                        for (Map.Entry<String, Map<String, String>> en : 
entries.entrySet()) {
-                            PropertySource ps = getPropertySource(en.getKey(), 
en.getValue(), format);
-                            if (ps != null) {
-                                propertySources.add(ps);
-                            } else {
-                                LOG.info(() -> "Config Entries read ignored by 
PropertySourceFactory: format=" + format +
-                                        ", entryType=" + en.getKey());
-                            }
-                        }
+                        ConfigurationData entries = 
format.readConfiguration(res);
+                        propertySources.addAll(getPropertySources(entries));
                     }
                 } catch (Exception e) {
                     LOG.log(Level.WARNING, "Failed to add resource based 
config: " + res, e);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/BaseSimpleFormatPropertySourceProvider.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/BaseSimpleFormatPropertySourceProvider.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/BaseSimpleFormatPropertySourceProvider.java
index 1fe08c2..64afdfe 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/BaseSimpleFormatPropertySourceProvider.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/BaseSimpleFormatPropertySourceProvider.java
@@ -64,40 +64,9 @@ public abstract class BaseSimpleFormatPropertySourceProvider 
implements Property
     /**
      * Method to create a {@link org.apache.tamaya.spi.PropertySource} based 
on the given entries read.
      *
-     * @param entryTypeName the entry type of the entries read, not null.
-     * @param entries       the entries read by the {@link ConfigurationFormat}
-     * @param formatUsed    the format instance used to read the entries.
+     * @param configData the config data read.
      * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready 
to be registered.
-     * @see ConfigurationFormat#getEntryTypes()
      */
-    protected abstract PropertySource getPropertySource(String entryTypeName, 
Map<String, String> entries,
-                                                        ConfigurationFormat 
formatUsed);
-
-    /**
-     * This method does dynamically resolve the paths using the current 
ClassLoader set. If no ClassLoader was
-     * explcitly set during creation the current Thread context ClassLoader is 
used. If none of the supported
-     * formats is able to parse a resource a WARNING log is written.
-     *
-     * @return the PropertySources successfully read
-     */
-    @Override
-    public Collection<PropertySource> getPropertySources() {
-        List<PropertySource> propertySources = new ArrayList<>();
-        try {
-            Map<String, Map<String, String>> entries = 
configFormat.readConfiguration(resource);
-            for (Map.Entry<String, Map<String, String>> en : 
entries.entrySet()) {
-                PropertySource ps = getPropertySource(en.getKey(), 
en.getValue(), configFormat);
-                if (ps != null) {
-                    propertySources.add(ps);
-                } else {
-                    LOG.info(() -> "Config Entries read ignored by 
PropertySourceFactory: format=" + configFormat +
-                            ", entryType=" + en.getKey());
-                }
-            }
-        } catch (Exception e) {
-            LOG.log(Level.WARNING, "Failed to add resource based config: " + 
resource, e);
-        }
-        return propertySources;
-    }
+    protected abstract Collection<PropertySource> 
createPropertySourcea(ConfigurationData configData);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
new file mode 100644
index 0000000..556d3ed
--- /dev/null
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
@@ -0,0 +1,140 @@
+/*
+ * 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.format;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * Builder for creating {@link org.apache.tamaya.format.ConfigurationData} 
instances. This class is not thread-safe.
+ */
+public final class ConfigurationDataBuilder {
+
+    /** The format instance used to read this instance. */
+    ConfigurationFormat format;
+    /** The resource read. */
+    URL resource;
+    /** The data read. */
+    Map<String,Map<String,String>> data = new HashMap<>();
+
+    /**
+     * Private constructor.
+     * @param resource the configuration resource URL, not null.
+     * @param format the format that read this data, not null.
+     */
+    private ConfigurationDataBuilder(URL resource, ConfigurationFormat format){
+        this.format = Objects.requireNonNull(format);
+        this.resource = Objects.requireNonNull(resource);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param resource the configuration resource URL, not null.
+     * @param format the format that read this data, not null.
+     */
+    public static ConfigurationDataBuilder of(URL resource, 
ConfigurationFormat format){
+        return new ConfigurationDataBuilder(resource, format);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param data an existing COnfigurationData instances used to initialize 
the builder.
+     */
+    public static ConfigurationDataBuilder of(ConfigurationData data){
+        ConfigurationDataBuilder b = new 
ConfigurationDataBuilder(data.getResource(), data.getFormat());
+        b.data.putAll(data.getData());
+        return b;
+    }
+
+    /**
+     * Adds (empty) sections,if they are not yet existing. Already existing 
sections will not be touched.
+     * @param sections the new sections to add.
+     * @return the builder for chaining.
+     */
+    public ConfigurationDataBuilder addSections(String... sections){
+        for(String section:sections) {
+            this.data.computeIfAbsent(section, (k) -> new HashMap<>());
+        }
+        return this;
+    }
+
+    /**
+     * Adds a single entry to a target section.
+     * @param section the target section (will be created if not existing).
+     * @param key the entry's key
+     * @param value the entry's value
+     * @return the builder for chaining.
+     */
+    public ConfigurationDataBuilder addProperty(String section, String key, 
String value){
+        Map<String,String> map = this.data.computeIfAbsent(section, (k) -> new 
HashMap<>());
+        map.put(key, value);
+        return this;
+    }
+
+    /**
+     * Adds a single entry to the <i>default</i> section.
+     * @param key the entry's key
+     * @param value the entry's value
+     * @return the builder for chaining.
+     */
+    public ConfigurationDataBuilder addProperty(String key, String value){
+        return addProperty(ConfigurationData.DEFAULT_SECTION_NAME, key, value);
+    }
+
+    /**
+     * Adds the given entries to the given section, all existing values will 
be overridden.
+     * @param section the target section (will be created if not existing).
+     * @param properties the entry's data
+     * @return the builder for chaining.
+     */
+    public ConfigurationDataBuilder addProperties(String section, 
Map<String,String> properties){
+        Map<String,String> map = this.data.computeIfAbsent(section, (k) -> new 
HashMap<>());
+        map.putAll(properties);
+        return this;
+    }
+
+    /**
+     * Adds the given entries to the <i>default</i> section, all existing 
values will be overridden.
+     * @param properties the entry's data
+     * @return the builder for chaining.
+     */
+    public ConfigurationDataBuilder addProperties( Map<String,String> 
properties){
+        return addProperties(ConfigurationData.DEFAULT_SECTION_NAME, 
properties);
+    }
+
+    /**
+     * Builds a new {@link org.apache.tamaya.format.ConfigurationData} 
instance.
+     * @return a new {@link org.apache.tamaya.format.ConfigurationData} 
instance, not null.
+     */
+    public ConfigurationData build(){
+        return new ConfigurationData(this);
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigurationDataBuilder{" +
+                "format=" + format +
+                ", data=" + data +
+                ", resource=" + resource.toString() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
index 53c171c..e35517b 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
@@ -19,56 +19,25 @@
 package org.apache.tamaya.format;
 
 import java.net.URL;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * Implementations current this class encapsulate the mechanism how to read a
  * resource including interpreting the format correctly (e.g. xml vs.
- * properties). In most cases file only contains entries of the same priority, 
which would then
- * result in only one {@link org.apache.tamaya.spi.PropertySource}. Complex 
file formats, hoiwever, may contain entries
- * of different priorities. In this cases, each ordinal type found must be 
returned as a separate
- * {@link org.apache.tamaya.spi.PropertySource} instance.
+ * properties vs. ini). In most cases file only contains entries of the same 
priority, which would then
+ * result in only one {@link org.apache.tamaya.spi.PropertySource}. Complex 
file formats, however, may contain entries
+ * of different priorities. In this cases, each ordinal type found typically 
is returned as a separate section so the
+ * consuming {@link org.apache.tamaya.spi.PropertySourceProvider} 
implementation can distribute the different part to
+ * individual {@link org.apache.tamaya.spi.PropertySource}s.<p>
+ * <h3>Implementation Requirements</h3>
+ * Implementations of this type must be
+ * <ul>
+ *     <li>thread-safe</li>
+ * </ul>
  */
+@FunctionalInterface
 public interface ConfigurationFormat {
 
     /**
-     * The default entry type returned if a format implementation does not 
support any explicit entry types.
-     */
-    public static final String DEFAULT_ENTRY_TYPE = "default";
-    public static final Set<String> DEFAULT_ENTRY_TYPE_SET = initDefaultSet();
-    public static final String DYNAMIC_ENTRY_TYPE = "<dynamic>";
-
-    static Set<String> initDefaultSet(){
-            Set<String> set = new HashSet<>();
-            set.add(DEFAULT_ENTRY_TYPE);
-            return Collections.unmodifiableSet(set);
-    };
-
-    /**
-     * Access the different entry types a format supports. Entries of the same 
entry type hereby share the same
-     * configuration priority. The reason for this concept is that a 
configuration format can produce different
-     * types of properties, e.g. default properties, named properties, 
overriding ones as illustrated below:
-     * <pre>
-     *     [defaults]
-     *     a.b.c=alphabet
-     *     foo.bar=any
-     *
-     *     [staged:development]
-     *     a.b.myEntry=1234
-     *
-     *     [management-overrides]
-     *     a.b.d=Alphabet
-     * </pre>
-     * If just using ordinary property files, of course, only one entry type 
is returned, called 'default'.
-     * #see DEFAULT_ENTRY_TYPE
-     * @return the set of supported entry types, never null and never empty.
-     */
-    public Set<String> getEntryTypes();
-
-    /**
      * Reads a list {@link org.apache.tamaya.spi.PropertySource} instances 
from a resource, using this format.
      * If the configuration format only contains entries of one ordinal type, 
normally only one single
      * instance of PropertySource is returned. Nevertheless custom formats may 
contain different sections or parts,
@@ -78,10 +47,9 @@ public interface ConfigurationFormat {
      *
      * @param url the url to read the configuration data from (could be a 
file, a remote location, a classpath
      *            resource or something else.
-     * @return the corresponding {@link java.util.Map} instances of properties 
read, never {@code null}. Each
-     * {@link java.util.Map} instance hereby is provided using a type key.
+     * @return the corresponding {@link ConfigurationData} containing 
sections/properties read, never {@code null}.
      * @throws org.apache.tamaya.ConfigException if parsing of the input fails.
      */
-    Map<String, Map<String,String>> readConfiguration(URL url);
+    ConfigurationData readConfiguration(URL url);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/IniConfigurationFormat.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/IniConfigurationFormat.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/IniConfigurationFormat.java
index cb73c1e..4e0efa9 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/IniConfigurationFormat.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/IniConfigurationFormat.java
@@ -24,12 +24,9 @@ import org.apache.commons.configuration.SubnodeConfiguration;
 import org.apache.tamaya.ConfigException;
 
 import java.net.URL;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Implements a ini file format based on the APache Commons
@@ -37,21 +34,9 @@ import java.util.Set;
  */
 public class IniConfigurationFormat implements ConfigurationFormat{
 
-    private Set<String> entryTypes = new HashSet<>();
-
-    public IniConfigurationFormat(){
-        entryTypes.add(ConfigurationFormat.DYNAMIC_ENTRY_TYPE);
-        entryTypes = Collections.unmodifiableSet(entryTypes);
-    }
-
-    @Override
-    public Set<String> getEntryTypes() {
-        return entryTypes;
-    }
-
     @Override
-    public Map<String, Map<String, String>> readConfiguration(URL url) {
-        Map<String, Map<String, String>> result = new HashMap<>();
+    public ConfigurationData readConfiguration(URL url) {
+        ConfigurationDataBuilder builder = ConfigurationDataBuilder.of(url, 
this);
         try {
             HierarchicalINIConfiguration commonIniConfiguration = new 
HierarchicalINIConfiguration(url);
             for(String section:commonIniConfiguration.getSections()){
@@ -62,11 +47,11 @@ public class IniConfigurationFormat implements 
ConfigurationFormat{
                     String key = keyIter.next();
                     properties.put(key, sectionConfig.getString(key));
                 }
-                result.put(section, properties);
+                builder.addProperties(section, properties);
             }
-            return result;
         } catch (ConfigurationException e) {
             throw new ConfigException("Failed to parse ini-file format from " 
+ url, e);
         }
+        return builder.build();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesFormat.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesFormat.java 
b/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesFormat.java
index 48a5288..62b6a4e 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesFormat.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesFormat.java
@@ -21,11 +21,9 @@ package org.apache.tamaya.format;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
-import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -40,28 +38,21 @@ public class PropertiesFormat implements 
ConfigurationFormat {
      */
     private final static Logger LOG = 
Logger.getLogger(PropertiesFormat.class.getName());
 
-    @Override
-    public Set<String> getEntryTypes() {
-        Set<String> set = new HashSet<>();
-        set.add(ConfigurationFormat.DEFAULT_ENTRY_TYPE);
-        return set;
-    }
 
     @SuppressWarnings("unchecked")
     @Override
-    public Map<String, Map<String, String>> readConfiguration(URL url) {
+    public ConfigurationData readConfiguration(URL url) {
         Objects.requireNonNull(url);
 
-        Map<String, Map<String, String>> result = new HashMap<>();
         try (InputStream is = url.openStream()) {
             if (is != null) {
                 final Properties p = new Properties();
                 p.load(is);
-                result.put(ConfigurationFormat.DEFAULT_ENTRY_TYPE, 
Map.class.cast(p));
+                return ConfigurationDataBuilder.of(url, this).addProperties( 
Map.class.cast(p)).build();
             }
         } catch (Exception e) {
             LOG.log(Level.FINEST, e, () -> "Failed to read config from 
resource: " + url);
         }
-        return result;
+        return ConfigurationDataBuilder.of(url, this).build();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/1e871d87/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesXmlFormat.java
----------------------------------------------------------------------
diff --git 
a/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesXmlFormat.java
 
b/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesXmlFormat.java
index 4ec0898..893ad80 100644
--- 
a/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesXmlFormat.java
+++ 
b/modules/formats/src/main/java/org/apache/tamaya/format/PropertiesXmlFormat.java
@@ -36,29 +36,21 @@ public class PropertiesXmlFormat implements 
ConfigurationFormat {
      */
     private final static Logger LOG = 
Logger.getLogger(PropertiesXmlFormat.class.getName());
 
-    @Override
-    public Set<String> getEntryTypes() {
-        Set<String> set = new HashSet<>();
-        set.add(ConfigurationFormat.DEFAULT_ENTRY_TYPE);
-        return set;
-    }
-
 
     @SuppressWarnings("unchecked")
     @Override
-    public Map<String, Map<String, String>> readConfiguration(URL url) {
+    public ConfigurationData readConfiguration(URL url) {
         Objects.requireNonNull(url);
 
-        Map<String, Map<String, String>> result = new HashMap<>();
         try (InputStream is = url.openStream()) {
             if (is != null) {
                 final Properties p = new Properties();
-                p.loadFromXML(is);
-                result.put(ConfigurationFormat.DEFAULT_ENTRY_TYPE, 
Map.class.cast(p));
+                p.load(is);
+                return ConfigurationDataBuilder.of(url, this).addProperties( 
Map.class.cast(p)).build();
             }
         } catch (Exception e) {
             LOG.log(Level.FINEST, e, () -> "Failed to read config from 
resource: " + url);
         }
-        return result;
+        return ConfigurationDataBuilder.of(url, this).build();
     }
 }

Reply via email to