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

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

commit 3202e9412601973ac95d71956a4d419a9526ce98
Author: Siegfried Goeschl <[email protected]>
AuthorDate: Mon Feb 8 21:18:10 2021 +0100

    FREEMARKER-172 [freemarker-generator] Propagate properties to data sources
---
 .../generator/base/datasource/DataSource.java      | 29 +++++++--
 .../base/datasource/DataSourceFactory.java         | 68 +++++++++++++++-------
 .../base/datasource/DataSourcesSupplier.java       | 12 ++--
 .../datasource/loader/FileDataSourceLoader.java    |  7 ++-
 .../datasource/loader/HttpDataSourceLoader.java    |  4 +-
 .../datasource/DataSourceFactoryTest.java          |  5 +-
 .../generator/datasource/DataSourceTest.java       | 23 ++++----
 .../datasource/DataSourcesSupplierTest.java        | 24 +++++++-
 .../generator/datasource/DataSourcesTest.java      |  4 +-
 .../examples/templates/datasources.ftl}            | 44 ++++++++++----
 .../cli/config/OutputGeneratorsSupplier.java       |  3 +-
 .../freemarker/generator/cli/ManualTest.java       |  2 +-
 .../src/test/templates/manual.ftl                  | 26 +++++++--
 13 files changed, 184 insertions(+), 67 deletions(-)

diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSource.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSource.java
index 0bb4b57..5d5d42d 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSource.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSource.java
@@ -35,6 +35,7 @@ import java.io.StringWriter;
 import java.net.URI;
 import java.nio.charset.Charset;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -90,28 +91,44 @@ public class DataSource implements Closeable, 
