This is an automated email from the ASF dual-hosted git repository.

sgoeschl pushed a commit to branch FREEMARKER-195
in repository https://gitbox.apache.org/repos/asf/freemarker-generator.git


The following commit(s) were added to refs/heads/FREEMARKER-195 by this push:
     new 9bc14cf  FREEMARKER-195 [freemarker-generator] Cleanup code and 
examples
9bc14cf is described below

commit 9bc14cf161b9c8e6bde568eb32b3e28ab237b62c
Author: Siegfried Goeschl <[email protected]>
AuthorDate: Mon Oct 4 22:43:33 2021 +0200

    FREEMARKER-195 [freemarker-generator] Cleanup code and examples
---
 .../generator/base/datasource/DataSources.java     | 78 +++++++++++-------
 .../generator/datasource/DataSourcesTest.java      |  6 +-
 .../src/app/examples/templates/datasources.ftl     | 93 ++++++++++------------
 .../generator/cli/model/DataSourcesAdapter.java    | 81 ++++---------------
 4 files changed, 112 insertions(+), 146 deletions(-)

diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
index e6b4c3f..129b996 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
@@ -23,6 +23,7 @@ import org.apache.freemarker.generator.base.util.Validate;
 import java.io.Closeable;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,24 +40,27 @@ public class DataSources implements Closeable {
     /** The underlying list of data sources */
     private final List<DataSource> dataSources;
 
+    /** Map of named data sources */
+    private final Map<String, DataSource> dataSourcesMap;
+
     public DataSources(Collection<DataSource> dataSources) {
-        Validate.notNull(dataSources, "No data sources provided");
-        this.dataSources = new ArrayList<>(dataSources);
+        Validate.notNull(dataSources, "dataSources must not be null");
+
+        this.dataSources = Collections.unmodifiableList(new 
ArrayList<>(dataSources));
+        this.dataSourcesMap = 
Collections.unmodifiableMap(dataSourcesMap(dataSources));
     }
 
     /**
      * Get the names of all data sources.
      *
-     * @return data source names
+     * @return list of data source names
      */
     public List<String> getNames() {
-        return dataSources.stream()
-                .map(DataSource::getName)
-                .collect(Collectors.toList());
+        return new ArrayList<>(dataSourcesMap.keySet());
     }
 
     /**
-     * Get the requested metadata value for all data sources.
+     * Get a list of unique metadata value for all data sources.
      *
      * @param key key of the metadata part
      * @return list of metadata values
@@ -64,13 +68,15 @@ public class DataSources implements Closeable {
     public List<String> getMetadata(String key) {
         return dataSources.stream()
                 .map(ds -> ds.getMetadata(key))
+                .filter(StringUtils::isNotEmpty)
+                .distinct()
                 .collect(Collectors.toList());
     }
 
     /**
-     * Get a list of unique groups of all data sources.
+     * Get a list of unique group names of all data sources.
      *
-     * @return list of groups
+     * @return list of group names
      */
     public List<String> getGroups() {
         return dataSources.stream()
@@ -80,21 +86,22 @@ public class DataSources implements Closeable {
                 .collect(Collectors.toList());
     }
 
+    /**
+     * Returns the number of elements in this list.
+     *
+     * @return the number of elements in this list
+     */
     public int size() {
         return dataSources.size();
     }
 
-    public boolean isEmpty() {
-        return dataSources.isEmpty();
-    }
-
     /**
-     * Get an array representation of the underlying data sources.
+     * Returns <tt>true</tt> if this list contains no elements.
      *
-     * @return list of data sources
+     * @return <tt>true</tt> if this list contains no elements
      */
-    public DataSource[] toArray() {
-        return dataSources.toArray(new DataSource[0]);
+    public boolean isEmpty() {
+        return dataSources.isEmpty();
     }
 
     /**
@@ -103,7 +110,7 @@ public class DataSources implements Closeable {
      * @return list of data sources
      */
     public List<DataSource> toList() {
-        return new ArrayList<>(dataSources);
+        return dataSources;
     }
 
     /**
@@ -118,15 +125,15 @@ public class DataSources implements Closeable {
      * @return linked hasp map of data sources
      */
     public Map<String, DataSource> toMap() {
-        return dataSources.stream().collect(Collectors.toMap(
-                DataSource::getName,
-                identity(),
-                (ds1, ds2) -> {
-                    throw new IllegalStateException("Duplicate key detected 
when generating map: " + ds1 + ", " + ds2);
-                },
-                LinkedHashMap::new));
+        return dataSourcesMap;
     }
 
+    /**
+     * Returns the element at the specified position in this list.
+     *
+     * @param index index of the element to return
+     * @return the element at the specified position in this list
+     */
     public DataSource get(int index) {
         return dataSources.get(index);
     }
@@ -160,9 +167,7 @@ public class DataSources implements Closeable {
      * @see <a 
href="https://commons.apache.org/proper/commons-io/javadocs/api-2.7/org/apache/commons/io/FilenameUtils.html#wildcardMatch-java.lang.String-java.lang.String-";>Apache
 Commons IO</a>
      */
     public List<DataSource> find(String wildcard) {
-        return dataSources.stream()
-                .filter(dataSource -> dataSource.match("name", wildcard))
-                .collect(Collectors.toList());
+        return find(DataSource.METADATA_NAME, wildcard);
     }
 
     /**
@@ -190,4 +195,21 @@ public class DataSources implements Closeable {
                 "dataSources=" + dataSources +
                 '}';
     }
+
+    private static List<DataSource> getNamedDataSources(Collection<DataSource> 
dataSources) {
+        return dataSources.stream()
+                .filter(dataSource -> 
StringUtils.isNotEmpty(dataSource.getName()))
+                .collect(Collectors.toList());
+    }
+
+    private Map<String, DataSource> dataSourcesMap(Collection<DataSource> 
dataSources) {
+        final List<DataSource> namedDataSources = 
getNamedDataSources(dataSources);
+        return namedDataSources.stream().collect(Collectors.toMap(
+                DataSource::getName,
+                identity(),
+                (ds1, ds2) -> {
+                    throw new IllegalStateException("Duplicate names detected 
when generating data source map: " + ds1 + ", " + ds2);
+                },
+                LinkedHashMap::new));
+    }
 }
diff --git 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
index 5dd4360..8ba7905 100644
--- 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
+++ 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
@@ -100,9 +100,9 @@ public class DataSourcesTest {
 
     @Test
     public void shouldGetMetadataParts() {
-        assertEquals(asList("", "pom.xml", ""), 
dataSources().getMetadata("fileName"));
-        assertEquals(asList("default", "default", "default"), 
dataSources().getMetadata("group"));
-        assertEquals(asList("", "xml", ""), 
dataSources().getMetadata("extension"));
+        assertEquals(asList("pom.xml"), dataSources().getMetadata("fileName"));
+        assertEquals(asList("default"), dataSources().getMetadata("group"));
+        assertEquals(asList("xml"), dataSources().getMetadata("extension"));
         assertEquals(asList("unknown", "pom.xml", "server.invalid?foo=bar"), 
dataSources().getMetadata("name"));
     }
 
diff --git 
a/freemarker-generator-cli/src/app/examples/templates/datasources.ftl 
b/freemarker-generator-cli/src/app/examples/templates/datasources.ftl
index 57445ce..32d58b5 100644
--- a/freemarker-generator-cli/src/app/examples/templates/datasources.ftl
+++ b/freemarker-generator-cli/src/app/examples/templates/datasources.ftl
@@ -1,19 +1,19 @@
 <#ftl output_format="plainText" strip_whitespace=true>
 <#--
-  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.
+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.
 -->
 Support FreeMarker Directives
 ==============================================================================
@@ -23,33 +23,33 @@ dataSources?size: ${dataSources?size}
 Use FTL Array-style Access
 ==============================================================================
 <#if dataSources?has_content>
-    dataSources[0]: ${dataSources[0].name}
+dataSources[0]: ${dataSources[0].name}
 <#else>
-    No data sources provided ...
+No data sources provided ...
 </#if>
 
 Iterate Over DataSources as List
 ==============================================================================
 <#list dataSources as dataSource>
-    dataSource[${dataSource?index}] => ${dataSource.uri}<#lt>
+- dataSource[${dataSource?index}] => ${dataSource.name}<#lt>
 </#list>
 
 Iterate Over DataSources as Map
 ==============================================================================
 <#list dataSources as name, dataSource>
-    dataSource["${name}"] => ${dataSource.uri}<#lt>
+- dataSource["${name}"] => ${dataSource.name}<#lt>
 </#list>
 
 Iterate Over DataSources as Values
 ==============================================================================
-<#list dataSources as dataSource>
-    dataSource[${dataSource?index}] => ${dataSource.uri}<#lt>
+<#list dataSources?values as dataSource>
+- dataSource[${dataSource?index}] => ${dataSource.name}<#lt>
 </#list>
 
 Get Document Names As Keys
 ==============================================================================
 <#list dataSources?keys as name>
-    - ${name}<#lt>
+- ${name}<#lt>
 </#list>
 
 Access Underlying DataSources API
@@ -61,39 +61,34 @@ DataSources.find(): ${dataSources?api.find("*")?size}
 Iterate Over DataSources Using Wildcard Search
 ==============================================================================
 <#if dataSources?has_content>
-    <#list dataSources?api.find("*") as dataSource>
-        - ${dataSource.name}
-    </#list>
+<#list dataSources?api.find("*") as dataSource>
+- ${dataSource.name}
+</#list>
 <#else>
-    No data sources provided ...
+No data sources provided ...
 </#if>
 
 <#if dataSources?has_content>
-    <#list dataSources as dataSource>
-        [#${dataSource?counter}] - ${dataSource.name}
-        
==============================================================================
+<#list dataSources as dataSource>
+[#${dataSource?counter}] - ${dataSource.name}
+==============================================================================
 
-        Invoke Arbitrary Methods On DataSource
-        
---------------------------------------------------------------------------
-        <#assign dataSource=dataSources?first>
-        Name                : ${dataSource.name}
-        Nr of lines         : ${dataSource.lines?size}
-        Content Type        : ${dataSource.contentType}
-        Charset             : ${dataSource.charset}
-        Extension           : ${dataSource.extension}
-        Nr of chars         : ${dataSource.text?length}
-        Nr of bytes         : ${dataSource.bytes?size}
+Invoke Arbitrary Methods On DataSource
+---------------------------------------------------------------------------
+<#assign dataSource=dataSources?first>
+Name                : ${dataSource.name}
+Nr of lines         : ${dataSource.lines?size}
+Content Type        : ${dataSource.contentType}
+Charset             : ${dataSource.charset}
+Extension           : ${dataSource.extension}
+Nr of chars         : ${dataSource.text?length}
+Nr of bytes         : ${dataSource.bytes?size}
 
-        Iterating Over Metadata Of A Datasource
-        
---------------------------------------------------------------------------
-        <#list dataSource.metadata as name, value>
-            ${name?right_pad(19)} : ${value}
-        </#list>
+Iterating Over Metadata Of A Datasource
+---------------------------------------------------------------------------
+<#list dataSource.metadata as name, value>
+${name?right_pad(19)} : ${value}
+</#list>
 
-        Iterating Over Properties Of A Datasource
-        
---------------------------------------------------------------------------
-        <#list dataSource.properties as name, value>
-            ${name?right_pad(19)} : ${value}
-        </#list>
-    </#list>
+</#list>
 </#if>
\ No newline at end of file
diff --git 
a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/model/DataSourcesAdapter.java
 
b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/model/DataSourcesAdapter.java
index 39e903b..3f49654 100644
--- 
a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/model/DataSourcesAdapter.java
+++ 
b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/model/DataSourcesAdapter.java
@@ -16,8 +16,6 @@
  */
 package org.apache.freemarker.generator.cli.model;
 
-import freemarker.core._DelayedJQuote;
-import freemarker.core._TemplateModelException;
 import freemarker.ext.util.WrapperTemplateModel;
 import freemarker.template.AdapterTemplateModel;
 import freemarker.template.MapKeyValuePairIterator;
@@ -31,23 +29,23 @@ import freemarker.template.TemplateModelWithAPISupport;
 import freemarker.template.TemplateSequenceModel;
 import freemarker.template.WrappingTemplateModel;
 import freemarker.template.utility.ObjectWrapperWithAPISupport;
-import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSources;
 
 import java.io.Serializable;
-import java.util.Map;
-import java.util.SortedMap;
+
+import static java.util.Objects.requireNonNull;
 
 /**
- * Wraps a map of <code>DataSorces</code> into a FreeMarker template model
- * providing sequence and hash type access.
+ * Wraps an instance of <code>DataSources</code> into a FreeMarker template 
model
+ * providing sequence and hash type access. If required the 
<code>DataSources</code>
+ * API can be accessed using FreeMarkers "?api" built-in.
  */
 public class DataSourcesAdapter extends WrappingTemplateModel
         implements TemplateHashModelEx2, AdapterTemplateModel, 
WrapperTemplateModel, TemplateModelWithAPISupport, TemplateSequenceModel,
         Serializable {
 
+    /** Wrapped instance */
     private final DataSources dataSources;
-    private final Map<String, DataSource> map;
 
     /**
      * Factory method for creating new adapter instances.
@@ -61,92 +59,43 @@ public class DataSourcesAdapter extends 
WrappingTemplateModel
     }
 
     private DataSourcesAdapter(DataSources dataSources, ObjectWrapper wrapper) 
{
-        super(wrapper);
-        this.dataSources = dataSources;
-        this.map = dataSources.toMap();
+        super(requireNonNull(wrapper));
+        this.dataSources = requireNonNull(dataSources);
     }
 
     @Override
     public TemplateModel get(String key) throws TemplateModelException {
-        Object val;
-        try {
-            val = map.get(key);
-        } catch (ClassCastException e) {
-            throw new _TemplateModelException(e,
-                    "ClassCastException while getting Map entry with String 
key ",
-                    new _DelayedJQuote(key));
-        } catch (NullPointerException e) {
-            throw new _TemplateModelException(e,
-                    "NullPointerException while getting Map entry with String 
key ",
-                    new _DelayedJQuote(key));
-        }
-
-        if (val == null) {
-            // Check for Character key if this is a single-character string.
-            // In SortedMap-s, however, we can't do that safely, as it can 
cause ClassCastException.
-            if (key.length() == 1 && !(map instanceof SortedMap)) {
-                final Character charKey = key.charAt(0);
-                try {
-                    val = map.get(charKey);
-                    if (val == null) {
-                        final TemplateModel wrappedNull = wrap(null);
-                        if (wrappedNull == null || !(map.containsKey(key) || 
map.containsKey(charKey))) {
-                            return null;
-                        } else {
-                            return wrappedNull;
-                        }
-                    }
-                } catch (ClassCastException e) {
-                    throw new _TemplateModelException(e,
-                            "Class casting exception while getting Map entry 
with Character key ",
-                            new _DelayedJQuote(charKey));
-                } catch (NullPointerException e) {
-                    throw new _TemplateModelException(e,
-                            "NullPointerException while getting Map entry with 
Character key ",
-                            new _DelayedJQuote(charKey));
-                }
-            } else {  // No char key fallback was possible
-                final TemplateModel wrappedNull = wrap(null);
-                if (wrappedNull == null || !map.containsKey(key)) {
-                    return null;
-                } else {
-                    return wrappedNull;
-                }
-            }
-        }
-
-        return wrap(val);
+        return wrap(dataSources.toMap().get(key));
     }
 
     @Override
     public boolean isEmpty() {
-        return map.isEmpty();
+        return dataSources.isEmpty();
     }
 
     @Override
     public int size() {
-        return map.size();
+        return dataSources.size();
     }
 
     @Override
     public TemplateCollectionModel keys() {
-        return new SimpleCollection(map.keySet(), getObjectWrapper());
+        return new SimpleCollection(dataSources.toMap().keySet(), 
getObjectWrapper());
     }
 
     @Override
     public TemplateCollectionModel values() {
-        return new SimpleCollection(map.values(), getObjectWrapper());
+        return new SimpleCollection(dataSources.toMap().values(), 
getObjectWrapper());
     }
 
     @Override
     public KeyValuePairIterator keyValuePairIterator() {
-        return new MapKeyValuePairIterator(map, getObjectWrapper());
+        return new MapKeyValuePairIterator(dataSources.toMap(), 
getObjectWrapper());
     }
 
     @Override
     public TemplateModel get(int index) throws TemplateModelException {
-        final DataSource[] array = this.dataSources.toArray();
-        return index >= 0 && index < array.length ? wrap(array[index]) : null;
+        return index >= 0 && index < dataSources.size() ? 
wrap(dataSources.get(index)) : null;
     }
 
     @Override

Reply via email to