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/02/29 00:06:08 UTC

[freemarker-generator] branch FREEMARKER-135 created (now f8a9c53)

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

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


      at f8a9c53  FREEMARKER-135 Support user-supplied names for datasources

This branch includes the following new commits:

     new 8f7415e  FREEMARKER-135 Support user-supplied names for datasources
     new 5536651  FREEMARKER-135 Support user-supplied names for datasources
     new 06a2db9  FREEMARKER-135 Support user-supplied names for datasources
     new 57dc39c  FREEMARKER-135 Support user-supplied names for datasources
     new 9a3b0b4  FREEMARKER-135 Support user-supplied names for datasources
     new f8a9c53  FREEMARKER-135 Support user-supplied names for datasources

The 6 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] 05/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit 9a3b0b4d0248f930e06b9764edd9d40bdba63822
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sat Feb 29 00:13:41 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../generator/base/activation/MimetypesFileTypeMapFactory.java      | 5 +++--
 .../freemarker/generator/base/datasource/DatasourceFactory.java     | 6 ++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
index 3623bc5..3631395 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
@@ -32,8 +32,9 @@ public class MimetypesFileTypeMapFactory {
             mimeTypes.addMimeTypes("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx XLSX");
             mimeTypes.addMimeTypes("application/xml xml XML");
             mimeTypes.addMimeTypes("text/csv csv CSV");
-            mimeTypes.addMimeTypes("text/plain properties");
-            mimeTypes.addMimeTypes("text/yaml yml yaml YML YAML");
+            mimeTypes.addMimeTypes("text/plain txt TXT log LOG ini INI properties");
+            mimeTypes.addMimeTypes("text/yaml yml YML yaml YAML");
+            mimeTypes.addMimeTypes("text/tab-separated-values tsv TSV");
         }
 
         return mimeTypes;
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 6f8571c..c53be60 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
@@ -46,6 +46,12 @@ public class DatasourceFactory {
         return create(url.getHost(), dataSource, location, UTF_8);
     }
 
