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/19 14:56:28 UTC
[freemarker-generator] branch master updated: FREEMARKER-141 Expose
user-supplied parameters in the data model (#12)
This is an automated email from the ASF dual-hosted git repository.
sgoeschl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/freemarker-generator.git
The following commit(s) were added to refs/heads/master by this push:
new a3603ca FREEMARKER-141 Expose user-supplied parameters in the data model (#12)
a3603ca is described below
commit a3603ca2d2f7e5c841ac3ae22712ae287741adf5
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Sun Apr 19 16:56:22 2020 +0200
FREEMARKER-141 Expose user-supplied parameters in the data model (#12)
---
.../base/activation/ByteArrayDataSource.java | 2 +-
.../base/activation/CachingUrlDataSource.java | 16 ++++
.../base/activation/InputStreamDataSource.java | 2 +-
.../base/activation/StringDataSource.java | 2 +-
.../generator/base/datasource/DataSource.java | 29 ++-----
.../base/datasource/DataSourceFactory.java | 16 +++-
.../generator/base/mime/MimetypeParser.java | 58 ++++++++++++++
.../base/{activation => mime}/Mimetypes.java | 18 ++++-
.../MimetypesFileTypeMapFactory.java | 28 +++----
.../generator/base/parameter/Parameter.java | 73 +++++++++++++++++
.../base/parameter/ParameterModelSupplier.java | 66 ++++++++++++++++
.../generator/base/parameter/ParameterParser.java | 66 ++++++++++++++++
.../freemarker/generator/base/uri/NamedUri.java | 8 +-
.../generator/base/uri/NamedUriStringParser.java | 12 +--
.../generator/base/util/StringUtils.java | 11 +++
.../datasource/DataSourceFactoryTest.java | 11 ++-
.../generator/datasource/DataSourceTest.java | 4 +-
.../datasource/DataSourcesSupplierTest.java | 12 +--
.../generator/mime/MimetypeParserTest.java | 59 ++++++++++++++
.../parameter/ParameterModelSupplierTest.java | 92 ++++++++++++++++++++++
.../generator/uri/NamedUriStringParserTest.java | 39 ++++++++-
freemarker-generator-cli/README.md | 52 ++++++------
.../org/apache/freemarker/generator/cli/Main.java | 10 +--
.../generator/cli/config/DataModelSupplier.java | 6 +-
.../freemarker/generator/cli/config/Settings.java | 35 ++------
.../freemarker/generator/cli/config/Suppliers.java | 5 ++
.../generator/cli/task/FreeMarkerTask.java | 26 +++---
.../src/site/markdown/cli/concepts/named-uris.md | 14 ++--
.../site/markdown/cli/concepts/user-parameters.md | 37 +++++++++
.../src/site/markdown/index.md | 1 +
.../freemarker/generator/cli/ExamplesTest.java | 2 +-
.../freemarker/generator/cli/ManualTest.java | 4 +-
.../freemarker/generator/cli/PicocliTest.java | 15 ++++
.../cli/config/DataModelSupplierTest.java | 8 +-
.../generator/cli/config/SettingsTest.java | 4 +-
.../templates/csv/fo/transform.ftl | 2 +-
.../templates/csv/transform.ftl | 8 +-
.../templates/excel/csv/custom.ftl | 2 +-
.../templates/excel/csv/transform.ftl | 2 +-
freemarker-generator-cli/templates/info.ftl | 39 +++++----
.../generator/tools/system/SystemTool.java | 8 +-
.../tools/snakeyaml/SnakeYamlToolTest.java | 3 +-
.../generator/tools/xml/XmlToolTest.java | 2 +-
43 files changed, 709 insertions(+), 200 deletions(-)
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/ByteArrayDataSource.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/ByteArrayDataSource.java
index 8933ea6..196b254 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/ByteArrayDataSource.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/ByteArrayDataSource.java
@@ -23,7 +23,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import static java.util.Objects.requireNonNull;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
public class ByteArrayDataSource implements DataSource {
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/CachingUrlDataSource.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/CachingUrlDataSource.java
index 24e02ac..6616598 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/CachingUrlDataSource.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/CachingUrlDataSource.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.activation;
import javax.activation.URLDataSource;
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/InputStreamDataSource.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/InputStreamDataSource.java
index 11b54b1..01f8fa6 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/InputStreamDataSource.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/InputStreamDataSource.java
@@ -21,7 +21,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import static java.util.Objects.requireNonNull;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
/**
* Wraps an InputStream into a DataSource. Please note that the input stream
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/StringDataSource.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/StringDataSource.java
index fd60cae..323aded 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/StringDataSource.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/StringDataSource.java
@@ -24,7 +24,7 @@ import java.nio.charset.Charset;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_PLAIN;
public class StringDataSource implements DataSource {
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 4864dc6..3a94c7b 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
@@ -21,6 +21,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.apache.freemarker.generator.base.activation.ByteArrayDataSource;
import org.apache.freemarker.generator.base.activation.StringDataSource;
+import org.apache.freemarker.generator.base.mime.MimetypeParser;
import org.apache.freemarker.generator.base.util.CloseableReaper;
import javax.activation.FileDataSource;
@@ -31,10 +32,7 @@ import java.io.StringWriter;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import static java.nio.charset.Charset.forName;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.io.IOUtils.lineIterator;
@@ -53,9 +51,6 @@ import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
*/
public class DataSource implements Closeable {
- /** Parse something like "application/json; charset=utf-8" */
- private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
-
/** Human-readable name of the data source */
private final String name;
@@ -110,7 +105,7 @@ public class DataSource implements Closeable {
}
public Charset getCharset() {
- return charset != null ? charset : getCharsetFromContentType(contentType(), UTF_8);
+ return charset != null ? charset : MimetypeParser.getCharset(contentType(), UTF_8);
}
/**
@@ -119,7 +114,7 @@ public class DataSource implements Closeable {
* @return content type
*/
public String getContentType() {
- return stripExtraParameterFronContentType(contentType());
+ return MimetypeParser.getMimetype(contentType());
}
public URI getUri() {
@@ -172,7 +167,7 @@ public class DataSource implements Closeable {
public String getText(String charsetName) {
final StringWriter writer = new StringWriter();
try (InputStream is = getUnsafeInputStream()) {
- IOUtils.copy(is, writer, forName(charsetName));
+ IOUtils.copy(is, writer, Charset.forName(charsetName));
return writer.toString();
} catch (IOException e) {
throw new RuntimeException("Failed to get text: " + toString(), e);
@@ -224,7 +219,7 @@ public class DataSource implements Closeable {
*/
public LineIterator getLineIterator(String charsetName) {
try {
- return closables.add(lineIterator(getUnsafeInputStream(), forName(charsetName)));
+ return closables.add(lineIterator(getUnsafeInputStream(), Charset.forName(charsetName)));
} catch (IOException e) {
throw new RuntimeException("Failed to create line iterator: " + toString(), e);
}
@@ -265,21 +260,7 @@ public class DataSource implements Closeable {
'}';
}
- 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 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).trim() : 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 76f5142..016a394 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
@@ -20,8 +20,8 @@ import org.apache.freemarker.generator.base.FreeMarkerConstants.Location;
import org.apache.freemarker.generator.base.activation.ByteArrayDataSource;
import org.apache.freemarker.generator.base.activation.CachingUrlDataSource;
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 org.apache.freemarker.generator.base.mime.MimetypesFileTypeMapFactory;
import org.apache.freemarker.generator.base.uri.NamedUri;
import org.apache.freemarker.generator.base.uri.NamedUriStringParser;
import org.apache.freemarker.generator.base.util.PropertiesFactory;
@@ -43,7 +43,7 @@ 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.mime.Mimetypes.MIME_TEXT_PLAIN;
import static org.apache.freemarker.generator.base.util.StringUtils.firstNonEmpty;
/**
@@ -53,6 +53,7 @@ public class DataSourceFactory {
private static final String NO_MIME_TYPE = null;
private static final Charset NO_CHARSET = null;
+ private static final String ROOT_DIR = "/";
private DataSourceFactory() {
}
@@ -82,7 +83,8 @@ public class DataSourceFactory {
final String name = namedUri.getNameOrElse(file.getName());
return fromFile(name, group, file, charset);
} else if (UriUtils.isEnvUri(uri)) {
- final String key = uri.getPath().substring(1);
+ // environment variables come with a leading "/" to be removed
+ final String key = stripRootDir(uri.getPath());
final String contentType = getMimeTypeOrElse(namedUri, MIME_TEXT_PLAIN);
final String name = firstNonEmpty(namedUri.getName(), key, Location.ENVIRONMENT);
if (StringUtils.isEmpty(key)) {
@@ -218,4 +220,12 @@ public class DataSourceFactory {
throw new IllegalArgumentException(uri.toString(), e);
}
}
+
+ private static String stripRootDir(String str) {
+ if (str.startsWith(ROOT_DIR)) {
+ return str.substring(ROOT_DIR.length());
+ } else {
+ return str;
+ }
+ }
}
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/MimetypeParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/MimetypeParser.java
new file mode 100644
index 0000000..46b82a6
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/MimetypeParser.java
@@ -0,0 +1,58 @@
+/*
+ * 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.mime;
+
+import java.nio.charset.Charset;
+
+import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
+
+/**
+ * Parse a mimetype.
+ * <p>
+ * Some examples
+ * <ul>
+ * <li>text/html;charset=utf-8</li>
+ * <li>text/html;charset=windows-1252</li>
+ * </ul>
+ */
+public class MimetypeParser {
+
+ public static String getMimetype(String raw) {
+ if (isEmpty(raw)) {
+ return null;
+ }
+
+ final int pos = raw.indexOf(';');
+ return pos > 0 ? raw.substring(0, pos).toLowerCase() : raw;
+ }
+
+ public static Charset getCharset(String raw) {
+ if (isEmpty(raw) || !raw.contains(";") || !raw.toLowerCase().contains("charset")) {
+ return null;
+ }
+
+ final int pos = raw.indexOf(';');
+ final String name = raw.substring(pos).split("=")[1].trim();
+
+ return Charset.forName(name);
+ }
+
+ public static Charset getCharset(String raw, Charset def) {
+ final Charset charset = getCharset(raw);
+ return charset != null ? charset : def;
+ }
+}
\ No newline at end of file
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/Mimetypes.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
similarity index 54%
rename from freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/Mimetypes.java
rename to freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
index 5bb4ebe..c8bb76c 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/Mimetypes.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
@@ -1,4 +1,20 @@
-package org.apache.freemarker.generator.base.activation;
+/*
+ * 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.mime;
public class Mimetypes {
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/mime/MimetypesFileTypeMapFactory.java
similarity index 62%
rename from freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/activation/MimetypesFileTypeMapFactory.java
rename to freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/MimetypesFileTypeMapFactory.java
index 4fff085..b91d534 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/mime/MimetypesFileTypeMapFactory.java
@@ -14,23 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.freemarker.generator.base.activation;
+package org.apache.freemarker.generator.base.mime;
import javax.activation.MimetypesFileTypeMap;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_JSON;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_XHTML;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_XML;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_CSV;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_HTML;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_MARKDOWM;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_PLAIN;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_RTF;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_TSV;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_YAML;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_VENDOR_MS_EXCEL;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_VENDOR_OPEN_XML_SPREADSHEET;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_JSON;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_XHTML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_XML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_CSV;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_HTML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_MARKDOWM;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_PLAIN;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_RTF;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_TSV;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_YAML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_VENDOR_MS_EXCEL;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_VENDOR_OPEN_XML_SPREADSHEET;
public class MimetypesFileTypeMapFactory {
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/Parameter.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/Parameter.java
new file mode 100644
index 0000000..707a038
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/Parameter.java
@@ -0,0 +1,73 @@
+/*
+ * 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.parameter;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;
+
+/**
+ * Caputeres the information of a user-supplied parameter.
+ */
+public class Parameter {
+
+ /** User-supplied name */
+ private final String name;
+
+ /** User-supplied group */
+ private final String group;
+
+ /** User-supplied value */
+ private final String value;
+
+ public Parameter(String name, String value) {
+ this.name = requireNonNull(name);
+ this.group = null;
+ this.value = requireNonNull(value);
+ }
+
+ public Parameter(String name, String group, String value) {
+ this.name = requireNonNull(name);
+ this.group = requireNonNull(group);
+ this.value = requireNonNull(value);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public boolean hasGroup() {
+ return isNotEmpty(group);
+ }
+
+ public String getKey() {
+ return hasGroup() ? format("%s:%s", name, group) : format("%s", name);
+ }
+
+ @Override
+ public String toString() {
+ return format("%s=%s", getKey(), value);
+ }
+}
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterModelSupplier.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterModelSupplier.java
new file mode 100644
index 0000000..ac74090
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterModelSupplier.java
@@ -0,0 +1,66 @@
+/*
+ * 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.parameter;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+/**
+ * Converts a map of parameters to a map. The resulting map contains
+ * either (key=String) or (key=Map<String, Object>).
+ */
+public class ParameterModelSupplier implements Supplier<Map<String, Object>> {
+
+ private final Map<String, String> parameters;
+
+ public ParameterModelSupplier(Map<String, String> parameters) {
+ this.parameters = parameters != null ? parameters : Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, Object> get() {
+ final Map<String, Object> map = new HashMap<>();
+
+ for (Map.Entry<String, String> entry : parameters.entrySet()) {
+ final Parameter parameter = ParameterParser.parse(entry.getKey(), entry.getValue());
+ final String name = parameter.getName();
+ final String value = parameter.getValue();
+
+ if (parameter.hasGroup()) {
+ final String group = parameter.getGroup();
+ getOrCreateGroupMap(map, group).put(name, value);
+ } else {
+ map.put(parameter.getName(), value);
+ }
+ }
+
+ return map;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Map<String, Object> getOrCreateGroupMap(Map<String, Object> map, String group) {
+ if (map.containsKey(group)) {
+ return (Map<String, Object>) map.get(group);
+ } else {
+ final Map<String, Object> groupMap = new HashMap<>();
+ map.put(group, groupMap);
+ return groupMap;
+ }
+ }
+}
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterParser.java
new file mode 100644
index 0000000..4bf7b75
--- /dev/null
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/parameter/ParameterParser.java
@@ -0,0 +1,66 @@
+/*
+ * 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.parameter;
+
+import org.apache.freemarker.generator.base.util.Validate;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.String.format;
+import static java.util.regex.Pattern.compile;
+import static org.apache.freemarker.generator.base.util.StringUtils.count;
+import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
+
+/**
+ * Parses a parameter provided by the user
+ * <ul>
+ * <li>name=value</li>
+ * <li>name:group=value</li>
+ * </ul>
+ */
+public class ParameterParser {
+
+ private static final String NAME = "name";
+ private static final String GROUP = "group";
+ private static final Pattern NAME_GROUP_REGEXP = compile("^(?<name>[a-zA-Z0-9-._]*):?(?<group>[a-zA-Z0-9-._]*)");
+
+ public static Parameter parse(String str) {
+ Validate.notEmpty(str, "parameter is empty");
+ Validate.isTrue(count(str, '=') == 1, "invalid parameter");
+
+ final String[] parts = str.split("=");
+ return parse(parts[0], parts[1]);
+ }
+
+ public static Parameter parse(String key, String value) {
+ Validate.notEmpty(key, "key is empty");
+ Validate.notEmpty(value, "value is empty");
+
+ final Matcher matcher = NAME_GROUP_REGEXP.matcher(key);
+
+ if (matcher.matches()) {
+ return parameter(matcher.group(NAME), matcher.group(GROUP), value);
+ } else {
+ throw new IllegalArgumentException(format("Unable to parse parameter: %s=%s", key, value));
+ }
+ }
+
+ private static Parameter parameter(String name, String group, String value) {
+ return isEmpty(group) ? new Parameter(name, value) : new Parameter(name, group, value);
+ }
+}
\ No newline at end of file
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 77cd1fa..45fb595 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
@@ -16,8 +16,6 @@
*/
package org.apache.freemarker.generator.base.uri;
-import org.apache.freemarker.generator.base.util.UriUtils;
-
import java.io.File;
import java.net.URI;
import java.util.Map;
@@ -101,11 +99,7 @@ public class NamedUri {
}
public File getFile() {
- if (UriUtils.isFileUri(uri)) {
- return new File(uri.getPath().substring(1));
- } else {
- return new File(uri.getPath());
- }
+ return new File(uri.getPath());
}
@Override
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriStringParser.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriStringParser.java
index 76d961d..6aabbd0 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriStringParser.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/uri/NamedUriStringParser.java
@@ -42,7 +42,7 @@ public class NamedUriStringParser {
private static final String GROUP = "group";
private static final String URI = "uri";
- private static final Pattern NAMED_URI_REGEXP = compile("^(?<name>[a-zA-Z0-9-_]*):?(?<group>[a-zA-Z0-9-_]*)=(?<uri>.*)");
+ private static final Pattern NAMED_URI_REGEXP = compile("^(?<name>[a-zA-Z0-9-_$@]*):?(?<group>[a-zA-Z0-9-_$@]*)=(?<uri>.*)");
public static NamedUri parse(String value) {
Validate.notEmpty(value, "Named URI is empty");
@@ -52,7 +52,7 @@ public class NamedUriStringParser {
if (matcher.matches()) {
final String name = matcher.group(NAME);
final String group = matcher.group(GROUP);
- final URI uri = uri(matcher.group(URI));
+ final URI uri = UriUtils.toURI(matcher.group(URI));
return new NamedUri(name, group, uri, parameters(uri));
} else {
final URI uri = UriUtils.toURI(value);
@@ -63,12 +63,4 @@ public class NamedUriStringParser {
private static Map<String, String> parameters(URI uri) {
return UriFragmentParser.parse(uri.getFragment());
}
-
- private static URI uri(String str) {
- if (!str.contains("://")) {
- return UriUtils.toURI("file:///" + str);
- } else {
- return UriUtils.toURI(str);
- }
- }
}
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..a36bf1e 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,15 @@ public class StringUtils {
return null;
}
+ public static int count(final String s, final char c) {
+ final char[] chars = s.toCharArray();
+ int count = 0;
+ for (final char aChar : chars) {
+ if (aChar == c) {
+ count++;
+ }
+ }
+ return count;
+ }
+
}
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 28062be..bf96829 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
@@ -20,6 +20,7 @@ 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.junit.Ignore;
import org.junit.Test;
import java.io.ByteArrayInputStream;
@@ -28,18 +29,21 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
+import java.nio.file.Paths;
+import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_XML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_XML;
import static org.junit.Assert.assertEquals;
public class DataSourceFactoryTest {
+ private static final String PWD = Paths.get(".").toAbsolutePath().normalize().toString();
private static final String ANY_TEXT = "Hello World";
private static final String ANY_FILE_NAME = "pom.xml";
- private static final String ANY_FILE_URI = "file:///pom.xml";
+ private static final String ANY_FILE_URI = format("file:///%s/pom.xml", PWD);
private static final Charset ANY_CHAR_SET = UTF_8;
private static final File ANY_FILE = new File(ANY_FILE_NAME);
private static final String ANY_NAMED_URL_STRING = "content:www=https://www.google.com?foo=bar#contenttype=application/json";
@@ -105,6 +109,7 @@ public class DataSourceFactoryTest {
}
@Test
+ @Ignore
public void shouldCreateDataSourceFromURL() throws IOException {
final URL url = new URL("https://jsonplaceholder.typicode.com/posts/2");
final DataSource dataSource = DataSourceFactory.fromUrl("jsonplaceholder.typicode.com", "default", url, null, null);
@@ -115,6 +120,7 @@ public class DataSourceFactoryTest {
}
@Test
+ @Ignore
public void shouldCreateDataSourceFromNamedURL() {
final NamedUri namedUri = NamedUriStringParser.parse(ANY_NAMED_URL_STRING);
final DataSource dataSource = DataSourceFactory.fromNamedUri(namedUri);
@@ -160,5 +166,4 @@ public class DataSourceFactoryTest {
assertEquals("env:///PWD", dataSource.getUri().toString());
assertEquals("text/plain", dataSource.getContentType());
}
-
}
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 040658e..bf2753c 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
@@ -17,9 +17,9 @@
package org.apache.freemarker.generator.datasource;
import org.apache.commons.io.LineIterator;
-import org.apache.freemarker.generator.base.activation.Mimetypes;
import org.apache.freemarker.generator.base.datasource.DataSource;
import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+import org.apache.freemarker.generator.base.mime.Mimetypes;
import org.junit.Ignore;
import org.junit.Test;
@@ -31,7 +31,7 @@ import java.util.Iterator;
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_APPLICATION_OCTET_STREAM;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_OCTET_STREAM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
index 68e6662..8089c48 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesSupplierTest.java
@@ -21,6 +21,7 @@ import org.apache.freemarker.generator.base.datasource.DataSourcesSupplier;
import org.junit.Test;
import java.nio.charset.Charset;
+import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
@@ -33,16 +34,17 @@ public class DataSourcesSupplierTest {
private static final String NO_EXCLUDE = null;
private static final String DATA_DIRECTORY = "./src/test/data";
+ private static final String PWD = Paths.get(".").toAbsolutePath().normalize().toString();
@Test
public void shouldResolveSingleFile() {
assertEquals(1, supplier("pom.xml", "*", NO_EXCLUDE).get().size());
assertEquals(1, supplier("./pom.xml", "*", NO_EXCLUDE).get().size());
- assertEquals(1, supplier("file://./pom.xml", "*", NO_EXCLUDE).get().size());
assertEquals(1, supplier("pom=pom.xml", "*", NO_EXCLUDE).get().size());
assertEquals(1, supplier("pom=./pom.xml", "*", NO_EXCLUDE).get().size());
- assertEquals(1, supplier("pom=file://./pom.xml", "*", NO_EXCLUDE).get().size());
- assertEquals(1, supplier("pom=file://./pom.xml?mimetype=application/xml", "*", NO_EXCLUDE).get().size());
+ assertEquals(1, supplier("pom=./pom.xml#mimetype=application/xml", "*", NO_EXCLUDE).get().size());
+ assertEquals(1, supplier("pom=" + PWD + "/pom.xml", "*", NO_EXCLUDE).get().size());
+ assertEquals(1, supplier("pom=file:///" + PWD + "/pom.xml#mimetype=application/xml", "*", NO_EXCLUDE).get().size());
}
@Test
@@ -127,9 +129,7 @@ public class DataSourcesSupplierTest {
public void shouldNormalizeDataSourceNameBasedOnFilePath() {
assertEquals("pom.xml", supplier("pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
assertEquals("pom.xml", supplier("./pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
- assertEquals("pom.xml", supplier("file://./pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
- assertEquals("pom.xml", supplier("file:///pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
- assertEquals("pom.xml", supplier("file://tmp/pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
+ assertEquals("pom.xml", supplier("file:///" + PWD + "/pom.xml", "*", NO_EXCLUDE).get().get(0).getName());
}
private static DataSourcesSupplier supplier(String directory, String include, String exclude) {
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/mime/MimetypeParserTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/mime/MimetypeParserTest.java
new file mode 100644
index 0000000..f682e13
--- /dev/null
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/mime/MimetypeParserTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.mime;
+
+import org.apache.freemarker.generator.base.mime.MimetypeParser;
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class MimetypeParserTest {
+
+ @Test
+ public void shouldHandleMissingMimeType() {
+ assertNull(MimetypeParser.getMimetype(null));
+ assertNull(MimetypeParser.getMimetype(""));
+ assertNull(MimetypeParser.getMimetype(" "));
+ }
+
+ @Test
+ public void shouldGetMimetype() {
+ assertEquals("text/html", MimetypeParser.getMimetype("text/html"));
+ assertEquals("text/html", MimetypeParser.getMimetype("text/html;charset=utf-8"));
+ }
+
+ @Test
+ public void shouldHandleMissingContentType() {
+ assertNull(MimetypeParser.getCharset(null));
+ assertNull(MimetypeParser.getCharset(""));
+ assertNull(MimetypeParser.getCharset(" "));
+ assertNull(MimetypeParser.getCharset("text/html"));
+ assertNull(MimetypeParser.getCharset("text/html;something=utf-8"));
+ }
+
+ @Test
+ public void shouldGetCharset() {
+ assertEquals(StandardCharsets.UTF_8, MimetypeParser.getCharset("text/html;charset=utf-8"));
+ assertEquals(StandardCharsets.UTF_8, MimetypeParser.getCharset("text/html;charset=UTF-8"));
+ assertEquals(StandardCharsets.UTF_8, MimetypeParser.getCharset("text/html; charset=utf-8"));
+ assertEquals(StandardCharsets.UTF_8, MimetypeParser.getCharset("text/html; charset=UTF-8"));
+ assertEquals(StandardCharsets.UTF_8, MimetypeParser.getCharset("text/html;Charset=UTF-8"));
+ }
+}
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/parameter/ParameterModelSupplierTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/parameter/ParameterModelSupplierTest.java
new file mode 100644
index 0000000..3ad7bc7
--- /dev/null
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/parameter/ParameterModelSupplierTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.parameter;
+
+import org.apache.freemarker.generator.base.parameter.Parameter;
+import org.apache.freemarker.generator.base.parameter.ParameterModelSupplier;
+import org.apache.freemarker.generator.base.parameter.ParameterParser;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class ParameterModelSupplierTest {
+
+ @Test
+ public void shouldConvertMissingParametersToMap() {
+ assertEquals(0, supplier(new String[0]).get().size());
+ }
+
+ @Test
+ public void shouldConverNameValueToMap() {
+ final Map<String, Object> map = supplier("name=value").get();
+
+ assertEquals(1, map.size());
+ assertEquals("value", map.get("name"));
+ }
+
+ @Test
+ public void shouldConverNameValueWithSpacesToMap() {
+ final Map<String, Object> map = supplier("name=value with spaces").get();
+
+ assertEquals(1, map.size());
+ assertEquals("value with spaces", map.get("name"));
+ }
+
+ @Test
+ public void shouldConvertGroupedNameValueToMap() {
+ final Map<String, Object> map = supplier("name1:group=value1").get();
+
+ assertEquals(1, map.size());
+ assertEquals("value1", toMap(map, "group").get("name1"));
+ }
+
+ @Test
+ public void shouldConvertGroupedNameValuesToMap() {
+ final Map<String, Object> map = supplier("name1:group=value1", "name2:group=value2").get();
+
+ assertEquals(1, map.size());
+ assertEquals("value1", toMap(map, "group").get("name1"));
+ assertEquals("value2", toMap(map, "group").get("name2"));
+ }
+
+ @Test
+ public void shouldConvertMultipleGroupedNameValuesToMap() {
+ final Map<String, Object> map = supplier("name1:group1=value1", "name1:group2=value1", "name2:group2=value2").get();
+
+ assertEquals(2, map.size());
+ assertEquals("value1", toMap(map, "group1").get("name1"));
+ assertEquals("value1", toMap(map, "group2").get("name1"));
+ assertEquals("value2", toMap(map, "group2").get("name2"));
+ }
+
+ private static ParameterModelSupplier supplier(String... values) {
+ final Map<String, String> parameters = Arrays.stream(values)
+ .map(ParameterParser::parse)
+ .collect(Collectors.toMap(Parameter::getKey, Parameter::getValue));
+
+ return new ParameterModelSupplier(parameters);
+ }
+
+ @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-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriStringParserTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriStringParserTest.java
index f007064..a4da79e 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriStringParserTest.java
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/uri/NamedUriStringParserTest.java
@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue;
public class NamedUriStringParserTest {
@Test
- public void shouldParseRelativeFileName() {
+ public void shouldParseFileName() {
final NamedUri namedURI = parse("users.csv");
assertNull(namedURI.getName());
@@ -39,6 +39,30 @@ public class NamedUriStringParserTest {
}
@Test
+ public void shouldParseFileNameWithFragment() {
+ final NamedUri namedURI = parse("users.csv#foo=bar");
+
+ assertNull(namedURI.getName());
+ assertNull(namedURI.getGroup());
+ assertEquals("users.csv#foo=bar", namedURI.getUri().toString());
+ assertEquals("users.csv", namedURI.getFile().getName());
+ assertEquals("foo=bar", namedURI.getUri().getFragment());
+ assertEquals(1, namedURI.getParameters().size());
+ assertEquals("bar", namedURI.getParameters().get("foo"));
+ }
+
+ @Test
+ public void shouldParseRelativeFileName() {
+ final NamedUri namedURI = parse("./users.csv");
+
+ assertNull(namedURI.getName());
+ assertNull(namedURI.getGroup());
+ assertEquals("./users.csv", namedURI.getUri().toString());
+ assertEquals("users.csv", namedURI.getFile().getName());
+ assertEquals(0, namedURI.getParameters().size());
+ }
+
+ @Test
public void shouldParseAbsoluteFileName() {
final NamedUri namedURI = parse("/data/users.csv");
@@ -77,7 +101,7 @@ public class NamedUriStringParserTest {
assertEquals("users", namedURI.getName());
assertNull(namedURI.getGroup());
- assertEquals("file:///users.csv", namedURI.getUri().toString());
+ assertEquals("users.csv", namedURI.getUri().toString());
assertEquals("users.csv", namedURI.getFile().getName());
assertEquals(0, namedURI.getParameters().size());
assertTrue(namedURI.hasName());
@@ -85,6 +109,17 @@ public class NamedUriStringParserTest {
}
@Test
+ public void shouldParseNamedGroupFileName() {
+ final NamedUri namedURI = parse("name:group=users.csv");
+
+ assertEquals("name", namedURI.getName());
+ assertEquals("group", namedURI.getGroup());
+ assertEquals("users.csv", namedURI.getUri().toString());
+ assertEquals("users.csv", namedURI.getFile().getName());
+ assertEquals(0, namedURI.getParameters().size());
+ }
+
+ @Test
public void shouldParseNamedFileUri() {
final NamedUri namedURI = parse("users=file:///users.csv");
diff --git a/freemarker-generator-cli/README.md b/freemarker-generator-cli/README.md
index 3fde98b..bd9ec0e 100644
--- a/freemarker-generator-cli/README.md
+++ b/freemarker-generator-cli/README.md
@@ -78,11 +78,11 @@ You can test the installation by executing
> ./bin/freemarker-cli -t templates/info.ftl
FreeMarker CLI Information
------------------------------------------------------------------------------
-FreeMarker version : 2.3.29
+FreeMarker version : 2.3.30
Template name : templates/info.ftl
Language : en
Locale : en_US
-Timestamp : Apr 4, 2020 12:39:28 PM
+Timestamp : Apr 14, 2020 11:34:13 PM
Output encoding : UTF-8
Output format : plainText
@@ -122,7 +122,7 @@ Command line : -t, templates/info.ftl
Host Name : W0GL5179.local
Java Home : /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home
User Name : sgoeschl
-Timestamp : 1,585,996,768,896
+Timestamp : 1,586,900,053,355
Writer : org.apache.freemarker.generator.base.util.NonClosableWriterWrapper
```
@@ -195,13 +195,14 @@ Please note that generated PDF files are very likely not found since they requir
```text
> ./bin/freemarker-cli -h
-Usage: freemarker-cli (-t=<template> | -i=<interactiveTemplate>) [-EhV]
+Usage: freemarker-cli (-t=<template> | -i=<interactiveTemplate>) [-hV]
[--stdin] [-b=<baseDir>] [--config=<configFile>]
[-e=<inputEncoding>] [--exclude=<exclude>]
- [--include=<include>] [-l=<locale>] [-o=<outputFile>]
- [--output-encoding=<outputEncoding>] [--times=<times>]
- [-D=<String=String>]... [-P=<String=String>]...
- [<sources>...]
+ [--include=<include>] [-l=<locale>] [--mode=<mode>]
+ [-o=<outputFile>] [--output-encoding=<outputEncoding>]
+ [--times=<times>] [-D=<String=String>]...
+ [-m=<dataModels>]... [-P=<String=String>]...
+ [-s=<dataSources>]... [<sources>...]
Apache FreeMarker CLI
[<sources>...] List of input files and/or input directories
-b, --basedir=<baseDir> Optional template base directory
@@ -210,24 +211,26 @@ Apache FreeMarker CLI
Set system property
-e, --input-encoding=<inputEncoding>
Encoding of data source
- -E, --expose-env Expose environment variables and user-supplied
- properties globally
--exclude=<exclude> File pattern for data source input directory
-h, --help Show this help message and exit.
-i, --interactive=<interactiveTemplate>
Interactive FreeMarker template
--include=<include> File pattern for data source input directory
-l, --locale=<locale> Locale being used for the output, e.g. 'en_US'
+ -m, --data-model=<dataModels>
+ Data model used for rendering
+ --mode=<mode> [template|datasource]
-o, --output=<outputFile> Output file
--output-encoding=<outputEncoding>
Encoding of output, e.g. UTF-8
-P, --param=<String=String>
Set parameter
- --stdin Read data source from stdin
+ -s, --data-source=<dataSources>
+ Data source used for rendering
+ --stdin Read data source from stdin
-t, --template=<template> FreeMarker template to render
--times=<times> Re-run X times for profiling
-V, --version Print version information and exit.
-
```
# 6. Examples
@@ -876,7 +879,7 @@ While this looks small and tidy there are some nifty features
Sometimes you have a CSV file which is not quite right - you need to change the format. Lets have a look how `freemarker-cli` can help
-> bin/freemarker-cli -Pcsv.in.delimiter=COMMA -Pcsv.out.delimiter=PIPE -t templates/csv/transform.ftl ./site/sample/csv/contract.csv
+> bin/freemarker-cli -PCVS_IN_DELIMITER=COMMA -PCSV_OUT_DELIMITER=PIPE -t templates/csv/transform.ftl ./site/sample/csv/contract.csv
renders the following template
@@ -892,15 +895,15 @@ renders the following template
</#compress>
<#function createCsvParser dataSource>
- <#assign initialCvsInFormat = CSVTool.formats[SystemTool.getParameter("csv.in.format", "DEFAULT")]>
- <#assign csvInDelimiter = CSVTool.toDelimiter(SystemTool.getParameter("csv.in.delimiter", initialCvsInFormat.getDelimiter()))>
+ <#assign initialCvsInFormat = CSVTool.formats[CSV_IN_FORMAT!"DEFAULT"]>
+ <#assign csvInDelimiter = CSVTool.toDelimiter(CSV_IN_DELIMITER!initialCvsInFormat.getDelimiter())>
<#assign cvsInFormat = initialCvsInFormat.withDelimiter(csvInDelimiter)>
<#return CSVTool.parse(dataSource, cvsInFormat)>
</#function>
<#function createCsvPrinter>
- <#assign initialCvsOutFormat = CSVTool.formats[SystemTool.getParameter("csv.out.format", "DEFAULT")]>
- <#assign csvOutDelimiter = CSVTool.toDelimiter(SystemTool.getParameter("csv.out.delimiter", initialCvsOutFormat.getDelimiter()))>
+ <#assign initialCvsOutFormat = CSVTool.formats[CSV_OUT_FORMAT!"DEFAULT"]>
+ <#assign csvOutDelimiter = CSVTool.toDelimiter(CSV_OUT_DELIMITER!initialCvsOutFormat.getDelimiter())>
<#assign cvsOutFormat = initialCvsOutFormat.withDelimiter(csvOutDelimiter)>
<#return CSVTool.printer(cvsOutFormat, SystemTool.writer)>
</#function>
@@ -1118,8 +1121,6 @@ Sometimes we simply need to transform a JSON into an equivalent YAML or the othe
> ./bin/freemarker-cli -i '${YamlTool.toYaml(GsonTool.parse(DataSources.get(0)))}' site/sample/json/swagger-spec.json
```
-
-
## 6.16 Using Advanced FreeMarker Features
There is a `demo.ftl` which shows some advanced FreeMarker functionality
@@ -1139,13 +1140,12 @@ gives you
```text
1) FreeMarker Special Variables
---------------------------------------------------------------------------
-FreeMarker version : 2.3.29
+FreeMarker version : 2.3.30
Template name : templates/demo.ftl
Language : en
Locale : en_US
-Timestamp : Feb 22, 2020 4:54:19 PM
+Timestamp : Apr 14, 2020 11:40:26 PM
Output encoding : UTF-8
-Output format : plainText
2) Invoke a constructor of a Java class
---------------------------------------------------------------------------
@@ -1264,13 +1264,13 @@ German Special Characters: äöüßÄÖÜ
---------------------------------------------------------------------------
Small Number : 1.23
Large Number : 12,345,678.90
-Date : Feb 22, 2020
-Time : 4:54:20 PM
+Date : Apr 14, 2020
+Time : 11:40:26 PM
17) Execute a program
---------------------------------------------------------------------------
> date
-Sat Feb 22 16:54:20 CET 2020
+Tue Apr 14 23:40:26 CEST 2020
```
# 7. Design Considerations
@@ -1298,9 +1298,9 @@ Within the script a FreeMarker data model is set up and passed to the template -
| JsoupTool | Processing HTML files using [Jsoup](https://jsoup.org) |
| PropertiesTool | Process JDK properties files |
| SystemTool | System-related utility methods |
+| UUIDTool | Create UUIDs |
| XmlTool | Process XML files using [Apache FreeMarker](https://freemarker.apache.org/docs/xgui.html) |
| YamlTool | Process YAML files using [SnakeYAML](https://bitbucket.org/asomov/snakeyaml/wiki/Home) |
-| UUIDTool | Create UUIDs |
# 8. Tips & Tricks
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 e3b17b4..fa2cd12 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
@@ -17,6 +17,7 @@
package org.apache.freemarker.generator.cli;
import org.apache.freemarker.generator.base.FreeMarkerConstants.GeneratorMode;
+import org.apache.freemarker.generator.base.parameter.ParameterModelSupplier;
import org.apache.freemarker.generator.base.util.ClosableUtils;
import org.apache.freemarker.generator.base.util.StringUtils;
import org.apache.freemarker.generator.cli.config.Settings;
@@ -38,7 +39,6 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -77,9 +77,6 @@ public class Main implements Callable<Integer> {
@Option(names = { "-e", "--input-encoding" }, description = "Encoding of data source", defaultValue = "UTF-8")
String inputEncoding;
- @Option(names = { "-E", "--expose-env" }, description = "Expose environment variables and user-supplied properties globally")
- boolean isEnvironmentExposed;
-
@Option(names = { "-l", "--locale" }, description = "Locale being used for the output, e.g. 'en_US'")
String locale;
@@ -208,8 +205,9 @@ public class Main implements Callable<Integer> {
}
private Settings settings(Properties configuration, List<File> templateDirectories) {
+ final ParameterModelSupplier parameterModelSupplier = new ParameterModelSupplier(parameters);
+
return Settings.builder()
- .isEnvironmentExposed(isEnvironmentExposed)
.isReadFromStdin(readFromStdin)
.setArgs(args)
.setConfiguration(configuration)
@@ -220,7 +218,7 @@ public class Main implements Callable<Integer> {
.setLocale(locale)
.setOutputEncoding(outputEncoding)
.setOutputFile(outputFile)
- .setParameters(parameters != null ? parameters : new HashMap<>())
+ .setParameters(parameterModelSupplier.get())
.setDataSources(getCombindedDataSources())
.setDataModels(dataModels)
.setSystemProperties(systemProperties != null ? systemProperties : new Properties())
diff --git a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelSupplier.java b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelSupplier.java
index 62ae775..d8e3491 100644
--- a/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelSupplier.java
+++ b/freemarker-generator-cli/src/main/java/org/apache/freemarker/generator/cli/config/DataModelSupplier.java
@@ -37,9 +37,9 @@ 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;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_TEXT_YAML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_JSON;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_PLAIN;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_YAML;
/**
* Create a map representing a data model based on a list of sources consisting of
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 51bbae8..5163aed 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
@@ -82,17 +82,14 @@ public class Settings {
/** Read from stdin? */
private final boolean isReadFromStdin;
- /** Expose environment variables globally in the data model? */
- private final boolean isEnvironmentExposed;
-
/** 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;
+ private final List<String> dataModels;
/** User-supplied parameters */
- private final Map<String, String> parameters;
+ private final Map<String, Object> parameters;
/** User-supplied system properties */
private final Properties sytemProperties;
@@ -114,10 +111,9 @@ public class Settings {
String exclude,
Locale locale,
boolean isReadFromStdin,
- boolean isEnvironmentExposed,
List<String> dataSources,
List<String> dataModels,
- Map<String, String> parameters,
+ Map<String, Object> parameters,
Properties sytemProperties,
Writer writer) {
if (isEmpty(template) && isEmpty(interactiveTemplate)) {
@@ -136,7 +132,6 @@ public class Settings {
this.exclude = exclude;
this.locale = requireNonNull(locale);
this.isReadFromStdin = isReadFromStdin;
- this.isEnvironmentExposed = isEnvironmentExposed;
this.dataSources = requireNonNull(dataSources);
this.dataModels = requireNonNull(dataModels);
this.parameters = requireNonNull(parameters);
@@ -205,10 +200,6 @@ public class Settings {
return isReadFromStdin;
}
- public boolean isEnvironmentExposed() {
- return isEnvironmentExposed;
- }
-
public List<String> getDataSources() {
return dataSources;
}
@@ -217,7 +208,7 @@ public class Settings {
return dataModels;
}
- public Map<String, String> getParameters() {
+ public Map<String, Object> getParameters() {
return parameters;
}
@@ -270,16 +261,9 @@ public class Settings {
", exclude='" + include + '\'' +
", locale=" + locale +
", isReadFromStdin=" + isReadFromStdin +
- ", isEnvironmentExposed=" + isEnvironmentExposed +
", dataSources=" + dataSources +
", properties=" + parameters +
", sytemProperties=" + sytemProperties +
- ", writer=" + writer +
- ", templateEncoding=" + getTemplateEncoding() +
- ", readFromStdin=" + isReadFromStdin() +
- ", environmentExposed=" + isEnvironmentExposed() +
- ", hasOutputFile=" + hasOutputFile() +
- ", toMap=" + toMap() +
'}';
}
@@ -296,10 +280,9 @@ public class Settings {
private String exclude;
private String locale;
private boolean isReadFromStdin;
- private boolean isEnvironmentExposed;
private List<String> dataSources;
private List<String> dataModels;
- private Map<String, String> parameters;
+ private Map<String, Object> parameters;
private Properties systemProperties;
private Properties configuration;
private Writer writer;
@@ -386,11 +369,6 @@ public class Settings {
return this;
}
- public SettingsBuilder isEnvironmentExposed(boolean isEnvironmentExposed) {
- this.isEnvironmentExposed = isEnvironmentExposed;
- return this;
- }
-
public SettingsBuilder setDataSources(List<String> dataSources) {
if (dataSources != null) {
this.dataSources = dataSources;
@@ -405,7 +383,7 @@ public class Settings {
return this;
}
- public SettingsBuilder setParameters(Map<String, String> parameters) {
+ public SettingsBuilder setParameters(Map<String, Object> parameters) {
if (parameters != null) {
this.parameters = parameters;
}
@@ -451,7 +429,6 @@ public class Settings {
exclude,
LocaleUtils.parseLocale(currLocale),
isReadFromStdin,
- isEnvironmentExposed,
dataSources,
dataModels,
parameters,
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 79f6e0a..6a57e59 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
@@ -22,6 +22,7 @@ import org.apache.freemarker.generator.base.file.PropertiesClassPathSupplier;
import org.apache.freemarker.generator.base.file.PropertiesFileSystemSupplier;
import org.apache.freemarker.generator.base.file.PropertiesSupplier;
+import java.util.Map;
import java.util.function.Supplier;
/**
@@ -60,6 +61,10 @@ public class Suppliers {
return new DataModelSupplier(settings.getDataModels());
}
+ public static Supplier<Map<String, Object>> parameterSupplier(Settings settings) {
+ return settings::getParameters;
+ }
+
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 a89bc33..803b9c2 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
@@ -45,6 +45,7 @@ import static org.apache.freemarker.generator.base.FreeMarkerConstants.Model.DAT
import static org.apache.freemarker.generator.cli.config.Suppliers.configurationSupplier;
import static org.apache.freemarker.generator.cli.config.Suppliers.dataModelSupplier;
import static org.apache.freemarker.generator.cli.config.Suppliers.dataSourcesSupplier;
+import static org.apache.freemarker.generator.cli.config.Suppliers.parameterSupplier;
import static org.apache.freemarker.generator.cli.config.Suppliers.toolsSupplier;
/**
@@ -58,21 +59,29 @@ public class FreeMarkerTask implements Callable<Integer> {
private final Supplier<Map<String, Object>> toolsSupplier;
private final Supplier<List<DataSource>> dataSourcesSupplier;
private final Supplier<Map<String, Object>> dataModelsSupplier;
+ private final Supplier<Map<String, Object>> parameterModelSupplier;
private final Supplier<Configuration> configurationSupplier;
public FreeMarkerTask(Settings settings) {
- this(settings, toolsSupplier(settings), dataSourcesSupplier(settings), dataModelSupplier(settings), configurationSupplier(settings));
+ this(settings,
+ toolsSupplier(settings),
+ dataSourcesSupplier(settings),
+ dataModelSupplier(settings),
+ parameterSupplier(settings),
+ configurationSupplier(settings));
}
public FreeMarkerTask(Settings settings,
Supplier<Map<String, Object>> toolsSupplier,
Supplier<List<DataSource>> dataSourcesSupplier,
Supplier<Map<String, Object>> dataModelsSupplier,
+ Supplier<Map<String, Object>> parameterModelSupplier,
Supplier<Configuration> configurationSupplier) {
this.settings = requireNonNull(settings);
this.toolsSupplier = requireNonNull(toolsSupplier);
this.dataSourcesSupplier = requireNonNull(dataSourcesSupplier);
this.dataModelsSupplier = requireNonNull(dataModelsSupplier);
+ this.parameterModelSupplier = requireNonNull(parameterModelSupplier);
this.configurationSupplier = requireNonNull(configurationSupplier);
}
@@ -80,7 +89,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, dataModelsSupplier, toolsSupplier);
+ final Map<String, Object> dataModel = dataModel(dataSources, parameterModelSupplier, dataModelsSupplier, toolsSupplier);
template.process(dataModel, writer);
return SUCCESS;
} catch (RuntimeException e) {
@@ -131,24 +140,15 @@ public class FreeMarkerTask implements Callable<Integer> {
}
private static Map<String, Object> dataModel(
- Settings settings,
DataSources dataSources,
+ Supplier<Map<String, Object>> parameterModelSupplier,
Supplier<Map<String, Object>> dataModelsSupplier,
Supplier<Map<String, Object>> tools) {
final Map<String, Object> result = new HashMap<>();
-
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
- result.putAll(System.getenv());
- result.putAll(settings.getParameters());
- }
-
+ result.putAll(parameterModelSupplier.get());
result.putAll(tools.get());
-
return result;
}
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
index 2a2469e..7ab78e8 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/named-uris.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/named-uris.md
@@ -18,13 +18,13 @@ 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` |
+| 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. |
+| 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`
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md
new file mode 100644
index 0000000..46f2d2e
--- /dev/null
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md
@@ -0,0 +1,37 @@
+# User-Supplied Parameters
+
+User-supplied parameters allow to pass additional information to an Apache FreeMarker template
+
+* `-Pname=value` to define a key/value pair
+* `-Pname:group=value` to define a map containing key/value pairs, i.e nested map
+
+Pass a simple name/value pair on the command line
+
+```
+> bin/freemarker-cli -t templates/info.ftl -P key=value
+
+User Supplied Parameters
+------------------------------------------------------------------------------
+- key ==> value
+```
+
+By providing a `group` you can create nested maps
+
+```
+> bin/freemarker-cli -t templates/info.ftl -P foo1:group=bar1 -P foo2:group=bar2
+
+User Supplied Parameters
+------------------------------------------------------------------------------
+- group ==> { foo1=bar1 foo2=bar2 }
+```
+
+It is also possible to mix and match the two approaches
+
+```
+> bin/freemarker-cli -t templates/info.ftl -P foo1:group=bar1 -P foo2:group=bar2 -P key=value
+
+User Supplied Parameters
+------------------------------------------------------------------------------
+- key ==> value
+- group ==> { foo1=bar1 foo2=bar2 }
+```
\ No newline at end of file
diff --git a/freemarker-generator-cli/src/site/markdown/index.md b/freemarker-generator-cli/src/site/markdown/index.md
index c5807bc..791ab12 100644
--- a/freemarker-generator-cli/src/site/markdown/index.md
+++ b/freemarker-generator-cli/src/site/markdown/index.md
@@ -2,5 +2,6 @@
### Concepts
+* [User-Supplied Parameters](cli/concepts/user-parameters.html)
* [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/ExamplesTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ExamplesTest.java
index 295b2e7..147a2d7 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ExamplesTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ExamplesTest.java
@@ -99,7 +99,7 @@ public class ExamplesTest extends AbstractMainTest {
@Test
public void shouldRunWithExposedEnvironmentVariableExamples() throws IOException {
- assertValid(execute("-b ./src/test -E -t templates/environment.ftl"));
+ assertValid(execute("-b ./src/test -m env:/// -t templates/environment.ftl"));
}
@Test
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 0dac268..210f32f 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
@@ -28,7 +28,7 @@ public class ManualTest {
// private static final String CMD = "-b ./src/test -l de_AT -DFOO=foo -DBAR=bar -t templates/info.ftl site/sample/csv/transactions.csv";
// private static final String CMD = "-b ./src/test -DFOO=foo -PBAR=bar -l de -t templates/demo.ftl site/sample/csv/transactions.csv";
// private static final String CMD = "-b ./src/test -DFOO=foo -PBAR=bar -t templates/demo.ftl site/sample/csv/transactions.csv";
- // private static final String CMD = "-b ./src/test -Dcsv.out.format=TDF -t templates/csv/transform.ftl site/sample/csv/contract.csv";
+ // private static final String CMD = "-b ./src/test -PCSV_OUT_FORMAT=TDF -t templates/csv/transform.ftl site/sample/csv/contract.csv";
// private static final String CMD = "-t templates/excel/csv/transform.ftl -l de_AT site/sample/excel/test.xlsx";
// private static final String CMD = "-i ${JsonPathTool.parse(DataSources.first).read('$.info.title')} site/sample/json/swagger-spec.json";
// private static final String CMD = "-i ${XmlTool.parse(DataSources.first)['recipients/person[1]/name']} site/sample/xml/recipients.xml";
@@ -48,7 +48,7 @@ public class ManualTest {
// 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";
+ private static final String CMD = "-b ./src/test -t templates/info.ftl -P name=value";
public static void main(String[] 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
index d5e15d6..d465fd0 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
@@ -81,6 +81,21 @@ public class PicocliTest {
assertNull(main.sources);
}
+ @Test
+ public void testSingleParameter() {
+ final Main main = parse("-t", TEMPLATE, "-P", "name:group=value");
+
+ assertEquals("value", main.parameters.get("name:group"));
+ }
+
+ @Test
+ public void testMultipleParameters() {
+ final Main main = parse("-t", TEMPLATE, "-P", "name1:group=value1", "-P", "name2:group=value2");
+
+ assertEquals("value1", main.parameters.get("name1:group"));
+ assertEquals("value2", main.parameters.get("name2:group"));
+ }
+
private static Main parse(String... args) {
final Main main = new Main();
new CommandLine(main).parseArgs(args);
diff --git a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelSupplierTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelSupplierTest.java
index 0dc0d78..def6a86 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelSupplierTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/config/DataModelSupplierTest.java
@@ -16,8 +16,10 @@
*/
package org.apache.freemarker.generator.cli.config;
+import org.junit.Ignore;
import org.junit.Test;
+import java.nio.file.Paths;
import java.util.Map;
import static java.util.Collections.singletonList;
@@ -27,6 +29,7 @@ import static org.junit.Assert.assertTrue;
public class DataModelSupplierTest {
+ private static final String PWD = Paths.get(".").toAbsolutePath().normalize().toString();
private static final String PWD_VALUE = System.getenv("PWD");
private static final int NR_OF_ALL_ENV_VARIABLES = System.getenv().size();
@@ -104,7 +107,7 @@ public class DataModelSupplierTest {
@Test
public void shouldResolvePropertiesUriToDataModelVariable() {
- final DataModelSupplier supplier = supplier("props=file://./src/test/data/properties/test.properties");
+ final DataModelSupplier supplier = supplier("props=file:///" + PWD + "/src/test/data/properties/test.properties");
final Map<String, Object> model = supplier.get();
@@ -140,6 +143,7 @@ public class DataModelSupplierTest {
// == URL ===
@Test
+ @Ignore
public void shouldResolveUrlToTopLevelDataModel() {
final DataModelSupplier supplier = supplier("post=https://jsonplaceholder.typicode.com/posts/2");
@@ -150,6 +154,7 @@ public class DataModelSupplierTest {
}
@Test
+ @Ignore
public void shouldResolveUrlToDataModelVariable() {
final DataModelSupplier supplier = supplier("https://jsonplaceholder.typicode.com/posts/2");
@@ -159,6 +164,7 @@ public class DataModelSupplierTest {
}
@Test(expected = RuntimeException.class)
+ @Ignore
public void shouldResolveUrlToDataModelVariables() {
supplier("https://jsonplaceholder.typicode.com/posts/does-not-exist").get();
}
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 3c71276..16032e4 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
@@ -42,7 +42,7 @@ public class SettingsTest {
private static final String ANY_OUTPUT_FILE = "outputFile";
private static final List<String> ANY_SOURCES = singletonList("sources");
private static final String ANY_TEMPLATE_NAME = "templateName";
- private static final Map<String, String> ANY_USER_PARAMETERS = new HashMap<>();
+ private static final Map<String, Object> ANY_USER_PARAMETERS = new HashMap<>();
private static final Properties ANY_SYSTEM_PROPERTIES = new Properties();
@Test
@@ -60,14 +60,12 @@ public class SettingsTest {
assertNotNull(settings.getParameters());
assertNotNull(settings.getSytemProperties());
assertTrue(settings.isReadFromStdin());
- assertTrue(settings.isEnvironmentExposed());
assertTrue(settings.isInteractiveTemplate());
assertTrue(settings.isVerbose());
}
private SettingsBuilder allSettingsBuilder() {
return Settings.builder()
- .isEnvironmentExposed(true)
.isReadFromStdin(true)
.setArgs(ANY_ARGS)
.setConfiguration(ANY_CONFIGURATION)
diff --git a/freemarker-generator-cli/templates/csv/fo/transform.ftl b/freemarker-generator-cli/templates/csv/fo/transform.ftl
index 7ce74c8..4efa596 100644
--- a/freemarker-generator-cli/templates/csv/fo/transform.ftl
+++ b/freemarker-generator-cli/templates/csv/fo/transform.ftl
@@ -15,7 +15,7 @@
specific language governing permissions and limitations
under the License.
-->
-<#assign csvFormatName = SystemTool.parameters["csv.format"]!"DEFAULT">
+<#assign csvFormatName = CVS_IN_FORMAT!"DEFAULT">
<#assign cvsFormat = CSVTool.formats[csvFormatName].withHeader()>
<#assign csvParser = CSVTool.parse(DataSources.get(0), cvsFormat)>
<#assign csvHeaders = csvParser.getHeaderMap()?keys>
diff --git a/freemarker-generator-cli/templates/csv/transform.ftl b/freemarker-generator-cli/templates/csv/transform.ftl
index b4e21ef..af091ec 100644
--- a/freemarker-generator-cli/templates/csv/transform.ftl
+++ b/freemarker-generator-cli/templates/csv/transform.ftl
@@ -25,15 +25,15 @@
</#compress>
<#function createCsvParser dataSource>
- <#assign initialCvsInFormat = CSVTool.formats[SystemTool.getParameter("csv.in.format", "DEFAULT")]>
- <#assign csvInDelimiter = CSVTool.toDelimiter(SystemTool.getParameter("csv.in.delimiter", initialCvsInFormat.getDelimiter()))>
+ <#assign initialCvsInFormat = CSVTool.formats[CSV_IN_FORMAT!"DEFAULT"]>
+ <#assign csvInDelimiter = CSVTool.toDelimiter(CSV_IN_DELIMITER!initialCvsInFormat.getDelimiter())>
<#assign cvsInFormat = initialCvsInFormat.withDelimiter(csvInDelimiter)>
<#return CSVTool.parse(dataSource, cvsInFormat)>
</#function>
<#function createCsvPrinter>
- <#assign initialCvsOutFormat = CSVTool.formats[SystemTool.getParameter("csv.out.format", "DEFAULT")]>
- <#assign csvOutDelimiter = CSVTool.toDelimiter(SystemTool.getParameter("csv.out.delimiter", initialCvsOutFormat.getDelimiter()))>
+ <#assign initialCvsOutFormat = CSVTool.formats[CSV_OUT_FORMAT!"DEFAULT"]>
+ <#assign csvOutDelimiter = CSVTool.toDelimiter(CSV_OUT_DELIMITER!initialCvsOutFormat.getDelimiter())>
<#assign cvsOutFormat = initialCvsOutFormat.withDelimiter(csvOutDelimiter)>
<#return CSVTool.printer(cvsOutFormat, SystemTool.writer)>
</#function>
\ No newline at end of file
diff --git a/freemarker-generator-cli/templates/excel/csv/custom.ftl b/freemarker-generator-cli/templates/excel/csv/custom.ftl
index 542d92b..a045bd3 100644
--- a/freemarker-generator-cli/templates/excel/csv/custom.ftl
+++ b/freemarker-generator-cli/templates/excel/csv/custom.ftl
@@ -15,7 +15,7 @@
specific language governing permissions and limitations
under the License.
-->
-<#assign format = SystemTool.parameters["csv.format"]!"DEFAULT">
+<#assign format = CVS_FORMAT!"DEFAULT">
<#assign salt = SystemTool.parameters["salt"]!"salt">
<#-- Parse the first data source & sheet of the Excel document -->
<#assign workbook = ExcelTool.parse(DataSources.get(0))>
diff --git a/freemarker-generator-cli/templates/excel/csv/transform.ftl b/freemarker-generator-cli/templates/excel/csv/transform.ftl
index d60421c..2455c49 100644
--- a/freemarker-generator-cli/templates/excel/csv/transform.ftl
+++ b/freemarker-generator-cli/templates/excel/csv/transform.ftl
@@ -15,7 +15,7 @@
specific language governing permissions and limitations
under the License.
-->
-<#assign format = SystemTool.parameters["csv.format"]!"DEFAULT">
+<#assign format = CVS_IN_FORMAT!"DEFAULT">
<#-- Parse the first data source & sheet of the Excel document -->
<#assign workbook = ExcelTool.parse(DataSources.get(0))>
<#assign sheet = ExcelTool.getSheets(workbook)[0]>
diff --git a/freemarker-generator-cli/templates/info.ftl b/freemarker-generator-cli/templates/info.ftl
index 01384c3..565e2ec 100644
--- a/freemarker-generator-cli/templates/info.ftl
+++ b/freemarker-generator-cli/templates/info.ftl
@@ -39,30 +39,29 @@ FreeMarker CLI Tools
</#if>
</#list>
-FreeMarker CLI DataSources
-------------------------------------------------------------------------------
-<#list DataSources.list as dataSource>
-[#${dataSource?counter}], name=${dataSource.name}, group=${dataSource.group}, contentType=${dataSource.contentType}, charset=${dataSource.charset}, length=${dataSource.length} Bytes
-URI : ${dataSource.uri}
+FreeMarker CLI Data Model
+---------------------------------------------------------------------------
+<#list .data_model?keys?sort as key>
+- ${key}<#lt>
</#list>
-User Supplied Parameters
+<#if DataSources.list?has_content>
+FreeMarker CLI DataSources
------------------------------------------------------------------------------
-<#list SystemTool.parameters as name,value>
-- ${name} ==> ${value}
+<#list DataSources.list as dataSource>
+ [#${dataSource?counter}], name=${dataSource.name}, group=${dataSource.group}, contentType=${dataSource.contentType}, charset=${dataSource.charset}, length=${dataSource.length} Bytes
+ URI : ${dataSource.uri}
</#list>
+</#if>
-User Supplied System Properties
+<#if SystemTool.parameters?has_content>
+FreeMarker CLI Parameters
------------------------------------------------------------------------------
-<#list SystemTool.userSystemProperties as name,value>
-- ${name} ==> ${value}
+<#list SystemTool.parameters as key,value>
+<#if value?is_hash>
+- ${key} ==> { <#list value as name,value>${name}=${value} </#list>}
+<#else>
+- ${key} ==> ${value}
+</#if>
</#list>
-
-SystemTool
-------------------------------------------------------------------------------
-Command line : ${SystemTool.getCommandLineArgs()?join(", ")}
-Host Name : ${SystemTool.getHostName()}
-Java Home : ${SystemTool.getEnv("JAVA_HOME", "N.A.")}
-User Name : ${SystemTool.getSystemProperty("user.name", "N.A.")}
-Timestamp : ${SystemTool.currentTimeMillis}
-Writer : ${SystemTool.writer.class.name}
+</#if>
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/system/SystemTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/system/SystemTool.java
index 2b50c99..183b9da 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/system/SystemTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/system/SystemTool.java
@@ -92,12 +92,12 @@ public class SystemTool {
return System.getProperties();
}
- public String getParameter(String key) {
- return parameters.get(key);
+ public String getParameter(String name) {
+ return parameters.get(name);
}
- public String getParameter(String key, String def) {
- return parameters.getOrDefault(key, def);
+ public String getParameter(String name, String def) {
+ return parameters.getOrDefault(name, def);
}
public Map<String, String> getParameters() {
diff --git a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/snakeyaml/SnakeYamlToolTest.java b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/snakeyaml/SnakeYamlToolTest.java
index 6850b25..d588094 100644
--- a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/snakeyaml/SnakeYamlToolTest.java
+++ b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/snakeyaml/SnakeYamlToolTest.java
@@ -16,9 +16,9 @@
*/
package org.apache.freemarker.generator.tools.snakeyaml;
-import org.apache.freemarker.generator.base.activation.Mimetypes;
import org.apache.freemarker.generator.base.datasource.DataSource;
import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+import org.apache.freemarker.generator.base.mime.Mimetypes;
import org.junit.Test;
import java.io.File;
@@ -27,7 +27,6 @@ import java.util.List;
import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;
import static org.apache.commons.io.FileUtils.readFileToString;
diff --git a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/xml/XmlToolTest.java b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/xml/XmlToolTest.java
index 475f8e9..f0f9676 100644
--- a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/xml/XmlToolTest.java
+++ b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/xml/XmlToolTest.java
@@ -23,7 +23,7 @@ import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
-import static org.apache.freemarker.generator.base.activation.Mimetypes.MIME_APPLICATION_XML;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_XML;
public class XmlToolTest {