You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by sg...@apache.org on 2020/04/05 22:03:49 UTC

[freemarker-generator] branch feature/FREEMARKER-140 created (now a5fbf1c)

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

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


      at a5fbf1c  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

This branch includes the following new commits:

     new 64cd092  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new ebe5994  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new 2e280e8  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new 1c56501  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new e2176cd  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new 6c12e9a  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new 3094787  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new 9175e88  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new c8af6ed  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new f80d16c  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
     new a5fbf1c  FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[freemarker-generator] 06/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6c12e9ab3dae68f9f2d5764b4b39d2e851cce242
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 21:03:25 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../base/datasource/DataSourceFactory.java         | 29 +++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

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 95e7e68..a2ee5e3 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
@@ -23,20 +23,26 @@ import org.apache.freemarker.generator.base.activation.MimetypesFileTypeMapFacto
 import org.apache.freemarker.generator.base.activation.StringDataSource;
 import org.apache.freemarker.generator.base.uri.NamedUri;
 import org.apache.freemarker.generator.base.uri.NamedUriStringParser;
+import org.apache.freemarker.generator.base.util.PropertiesFactory;
 import org.apache.freemarker.generator.base.util.StringUtils;
 import org.apache.freemarker.generator.base.util.UriUtils;
 
 import javax.activation.FileDataSource;
 import javax.activation.URLDataSource;
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.StringWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.Properties;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_GROUP;
+import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
+import static org.apache.freemarker.generator.base.util.StringUtils.firstNonEmpty;
 
 /**
  * Creates a FreeMarker data source from various sources.
@@ -67,9 +73,13 @@ public class DataSourceFactory {
             return fromFile(name, group, file, charset);
         } else if (UriUtils.isEnvUri(uri)) {
             final String key = uri.getPath().substring(1);
-            final String name = StringUtils.firstNonEmpty(namedUri.getName(), key, "env");
-            final String contentType = getMimeTypeOrElse(namedUri, "text/plain");
-            return fromEnvironment(name, group, key, contentType);
+            final String contentType = getMimeTypeOrElse(namedUri, MIME_TEXT_PLAIN);
+            final String name = firstNonEmpty(namedUri.getName(), key, Location.ENVIRONMENT);
+            if (StringUtils.isEmpty(key)) {
+                return fromEnvironment(name, group, contentType);
+            } else {
+                return fromEnvironment(name, group, key, contentType);
+            }
         } else {
             throw new IllegalArgumentException("Don't knowm how to handle: " + namedUri);
         }
@@ -135,6 +145,19 @@ public class DataSourceFactory {
 
     // == Environment =======================================================
 
+    public static DataSource fromEnvironment(String name, String group, String contentType) {
+        try {
+            final Properties properties = PropertiesFactory.create(System.getenv());
+            final StringWriter writer = new StringWriter();
+            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);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     public static DataSource fromEnvironment(String name, String group, String key, String contentType) {
         final String value = System.getenv(key);
         final StringDataSource dataSource = new StringDataSource(name, value, contentType, UTF_8);


[freemarker-generator] 02/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ebe599460d557494685683085a5cd7a894378e9f
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 20:36:45 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../generator/base/datasource/DataSource.java      | 42 +++++++++++++---------
 1 file changed, 25 insertions(+), 17 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 9f2ee51..d757b5a 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
@@ -131,9 +131,8 @@ public class DataSource implements Closeable {
      * Get an input stream which is closed together with this data source.
      *
      * @return InputStream
-     * @throws IOException Operation failed
      */