+    public static Datasource create(String name, URL url, Charset charset) {
+        final String location = url.toString();
+        final URLDataSource dataSource = new URLDataSource(url);
+        return create(name, dataSource, location, charset);
+    }
+
     public static Datasource create(String name, String content) {
         final StringDataSource dataSource = new StringDataSource(name, content, UTF_8);
         return create(name, dataSource, Location.STRING, UTF_8);


[freemarker-generator] 03/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit 06a2db9ebc4ba806c9e5bb50b7084204ffd7d586
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Fri Feb 28 22:58:12 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../activation/MimetypesFileTypeMapFactory.java    | 41 ++++++++++++++++++++++
 .../base/datasource/DatasourceFactory.java         |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
new file mode 100644
index 0000000..3623bc5
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.activation;
+
+import javax.activation.MimetypesFileTypeMap;
+
+public class MimetypesFileTypeMapFactory {
+
+    private static MimetypesFileTypeMap mimeTypes;
+
+    public static synchronized MimetypesFileTypeMap create() {
+        if (mimeTypes == null) {
+            mimeTypes = new MimetypesFileTypeMap();
+            mimeTypes.addMimeTypes("application/json json JSON");
+            mimeTypes.addMimeTypes("application/octet-stream bin");
+            mimeTypes.addMimeTypes("application/vnd.ms-excel xls XLS");
+            mimeTypes.addMimeTypes("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx XLSX");
+            mimeTypes.addMimeTypes("application/xml xml XML");
+            mimeTypes.addMimeTypes("text/csv csv CSV");
+            mimeTypes.addMimeTypes("text/plain properties");
+            mimeTypes.addMimeTypes("text/yaml yml yaml YML YAML");
+        }
+
+        return mimeTypes;
+    }
+}
\ No newline at end of file
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 08af5df..6f8571c 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
@@ -19,6 +19,7 @@ package org.apache.freemarker.generator.base.datasource;
 import org.apache.freemarker.generator.base.FreeMarkerConstants.Location;
 import org.apache.freemarker.generator.base.activation.ByteArrayDataSource;
 import org.apache.freemarker.generator.base.activation.InputStreamDataSource;
+import org.apache.freemarker.generator.base.activation.MimetypesFileTypeMapFactory;
 import org.apache.freemarker.generator.base.activation.StringDataSource;
 
 import javax.activation.DataSource;
@@ -56,6 +57,7 @@ public class DatasourceFactory {
 
     public static Datasource create(String name, File file, Charset charset) {
         final FileDataSource dataSource = new FileDataSource(file);
+        dataSource.setFileTypeMap(MimetypesFileTypeMapFactory.create());
         return create(name, dataSource, file.getAbsolutePath(), charset);
     }
 


[freemarker-generator] 06/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit f8a9c5376e349b3d4e96f1d1196ebec488f80ae7
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sat Feb 29 01:05:06 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../base/datasource/DatasourcesSupplier.java       | 36 +++++++++++----
 .../generator/base/uri/NamedUriFragmentParser.java |  4 +-
 .../generator/base/uri/NamedUriParser.java         | 51 ++++++++--------------
 .../generator/datasource/DatasourceTest.java       |  3 ++
 .../generator/uri/NamedUriParserTest.java          | 50 +++++++++++++++++++--
 .../freemarker/generator/cli/ManualTest.java       |  2 +-
 6 files changed, 97 insertions(+), 49 deletions(-)

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 7ae7819..c671fcf 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
@@ -21,6 +21,7 @@ import org.apache.freemarker.generator.base.uri.NamedUri;
 import org.apache.freemarker.generator.base.uri.NamedUriParser;
 
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
@@ -28,6 +29,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.function.Supplier;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Collections.singletonList;
 import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.toList;
@@ -73,22 +75,32 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
     }
 
     private List<Datasource> get(String source) {
-        if (isHttpUrl(source)) {
-            return singletonList(resolveHttpUrl(source));
-        } else {
-            return resolveFile(source, include, exclude, charset);
+        try {
+            if (isHttpUrl(source)) {
+                return singletonList(resolveHttpUrl(source));
+            } else {
+                return resolveFile(source, include, exclude, charset);
+            }
+        }
+        catch(RuntimeException e) {
+            throw new RuntimeException("Unable to create the datasource: " + source, e);
         }
     }
 
-    private static Datasource resolveHttpUrl(String url) {
-        return DatasourceFactory.create(toUrl(url));
+    private static Datasource resolveHttpUrl(String source) {
+        final NamedUri namedUri = NamedUriParser.parse(source);
+        final URI uri = namedUri.getUri();
+        final String location = uri.getScheme() + "://" + uri.getHost();
+        final String name = namedUri.hasName() ? namedUri.getName() : location;
+        final Charset currCharset = getCharset(namedUri, UTF_8);
+        return DatasourceFactory.create(name, toUrl(uri), currCharset);
     }
 
     private static List<Datasource> resolveFile(String source, String include, String exclude, Charset charset) {
         final NamedUri namedUri = NamedUriParser.parse(source);
         final String path = namedUri.getUri().getPath();
-        final Charset currCharset = getCharset(namedUri, charset);
         final String name = namedUri.hasName() ? namedUri.getName() : path;
+        final Charset currCharset = getCharset(namedUri, charset);
         return fileResolver(path, include, exclude).get().stream()
                 .map(file -> DatasourceFactory.create(name, file, currCharset))
                 .collect(toList());
@@ -99,7 +111,7 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
     }
 
     private static boolean isHttpUrl(String value) {
-        return value.contains("http://") || value.startsWith("https://");
+        return value.contains("http://") || value.contains("https://");
     }
 
     private static URL toUrl(String value) {
@@ -110,6 +122,14 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
         }
     }
 
+    private static URL toUrl(URI uri) {
+        try {
+            return uri.toURL();
+        } catch (MalformedURLException e) {
+            throw new IllegalArgumentException(uri.toString(), e);
+        }
+    }
+
     private static Charset getCharset(NamedUri namedUri, Charset def) {
         return Charset.forName(namedUri.getParameters().getOrDefault("charset", def.name()));
     }
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
index a94d3da..304a233 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
@@ -17,9 +17,9 @@
 package org.apache.freemarker.generator.base.uri;
 
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Map;
 
+import static java.util.Collections.emptyMap;
 import static java.util.stream.Collectors.toMap;
 import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
 
@@ -30,7 +30,7 @@ public class NamedUriFragmentParser {
 
     public static Map<String, String> parse(String fragment) {
         if (isEmpty(fragment)) {
-            return Collections.emptyMap();
+            return emptyMap();
         }
 
         try {
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java
index a18d914..174a303 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java
@@ -22,8 +22,6 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static java.util.Objects.requireNonNull;
-
 /**
  * Parses a named URI provided by the caller.
  * <ul>
@@ -35,47 +33,32 @@ import static java.util.Objects.requireNonNull;
  */
 public class NamedUriParser {
 
-    private static final String NAME_GROUP = "name";
-    private static final String URI_GROUP = "uri";
-    private static final int NR_OF_NAMED_GROUPS = 2;
+    private static final String REGEXP_GROUP_NAME = "name";
+    private static final String REGEXP_GROUP_URI = "uri";
     private static final Pattern NAMED_URI_REGEXP = Pattern.compile("^(?<name>[a-zA-Z0-9-_]*)=(?<uri>.*)");
 
     public static NamedUri parse(String value) {
-        final String sanitzedUri = requireNonNull(value).trim();
+        final Matcher matcher = NAMED_URI_REGEXP.matcher(value);
 
-        if (sanitzedUri.isEmpty()) {
-            throw new IllegalArgumentException("Empty named URI");
+        if (matcher.matches()) {
+            final String name = matcher.group(REGEXP_GROUP_NAME);
+            final URI uri = uri(matcher.group(REGEXP_GROUP_URI));
+            return new NamedUri(name, uri, parameters(uri));
+        } else {
+            final URI uri = uri(value);
+            return new NamedUri(uri, parameters(uri));
         }
+    }
 
+    private static URI uri(String value) {
         try {
-            // avoid invoking the regexp if it can't match anyway
-            if (isSimpleUri(sanitzedUri)) {
-                return new NamedUri(new URI(sanitzedUri));
-            }
-
-            final Matcher matcher = NAMED_URI_REGEXP.matcher(sanitzedUri);
-
-            if (!matcher.matches() || matcher.groupCount() > NR_OF_NAMED_GROUPS) {
-                throw new IllegalArgumentException("Invalid named URI: " + value);
-            }
-
-            if (matcher.groupCount() == NR_OF_NAMED_GROUPS) {
-                final String name = matcher.group(NAME_GROUP);
-                final URI uri = new URI(matcher.group(URI_GROUP));
-                final Map<String, String> parameters = NamedUriFragmentParser.parse(uri.getFragment());
-                return new NamedUri(name, uri, parameters);
-            } else {
-                final URI uri = new URI(matcher.group(sanitzedUri));
-                final Map<String, String> parameters = NamedUriFragmentParser.parse(uri.getFragment());
-                return new NamedUri(uri, parameters);
-            }
-        } catch (URISyntaxException | RuntimeException e) {
-            throw new RuntimeException("Failed to parse named URI: " + value, e);
+            return new URI(value);
+        } catch (URISyntaxException e) {
+            throw new RuntimeException("Failed to parse URI: " + value, e);
         }
     }
 
-    private static boolean isSimpleUri(String uri) {
-        return !uri.contains("=");
+    private static Map<String, String> parameters(URI uri) {
+        return NamedUriFragmentParser.parse(uri.getFragment());
     }
-
 }
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 878dd2c..5aba8de 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
@@ -49,6 +49,7 @@ public class DatasourceTest {
             assertEquals("", datasource.getExtension());
             assertEquals("string", datasource.getLocation());
             assertEquals(UTF_8, datasource.getCharset());
+            assertEquals("plain/text", datasource.getContentType());
             assertTrue(datasource.getLength() > 0);
             assertEquals(ANY_TEXT, datasource.getText());
         }
@@ -62,6 +63,7 @@ public class DatasourceTest {
             assertEquals("xml", datasource.getExtension());
             assertEquals(ANY_FILE.getAbsolutePath(), datasource.getLocation());
             assertEquals(Charset.defaultCharset(), datasource.getCharset());
+            assertEquals("application/xml", datasource.getContentType());
             assertTrue(datasource.getLength() > 0);
             assertFalse(datasource.getText().isEmpty());
         }
@@ -75,6 +77,7 @@ public class DatasourceTest {
             assertEquals("google", datasource.getBaseName());
             assertEquals("com", datasource.getExtension());
             assertEquals("https://google.com", datasource.getLocation());
+            assertEquals("text/html; charset=ISO-8859-1", datasource.getContentType());
             assertEquals(UTF_8, datasource.getCharset());
             assertEquals(-1, datasource.getLength());
             assertFalse(datasource.getText().isEmpty());
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java
index 37819a3..075491d 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java
@@ -44,7 +44,7 @@ public class NamedUriParserTest {
     }
 
     @Test
-    public void shouldParseSimpleFileUri() {
+    public void shouldParseFileUri() {
         final NamedUri namedURI = parse("file:///users.csv");
 
         assertNull(namedURI.getName());
@@ -72,9 +72,51 @@ public class NamedUriParserTest {
         assertEquals("text/csv", namedURI.getParameters().get("mimetype"));
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowIllegalArgumentExceptionForEmptyUri() {
-        parse("");
+    @Test
+    public void shouldParseUrl() {
+        final NamedUri namedURI = parse("http://google.com");
+
+        assertNull(namedURI.getName());
+        assertEquals("http://google.com", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseUrlWithFragment() {
+        final NamedUri namedURI = parse("http://google.com#charset=UTF-16");
+
+        assertNull(namedURI.getName());
+        assertEquals("http://google.com#charset=UTF-16", namedURI.getUri().toString());
+        assertEquals(1, namedURI.getParameters().size());
+        assertEquals("UTF-16", namedURI.getParameters().get("charset"));
+    }
+
+    @Test
+    public void shouldParseNamedUrl() {
+        final NamedUri namedURI = parse("google=http://google.com");
+
+        assertEquals("google", namedURI.getName());
+        assertEquals("http://google.com", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseNamedUrlWithQuery() {
+        final NamedUri namedURI = parse("google=http://google.com?foo=bar");
+
+        assertEquals("google", namedURI.getName());
+        assertEquals("http://google.com?foo=bar", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseNamedUrlWithQueryAndFragment() {
+        final NamedUri namedURI = parse("google=http://google.com?foo=bar#charset=UTF-16");
+
+        assertEquals("google", namedURI.getName());
+        assertEquals("http://google.com?foo=bar#charset=UTF-16", namedURI.getUri().toString());
+        assertEquals(1, namedURI.getParameters().size());
+        assertEquals("UTF-16", namedURI.getParameters().get("charset"));
     }
 
     private static NamedUri parse(String value) {
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 f2a8e8a..15e918a 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
@@ -36,7 +36,7 @@ public class ManualTest {
     // 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 = "-b ./src/test -l de_AT -DFOO=foo -DBAR=bar -t templates/info.ftl site/sample/csv/transactions.csv -d contract=site/sample/csv/contract.csv#charset=UTF-16";
+    private static final String CMD = "-b ./src/test -l de_AT -DFOO=foo -DBAR=bar -t templates/info.ftl google=https://google.com?foo=bar#charset=UTF-16";
 
     public static void main(String[] args) {
         Main.execute(toArgs(CMD));


[freemarker-generator] 01/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit 8f7415e7e66eb83f5b261812c42847ba5e09e9b9
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Fri Feb 28 20:46:51 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../freemarker/generator/base/uri/NamedUri.java    | 77 ++++++++++++++++++++
 .../NamedUriFragmentParser.java}                   | 28 +++++---
 .../generator/base/uri/NamedUriParser.java         | 81 +++++++++++++++++++++
 .../generator/base/util/CachingSupplier.java       | 16 +++++
 .../generator/base/util/LocaleUtils.java           |  1 +
 .../generator/uri/NamedUriParserTest.java          | 83 ++++++++++++++++++++++
 .../org/apache/freemarker/generator/cli/Main.java  | 43 ++++++-----
 .../freemarker/generator/cli/PicocliTest.java      | 74 +++++++++++++++++++
 8 files changed, 377 insertions(+), 26 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java
new file mode 100644
index 0000000..cc0b52c
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java
@@ -0,0 +1,77 @@
+/*
+ * 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.uri;
+
+import java.net.URI;
+import java.util.Map;
+
+import static java.util.Collections.emptyMap;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Caputeres the information of a user-supplied "named URI".
+ */
+public class NamedUri {
+
+    /** User-supplied name */
+    private final String name;
+
+    /** The URI */
+    private final URI uri;
+
+    /** Name/value pairs parsed from URI fragment */
+    private final Map<String, String> parameters;
+
+    public NamedUri(URI uri) {
+        this.name = null;
+        this.uri = requireNonNull(uri);
+        this.parameters = emptyMap();
+    }
+
+    public NamedUri(URI uri, Map<String, String> parameters) {
+        this.name = null;
+        this.uri = requireNonNull(uri);
+        this.parameters = requireNonNull(parameters);
+    }
+
+    public NamedUri(String name, URI uri, Map<String, String> parameters) {
+        this.name = requireNonNull(name);
+        this.uri = requireNonNull(uri);
+        this.parameters = requireNonNull(parameters);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public Map<String, String> getParameters() {
+        return parameters;
+    }
+
+    @Override
+    public String toString() {
+        return "NamedUri{" +
+                "name='" + name + '\'' +
+                ", uri=" + uri +
+                ", parameters=" + parameters +
+                '}';
+    }
+}
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
similarity index 52%
copy from freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java
copy to freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
index 5edd405..a94d3da 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriFragmentParser.java
@@ -14,20 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.base.util;
+package org.apache.freemarker.generator.base.uri;
 
-import java.util.Locale;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
 
+import static java.util.stream.Collectors.toMap;
 import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
 
-public class LocaleUtils {
+/**
+ * Parses the URI fragment as list of name/value pairs seperated by an ampersand.
+ */
+public class NamedUriFragmentParser {
 
-    public static Locale parseLocale(String value) {
-        if (isEmpty(value) || value.equalsIgnoreCase("JVM default") || value.equalsIgnoreCase("default")) {
-            return Locale.getDefault();
+    public static Map<String, String> parse(String fragment) {
+        if (isEmpty(fragment)) {
+            return Collections.emptyMap();
         }
 
-        final String[] parts = value.split("_");
-        return parts.length == 1 ? new Locale(parts[0]) : new Locale(parts[0], parts[1]);
+        try {
+            final String[] nameValuePairs = fragment.split("&");
+            return Arrays.stream(nameValuePairs)
+                    .map(s -> s.split("="))
+                    .collect(toMap(parts -> parts[0], parts -> parts[1]));
+        } catch (RuntimeException e) {
+            throw new RuntimeException("Unable to parse URI fragment: " + fragment, e);
+        }
     }
 }
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java
new file mode 100644
index 0000000..a18d914
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriParser.java
@@ -0,0 +1,81 @@
+/*
+ * 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.uri;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Parses a named URI provided by the caller.
+ * <ul>
+ *     <li>users.csv</li>
+ *     <li>file:///users.csv</li>
+ *     <li>user=file:///users.csv</li>
+ *     <li>users=file:///users.csv#charset=UTF-16&mimetype=text/csv</li>
+ * </ul>
+ */
+public class NamedUriParser {
+
+    private static final String NAME_GROUP = "name";
+    private static final String URI_GROUP = "uri";
+    private static final int NR_OF_NAMED_GROUPS = 2;
+    private static final Pattern NAMED_URI_REGEXP = Pattern.compile("^(?<name>[a-zA-Z0-9-_]*)=(?<uri>.*)");
+
+    public static NamedUri parse(String value) {
+        final String sanitzedUri = requireNonNull(value).trim();
+
+        if (sanitzedUri.isEmpty()) {
+            throw new IllegalArgumentException("Empty named URI");
+        }
+
+        try {
+            // avoid invoking the regexp if it can't match anyway
+            if (isSimpleUri(sanitzedUri)) {
+                return new NamedUri(new URI(sanitzedUri));
+            }
+
+            final Matcher matcher = NAMED_URI_REGEXP.matcher(sanitzedUri);
+
+            if (!matcher.matches() || matcher.groupCount() > NR_OF_NAMED_GROUPS) {
+                throw new IllegalArgumentException("Invalid named URI: " + value);
+            }
+
+            if (matcher.groupCount() == NR_OF_NAMED_GROUPS) {
+                final String name = matcher.group(NAME_GROUP);
+                final URI uri = new URI(matcher.group(URI_GROUP));
+                final Map<String, String> parameters = NamedUriFragmentParser.parse(uri.getFragment());
+                return new NamedUri(name, uri, parameters);
+            } else {
+                final URI uri = new URI(matcher.group(sanitzedUri));
+                final Map<String, String> parameters = NamedUriFragmentParser.parse(uri.getFragment());
+                return new NamedUri(uri, parameters);
+            }
+        } catch (URISyntaxException | RuntimeException e) {
+            throw new RuntimeException("Failed to parse named URI: " + value, e);
+        }
+    }
+
+    private static boolean isSimpleUri(String uri) {
+        return !uri.contains("=");
+    }
+
+}
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/CachingSupplier.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/CachingSupplier.java
index fbada67..dab4334 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/CachingSupplier.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/CachingSupplier.java
@@ -1,3 +1,19 @@
+/*
+ * 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.util;
 
 import java.util.function.Supplier;
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java
index 5edd405..95f6a7f 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/util/LocaleUtils.java
@@ -23,6 +23,7 @@ import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
 public class LocaleUtils {
 
     public static Locale parseLocale(String value) {
+        // "JVM default" is a special value defined by FreeMarker
         if (isEmpty(value) || value.equalsIgnoreCase("JVM default") || value.equalsIgnoreCase("default")) {
             return Locale.getDefault();
         }
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java
new file mode 100644
index 0000000..37819a3
--- /dev/null
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriParserTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.uri;
+
+import org.apache.freemarker.generator.base.uri.NamedUri;
+import org.apache.freemarker.generator.base.uri.NamedUriParser;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class NamedUriParserTest {
+
+    @Test
+    public void shouldParseFileName() {
+        final NamedUri namedURI = parse("users.csv");
+
+        assertNull(namedURI.getName());
+        assertEquals("users.csv", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseDirectoryName() {
+        final NamedUri namedURI = parse("users/");
+
+        assertNull(namedURI.getName());
+        assertEquals("users/", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseSimpleFileUri() {
+        final NamedUri namedURI = parse("file:///users.csv");
+
+        assertNull(namedURI.getName());
+        assertEquals("file:///users.csv", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseNamedFileUri() {
+        final NamedUri namedURI = parse("users=file:///users.csv");
+
+        assertEquals("users", namedURI.getName());
+        assertEquals("file:///users.csv", namedURI.getUri().toString());
+        assertEquals(0, namedURI.getParameters().size());
+    }
+
+    @Test
+    public void shouldParseNamedFileUriWithFragment() {
+        final NamedUri namedURI = parse("users=file:///users.csv#charset=UTF-16&mimetype=text/csv");
+
+        assertEquals("users", namedURI.getName());
+        assertEquals("file:///users.csv#charset=UTF-16&mimetype=text/csv", namedURI.getUri().toString());
+        assertEquals(2, namedURI.getParameters().size());
+        assertEquals("UTF-16", namedURI.getParameters().get("charset"));
+        assertEquals("text/csv", namedURI.getParameters().get("mimetype"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void shouldThrowIllegalArgumentExceptionForEmptyUri() {
+        parse("");
+    }
+
+    private static NamedUri parse(String value) {
+        return NamedUriParser.parse(value);
+    }
+}
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 82dbc6f..93ea256 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
@@ -51,9 +51,9 @@ public class Main implements Callable<Integer> {
     private static final String FREEMARKER_CLI_PROPERTY_FILE = "freemarker-cli.properties";
 
     @ArgGroup(multiplicity = "1")
-    private TemplateSourceOptions templateSourceOptions;
+    TemplateSourceOptions templateSourceOptions;
 
-    private static final class TemplateSourceOptions {
+    static final class TemplateSourceOptions {
         @Option(names = { "-t", "--template" }, description = "FreeMarker template to render")
         private String template;
 
@@ -62,52 +62,59 @@ public class Main implements Callable<Integer> {
     }
 
     @Option(names = { "-b", "--basedir" }, description = "Optional template base directory")
-    private String baseDir;
+    String baseDir;
+
+    @Option(names = { "-d", "--datasource" }, description = "Datasource used for rendering")
+    List<String> datasources;
 
     @Option(names = { "-D", "--system-property" }, description = "Set system property")
-    private Properties systemProperties;
+    Properties systemProperties;
 
     @Option(names = { "-e", "--input-encoding" }, description = "Encoding of datasource", defaultValue = "UTF-8")
-    private String inputEncoding;
+    String inputEncoding;
 
     @Option(names = { "-E", "--expose-env" }, description = "Expose environment variables and user-supplied properties globally")
-    private boolean isEnvironmentExposed;
+    boolean isEnvironmentExposed;
 
     @Option(names = { "-l", "--locale" }, description = "Locale being used for the output, e.g. 'en_US'")
-    private String locale;
+    String locale;
 
     @Option(names = { "-o", "--output" }, description = "Output file")
-    private String outputFile;
+    String outputFile;
 
     @Option(names = { "-P", "--param" }, description = "Set parameter")
-    private Map<String, String> parameters;
+    Map<String, String> parameters;
 
     @Option(names = { "--config" }, defaultValue = FREEMARKER_CLI_PROPERTY_FILE, description = "FreeMarker CLI configuration file")
-    private String configFile;
+    String configFile;
 
     @Option(names = { "--include" }, description = "File pattern for datasource input directory")
-    private String include;
+    String include;
 
     @Option(names = { "--exclude" }, description = "File pattern for datasource input directory")
-    private String exclude;
+    String exclude;
 
     @Option(names = { "--output-encoding" }, description = "Encoding of output, e.g. UTF-8", defaultValue = "UTF-8")
-    private String outputEncoding;
+    String outputEncoding;
 
     @Option(names = { "--stdin" }, description = "Read datasource from stdin")
-    private boolean readFromStdin;
+    boolean readFromStdin;
 
     @Option(names = { "--times" }, defaultValue = "1", description = "Re-run X times for profiling")
-    private int times;
+    int times;
 
     @Parameters(description = "List of input files and/or input directories")
-    private List<String> sources;
+    List<String> sources;
 
     /** User-supplied command line parameters */
-    private final String[] args;
+    final String[] args;
 
     /** User-supplied writer (used mainly for unit testing) */
-    private Writer userSuppliedWriter;
+    Writer userSuppliedWriter;
+
+    Main() {
+        this.args = new String[0];
+    }
 
     private Main(String[] args) {
         this.args = requireNonNull(args);
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
new file mode 100644
index 0000000..95662f0
--- /dev/null
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/PicocliTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.cli;
+
+import org.junit.Test;
+import picocli.CommandLine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class PicocliTest {
+
+    private static final String TEMPLATE = "template.ftl";
+    private static final String ANY_FILE = "users.csv";
+    private static final String ANY_NAMED_FILE = "users=users.csv";
+    private static final String OTHER_FILE = "transctions.csv";
+    private static final String ANY_FILE_URI = "file:///users.csv";
+    private static final String OTHER_FILE_URI = "file:///transctions.csv";
+
+    @Test
+    public void testSinglePositionalParameter() {
+        assertEquals(ANY_FILE_URI, parse("-t", TEMPLATE, ANY_FILE_URI).sources.get(0));
+        assertNull(ANY_FILE, parse("-t", TEMPLATE, ANY_FILE_URI).datasources);
+    }
+
+    @Test
+    public void testMultiplePositionalParameter() {
+        assertEquals(ANY_FILE, parse("-t", TEMPLATE, ANY_FILE, OTHER_FILE).sources.get(0));
+        assertEquals(OTHER_FILE, parse("-t", TEMPLATE, ANY_FILE, OTHER_FILE).sources.get(1));
+
+        assertEquals(ANY_FILE, parse("-t", TEMPLATE, ANY_FILE, OTHER_FILE_URI).sources.get(0));
+        assertEquals(OTHER_FILE_URI, parse("-t", TEMPLATE, ANY_FILE, OTHER_FILE_URI).sources.get(1));
+
+        assertEquals(ANY_FILE_URI, parse("-t", TEMPLATE, ANY_FILE_URI, OTHER_FILE_URI).sources.get(0));
+        assertEquals(OTHER_FILE_URI, parse("-t", TEMPLATE, ANY_FILE_URI, OTHER_FILE_URI).sources.get(1));
+    }
+
+    @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, "--datasource", ANY_FILE).datasources.get(0));
+        assertEquals(ANY_FILE_URI, parse("-t", TEMPLATE, "--datasource", ANY_FILE_URI).datasources.get(0));
+    }
+
+    @Test
+    public void testMultipleNamedDatasource() {
+        final Main main = parse("-t", TEMPLATE, "-d", ANY_FILE, "--datasource", OTHER_FILE_URI);
+
+        assertEquals(ANY_FILE, main.datasources.get(0));
+        assertEquals(OTHER_FILE_URI, main.datasources.get(1));
+        assertNull(main.sources);
+    }
+
+    private static Main parse(String... args) {
+        final Main main = new Main();
+        new CommandLine(main).parseArgs(args);
+        return main;
+    }
+}


[freemarker-generator] 02/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit 55366518bf7ca8662d9557cc6f2ab92d56a7b9d6
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Fri Feb 28 22:25:07 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../generator/base/FreeMarkerConstants.java        |  5 ++++
 .../base/datasource/DatasourceFactory.java         |  6 +++-
 .../base/datasource/DatasourcesSupplier.java       | 16 +++++++++--
 .../freemarker/generator/base/uri/NamedUri.java    |  5 ++++
 .../org/apache/freemarker/generator/cli/Main.java  | 32 ++++++++++++++++++++--
 .../freemarker/generator/cli/config/Settings.java  | 26 +++++++++---------
 .../freemarker/generator/cli/config/Suppliers.java |  2 +-
 .../freemarker/generator/cli/ManualTest.java       |  3 +-
 .../generator/cli/config/SettingsTest.java         |  4 +--
 freemarker-generator-cli/templates/info.ftl        |  2 +-
 10 files changed, 77 insertions(+), 24 deletions(-)

diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/FreeMarkerConstants.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/FreeMarkerConstants.java
index 94508d1..c40c29e 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/FreeMarkerConstants.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/FreeMarkerConstants.java
@@ -26,6 +26,11 @@ public class FreeMarkerConstants {
     /* Default encoding for textual content */
     public static final Charset DEFAULT_CHARSET = UTF_8;
 
+    public enum GeneratorMode {
+        DATASOURCE,
+        TEMPLATE
+    }
+
     public static class Configuration {
 
         private Configuration() {
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 c54aa4e..08af5df 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
@@ -51,8 +51,12 @@ public class DatasourceFactory {
     }
 
     public static Datasource create(File file, Charset charset) {
+        return create(file.getName(), file, charset);
+    }
+
+    public static Datasource create(String name, File file, Charset charset) {
         final FileDataSource dataSource = new FileDataSource(file);
-        return create(file.getName(), dataSource, file.getAbsolutePath(), charset);
+        return create(name, dataSource, file.getAbsolutePath(), charset);
     }
 
     public static Datasource create(String name, byte[] content) {
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 3e5a686..7ae7819 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
@@ -17,6 +17,8 @@
 package org.apache.freemarker.generator.base.datasource;
 
 import org.apache.freemarker.generator.base.file.RecursiveFileSupplier;
+import org.apache.freemarker.generator.base.uri.NamedUri;
+import org.apache.freemarker.generator.base.uri.NamedUriParser;
 
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -83,8 +85,12 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
     }
 
     private static List<Datasource> resolveFile(String source, String include, String exclude, Charset charset) {
-        return fileResolver(source, include, exclude).get().stream()
-                .map(file -> DatasourceFactory.create(file, charset))
+        final NamedUri namedUri = NamedUriParser.parse(source);
+        final String path = namedUri.getUri().getPath();
+        final Charset currCharset = getCharset(namedUri, charset);
+        final String name = namedUri.hasName() ? namedUri.getName() : path;
+        return fileResolver(path, include, exclude).get().stream()
+                .map(file -> DatasourceFactory.create(name, file, currCharset))
                 .collect(toList());
     }
 
@@ -93,7 +99,7 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
     }
 
     private static boolean isHttpUrl(String value) {
-        return value.startsWith("http://") || value.startsWith("https://");
+        return value.contains("http://") || value.startsWith("https://");
     }
 
     private static URL toUrl(String value) {
@@ -103,4 +109,8 @@ public class DatasourcesSupplier implements Supplier<List<Datasource>> {
             throw new IllegalArgumentException(value, e);
         }
     }
+
+    private static Charset getCharset(NamedUri namedUri, Charset def) {
+        return Charset.forName(namedUri.getParameters().getOrDefault("charset", def.name()));
+    }
 }
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java
index cc0b52c..c2dffdb 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUri.java
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import static java.util.Collections.emptyMap;
 import static java.util.Objects.requireNonNull;
+import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
 
 /**
  * Caputeres the information of a user-supplied "named URI".
@@ -66,6 +67,10 @@ public class NamedUri {
         return parameters;
     }
 
+    public boolean hasName() {
+        return !isEmpty(this.name);
+    }
+
     @Override
     public String toString() {
         return "NamedUri{" +
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 93ea256..406c70e 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
@@ -16,6 +16,7 @@
  */
 package org.apache.freemarker.generator.cli;
 
+import org.apache.freemarker.generator.base.FreeMarkerConstants.GeneratorMode;
 import org.apache.freemarker.generator.base.util.ClosableUtils;
 import org.apache.freemarker.generator.base.util.StringUtils;
 import org.apache.freemarker.generator.cli.config.Settings;
@@ -33,13 +34,16 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.concurrent.Callable;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 import static java.util.Objects.requireNonNull;
 import static org.apache.freemarker.generator.cli.config.Suppliers.propertiesSupplier;
@@ -79,6 +83,9 @@ 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")
+    GeneratorMode mode;
+
     @Option(names = { "-o", "--output" }, description = "Output file")
     String outputFile;
 
@@ -185,7 +192,7 @@ public class Main implements Callable<Integer> {
                 .setOutputEncoding(outputEncoding)
                 .setOutputFile(outputFile)
                 .setParameters(parameters != null ? parameters : new HashMap<>())
-                .setSources(sources != null ? sources : new ArrayList<>())
+                .setDatasources(getCombindedDatasources())
                 .setSystemProperties(systemProperties != null ? systemProperties : new Properties())
                 .setTemplateDirectories(templateDirectories)
                 .setTemplateName(templateSourceOptions.template)
@@ -213,6 +220,27 @@ public class Main implements Callable<Integer> {
         }
     }
 
+    /**
+     * Datasources can be passed via command line option and/or
+     * positional parameter so we need to merge them.
+     *
+     * @return List of datasources
+     */
+    private List<String> getCombindedDatasources() {
+        if (isTemplateDrivenGeneration()) {
+            return Stream.of(datasources, sources)
+                    .filter(Objects::nonNull)
+                    .flatMap(Collection::stream)
+                    .collect(Collectors.toList());
+        } else {
+            throw new IllegalArgumentException("Not implemented yet");
+        }
+    }
+
+    private boolean isTemplateDrivenGeneration() {
+        return mode == GeneratorMode.TEMPLATE;
+    }
+
     private static List<File> getTemplateDirectories(String baseDir) {
         return templateDirectorySupplier(baseDir).get();
     }
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 c1a63b3..5facf82 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
@@ -52,7 +52,7 @@ public class Settings {
     /** List of FreeMarker template directories */
     private final List<File> templateDirectories;
 
-    /** Name of the template to be loaded and rendered  */
+    /** Name of the template to be loaded and rendered */
     private final String templateName;
 
     /** Template provided by the user interactivly */
@@ -86,7 +86,7 @@ public class Settings {
     private final boolean isEnvironmentExposed;
 
     /** User-supplied list of source files or directories */
-    private final List<String> sources;
+    private final List<String> datasources;
 
     /** User-supplied parameters */
     private final Map<String, String> parameters;
@@ -112,7 +112,7 @@ public class Settings {
             Locale locale,
             boolean isReadFromStdin,
             boolean isEnvironmentExposed,
-            List<String> sources,
+            List<String> datasources,
             Map<String, String> parameters,
             Properties sytemProperties,
             Writer writer) {
@@ -133,7 +133,7 @@ public class Settings {
         this.locale = requireNonNull(locale);
         this.isReadFromStdin = isReadFromStdin;
         this.isEnvironmentExposed = isEnvironmentExposed;
-        this.sources = requireNonNull(sources);
+        this.datasources = requireNonNull(datasources);
         this.parameters = requireNonNull(parameters);
         this.sytemProperties = requireNonNull(sytemProperties);
         this.configuration = requireNonNull(configuration);
@@ -204,8 +204,8 @@ public class Settings {
         return isEnvironmentExposed;
     }
 
-    public List<String> getSources() {
-        return sources;
+    public List<String> getDatasources() {
+        return datasources;
     }
 
     public Map<String, String> getParameters() {
@@ -262,7 +262,7 @@ public class Settings {
                 ", locale=" + locale +
                 ", isReadFromStdin=" + isReadFromStdin +
                 ", isEnvironmentExposed=" + isEnvironmentExposed +
-                ", sources=" + sources +
+                ", datasources=" + datasources +
                 ", properties=" + parameters +
                 ", sytemProperties=" + sytemProperties +
                 ", writer=" + writer +
@@ -288,7 +288,7 @@ public class Settings {
         private String locale;
         private boolean isReadFromStdin;
         private boolean isEnvironmentExposed;
-        private List<String> sources;
+        private List<String> datasources;
         private Map<String, String> parameters;
         private Properties systemProperties;
         private Properties configuration;
@@ -302,7 +302,7 @@ public class Settings {
             this.systemProperties = new Properties();
             this.setInputEncoding(DEFAULT_CHARSET.name());
             this.setOutputEncoding(DEFAULT_CHARSET.name());
-            this.sources = emptyList();
+            this.datasources = emptyList();
             this.templateDirectories = emptyList();
         }
 
@@ -380,8 +380,8 @@ public class Settings {
             return this;
         }
 
-        public SettingsBuilder setSources(List<String> sources) {
-            this.sources = sources;
+        public SettingsBuilder setDatasources(List<String> datasources) {
+            this.datasources = datasources;
             return this;
         }
 
@@ -393,7 +393,7 @@ public class Settings {
         }
 
         public SettingsBuilder setSystemProperties(Properties systemProperties) {
-            if(systemProperties != null) {
+            if (systemProperties != null) {
                 this.systemProperties = systemProperties;
             }
             return this;
@@ -432,7 +432,7 @@ public class Settings {
                     LocaleUtils.parseLocale(currLocale),
                     isReadFromStdin,
                     isEnvironmentExposed,
-                    sources,
+                    datasources,
                     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 7d2f5f1..0a7a9f2 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
@@ -34,7 +34,7 @@ public class Suppliers {
     }
 
     public static DatasourcesSupplier datasourcesSupplier(Settings settings) {
-        return new DatasourcesSupplier(settings.getSources(),
+        return new DatasourcesSupplier(settings.getDatasources(),
                 settings.getInclude(),
                 settings.getExclude(),
                 settings.getInputEncoding());
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 35b1069..f2a8e8a 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,7 +35,8 @@ 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 site/sample/csv/transactions.csv -d contract=site/sample/csv/contract.csv#charset=UTF-16";
 
     public static void main(String[] args) {
         Main.execute(toArgs(CMD));
diff --git a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/SettingsTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/SettingsTest.java
index 4821723..655fdf6 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/SettingsTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/SettingsTest.java
@@ -56,7 +56,7 @@ public class SettingsTest {
         assertEquals(ANY_OUTPUT_ENCODING, settings.getOutputEncoding().name());
         assertEquals(ANY_OUTPUT_FILE, settings.getOutputFile().getName());
         assertEquals(ANY_TEMPLATE_NAME, settings.getTemplateName());
-        assertNotNull(settings.getSources());
+        assertNotNull(settings.getDatasources());
         assertNotNull(settings.getParameters());
         assertNotNull(settings.getSytemProperties());
         assertTrue(settings.isReadFromStdin());
@@ -78,7 +78,7 @@ public class SettingsTest {
                 .setOutputEncoding(ANY_OUTPUT_ENCODING)
                 .setOutputFile(ANY_OUTPUT_FILE)
                 .setParameters(ANY_USER_PARAMETERS)
-                .setSources(ANY_SOURCES)
+                .setDatasources(ANY_SOURCES)
                 .setSystemProperties(ANY_SYSTEM_PROPERTIES)
                 .setTemplateName(ANY_TEMPLATE_NAME)
                 .setWriter(new StringWriter())
diff --git a/freemarker-generator-cli/templates/info.ftl b/freemarker-generator-cli/templates/info.ftl
index 3ec4891..154416e 100644
--- a/freemarker-generator-cli/templates/info.ftl
+++ b/freemarker-generator-cli/templates/info.ftl
@@ -42,7 +42,7 @@ FreeMarker CLI Tools
 FreeMarker CLI Datasources
 ---------------------------------------------------------------------------
 <#list Datasources.list as datasource>
-[${datasource?counter}] ${datasource.name}, ${datasource.location}, ${datasource.length} Bytes
+[${datasource?counter}] ${datasource.name}, ${datasource.location}, ${datasource.charset}, ${datasource.length} Bytes
 </#list>
 
 User Supplied Parameters


[freemarker-generator] 04/06: FREEMARKER-135 Support user-supplied names for datasources

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

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

commit 57dc39c4d7edfcf9c214292ee59117117e8e9195
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sat Feb 29 00:13:00 2020 +0100

    FREEMARKER-135 Support user-supplied names for datasources
---
 .../freemarker/generator/base/datasource/Datasource.java      | 11 +++++++++++
 freemarker-generator-cli/templates/info.ftl                   |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

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 5de9cae..c3c45b8 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
@@ -59,6 +59,9 @@ public class Datasource implements Closeable {
     /** Collect all closables handed out to the caller to be closed when the datasource is closed itself */
     private final CloseableReaper closables;
 
+    /** Cached content type - UrlDataSource actually opens a connection so we should cache the result */
+    private String contentType = null;
+
     public Datasource(String name, DataSource dataSource, String location, Charset charset) {
         this.name = requireNonNull(name);
         this.dataSource = requireNonNull(dataSource);
@@ -83,6 +86,14 @@ public class Datasource implements Closeable {
         return charset;
     }
 
+    public synchronized String getContentType() {
+        if (contentType == null) {
+            contentType = dataSource.getContentType();
+        }
+
+        return contentType;
+    }
+
     public String getLocation() {
         return location;
     }
diff --git a/freemarker-generator-cli/templates/info.ftl b/freemarker-generator-cli/templates/info.ftl
index 154416e..2000d4e 100644
--- a/freemarker-generator-cli/templates/info.ftl
+++ b/freemarker-generator-cli/templates/info.ftl
@@ -42,7 +42,7 @@ FreeMarker CLI Tools
 FreeMarker CLI Datasources
 ---------------------------------------------------------------------------
 <#list Datasources.list as datasource>
-[${datasource?counter}] ${datasource.name}, ${datasource.location}, ${datasource.charset}, ${datasource.length} Bytes
+[${datasource?counter}] ${datasource.name}, ${datasource.location}, ${datasource.charset}, ${datasource.contentType}, ${datasource.length} Bytes
 </#list>
 
 User Supplied Parameters