javax.activation.DataSource {
     /** The underlying "javax.activation.DataSource" */
     private final javax.activation.DataSource dataSource;
 
-    /** Content type of data source either provided by the user or fetched 
directly from the data source */
+    /** Content type of data source either provided by the caller or fetched 
directly from the data source */
     private final String contentType;
 
     /** Charset for directly accessing text-based content */
     private final Charset charset;
 
+    /** Additional properties as name/value pairs */
+    private final Map<String, String> properties;
+
     /** Collect all closeables handed out to the caller to be closed when the 
data source is closed itself */
     private final CloseableReaper closeables;
 
+    /**
+     * Constructor.
+     *
+     * @param name        Human-readable name of the data source
+     * @param group       Optional group of data source
+     * @param uri         source URI of the data source
+     * @param dataSource  JAF data source being wrapped
+     * @param contentType content type of data source either provided by the 
caller or fetched directly from the data source
+     * @param charset     option charset for directly accessing text-based 
content
+     * @param properties  optional name/value pairs
+     */
     public DataSource(
             String name,
             String group,
             URI uri,
             javax.activation.DataSource dataSource,
             String contentType,
-            Charset charset) {
-        this.name = requireNonNull(name);
+            Charset charset,
+            Map<String, String> properties) {
+        this.name = requireNonNull(name).trim();
         this.group = StringUtils.emptyToNull(group);
         this.uri = requireNonNull(uri);
         this.dataSource = requireNonNull(dataSource);
         this.contentType = contentType;
         this.charset = charset;
+        this.properties = properties != null ? new HashMap<>(properties) : new 
HashMap<>();
         this.closeables = new CloseableReaper();
     }
 
@@ -206,6 +223,10 @@ public class DataSource implements Closeable, 
javax.activation.DataSource {
         return uri;
     }
 
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
     /**
      * Try to get the length lazily, efficient and without consuming the input 
stream.
      *
@@ -339,7 +360,7 @@ public class DataSource implements Closeable, 
javax.activation.DataSource {
             case METADATA_MIME_TYPE:
                 return getMimeType();
             default:
-                throw new IllegalArgumentException("Unknown key: " + key);
+                throw new IllegalArgumentException("Unknown metatdata key: " + 
key);
         }
     }
 
diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourceFactory.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourceFactory.java
index c9467a8..6930e91 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourceFactory.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourceFactory.java
@@ -36,6 +36,8 @@ import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 
@@ -57,18 +59,39 @@ public abstract class DataSourceFactory {
             String group,
             URI uri,
             javax.activation.DataSource dataSource,
+            Map<String, String> properties) {
+        return new DataSource(name, group, uri, dataSource, null, null, 
properties);
+    }
+
+    public static DataSource create(
+            String name,
+            String group,
+            URI uri,
+            javax.activation.DataSource dataSource,
             String contentType,
-            Charset charset
-    ) {
-        return new DataSource(name, group, uri, dataSource, contentType, 
charset);
+            Charset charset,
+            Map<String, String> properties) {
+        return new DataSource(name, group, uri, dataSource, contentType, 
charset, properties);
     }
 
     // == URL ===============================================================
 
-    public static DataSource fromUrl(String name, String group, URL url, 
String contentType, Charset charset) {
+    public static DataSource fromUrl(String name, String group, URL url) {
+        final URLDataSource dataSource = new CachingUrlDataSource(url);
+        final URI uri = UriUtils.toUri(url);
+        return create(name, group, uri, dataSource, noProperties());
+    }
+
+    public static DataSource fromUrl(
+            String name,
+            String group,
+            URL url,
+            String contentType,
+            Charset charset,
+            Map<String, String> properties) {
         final URLDataSource dataSource = new CachingUrlDataSource(url);
         final URI uri = UriUtils.toUri(url);
-        return create(name, group, uri, dataSource, contentType, charset);
+        return create(name, group, uri, dataSource, contentType, charset, 
properties);
     }
 
     // == String ============================================================
@@ -76,22 +99,28 @@ public abstract class DataSourceFactory {
     public static DataSource fromString(String name, String group, String 
content, String contentType) {
         final StringDataSource dataSource = new StringDataSource(name, 
content, contentType, UTF_8);
         final URI uri = UriUtils.toUri(Location.STRING, 
UUID.randomUUID().toString());
-        return create(name, group, uri, dataSource, contentType, UTF_8);
+        return create(name, group, uri, dataSource, contentType, UTF_8, 
noProperties());
     }
 
     // == File ==============================================================
 
     public static DataSource fromFile(File file, Charset charset) {
-        return fromFile(file.getName(), DEFAULT_GROUP, file, charset);
+        return fromFile(file.getName(), DEFAULT_GROUP, file, charset, 
noProperties());
     }
 
-    public static DataSource fromFile(String name, String group, File file, 
Charset charset) {
+    public static DataSource fromFile(
+            String name,
+            String group,
+            File file,
+            Charset charset,
+            Map<String, String> properties) {
         Validate.isTrue(file.exists(), "File not found: " + file);
 
         final FileDataSource dataSource = new FileDataSource(file);
+        // content type is determined from file extension
         dataSource.setFileTypeMap(MimetypesFileTypeMapFactory.create());
         final String contentType = dataSource.getContentType();
-        return create(name, group, file.toURI(), dataSource, contentType, 
charset);
+        return create(name, group, file.toURI(), dataSource, contentType, 
charset, properties);
     }
 
     // == Bytes ============================================================
@@ -99,26 +128,21 @@ public abstract class DataSourceFactory {
     public static DataSource fromBytes(String name, String group, byte[] 
content, String contentType) {
         final ByteArrayDataSource dataSource = new ByteArrayDataSource(name, 
content);
         final URI uri = UriUtils.toUri(Location.BYTES + ":///");
-        return create(name, group, uri, dataSource, contentType, UTF_8);
+        return create(name, group, uri, dataSource, contentType, UTF_8, 
noProperties());
     }
 
     // == InputStream =======================================================
 
-    public static DataSource fromInputStream(String name, String group, 
InputStream is, String contentType, Charset charset) {
-        final URI uri = UriUtils.toUri(Location.INPUTSTREAM + ":///");
-        return fromInputStream(name, group, uri, is, contentType, charset);
-    }
-
     public static DataSource fromInputStream(
             String name,
             String group,
             URI uri,
             InputStream is,
             String contentType,
-            Charset charset
-    ) {
+            Charset charset,
+            Map<String, String> properties) {
         final InputStreamDataSource dataSource = new 
InputStreamDataSource(name, is);
-        return create(name, group, uri, dataSource, contentType, charset);
+        return create(name, group, uri, dataSource, contentType, charset, 
properties);
     }
 
     // == Environment =======================================================
@@ -130,7 +154,7 @@ public abstract class DataSourceFactory {
             properties.store(writer, null);
             final StringDataSource dataSource = new StringDataSource(name, 
writer.toString(), contentType, UTF_8);
             final URI uri = UriUtils.toUri(Location.ENVIRONMENT, "");
-            return create(name, group, uri, dataSource, contentType, UTF_8);
+            return create(name, group, uri, dataSource, contentType, UTF_8, 
noProperties());
         } catch (IOException e) {
             throw new RuntimeException("Unable to load environment variables", 
e);
         }
@@ -141,7 +165,7 @@ public abstract class DataSourceFactory {
 
         final StringDataSource dataSource = new StringDataSource(name, 
System.getenv(key), contentType, UTF_8);
         final URI uri = UriUtils.toUri(Location.ENVIRONMENT, key);
-        return create(name, group, uri, dataSource, contentType, UTF_8);
+        return create(name, group, uri, dataSource, contentType, UTF_8, 
noProperties());
     }
 
     public static URL toUrl(String url) {
@@ -151,4 +175,8 @@ public abstract class DataSourceFactory {
             throw new IllegalArgumentException(url, e);
         }
     }
+
+    private static Map<String, String> noProperties() {
+        return new HashMap<>();
+    }
 }
diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourcesSupplier.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourcesSupplier.java
index c2604ba..7f7906e 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourcesSupplier.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSourcesSupplier.java
@@ -27,16 +27,17 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Supplier;
 
 import static java.util.Collections.singletonList;
 import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.toList;
 import static 
org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_GROUP;
+import static 
org.apache.freemarker.generator.base.datasource.DataSourceFactory.fromFile;
 
 /**
- * Create a list of <code>DataSource</code> based on a list of sources 
consisting of
- * URIs, directories and files.
+ * Create a list of <code>DataSource</code> based on a list URIs, directories 
and files.
  */
 public class DataSourcesSupplier implements Supplier<List<DataSource>> {
 
@@ -57,14 +58,14 @@ public class DataSourcesSupplier implements 
Supplier<List<DataSource>> {
     /**
      * Constructor.
      *
-     * @param sources List of source files and/or directories
+     * @param sources List of source files and/or directories supporting 
<code>NamedUri</code> syntax
      * @param include Optional include pattern for resolving source files or 
directory
      * @param exclude Optional exclude pattern for resolving source files or 
directory
      * @param charset The charset for loading text files
      */
     public DataSourcesSupplier(Collection<String> sources, String include, 
String exclude, Charset charset) {
         this.dataSourceLoader = DataSourceLoaderFactory.create();
-        this.sources = new ArrayList<>(sources);
+        this.sources = new ArrayList<>(requireNonNull(sources));
         this.include = include;
         this.exclude = exclude;
         this.charset = requireNonNull(charset);
@@ -113,8 +114,9 @@ public class DataSourcesSupplier implements 
Supplier<List<DataSource>> {
         final String path = namedUri.getFile().getPath();
         final String group = namedUri.getGroupOrElse(DEFAULT_GROUP);
         final Charset currCharset = getCharsetOrElse(namedUri, charset);
+        final Map<String, String> parameters = namedUri.getParameters();
         return fileSupplier(path, include, exclude).get().stream()
-                .map(file -> 
DataSourceFactory.fromFile(getDataSourceName(namedUri, file), group, file, 
currCharset))
+                .map(file -> fromFile(getDataSourceName(namedUri, file), 
group, file, currCharset, parameters))
                 .collect(toList());
     }
 
diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/FileDataSourceLoader.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/FileDataSourceLoader.java
index 1ee8b66..1a0aec5 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/FileDataSourceLoader.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/FileDataSourceLoader.java
@@ -26,6 +26,7 @@ import org.apache.freemarker.generator.base.util.UriUtils;
 
 import java.io.File;
 import java.nio.charset.Charset;
+import java.util.Map;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
@@ -44,7 +45,8 @@ public class FileDataSourceLoader implements DataSourceLoader 
{
         final Charset charset = namedUri.getCharsetOrElse(UTF_8);
         final File file = namedUri.getFile();
         final String name = namedUri.getNameOrElse(file.getName());
-        return DataSourceFactory.fromFile(name, group, file, charset);
+        final Map<String, String> parameters = namedUri.getParameters();
+        return DataSourceFactory.fromFile(name, group, file, charset, 
parameters);
     }
 
     @Override
@@ -53,7 +55,8 @@ public class FileDataSourceLoader implements DataSourceLoader 
{
         final String group = 
namedUri.getGroupOrElse(FreeMarkerConstants.DEFAULT_GROUP);
         final File file = namedUri.getFile();
         final String name = 
namedUri.getNameOrElse(UriUtils.toStringWithoutFragment(file.toURI()));
-        return DataSourceFactory.fromFile(name, group, file, charset);
+        final Map<String, String> parameters = namedUri.getParameters();
+        return DataSourceFactory.fromFile(name, group, file, charset, 
parameters);
     }
 
 }
diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/HttpDataSourceLoader.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/HttpDataSourceLoader.java
index 10755f9..aac4bc0 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/HttpDataSourceLoader.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/loader/HttpDataSourceLoader.java
@@ -27,6 +27,7 @@ import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.Map;
 
 import static 
org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_GROUP;
 import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
@@ -47,7 +48,8 @@ public class HttpDataSourceLoader implements DataSourceLoader 
{
         final String mimeType = namedUri.getMimeType();
         final URL url = toUrl(uri);
         final String name = 
namedUri.getNameOrElse(UriUtils.toStringWithoutFragment(uri));
-        return DataSourceFactory.fromUrl(name, group, url, mimeType, charset);
+        final Map<String, String> parameters = namedUri.getParameters();
+        return DataSourceFactory.fromUrl(name, group, url, mimeType, charset, 
parameters);
     }
 
     @Override
diff --git 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceFactoryTest.java
 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceFactoryTest.java
index 37d1f92..20733c7 100644
--- 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceFactoryTest.java
+++ 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceFactoryTest.java
@@ -30,6 +30,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.HashMap;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static junit.framework.TestCase.assertFalse;
@@ -85,7 +86,7 @@ public class DataSourceFactoryTest {
     public void shouldCreateDataSourceFromInputStream() {
         final URI uri = UriUtils.toUri(Location.INPUTSTREAM + ":///");
         final InputStream is = new 
ByteArrayInputStream(ANY_TEXT.getBytes(UTF_8));
-        final DataSource dataSource = 
DataSourceFactory.fromInputStream("test.txt", "default", uri, is, "text/plain", 
UTF_8);
+        final DataSource dataSource = 
DataSourceFactory.fromInputStream("test.txt", "default", uri, is, "text/plain", 
UTF_8, new HashMap<>());
 
         assertEquals("test.txt", dataSource.getName());
         assertEquals(UTF_8, dataSource.getCharset());
@@ -98,7 +99,7 @@ public class DataSourceFactoryTest {
     @Ignore
     public void shouldCreateDataSourceFromURL() throws IOException {
         final URL url = new 
URL("https://jsonplaceholder.typicode.com/posts/2";);
-        final DataSource dataSource = 
DataSourceFactory.fromUrl("jsonplaceholder.typicode.com", "default", url, null, 
null);
+        final DataSource dataSource = 
DataSourceFactory.fromUrl("jsonplaceholder.typicode.com", "default", url);
 
         assertEquals("jsonplaceholder.typicode.com", dataSource.getName());
         assertEquals("jsonplaceholder.typicode.com", dataSource.getFileName());
diff --git 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceTest.java
 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceTest.java
index 8961359..e1a8f80 100644
--- 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceTest.java
+++ 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourceTest.java
@@ -28,6 +28,7 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.Iterator;
+import java.util.Map;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static 
org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_GROUP;
@@ -84,7 +85,7 @@ public class DataSourceTest {
     @Test
     @Ignore("Requires internet access")
     public void shouldSupportUrlDataSource() {
-        try (DataSource dataSource = 
DataSourceFactory.fromUrl("www.google.com", DEFAULT_GROUP, 
toUrl("https://www.google.com/?foo=bar";), null, null)) {
+        try (DataSource dataSource = 
DataSourceFactory.fromUrl("www.google.com", DEFAULT_GROUP, 
toUrl("https://www.google.com/?foo=bar";), null, null, null)) {
             assertEquals("www.google.com", dataSource.getName());
             assertEquals(DEFAULT_GROUP, dataSource.getGroup());
             assertEquals("", dataSource.getBaseName());
@@ -125,15 +126,17 @@ public class DataSourceTest {
     @Test
     public void shouldGetMetadata() {
         try (DataSource dataSource = stringDataSource()) {
-            assertEquals(8, dataSource.getMetadata().size());
-            assertEquals("", dataSource.getMetadata().get("basename"));
-            assertEquals("", dataSource.getMetadata().get("extension"));
-            assertEquals("", dataSource.getMetadata().get("filename"));
-            assertEquals("/", dataSource.getMetadata().get("filepath"));
-            assertEquals("default", dataSource.getMetadata().get("group"));
-            assertEquals("stdin", dataSource.getMetadata().get("name"));
-            
assertTrue(dataSource.getMetadata().get("uri").startsWith("string://"));
-            assertEquals("text/plain", 
dataSource.getMetadata().get("mimetype"));
+            final Map<String, String> metadata = dataSource.getMetadata();
+
+            assertEquals(8, metadata.size());
+            assertEquals("", metadata.get("basename"));
+            assertEquals("", metadata.get("extension"));
+            assertEquals("", metadata.get("filename"));
+            assertEquals("/", metadata.get("filepath"));
+            assertEquals("default", metadata.get("group"));
+            assertEquals("stdin", metadata.get("name"));
+            assertTrue(metadata.get("uri").startsWith("string://"));
+            assertEquals("text/plain", metadata.get("mimetype"));
         }
     }
 
diff --git 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
index 779485c..1fb5fe7 100644
--- 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
+++ 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
@@ -35,6 +35,8 @@ public class DataSourcesSupplierTest {
 
     private static final String NO_EXCLUDE = null;
     private static final String DATA_DIRECTORY = "./src/test/data";
+    private static final String DATA_DIRECTORY_WITH_FRAGMENT = 
"./src/test/data#scope=test";
+    private static final String DATA_DIRECTORY_WITH_GROUP = 
":data=src/test/data";
     private static final String PWD = FilenameUtils.separatorsToUnix(new 
File("").getAbsolutePath());
 
     @Test
@@ -106,6 +108,26 @@ public class DataSourcesSupplierTest {
     }
 
     @Test
+    public void shouldUseFragmentForDataSourceWhenResolvingDirectory() {
+        final List<DataSource> dataSources = 
supplier(DATA_DIRECTORY_WITH_FRAGMENT, "*.*", NO_EXCLUDE).get();
+
+        for (DataSource dataSource : dataSources) {
+            assertEquals(1, dataSource.getProperties().size());
+            assertEquals("test", dataSource.getProperties().get("scope"));
+        }
+    }
+
+    @Test
+    public void shouldUseGroupNameForDataSourceWhenResolvingDirectory() {
+        final List<DataSource> dataSources = 
supplier(DATA_DIRECTORY_WITH_GROUP, "*.*", NO_EXCLUDE).get();
+
+        for (DataSource dataSource : dataSources) {
+            assertEquals(0, dataSource.getProperties().size());
+            assertEquals("data", dataSource.getGroup());
+        }
+    }
+
+    @Test
     public void shouldResolveEnvironmentVariable() {
         assertEquals(1, supplier("env:///PATH", "*", NO_EXCLUDE).get().size());
         assertEquals(1, supplier("path=env:///PATH", "*", 
NO_EXCLUDE).get().size());
@@ -118,7 +140,7 @@ public class DataSourcesSupplierTest {
     }
 
     @Test(expected = RuntimeException.class)
-    public void shouldThrowExceptionForNonexistingSourceDirectory() {
+    public void shouldThrowRuntimeExceptionForNonexistingSourceDirectory() {
         assertEquals(0, supplier("/does-not-exist", "*", null).get().size());
     }
 
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 3591e38..030ea62 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
@@ -24,6 +24,7 @@ import org.junit.Test;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.HashMap;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Arrays.asList;
@@ -32,7 +33,6 @@ import static 
org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_G
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
 public class DataSourcesTest {
 
@@ -133,7 +133,7 @@ public class DataSourcesTest {
     }
 
     private static DataSource urlDataSource() {
-        return DataSourceFactory.fromUrl("server.invalid?foo=bar", "default", 
toUrl(ANY_URL), "plain/text", UTF_8);
+        return DataSourceFactory.fromUrl("server.invalid?foo=bar", "default", 
toUrl(ANY_URL), "plain/text", UTF_8, new HashMap<>());
     }
 
     private static URL toUrl(String value) {
diff --git a/freemarker-generator-cli/src/test/templates/manual.ftl 
b/freemarker-generator-cli/src/app/examples/templates/datasources.ftl
similarity index 71%
copy from freemarker-generator-cli/src/test/templates/manual.ftl
copy to freemarker-generator-cli/src/app/examples/templates/datasources.ftl
index 3ad42c6..364a7ba 100644
--- a/freemarker-generator-cli/src/test/templates/manual.ftl
+++ b/freemarker-generator-cli/src/app/examples/templates/datasources.ftl
@@ -1,4 +1,4 @@
-<#ftl output_format="plainText" >
+<#ftl output_format="plainText">
 <#--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
@@ -16,43 +16,63 @@
   under the License.
 -->
 Support FreeMarker Directives
----------------------------------------------------------------------------
-Has Content: ${dataSources?has_content?c}
-Nr. of Documents: ${dataSources?size}
+==============================================================================
+has_content: ${dataSources?has_content?c}
+size: ${dataSources?size}
 
 Use FTL Array-style Access
----------------------------------------------------------------------------
-${dataSources?values[0].toString()}
-${dataSources?values?first.toString()}
+==============================================================================
+${dataSources?values[0].name}
+${dataSources?values?first.name}
 
 Get Document Names As Keys
----------------------------------------------------------------------------
+==============================================================================
 <#list dataSources?keys as name>
     ${name}<#lt>
 </#list>
 
 Iterate Over Names & DataSources
----------------------------------------------------------------------------
+==============================================================================
 <#list dataSources as name, dataSource>
     ${name} => ${dataSource.uri}<#lt>
 </#list>
 
+<#if dataSources?has_content>
+    <#list dataSources?values as dataSource>
+        <@writeDataSource dataSource/>
+    </#list>
+<#else>
+    No data sources found ...
+</#if>
+
+<#macro writeDataSource dataSource>
+
+${dataSource.name}
+==============================================================================
+
 Invoke Arbitrary Methods On DataSource
 ---------------------------------------------------------------------------
-<#if dataSources?has_content>
 <#assign dataSource=dataSources?values?first>
 Name            : ${dataSource.name}
+Group           : ${dataSource.group}
 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}
-File name       : ${dataSource.metadata["filename"]}
+File name       : ${dataSource.fileName}
+URI schema      : ${dataSource.uri.scheme}
 
 Iterating Over Metadata Of A Datasource
 ---------------------------------------------------------------------------
 <#list dataSource.metadata as name, value>
 ${name?right_pad(15)} : ${value}
 </#list>
-</#if>
+
+Iterating Over Properties Of A Datasource
+---------------------------------------------------------------------------
+<#list dataSource.properties as name, value>
+${name?right_pad(15)} : ${value}
+</#list>
+</#macro>
diff --git 
a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/OutputGeneratorsSupplier.java
 
b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/OutputGeneratorsSupplier.java
index 085ad60..059a9ab 100644
--- 
a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/OutputGeneratorsSupplier.java
+++ 
b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/OutputGeneratorsSupplier.java
@@ -31,6 +31,7 @@ import 
org.apache.freemarker.generator.cli.picocli.TemplateSourceDefinition;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
@@ -136,6 +137,6 @@ public class OutputGeneratorsSupplier implements 
Supplier<List<OutputGenerator>>
 
     private static DataSource stdinDataSource() {
         final URI uri = UriUtils.toUri(Location.SYSTEM, STDIN);
-        return DataSourceFactory.fromInputStream(STDIN, DEFAULT_GROUP, uri, 
System.in, MIME_TEXT_PLAIN, UTF_8);
+        return DataSourceFactory.fromInputStream(STDIN, DEFAULT_GROUP, uri, 
System.in, MIME_TEXT_PLAIN, UTF_8, new HashMap<>());
     }
 }
diff --git 
a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
 
b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
index 54be597..f08e38b 100644
--- 
a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
+++ 
b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 public class ManualTest extends AbstractMainTest {
 
     // private static final String CMD = "-V";
-    private static final String CMD = "-t src/test/templates/manual.ftl -s 
src/app/examples/data/csv";
+    private static final String CMD = "-t 
src/app/examples/templates/datasources.ftl -s 
:csv-data=src/app/examples/data/csv#separator=COLON 
https://xkcd.com/info.0.json";;
 
     @Override
     public String execute(String commandLine) throws IOException {
diff --git a/freemarker-generator-cli/src/test/templates/manual.ftl 
b/freemarker-generator-cli/src/test/templates/manual.ftl
index 3ad42c6..c1112be 100644
--- a/freemarker-generator-cli/src/test/templates/manual.ftl
+++ b/freemarker-generator-cli/src/test/templates/manual.ftl
@@ -1,4 +1,4 @@
-<#ftl output_format="plainText" >
+<#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
@@ -16,30 +16,34 @@
   under the License.
 -->
 Support FreeMarker Directives
----------------------------------------------------------------------------
+==============================================================================
 Has Content: ${dataSources?has_content?c}
 Nr. of Documents: ${dataSources?size}
 
 Use FTL Array-style Access
----------------------------------------------------------------------------
+==============================================================================
 ${dataSources?values[0].toString()}
 ${dataSources?values?first.toString()}
 
 Get Document Names As Keys
----------------------------------------------------------------------------
+==============================================================================
 <#list dataSources?keys as name>
     ${name}<#lt>
 </#list>
 
 Iterate Over Names & DataSources
----------------------------------------------------------------------------
+==============================================================================
 <#list dataSources as name, dataSource>
     ${name} => ${dataSource.uri}<#lt>
 </#list>
 
+<#if dataSources?has_content>
+    <#list dataSources?values as dataSource>
+[#${dataSource?counter}] - ${dataSource.name}
+==============================================================================
+
 Invoke Arbitrary Methods On DataSource
 ---------------------------------------------------------------------------
-<#if dataSources?has_content>
 <#assign dataSource=dataSources?values?first>
 Name            : ${dataSource.name}
 Nr of lines     : ${dataSource.lines?size}
@@ -55,4 +59,14 @@ Iterating Over Metadata Of A Datasource
 <#list dataSource.metadata as name, value>
 ${name?right_pad(15)} : ${value}
 </#list>
+
+Iterating Over Properties Of A Datasource
+---------------------------------------------------------------------------
+<#list dataSource.properties as name, value>
+${name?right_pad(15)} : ${value}
+</#list>
+
+    </#list>
+<#else>
+No data sources found ...
 </#if>

Reply via email to