-    public InputStream getInputStream() throws IOException {
+    public InputStream getInputStream() {
         return closables.add(getUnsafeInputStream());
     }
 
@@ -141,21 +140,26 @@ public class DataSource implements Closeable {
      * Get an input stream which needs to be closed by the caller.
      *
      * @return InputStream
-     * @throws IOException Operation failed
      */
-    public InputStream getUnsafeInputStream() throws IOException {
-        return dataSource.getInputStream();
+    public InputStream getUnsafeInputStream() {
+        try {
+            return dataSource.getInputStream();
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to get input stream: " + toString(), e);
+        }
     }
 
-    public String getText() throws IOException {
+    public String getText() {
         return getText(getCharset().name());
     }
 
-    public String getText(String charsetName) throws IOException {
+    public String getText(String charsetName) {
         final StringWriter writer = new StringWriter();
         try (InputStream is = getUnsafeInputStream()) {
             IOUtils.copy(is, writer, forName(charsetName));
             return writer.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to get text: " + toString(), e);
         }
     }
 
@@ -164,9 +168,8 @@ public class DataSource implements Closeable {
      * one entry per line, using the specified character encoding.
      *
      * @return the list of Strings, never null
-     * @throws IOException if an I/O error occurs
      */
-    public List<String> getLines() throws IOException {
+    public List<String> getLines() {
         return getLines(getCharset().name());
     }
 
@@ -176,11 +179,12 @@ public class DataSource implements Closeable {
      *
      * @param charsetName The name of the requested charset
      * @return the list of Strings, never null
-     * @throws IOException if an I/O error occurs
      */
-    public List<String> getLines(String charsetName) throws IOException {
+    public List<String> getLines(String charsetName) {
         try (InputStream inputStream = getUnsafeInputStream()) {
             return IOUtils.readLines(inputStream, charsetName);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to get lines: " + toString(), e);
         }
     }
 
@@ -190,9 +194,8 @@ public class DataSource implements Closeable {
      * the line iterator.
      *
      * @return line iterator
-     * @throws IOException if an I/O error occurs
      */
-    public LineIterator getLineIterator() throws IOException {
+    public LineIterator getLineIterator() {
         return getLineIterator(getCharset().name());
     }
 
@@ -202,15 +205,20 @@ public class DataSource implements Closeable {
      *
      * @param charsetName The name of the requested charset
      * @return line iterator
-     * @throws IOException if an I/O error occurs
      */
-    public LineIterator getLineIterator(String charsetName) throws IOException {
-        return closables.add(lineIterator(getUnsafeInputStream(), forName(charsetName)));
+    public LineIterator getLineIterator(String charsetName) {
+        try {
+            return closables.add(lineIterator(getUnsafeInputStream(), forName(charsetName)));
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to create line iterator: " + toString(), e);
+        }
     }
 
-    public byte[] getBytes() throws IOException {
+    public byte[] getBytes() {
         try (InputStream inputStream = getUnsafeInputStream()) {
             return IOUtils.toByteArray(inputStream);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to get bytes: " + toString(), e);
         }
     }
 


[freemarker-generator] 07/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 30947874f1a1c06942afbb762c0ea590d56a92bf
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 22:42:58 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../base/datamodel/DataModelsSupplier.java         |  61 ++++++++++---
 .../base/datasource/DataSourceFactory.java         |   7 +-
 .../generator/base/util/StringUtils.java           |  10 --
 .../datamodel/DataModelsSupplierTest.java          | 101 +++++++++++++++++++++
 .../freemarker/generator/cli/ManualTest.java       |   7 +-
 5 files changed, 158 insertions(+), 28 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
index 8f9f268..f9da638 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
@@ -18,15 +18,23 @@ package org.apache.freemarker.generator.base.datamodel;
 
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+import org.apache.freemarker.generator.base.uri.NamedUri;
+import org.apache.freemarker.generator.base.uri.NamedUriStringParser;
+import org.apache.freemarker.generator.base.util.PropertiesFactory;
+import org.apache.freemarker.generator.base.util.UriUtils;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
 import java.util.function.Supplier;
 
-import static java.util.stream.Collectors.toList;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toMap;
+import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
 
 /**
  * Create a list of <code>DataSource</code> based on a list of sources consisting of
@@ -34,7 +42,6 @@ import static java.util.stream.Collectors.toList;
  */
 public class DataModelsSupplier implements Supplier<Map<String, Object>> {
 
-    /** List of source files, named URIs and URIs */
     private final Collection<String> sources;
 
     /**
@@ -43,22 +50,46 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
      * @param sources List of sources
      */
     public DataModelsSupplier(Collection<String> sources) {
-        this.sources = new ArrayList<>(sources);
+        this.sources = new ArrayList<>(requireNonNull(sources));
     }
 
     @Override
     public Map<String, Object> get() {
-        final List<DataSource> dataModels = sources.stream().map(this::resolve).collect(toList());
-        return Collections.emptyMap();
+        return sources.stream()
+                .map(this::toDataModel)
+                .flatMap(map -> map.entrySet().stream())
+                .collect(toMap(Entry::getKey, Entry::getValue));
     }
 
-    /**
-     * Resolve a <code>source</code> to a <code>DataSource</code>.
-     *
-     * @param source the source being a file name, an <code>URI</code> or <code>NamedUri</code>
-     * @return list of <code>DataSource</code>
-     */
-    protected DataSource resolve(String source) {
-        return DataSourceFactory.create(source);
+    protected Map<String, Object> toDataModel(String source) {
+        final NamedUri namedUri = NamedUriStringParser.parse(source);
+        final DataSource dataSource = DataSourceFactory.fromNamedUri(namedUri);
+        final boolean isExplodedDataModel = !namedUri.hasName();
+        final String contentType = dataSource.getContentType();
+
+        switch (contentType) {
+            case MIME_TEXT_PLAIN:
+                return fromProperties(dataSource, isExplodedDataModel);
+            default:
+                throw new IllegalArgumentException("Don't know how to handle :" + contentType);
+        }
+    }
+
+    protected Map<String, Object> fromProperties(DataSource dataSource, boolean isExplodedDataModel) {
+        final Map<String, Object> result = new HashMap<>();
+        final URI uri = dataSource.getUri();
+
+        if (UriUtils.isEnvUri(uri) && !"env:///".equals(uri.toString())) {
+            result.put(dataSource.getName(), dataSource.getText());
+        } else {
+            final Properties properties = PropertiesFactory.create(dataSource.getText());
+            if (isExplodedDataModel) {
+                properties.forEach((key, value) -> result.put(key.toString(), value));
+            } else {
+                result.put(dataSource.getName(), properties);
+            }
+        }
+
+        return result;
     }
 }
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 a2ee5e3..3f98adc 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
@@ -81,7 +81,10 @@ public class DataSourceFactory {
                 return fromEnvironment(name, group, key, contentType);
             }
         } else {
-            throw new IllegalArgumentException("Don't knowm how to handle: " + namedUri);
+            // handle things such as "foo=some.file"
+            final File file = namedUri.getFile();
+            final String name = namedUri.getNameOrElse(file.getName());
+            return fromFile(name, group, file, charset);
         }
     }
 
@@ -151,7 +154,7 @@ public class DataSourceFactory {
             final StringWriter writer = new StringWriter();
             properties.store(writer, null);
             final StringDataSource dataSource = new StringDataSource(name, writer.toString(), contentType, UTF_8);
-            final URI uri = UriUtils.toURI(Location.ENVIRONMENT);
+            final URI uri = UriUtils.toURI(Location.ENVIRONMENT, "");
             return create(name, group, uri, dataSource, contentType, UTF_8);
         } catch (IOException e) {
             throw new RuntimeException(e);
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
index bee41e7..24b81af 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
@@ -45,14 +45,4 @@ public class StringUtils {
         return null;
     }
 
-    public static String firstNonNull(final String... values) {
-        if (values != null) {
-            for (final String value : values) {
-                if (value != null) {
-                    return value;
-                }
-            }
-        }
-        return null;
-    }
 }
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java
new file mode 100644
index 0000000..e3ebb6e
--- /dev/null
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.freemarker.generator.datamodel;
+
+import org.apache.freemarker.generator.base.datamodel.DataModelsSupplier;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertEquals;
+
+public class DataModelsSupplierTest {
+
+    private static final String PWD_VALUE = System.getenv("PWD");
+    private static final int NR_OF_ENVS = System.getenv().size();
+
+    @Test
+    public void shouldResolveAllEnvironmentVariablesToTopLevelDataModel() {
+        final DataModelsSupplier supplier = supplier("env:///");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(NR_OF_ENVS, model.size());
+        assertEquals(PWD_VALUE, model.get("PWD"));
+    }
+
+    @Test
+    public void shouldResolveAllEnvironmentVariablesToDataModelVariable() {
+        final DataModelsSupplier supplier = supplier("env=env:///");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(1, model.size());
+        assertEquals(NR_OF_ENVS, toMap(model, "env").size());
+        assertEquals(PWD_VALUE, toMap(model, "env").get("PWD"));
+    }
+
+    @Test
+    public void shouldResolveEnvironmentVariableToDataModelVariable() {
+        final DataModelsSupplier supplier = supplier("foo=env:///PWD");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(1, model.size());
+        assertEquals(PWD_VALUE, model.get("foo"));
+    }
+
+    @Test
+    public void shouldResolvePropertiesFileToTopLevelDataModel() {
+        final DataModelsSupplier supplier = supplier("./src/test/data/properties/test.properties");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(1, model.size());
+        assertEquals("bar", model.get("foo"));
+    }
+
+    @Test
+    public void shouldResolvePropertiesFileToDataModelVariable() {
+        final DataModelsSupplier supplier = supplier("props=./src/test/data/properties/test.properties");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(1, model.size());
+        assertEquals("bar", toMap(model, "props").get("foo"));
+    }
+
+    @Test
+    public void shouldResolvePropertiesUriToDataModelVariable() {
+        final DataModelsSupplier supplier = supplier("props=file://./src/test/data/properties/test.properties");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(1, model.size());
+        assertEquals("bar", toMap(model, "props").get("foo"));
+    }
+
+    private static DataModelsSupplier supplier(String source) {
+        return new DataModelsSupplier(singletonList(source));
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Map<String, Object> toMap(Map<String, Object> model, String key) {
+        return (Map<String, Object>) model.get(key);
+    }
+}
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 67e8e39..3e44808 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
@@ -35,13 +35,18 @@ public class ManualTest {
     // private static final String CMD = "-i ${JsoupTool.parse(DataSources.first).select('a')[0]} site/sample/html/dependencies.html";
     // private static final String CMD = "-b ./src/test -t templates/properties/csv/locker-test-users.ftl site/sample/properties";
     // private static final String CMD = "-b ./src/test -e UTF-8 -l de_AT -Dcolumn=Order%20ID -Dvalues=226939189,957081544 -Dformat=DEFAULT -Ddelimiter=COMMA -t templates/csv/md/filter.ftl site/sample/csv/sales-records.csv";
-    private static final String CMD = "-E -b ./src/test -t templates/environment.ftl";
+    // private static final String CMD = "-E -b ./src/test -t templates/environment.ftl";
     // private static final String CMD = "-b ./src/test -l de_AT -DFOO=foo -DBAR=bar -t templates/info.ftl -d user:admin=site/sample/csv/contract.csv#charset=UTF-16 google:www=https://www.google.com?foo=bar#contenttype=application/json";
     // private static final String CMD = "-b ./src/test -t templates/info.ftl -d :user=site/sample/properties -d contract=site/sample/csv/contract.csv";
     // private static final String CMD = "-b ./src/test -t site/sample/ftl/nginx/nginx.conf.ftl -d env=site/sample/ftl/nginx/nginx.env";
     // private static final String CMD = "-b ./src/test -t templates/info.ftl -d env=site/sample/ftl/nginx/nginx.env";
     // private static final String CMD = "-b ./src/test -t templates/json/yaml/transform.ftl site/sample/json/swagger-spec.json";
     // private static final String CMD = "-b ./src/test -t templates/yaml/json/transform.ftl site/sample/yaml/swagger-spec.yaml";
+    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env=env:///";
+    private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env:///";
+    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env:///HOME";
+    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env=./site/sample/properties/user_0001/user.properties";
+    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m ./site/sample/properties/user_0001/user.properties";
 
     public static void main(String[] args) {
         Main.execute(toArgs(CMD));


[freemarker-generator] 05/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e2176cdfd6cfb2235f2034a2c510832a4f4f154e
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 20:39:35 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../apache/freemarker/generator/base/util/PropertiesFactory.java   | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/PropertiesFactory.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/PropertiesFactory.java
index 561b185..8805150 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/PropertiesFactory.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/PropertiesFactory.java
@@ -19,6 +19,7 @@ package org.apache.freemarker.generator.base.util;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
+import java.util.Map;
 import java.util.Properties;
 
 public class PropertiesFactory {
@@ -42,4 +43,10 @@ public class PropertiesFactory {
             throw new RuntimeException("Failed to parse properties: " + value, e);
         }
     }
+
+    public static Properties create(Map<?, ?> map) {
+        final Properties properties = new Properties();
+        map.forEach((key, value) -> properties.setProperty(key.toString(), value.toString()));
+        return properties;
+    }
 }


[freemarker-generator] 03/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2e280e84e1c39d3a4d5c4a88ff5094e43948859b
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 20:38:27 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../apache/freemarker/generator/base/util/UriUtils.java   | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/UriUtils.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/UriUtils.java
index cbc401b..71ed654 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/UriUtils.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/UriUtils.java
@@ -20,6 +20,8 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 
+import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
+
 public class UriUtils {
 
     public static URI toURI(String str) {
@@ -39,18 +41,27 @@ public class UriUtils {
     }
 
     public static boolean isUri(String str) {
-        return str.contains("://");
+        return isNotEmpty(str) && str.contains("://");
     }
 
     public static boolean isHttpURI(URI uri) {
-        return uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https");
+        if (uri == null) {
+            return false;
+        }
+        return "http".equals(uri.getScheme()) || "https".equals(uri.getScheme());
     }
 
     public static boolean isFileUri(URI uri) {
+        if (uri == null) {
+            return false;
+        }
         return "file".equalsIgnoreCase(uri.getScheme());
     }
 
     public static boolean isEnvUri(URI uri) {
+        if (uri == null) {
+            return false;
+        }
         return "env".equalsIgnoreCase(uri.getScheme());
     }
 }


[freemarker-generator] 09/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c8af6edc68ade0ba6418d0825204dc503259a296
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 23:25:01 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../generator/cli/config}/DataModelsSupplier.java    | 20 +++++++++++++++++++-
 .../freemarker/generator/cli/config/Suppliers.java   |  1 -
 .../src/test/data/json/environments.json             |  4 ++++
 .../src/test/data/properties/test.properties         | 17 +++++++++++++++++
 .../cli/config}/DataModelsSupplierTest.java          | 14 ++++++++++++--
 .../freemarker/generator/tools/gson/GsonTool.java    |  4 +++-
 6 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
similarity index 81%
rename from freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
rename to freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
index f9da638..91187c4 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.base.datamodel;
+package org.apache.freemarker.generator.cli.config;
 
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
@@ -22,6 +22,7 @@ import org.apache.freemarker.generator.base.uri.NamedUri;
 import org.apache.freemarker.generator.base.uri.NamedUriStringParser;
 import org.apache.freemarker.generator.base.util.PropertiesFactory;
 import org.apache.freemarker.generator.base.util.UriUtils;
+import org.apache.freemarker.generator.tools.gson.GsonTool;
 
 import java.net.URI;
 import java.util.ArrayList;
@@ -34,6 +35,7 @@ import java.util.function.Supplier;
 
 import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.toMap;
+import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_JSON;
 import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
 
 /**
@@ -70,11 +72,27 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
         switch (contentType) {
             case MIME_TEXT_PLAIN:
                 return fromProperties(dataSource, isExplodedDataModel);
+            case MIME_APPLICATION_JSON:
+                return fromJson(dataSource, isExplodedDataModel);
             default:
                 throw new IllegalArgumentException("Don't know how to handle :" + contentType);
         }
     }
 
+    protected Map<String, Object> fromJson(DataSource dataSource, boolean isExplodedDataModel) {
+        final Map<String, Object> result = new HashMap<>();
+        final GsonTool gsonTool = new GsonTool();
+        final Map<String, Object> map = gsonTool.parse(dataSource);
+
+        if (isExplodedDataModel) {
+            map.forEach((key, value) -> result.put(key.toString(), value));
+        } else {
+            result.put(dataSource.getName(), map);
+        }
+
+        return result;
+    }
+
     protected Map<String, Object> fromProperties(DataSource dataSource, boolean isExplodedDataModel) {
         final Map<String, Object> result = new HashMap<>();
         final URI uri = dataSource.getUri();
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
index 41cd94a..1692443 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
@@ -17,7 +17,6 @@
 package org.apache.freemarker.generator.cli.config;
 
 import freemarker.cache.TemplateLoader;
-import org.apache.freemarker.generator.base.datamodel.DataModelsSupplier;
 import org.apache.freemarker.generator.base.datasource.DataSourcesSupplier;
 import org.apache.freemarker.generator.base.file.PropertiesClassPathSupplier;
 import org.apache.freemarker.generator.base.file.PropertiesFileSystemSupplier;
diff --git a/freemarker-generator-cli/src/test/data/json/environments.json b/freemarker-generator-cli/src/test/data/json/environments.json
new file mode 100644
index 0000000..eb11bc4
--- /dev/null
+++ b/freemarker-generator-cli/src/test/data/json/environments.json
@@ -0,0 +1,4 @@
+{
+   "db_default_user": "scott",
+   "db_default_password": "tiger"
+}
\ No newline at end of file
diff --git a/freemarker-generator-cli/src/test/data/properties/test.properties b/freemarker-generator-cli/src/test/data/properties/test.properties
new file mode 100644
index 0000000..6431653
--- /dev/null
+++ b/freemarker-generator-cli/src/test/data/properties/test.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+foo=bar
\ No newline at end of file
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
similarity index 88%
rename from freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java
rename to freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
index e3ebb6e..0c831c7 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datamodel/DataModelsSupplierTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
@@ -14,9 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.datamodel;
+package org.apache.freemarker.generator.cli.config;
 
-import org.apache.freemarker.generator.base.datamodel.DataModelsSupplier;
 import org.junit.Test;
 
 import java.util.Map;
@@ -90,6 +89,17 @@ public class DataModelsSupplierTest {
         assertEquals("bar", toMap(model, "props").get("foo"));
     }
 
+    @Test
+    public void shouldResolveJsonFileToTopLevelDataModel() {
+        final DataModelsSupplier supplier = supplier("./src/test/data/json/environments.json");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(2, model.size());
+        assertEquals("scott", model.get("db_default_user"));
+        assertEquals("tiger", model.get("db_default_password"));
+    }
+
     private static DataModelsSupplier supplier(String source) {
         return new DataModelsSupplier(singletonList(source));
     }
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/gson/GsonTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/gson/GsonTool.java
index 9805afd..6a864eb 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/gson/GsonTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/gson/GsonTool.java
@@ -32,9 +32,11 @@ public class GsonTool {
     private Gson gson;
     private Type type;
 
-    public Map<String, Object> parse(DataSource dataSource) throws IOException {
+    public Map<String, Object> parse(DataSource dataSource) {
         try (JsonReader reader = new JsonReader(new InputStreamReader(dataSource.getUnsafeInputStream()))) {
             return gson().fromJson(reader, type());
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to parse data source:" + dataSource, e);
         }
     }
 


[freemarker-generator] 04/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1c56501fcf98b70b67c39a4843bb4bb7b6d7a9ff
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 20:39:04 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../org/apache/freemarker/generator/base/util/StringUtils.java | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
index 24b81af..bee41e7 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/StringUtils.java
@@ -45,4 +45,14 @@ public class StringUtils {
         return null;
     }
 
+    public static String firstNonNull(final String... values) {
+        if (values != null) {
+            for (final String value : values) {
+                if (value != null) {
+                    return value;
+                }
+            }
+        }
+        return null;
+    }
 }


[freemarker-generator] 11/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a5fbf1c0ebb80fbf77823a572bf31c9d144668b3
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 23:59:13 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../generator/base/datasource/DataSource.java      |  4 +--
 .../base/datasource/DataSourceFactory.java         |  5 +--
 .../generator/cli/config/DataModelsSupplier.java   | 38 ++++++++++------------
 .../freemarker/generator/cli/ManualTest.java       |  4 +--
 4 files changed, 24 insertions(+), 27 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 d757b5a..d968e54 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
@@ -77,7 +77,7 @@ public class DataSource implements Closeable {
         this.group = emptyToNull(group);
         this.uri = requireNonNull(uri);
         this.dataSource = requireNonNull(dataSource);
-        this.contentType = requireNonNull(contentType);
+        this.contentType = contentType;
         this.charset = requireNonNull(charset);
         this.closables = new CloseableReaper();
     }
@@ -103,7 +103,7 @@ public class DataSource implements Closeable {
     }
 
     public String getContentType() {
-        return contentType;
+        return contentType != null ? contentType : dataSource.getContentType();
     }
 
     public URI getUri() {
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 3f98adc..47bea88 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
@@ -62,11 +62,12 @@ public class DataSourceFactory {
         final URI uri = namedUri.getUri();
         final String group = namedUri.getGroupOrElse(DEFAULT_GROUP);
         final Charset charset = getCharsetOrElse(namedUri, UTF_8);
+        final String mimeType = getMimeTypeOrElse(namedUri, null);
 
         if (UriUtils.isHttpURI(uri)) {
             final URL url = toURL(uri);
             final String name = namedUri.getNameOrElse(url.getHost());
-            return fromUrl(name, group, url, charset);
+            return fromUrl(name, group, url, mimeType, charset);
         } else if (UriUtils.isFileUri(uri)) {
             final File file = namedUri.getFile();
             final String name = namedUri.getNameOrElse(file.getName());
@@ -91,7 +92,7 @@ public class DataSourceFactory {
     // == URL ===============================================================
 
     public static DataSource fromUrl(String name, String group, URL url, Charset charset) {
-        return fromUrl(name, group, url, "application/octet-stream", charset);
+        return fromUrl(name, group, url, null, charset);
     }
 
     public static DataSource fromUrl(String name, String group, URL url, String contentType, Charset charset) {
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
index 4303195..22251d0 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
@@ -41,7 +41,7 @@ import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEX
 import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_YAML;
 
 /**
- * Create a list of <code>DataSource</code> based on a list of sources consisting of
+ * Create a list of <code>DataModel</code> based on a list of sources consisting of
  * URIs, named URIs or files.
  */
 public class DataModelsSupplier implements Supplier<Map<String, Object>> {
@@ -72,10 +72,10 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
         final String contentType = dataSource.getContentType();
 
         switch (contentType) {
-            case MIME_TEXT_PLAIN:
-                return fromProperties(dataSource, isExplodedDataModel);
             case MIME_APPLICATION_JSON:
                 return fromJson(dataSource, isExplodedDataModel);
+            case MIME_TEXT_PLAIN:
+                return fromProperties(dataSource, isExplodedDataModel);
             case MIME_TEXT_YAML:
                 return fromYaml(dataSource, isExplodedDataModel);
             default:
@@ -84,31 +84,15 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
     }
 
     protected Map<String, Object> fromJson(DataSource dataSource, boolean isExplodedDataModel) {
-        final Map<String, Object> result = new HashMap<>();
         final GsonTool gsonTool = new GsonTool();
         final Map<String, Object> map = gsonTool.parse(dataSource);
-
-        if (isExplodedDataModel) {
-            map.forEach((key, value) -> result.put(key.toString(), value));
-        } else {
-            result.put(dataSource.getName(), map);
-        }
-
-        return result;
+        return fromMap(dataSource.getName(), map, isExplodedDataModel);
     }
 
     protected Map<String, Object> fromYaml(DataSource dataSource, boolean isExplodedDataModel) {
-        final Map<String, Object> result = new HashMap<>();
         final SnakeYamlTool snakeYamlTool = new SnakeYamlTool();
         final Map<String, Object> map = snakeYamlTool.parse(dataSource);
-
-        if (isExplodedDataModel) {
-            map.forEach((key, value) -> result.put(key.toString(), value));
-        } else {
-            result.put(dataSource.getName(), map);
-        }
-
-        return result;
+        return fromMap(dataSource.getName(), map, isExplodedDataModel);
     }
 
     protected Map<String, Object> fromProperties(DataSource dataSource, boolean isExplodedDataModel) {
@@ -128,4 +112,16 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
 
         return result;
     }
+
+    private Map<String, Object> fromMap(String name, Map<String, Object> map, boolean isExplodedDataModel) {
+        final Map<String, Object> result = new HashMap<>();
+
+        if (isExplodedDataModel) {
+            map.forEach(result::put);
+        } else {
+            result.put(name, map);
+        }
+
+        return result;
+    }
 }
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 3e44808..16aec0c 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
@@ -43,10 +43,10 @@ public class ManualTest {
     // private static final String CMD = "-b ./src/test -t templates/json/yaml/transform.ftl site/sample/json/swagger-spec.json";
     // private static final String CMD = "-b ./src/test -t templates/yaml/json/transform.ftl site/sample/yaml/swagger-spec.yaml";
     // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env=env:///";
-    private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env:///";
+    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m api=https://httpbin.org/get";
     // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env:///HOME";
     // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m env=./site/sample/properties/user_0001/user.properties";
-    // private static final String CMD = "-b ./src/test -t templates/demo.ftl -m ./site/sample/properties/user_0001/user.properties";
+    private static final String CMD = "-b ./src/test -t templates/demo.ftl -m ./site/sample/properties/user_0001/user.properties";
 
     public static void main(String[] args) {
         Main.execute(toArgs(CMD));


[freemarker-generator] 08/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9175e88f60e7e34d36af8967d56c3a8d53e30363
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 22:56:28 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../org/apache/freemarker/generator/cli/Main.java     | 14 +++++++-------
 .../apache/freemarker/generator/cli/PicocliTest.java  | 19 +++++++++++++++++--
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
index 6522c85..e3b17b4 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
@@ -71,9 +71,6 @@ public class Main implements Callable<Integer> {
     @Option(names = { "-b", "--basedir" }, description = "Optional template base directory")
     String baseDir;
 
-    @Option(names = { "-d", "--data-source" }, description = "Data source used for rendering")
-    List<String> dataSources;
-
     @Option(names = { "-D", "--system-property" }, description = "Set system property")
     Properties systemProperties;
 
@@ -86,8 +83,8 @@ public class Main implements Callable<Integer> {
     @Option(names = { "-l", "--locale" }, description = "Locale being used for the output, e.g. 'en_US'")
     String locale;
 
-    @Option(names = { "--mode" }, description = "[template|datasource]", defaultValue = "TEMPLATE")
-    GeneratorMode mode;
+    @Option(names = { "-m", "--data-model" }, description = "Data model used for rendering")
+    List<String> dataModels;
 
     @Option(names = { "-o", "--output" }, description = "Output file")
     String outputFile;
@@ -95,8 +92,8 @@ public class Main implements Callable<Integer> {
     @Option(names = { "-P", "--param" }, description = "Set parameter")
     Map<String, String> parameters;
 
-    @Option(names = { "-m", "--data-model" }, description = "Data model used for rendering")
-    List<String> dataModels;
+    @Option(names = { "-s", "--data-source" }, description = "Data source used for rendering")
+    List<String> dataSources;
 
     @Option(names = { "--config" }, defaultValue = FREEMARKER_CLI_PROPERTY_FILE, description = "FreeMarker CLI configuration file")
     String configFile;
@@ -110,6 +107,9 @@ public class Main implements Callable<Integer> {
     @Option(names = { "--output-encoding" }, description = "Encoding of output, e.g. UTF-8", defaultValue = "UTF-8")
     String outputEncoding;
 
+    @Option(names = { "--mode" }, description = "[template|datasource]", defaultValue = "TEMPLATE")
+    GeneratorMode mode;
+
     @Option(names = { "--stdin" }, description = "Read data  source from stdin")
     boolean readFromStdin;
 
diff --git a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/PicocliTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/PicocliTest.java
index fdd7fc2..d5e15d6 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/PicocliTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/PicocliTest.java
@@ -52,20 +52,35 @@ public class PicocliTest {
     @Test
     public void testSingleNamedDataSource() {
         assertEquals(ANY_FILE, parse("-t", TEMPLATE, ANY_FILE).sources.get(0));
-        assertEquals(ANY_FILE, parse("-t", TEMPLATE, "-d", ANY_FILE).dataSources.get(0));
+        assertEquals(ANY_FILE, parse("-t", TEMPLATE, "-s", ANY_FILE).dataSources.get(0));
         assertEquals(ANY_FILE, parse("-t", TEMPLATE, "--data-source", ANY_FILE).dataSources.get(0));
         assertEquals(ANY_FILE_URI, parse("-t", TEMPLATE, "--data-source", ANY_FILE_URI).dataSources.get(0));
     }
 
     @Test
     public void testMultipleNamedDataSource() {
-        final Main main = parse("-t", TEMPLATE, "-d", ANY_FILE, "--data-source", OTHER_FILE_URI);
+        final Main main = parse("-t", TEMPLATE, "-s", ANY_FILE, "--data-source", OTHER_FILE_URI);
 
         assertEquals(ANY_FILE, main.dataSources.get(0));
         assertEquals(OTHER_FILE_URI, main.dataSources.get(1));
         assertNull(main.sources);
     }
 
+    @Test
+    public void testSingleDataModel() {
+        assertEquals(ANY_FILE, parse("-t", TEMPLATE, "-m", ANY_FILE).dataModels.get(0));
+        assertEquals(ANY_FILE, parse("-t", TEMPLATE, "--data-model", ANY_FILE).dataModels.get(0));
+    }
+
+    @Test
+    public void testMultipleDataModels() {
+        final Main main = parse("-t", TEMPLATE, "-m", ANY_FILE, "--data-model", OTHER_FILE_URI);
+
+        assertEquals(ANY_FILE, main.dataModels.get(0));
+        assertEquals(OTHER_FILE_URI, main.dataModels.get(1));
+        assertNull(main.sources);
+    }
+
     private static Main parse(String... args) {
         final Main main = new Main();
         new CommandLine(main).parseArgs(args);


[freemarker-generator] 01/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 64cd0929f7a217d4043e508300cde7a69ce517d0
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 17:20:27 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../base/datamodel/DataModelsSupplier.java         | 64 ++++++++++++++++++++++
 .../org/apache/freemarker/generator/cli/Main.java  |  6 +-
 .../freemarker/generator/cli/config/Settings.java  | 25 ++++++++-
 .../freemarker/generator/cli/config/Suppliers.java |  5 ++
 .../generator/cli/task/FreeMarkerTask.java         | 28 +++++++---
 .../freemarker/generator/cli/ManualTest.java       |  4 +-
 6 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
new file mode 100644
index 0000000..8f9f268
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datamodel/DataModelsSupplier.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.freemarker.generator.base.datamodel;
+
+import org.apache.freemarker.generator.base.datasource.DataSource;
+import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Create a list of <code>DataSource</code> based on a list of sources consisting of
+ * URIs, named URIs or files.
+ */
+public class DataModelsSupplier implements Supplier<Map<String, Object>> {
+
+    /** List of source files, named URIs and URIs */
+    private final Collection<String> sources;
+
+    /**
+     * Constructor.
+     *
+     * @param sources List of sources
+     */
+    public DataModelsSupplier(Collection<String> sources) {
+        this.sources = new ArrayList<>(sources);
+    }
+
+    @Override
+    public Map<String, Object> get() {
+        final List<DataSource> dataModels = sources.stream().map(this::resolve).collect(toList());
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Resolve a <code>source</code> to a <code>DataSource</code>.
+     *
+     * @param source the source being a file name, an <code>URI</code> or <code>NamedUri</code>
+     * @return list of <code>DataSource</code>
+     */
+    protected DataSource resolve(String source) {
+        return DataSourceFactory.create(source);
+    }
+}
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
index e890120..6522c85 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/Main.java
@@ -86,7 +86,7 @@ public class Main implements Callable<Integer> {
     @Option(names = { "-l", "--locale" }, description = "Locale being used for the output, e.g. 'en_US'")
     String locale;
 
-    @Option(names = { "-m", "--mode" }, description = "[template|datasource]", defaultValue = "TEMPLATE")
+    @Option(names = { "--mode" }, description = "[template|datasource]", defaultValue = "TEMPLATE")
     GeneratorMode mode;
 
     @Option(names = { "-o", "--output" }, description = "Output file")
@@ -95,6 +95,9 @@ public class Main implements Callable<Integer> {
     @Option(names = { "-P", "--param" }, description = "Set parameter")
     Map<String, String> parameters;
 
+    @Option(names = { "-m", "--data-model" }, description = "Data model used for rendering")
+    List<String> dataModels;
+
     @Option(names = { "--config" }, defaultValue = FREEMARKER_CLI_PROPERTY_FILE, description = "FreeMarker CLI configuration file")
     String configFile;
 
@@ -219,6 +222,7 @@ public class Main implements Callable<Integer> {
                 .setOutputFile(outputFile)
                 .setParameters(parameters != null ? parameters : new HashMap<>())
                 .setDataSources(getCombindedDataSources())
+                .setDataModels(dataModels)
                 .setSystemProperties(systemProperties != null ? systemProperties : new Properties())
                 .setTemplateDirectories(templateDirectories)
                 .setTemplateName(templateSourceOptions.template)
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Settings.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Settings.java
index 30f6d9c..51bbae8 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Settings.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Settings.java
@@ -85,9 +85,12 @@ public class Settings {
     /** Expose environment variables globally in the data model? */
     private final boolean isEnvironmentExposed;
 
-    /** User-supplied list of source files or directories */
+    /** User-supplied list of data sources or directories */
     private final List<String> dataSources;
 
+    /** User-supplied list of data sources directly exposed in the data model */
+    private List<String> dataModels;
+
     /** User-supplied parameters */
     private final Map<String, String> parameters;
 
@@ -113,6 +116,7 @@ public class Settings {
             boolean isReadFromStdin,
             boolean isEnvironmentExposed,
             List<String> dataSources,
+            List<String> dataModels,
             Map<String, String> parameters,
             Properties sytemProperties,
             Writer writer) {
@@ -134,6 +138,7 @@ public class Settings {
         this.isReadFromStdin = isReadFromStdin;
         this.isEnvironmentExposed = isEnvironmentExposed;
         this.dataSources = requireNonNull(dataSources);
+        this.dataModels = requireNonNull(dataModels);
         this.parameters = requireNonNull(parameters);
         this.sytemProperties = requireNonNull(sytemProperties);
         this.configuration = requireNonNull(configuration);
@@ -208,6 +213,10 @@ public class Settings {
         return dataSources;
     }
 
+    public List<String> getDataModels() {
+        return dataModels;
+    }
+
     public Map<String, String> getParameters() {
         return parameters;
     }
@@ -289,6 +298,7 @@ public class Settings {
         private boolean isReadFromStdin;
         private boolean isEnvironmentExposed;
         private List<String> dataSources;
+        private List<String> dataModels;
         private Map<String, String> parameters;
         private Properties systemProperties;
         private Properties configuration;
@@ -303,6 +313,7 @@ public class Settings {
             this.setInputEncoding(DEFAULT_CHARSET.name());
             this.setOutputEncoding(DEFAULT_CHARSET.name());
             this.dataSources = emptyList();
+            this.dataModels = emptyList();
             this.templateDirectories = emptyList();
         }
 
@@ -381,7 +392,16 @@ public class Settings {
         }
 
         public SettingsBuilder setDataSources(List<String> dataSources) {
-            this.dataSources = dataSources;
+            if (dataSources != null) {
+                this.dataSources = dataSources;
+            }
+            return this;
+        }
+
+        public SettingsBuilder setDataModels(List<String> dataModels) {
+            if (dataModels != null) {
+                this.dataModels = dataModels;
+            }
             return this;
         }
 
@@ -433,6 +453,7 @@ public class Settings {
                     isReadFromStdin,
                     isEnvironmentExposed,
                     dataSources,
+                    dataModels,
                     parameters,
                     systemProperties,
                     writer
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
index 0766ad3..41cd94a 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/Suppliers.java
@@ -17,6 +17,7 @@
 package org.apache.freemarker.generator.cli.config;
 
 import freemarker.cache.TemplateLoader;
+import org.apache.freemarker.generator.base.datamodel.DataModelsSupplier;
 import org.apache.freemarker.generator.base.datasource.DataSourcesSupplier;
 import org.apache.freemarker.generator.base.file.PropertiesClassPathSupplier;
 import org.apache.freemarker.generator.base.file.PropertiesFileSystemSupplier;
@@ -56,6 +57,10 @@ public class Suppliers {
                 settings.getInputEncoding());
     }
 
+    public static DataModelsSupplier dataModelsSupplier(Settings settings) {
+        return new DataModelsSupplier(settings.getDataModels());
+    }
+
     public static PropertiesSupplier propertiesSupplier(String fileName) {
         return new PropertiesSupplier(
                 new PropertiesFileSystemSupplier(fileName),
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/task/FreeMarkerTask.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/task/FreeMarkerTask.java
index 0fa4482..d9fe61b 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/task/FreeMarkerTask.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/task/FreeMarkerTask.java
@@ -43,6 +43,7 @@ import static org.apache.freemarker.generator.base.FreeMarkerConstants.DEFAULT_G
 import static org.apache.freemarker.generator.base.FreeMarkerConstants.Location.STDIN;
 import static org.apache.freemarker.generator.base.FreeMarkerConstants.Model.DATASOURCES;
 import static org.apache.freemarker.generator.cli.config.Suppliers.configurationSupplier;
+import static org.apache.freemarker.generator.cli.config.Suppliers.dataModelsSupplier;
 import static org.apache.freemarker.generator.cli.config.Suppliers.dataSourcesSupplier;
 import static org.apache.freemarker.generator.cli.config.Suppliers.toolsSupplier;
 
@@ -56,19 +57,22 @@ public class FreeMarkerTask implements Callable<Integer> {
     private final Settings settings;
     private final Supplier<Map<String, Object>> toolsSupplier;
     private final Supplier<List<DataSource>> dataSourcesSupplier;
+    private final Supplier<Map<String, Object>> dataModelsSupplier;
     private final Supplier<Configuration> configurationSupplier;
 
     public FreeMarkerTask(Settings settings) {
-        this(settings, toolsSupplier(settings), dataSourcesSupplier(settings), configurationSupplier(settings));
+        this(settings, toolsSupplier(settings), dataSourcesSupplier(settings), dataModelsSupplier(settings), configurationSupplier(settings));
     }
 
     public FreeMarkerTask(Settings settings,
                           Supplier<Map<String, Object>> toolsSupplier,
                           Supplier<List<DataSource>> dataSourcesSupplier,
+                          Supplier<Map<String, Object>> dataModelsSupplier,
                           Supplier<Configuration> configurationSupplier) {
         this.settings = requireNonNull(settings);
         this.toolsSupplier = requireNonNull(toolsSupplier);
         this.dataSourcesSupplier = requireNonNull(dataSourcesSupplier);
+        this.dataModelsSupplier = requireNonNull(dataModelsSupplier);
         this.configurationSupplier = requireNonNull(configurationSupplier);
     }
 
@@ -76,7 +80,7 @@ public class FreeMarkerTask implements Callable<Integer> {
     public Integer call() {
         final Template template = template(settings, configurationSupplier);
         try (Writer writer = settings.getWriter(); DataSources dataSources = dataSources(settings, dataSourcesSupplier)) {
-            final Map<String, Object> dataModel = dataModel(settings, dataSources, toolsSupplier);
+            final Map<String, Object> dataModel = dataModel(settings, dataSources, dataModelsSupplier, toolsSupplier);
             template.process(dataModel, writer);
             return SUCCESS;
         } catch (RuntimeException e) {
@@ -126,20 +130,26 @@ public class FreeMarkerTask implements Callable<Integer> {
         }
     }
 
-    private static Map<String, Object> dataModel(Settings settings, DataSources dataSources, Supplier<Map<String, Object>> tools) {
-        final Map<String, Object> dataModel = new HashMap<>();
+    private static Map<String, Object> dataModel(
+            Settings settings,
+            DataSources dataSources,
+            Supplier<Map<String, Object>> dataModelsSupplier,
+            Supplier<Map<String, Object>> tools) {
+        final Map<String, Object> result = new HashMap<>();
 
-        dataModel.put(DATASOURCES, dataSources);
+        result.putAll(dataModelsSupplier.get());
+        result.put(DATASOURCES, dataSources);
 
+        // TODO rework  based on FREEMARKER-140
         if (settings.isEnvironmentExposed()) {
             // add all system & user-supplied properties as top-level entries
-            dataModel.putAll(System.getenv());
-            dataModel.putAll(settings.getParameters());
+            result.putAll(System.getenv());
+            result.putAll(settings.getParameters());
         }
 
-        dataModel.putAll(tools.get());
+        result.putAll(tools.get());
 
-        return dataModel;
+        return result;
     }
 
     private static boolean isAbsoluteTemplateFile(Settings settings) {
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 0d8ca31..67e8e39 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
@@ -35,12 +35,12 @@ public class ManualTest {
     // private static final String CMD = "-i ${JsoupTool.parse(DataSources.first).select('a')[0]} site/sample/html/dependencies.html";
     // private static final String CMD = "-b ./src/test -t templates/properties/csv/locker-test-users.ftl site/sample/properties";
     // private static final String CMD = "-b ./src/test -e UTF-8 -l de_AT -Dcolumn=Order%20ID -Dvalues=226939189,957081544 -Dformat=DEFAULT -Ddelimiter=COMMA -t templates/csv/md/filter.ftl site/sample/csv/sales-records.csv";
-    // private static final String CMD = "-E -b ./src/test -t templates/environment.ftl";
+    private static final String CMD = "-E -b ./src/test -t templates/environment.ftl";
     // private static final String CMD = "-b ./src/test -l de_AT -DFOO=foo -DBAR=bar -t templates/info.ftl -d user:admin=site/sample/csv/contract.csv#charset=UTF-16 google:www=https://www.google.com?foo=bar#contenttype=application/json";
     // private static final String CMD = "-b ./src/test -t templates/info.ftl -d :user=site/sample/properties -d contract=site/sample/csv/contract.csv";
     // private static final String CMD = "-b ./src/test -t site/sample/ftl/nginx/nginx.conf.ftl -d env=site/sample/ftl/nginx/nginx.env";
     // private static final String CMD = "-b ./src/test -t templates/info.ftl -d env=site/sample/ftl/nginx/nginx.env";
-    private static final String CMD = "-b ./src/test -t templates/json/yaml/transform.ftl site/sample/json/swagger-spec.json";
+    // private static final String CMD = "-b ./src/test -t templates/json/yaml/transform.ftl site/sample/json/swagger-spec.json";
     // private static final String CMD = "-b ./src/test -t templates/yaml/json/transform.ftl site/sample/yaml/swagger-spec.yaml";
 
     public static void main(String[] args) {


[freemarker-generator] 10/11: FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model

Posted by sg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f80d16c73d9362a14e67037f678040e89d6b446c
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 5 23:28:22 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../generator/cli/config/DataModelsSupplier.java       | 18 ++++++++++++++++++
 .../src/test/data/yaml/environments.yaml               |  3 +++
 .../generator/cli/config/DataModelsSupplierTest.java   | 11 +++++++++++
 3 files changed, 32 insertions(+)

diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
index 91187c4..4303195 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelsSupplier.java
@@ -23,6 +23,7 @@ import org.apache.freemarker.generator.base.uri.NamedUriStringParser;
 import org.apache.freemarker.generator.base.util.PropertiesFactory;
 import org.apache.freemarker.generator.base.util.UriUtils;
 import org.apache.freemarker.generator.tools.gson.GsonTool;
+import org.apache.freemarker.generator.tools.snakeyaml.SnakeYamlTool;
 
 import java.net.URI;
 import java.util.ArrayList;
@@ -37,6 +38,7 @@ import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.toMap;
 import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_JSON;
 import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
+import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_YAML;
 
 /**
  * Create a list of <code>DataSource</code> based on a list of sources consisting of
@@ -74,6 +76,8 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
                 return fromProperties(dataSource, isExplodedDataModel);
             case MIME_APPLICATION_JSON:
                 return fromJson(dataSource, isExplodedDataModel);
+            case MIME_TEXT_YAML:
+                return fromYaml(dataSource, isExplodedDataModel);
             default:
                 throw new IllegalArgumentException("Don't know how to handle :" + contentType);
         }
@@ -93,6 +97,20 @@ public class DataModelsSupplier implements Supplier<Map<String, Object>> {
         return result;
     }
 
+    protected Map<String, Object> fromYaml(DataSource dataSource, boolean isExplodedDataModel) {
+        final Map<String, Object> result = new HashMap<>();
+        final SnakeYamlTool snakeYamlTool = new SnakeYamlTool();
+        final Map<String, Object> map = snakeYamlTool.parse(dataSource);
+
+        if (isExplodedDataModel) {
+            map.forEach((key, value) -> result.put(key.toString(), value));
+        } else {
+            result.put(dataSource.getName(), map);
+        }
+
+        return result;
+    }
+
     protected Map<String, Object> fromProperties(DataSource dataSource, boolean isExplodedDataModel) {
         final Map<String, Object> result = new HashMap<>();
         final URI uri = dataSource.getUri();
diff --git a/freemarker-generator-cli/src/test/data/yaml/environments.yaml b/freemarker-generator-cli/src/test/data/yaml/environments.yaml
new file mode 100644
index 0000000..a9c9d0a
--- /dev/null
+++ b/freemarker-generator-cli/src/test/data/yaml/environments.yaml
@@ -0,0 +1,3 @@
+---
+db_default_user: scott
+db_default_password: tiger
diff --git a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
index 0c831c7..bcb5d11 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelsSupplierTest.java
@@ -100,6 +100,17 @@ public class DataModelsSupplierTest {
         assertEquals("tiger", model.get("db_default_password"));
     }
 
+    @Test
+    public void shouldResolveYamlFileToTopLevelDataModel() {
+        final DataModelsSupplier supplier = supplier("./src/test/data/yaml/environments.yaml");
+
+        final Map<String, Object> model = supplier.get();
+
+        assertEquals(2, model.size());
+        assertEquals("scott", model.get("db_default_user"));
+        assertEquals("tiger", model.get("db_default_password"));
+    }
+
     private static DataModelsSupplier supplier(String source) {
         return new DataModelsSupplier(singletonList(source));
     }