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


The following commit(s) were added to refs/heads/feature/FREEMARKER-140 by this 
push:
     new 57f270e  FREEMARKER-140 freemarker-cli: Expose DataSources directly in 
the data model
57f270e is described below

commit 57f270ec6e453709dbad5bb376ecf959cfe2e1fa
Author: Siegfried Goeschl <[email protected]>
AuthorDate: Mon Apr 6 21:13:53 2020 +0200

    FREEMARKER-140 freemarker-cli: Expose DataSources directly in the data model
---
 .../generator/base/datasource/DataSource.java      | 35 ++++++++-----
 .../base/datasource/DataSourceFactory.java         |  5 +-
 .../datasource/DataSourceFactoryTest.java          |  4 +-
 .../data-models.md}                                |  2 +-
 .../src/site/markdown/cli/concepts/named-uris.md   | 59 ++++++++++++++++++++++
 .../src/site/markdown/index.md                     |  7 ++-
 .../freemarker/generator/cli/ManualTest.java       |  4 +-
 7 files changed, 97 insertions(+), 19 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 35cac8e..dd055f2 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
@@ -31,10 +31,8 @@ import java.io.StringWriter;
 import java.net.URI;
 import java.nio.charset.Charset;
 import java.util.List;
-import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import java.util.stream.Stream;
 
 import static java.nio.charset.Charset.forName;
 import static java.nio.charset.StandardCharsets.UTF_8;
@@ -42,12 +40,16 @@ import static java.util.Objects.requireNonNull;
 import static org.apache.commons.io.IOUtils.lineIterator;
 import static 
org.apache.freemarker.generator.base.FreeMarkerConstants.DATASOURCE_UNKNOWN_LENGTH;
 import static 
org.apache.freemarker.generator.base.util.StringUtils.emptyToNull;
-import static 
org.apache.freemarker.generator.base.util.StringUtils.firstNonEmpty;
+import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
 
 /**
  * Data source which encapsulates data to be used for rendering
  * a template. When accessing content it is loaded on demand on not
  * kept in memory to allow processing of large volumes of data.
+ * <b/>
+ * There is also special support of <code>UrlDataSource</code> since
+ * the content type &amp; charset might be determined using a network
+ * call.
  */
 public class DataSource implements Closeable {
 
@@ -108,14 +110,16 @@ public class DataSource implements Closeable {
     }
 
     public Charset getCharset() {
-        return Stream.of(charset, 
parseCharsetFromContentType(getContentType()))
-                .filter(Objects::nonNull)
-                .findFirst()
-                .orElse(UTF_8);
+        return charset != null ? charset : 
getCharsetFromContentType(contentType(), UTF_8);
     }
 
+    /**
+     * Get the content type without additional parameters, e.g. "charset".
+     *
+     * @return content type
+     */
     public String getContentType() {
-        return firstNonEmpty(contentType, dataSource.getContentType());
+        return stripExtraParameterFronContentType(contentType());
     }
 
     public URI getUri() {
@@ -258,17 +262,24 @@ public class DataSource implements Closeable {
                 "name='" + name + '\'' +
                 ", group='" + group + '\'' +
                 ", uri=" + uri +
-                ", contentType='" + contentType + '\'' +
-                ", charset=" + charset +
                 '}';
     }
 
-    private Charset parseCharsetFromContentType(String contentType) {
+    private Charset getCharsetFromContentType(String contentType, Charset def) 
{
         final Matcher matcher = CHARSET_PATTERN.matcher(contentType);
         if (matcher.find()) {
             final String name = matcher.group(1).trim().toUpperCase();
             return Charset.forName(name);
         }
-        return null;
+        return def;
+    }
+
+    private String contentType() {
+        return isNotEmpty(contentType) ? contentType : 
dataSource.getContentType();
+    }
+
+    private String stripExtraParameterFronContentType(String contentType) {
+        final int end = contentType.indexOf(";");
+        return end > 0 ? contentType.substring(0, end) : contentType;
     }
 }
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 4b5d976..d3b84e0 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,7 +62,7 @@ public class DataSourceFactory {
     public static DataSource fromNamedUri(NamedUri namedUri) {
         final URI uri = namedUri.getUri();
         final String group = namedUri.getGroupOrElse(DEFAULT_GROUP);
-        final Charset charset = getCharsetOrElse(namedUri, UTF_8);
+        final Charset charset = getCharsetOrElse(namedUri, null);
         final String mimeType = getMimeTypeOrElse(namedUri, null);
 
         if (UriUtils.isHttpURI(uri)) {
@@ -196,7 +196,8 @@ public class DataSourceFactory {
     }
 
     private static Charset getCharsetOrElse(NamedUri namedUri, Charset def) {
-        return Charset.forName(namedUri.getParameter(NamedUri.CHARSET, 
def.name()));
+        final String charsetName = namedUri.getParameter(NamedUri.CHARSET);
+        return StringUtils.isEmpty(charsetName) ? def : 
Charset.forName(charsetName);
     }
 
     private static URL toURL(URI uri) {
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 035566e..57029df 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
@@ -108,7 +108,7 @@ public class DataSourceFactoryTest {
         final DataSource dataSource = 
DataSourceFactory.fromUrl("jsonplaceholder.typicode.com", "default", url, null, 
null);
 
         assertEquals("jsonplaceholder.typicode.com", dataSource.getName());
-        assertEquals("application/json; charset=utf-8", 
dataSource.getContentType());
+        assertEquals("application/json", dataSource.getContentType());
         assertEquals(UTF_8, dataSource.getCharset());
     }
 
@@ -119,7 +119,7 @@ public class DataSourceFactoryTest {
 
         assertEquals(namedUri.getName(), dataSource.getName());
         assertEquals(namedUri.getGroup(), dataSource.getGroup());
-        assertEquals(UTF_8, dataSource.getCharset());
+        assertEquals("ISO-8859-1", dataSource.getCharset().toString());
         assertEquals(namedUri.getUri().toString(), 
dataSource.getUri().toString());
     }
 }
diff --git 
a/freemarker-generator-cli/src/site/markdown/cli/working-with-datamodels.md 
b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
similarity index 98%
rename from 
freemarker-generator-cli/src/site/markdown/cli/working-with-datamodels.md
rename to freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
index 6b46397..c05323c 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/working-with-datamodels.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
@@ -1,4 +1,4 @@
-## Working With DataModels
+## DataModels
 
 A `DataModel` is an eagerly loaded `DataSource` available in Apache 
FreeMarker's model (context) when rendering a template.
 
diff --git 
a/freemarker-generator-cli/src/site/markdown/cli/concepts/named-uris.md 
b/freemarker-generator-cli/src/site/markdown/cli/concepts/named-uris.md
new file mode 100644
index 0000000..2a2469e
--- /dev/null
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/named-uris.md
@@ -0,0 +1,59 @@
+# Named URIs
+
+Named URIs allow to identify `DataSources` and pass additional information 
+
+A Named URI consists of
+
+* an optional name
+* an URI or simple file name
+
+As a refresher, a URI is made up of the following components (inspired by 
https://docs.gomplate.ca/datasources/)
+
+```
+  foo://[email protected]:8042/over/there?name=ferret#nose
+  \_/   \_______________________/\_________/ \_________/ \__/
+   |           |                    |            |        |
+scheme     authority               path        query   fragment
+```
+
+For our purposes, the scheme and the path components are especially important, 
though the other components are used by certain datasources for particular 
purposes.
+
+| Component | Purpose |
+|-----------|---------|
+| scheme       | All datasources require a scheme (except for file when using 
relative paths) |
+| authority    | Used only by remote datasources, and can be omitted in some 
of those cases. Consists of userinfo (user:pass), host, and port. |
+| path     | Can be omitted, but usually used as the basis of the locator for 
the datasource. |
+| query            | Used mainly for HTTP and HTTPS URLs |
+| fragment     | Used rarely for providing additional attributes, e.g. 
`mimetype` of `charset` |
+
+The following Named URI loads a "user.csv" and the data source is available as 
`my_users` 
+
+```
+bin/freemarker-cli -t templates/info.ftl my_users=site/sample/csv/user.csv
+[#1], name=my_users, group=default, contentType=text/csv, charset=UTF-8, 
length=376 Bytes
+URI : file:site/sample/csv/user.csv
+```
+
+A Named URI allows to pass additional information as part of the fragment, 
e.g. the charset of the text file 
+
+```
+bin/freemarker-cli -t templates/info.ftl 
my_users=site/sample/csv/user.csv#charset=UTF-16
+[#1], name=my_users, group=default, contentType=text/csv, charset=UTF-16, 
length=376 Bytes
+URI : file:site/sample/csv/user.csv
+```
+
+In addition to the simplified file syntax full URIs can be used
+
+```
+bin/freemarker-cli -t templates/info.ftl http://google.com?foo=bar
+[#1], name=google.com, group=default, contentType=text/html, 
charset=ISO-8859-1, length=-1 Bytes
+URI : http://google.com?foo=bar
+```
+
+and also combined with a name
+
+```
+bin/freemarker-cli -t templates/info.ftl page=http://google.com?foo=bar
+[#1], name=page, group=default, contentType=text/html, charset=ISO-8859-1, 
length=-1 Bytes
+URI : http://google.com?foo=bar
+```
diff --git a/freemarker-generator-cli/src/site/markdown/index.md 
b/freemarker-generator-cli/src/site/markdown/index.md
index 2fd9f95..c5807bc 100644
--- a/freemarker-generator-cli/src/site/markdown/index.md
+++ b/freemarker-generator-cli/src/site/markdown/index.md
@@ -1 +1,6 @@
-TBD
\ No newline at end of file
+## FreeMarker Generator CLI
+
+### Concepts
+
+* [Named URIs](cli/concepts/named-uris.html)
+* [Data Models](cli/concepts/data-models.html)
\ No newline at end of file
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 59952de..0dac268 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
@@ -45,9 +45,11 @@ public class ManualTest {
     // 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 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 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 --data-model 
post=https://jsonplaceholder.typicode.com/posts/2 -t templates/info.ftl";
+    private static final String CMD = "-b ./src/test -t templates/info.ftl 
google=https://www.google.com";;
+
 
     public static void main(String[] args) {
         Main.execute(toArgs(CMD));

Reply via email to