Merge remote-tracking branch 'origin/master' into FREEMARKER-200
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 de2b295..d6735cf 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
@@ -20,6 +20,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.InputStreamDataSource;
 import org.apache.freemarker.generator.base.activation.StringDataSource;
 import org.apache.freemarker.generator.base.mime.MimeTypeParser;
 import org.apache.freemarker.generator.base.util.CloseableReaper;
@@ -193,7 +194,7 @@
      * @return file name or empty string
      */
     public String getFileName() {
-        return isFileDataSource() ? FilenameUtils.getName(dataSource.getName()) : "";
+        return isHierarchicalPathSupported() ? FilenameUtils.getName(uri.getPath()) : "";
     }
 
     /**
@@ -203,7 +204,7 @@
      * @return file name or empty string
      */
     public String getFilePath() {
-        return isFileDataSource() ? FilenameUtils.getFullPathNoEndSeparator(uri.getPath()) : "";
+        return isHierarchicalPathSupported() ? FilenameUtils.getFullPathNoEndSeparator(uri.getPath()) : "";
     }
 
     /**
@@ -477,6 +478,16 @@
         return dataSource instanceof ByteArrayDataSource;
     }
 
+    private boolean isInputStreamDataSource() {
+        return dataSource instanceof InputStreamDataSource;
+    }
+
+    private boolean isHierarchicalPathSupported() {
+        return !isByteArrayDataSource()
+                && !isStringDataSource()
+                && !isInputStreamDataSource();
+    }
+
     public static final class DataSourceBuilder {
         private String name;
         private String group;
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
index 6f70b69..969c631 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/mime/Mimetypes.java
@@ -20,6 +20,7 @@
 
     public static final String MIME_APPLICATION_JSON = "application/json";
     public static final String MIME_APPLICATION_OCTET_STREAM = "application/octet-stream";
+    public static final String MIME_APPLICATION_YAML = "application/yaml";
     public static final String MIME_APPLICATION_XML = "application/xml";
     public static final String MIME_APPLICATION_XHTML = "application/xhtml+xml";
 
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 cb7b252..5413600 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
@@ -51,6 +51,7 @@
         try (DataSource dataSource = DataSourceFactory.fromString("stdin", ANY_GROUP, ANY_TEXT, Mimetypes.MIME_TEXT_PLAIN)) {
             assertEquals("stdin", dataSource.getName());
             assertEquals(ANY_GROUP, dataSource.getGroup());
+            assertEquals("", dataSource.getFileName());
             assertEquals("", dataSource.getBaseName());
             assertEquals("", dataSource.getExtension());
             assertTrue(dataSource.getUri().toString().startsWith("string:///"));
@@ -69,6 +70,7 @@
         try (DataSource dataSource = DataSourceFactory.fromFile(ANY_FILE, ANY_CHAR_SET)) {
             assertEquals(ANY_FILE_NAME, dataSource.getFileName());
             assertEquals(DEFAULT_GROUP, dataSource.getGroup());
+            assertEquals("pom.xml", dataSource.getFileName());
             assertEquals("pom", dataSource.getBaseName());
             assertEquals("xml", dataSource.getExtension());
             assertEquals(ANY_FILE.toURI().toString(), dataSource.getUri().toString());
@@ -90,6 +92,7 @@
         try (DataSource dataSource = DataSourceFactory.fromUrl("www.google.com", DEFAULT_GROUP, toUrl("https://www.google.com/?foo=bar"), null, null, null)) {
             assertEquals("www.google.com", dataSource.getName());
             assertEquals(DEFAULT_GROUP, dataSource.getGroup());
+            assertEquals("", dataSource.getFileName());
             assertEquals("", dataSource.getBaseName());
             assertEquals("", dataSource.getExtension());
             assertEquals("https://www.google.com/?foo=bar", dataSource.getUri().toString());
@@ -103,6 +106,26 @@
     }
 
     @Test
+    @Ignore("Requires internet access")
+    public void shouldSupportPathLikeUrlDataSource() {
+        final String url = "https://petstore.swagger.io/v2/swagger.yaml";
+        try (DataSource dataSource = DataSourceFactory.fromUrl(url, DEFAULT_GROUP, toUrl(url), null, null, null)) {
+            assertEquals(url, dataSource.getName());
+            assertEquals(DEFAULT_GROUP, dataSource.getGroup());
+            assertEquals("swagger.yaml", dataSource.getFileName());
+            assertEquals("swagger", dataSource.getBaseName());
+            assertEquals("yaml", dataSource.getExtension());
+            assertEquals(url, dataSource.getUri().toString());
+            assertEquals("", dataSource.getRelativeFilePath());
+            assertEquals("application/yaml", dataSource.getContentType());
+            assertEquals("application/yaml", dataSource.getMimeType());
+            assertEquals("UTF-8", dataSource.getCharset().name());
+            assertEquals(-1, dataSource.getLength());
+            assertFalse(dataSource.getText().isEmpty());
+        }
+    }
+
+    @Test
     public void shouldSupportLineIterator() throws IOException {
         try (DataSource dataSource = stringDataSource()) {
             try (LineIterator iterator = dataSource.getLineIterator()) {
diff --git a/freemarker-generator-cli/CHANGELOG.md b/freemarker-generator-cli/CHANGELOG.md
index c440886..ef74913 100644
--- a/freemarker-generator-cli/CHANGELOG.md
+++ b/freemarker-generator-cli/CHANGELOG.md
@@ -10,6 +10,9 @@
 ### Changed
 * [FREEMARKER-195] Improve exposure of DataSources using TemplateHashModelEx2
 
+### Fixed
+* [FREEMARKER-200] Handle non-standard content types for JSON & YAML data models
+
 ## 0.1.0-SNAPSHOT (unreleased)
 
 ### Added
@@ -94,4 +97,5 @@
 [FREEMARKER-188]: https://issues.apache.org/jira/browse/FREEMARKER-188
 [FREEMARKER-195]: https://issues.apache.org/jira/browse/FREEMARKER-195
 [FREEMARKER-199]: https://issues.apache.org/jira/browse/FREEMARKER-199
+[FREEMARKER-200]: https://issues.apache.org/jira/browse/FREEMARKER-200
 
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 6cc81d0..ec26eb1 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
@@ -16,7 +16,6 @@
  */
 package org.apache.freemarker.generator.cli.config;
 
-import org.apache.commons.io.FilenameUtils;
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSourceLoader;
 import org.apache.freemarker.generator.base.datasource.DataSourceLoaderFactory;
@@ -41,6 +40,7 @@
 
 import static java.util.Objects.requireNonNull;
 import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_JSON;
+import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_APPLICATION_YAML;
 import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_PLAIN;
 import static org.apache.freemarker.generator.base.mime.Mimetypes.MIME_TEXT_YAML;
 
@@ -78,7 +78,7 @@
         final boolean isExplodedDataModel = !namedUri.hasName();
         final String contentType = dataSource.getContentType();
 
-        if (contentType.startsWith(MIME_APPLICATION_JSON)) {
+        if (isJsonDataSource(dataSource)) {
             return fromJson(dataSource, isExplodedDataModel);
         } else if (isYamlDataSource(dataSource)) {
             return fromYaml(dataSource, isExplodedDataModel);
@@ -91,9 +91,21 @@
 
     private static boolean isYamlDataSource(DataSource dataSource) {
         final String contentType = dataSource.getContentType();
-        final String extension = FilenameUtils.getExtension(dataSource.getUri().toString());
-        return contentType.startsWith(MIME_TEXT_YAML)
-                || (contentType.startsWith(MIME_TEXT_PLAIN)) && "yaml".equalsIgnoreCase(extension);
+        if(contentType.startsWith(MIME_TEXT_YAML) || contentType.startsWith(MIME_APPLICATION_YAML)) {
+            return true;
+        }
+
+        final String extension = dataSource.getExtension();
+        final boolean hasYamlExtension = "yml".equalsIgnoreCase(extension) || "yaml".equalsIgnoreCase(extension);
+        return (contentType.startsWith(MIME_TEXT_PLAIN)) && hasYamlExtension;
+    }
+
+    private static boolean isJsonDataSource(DataSource dataSource) {
+        final String contentType = dataSource.getContentType();
+        final String extension = dataSource.getExtension();
+        final boolean hasJsonExtension = "json".equalsIgnoreCase(extension);
+        return contentType.startsWith(MIME_APPLICATION_JSON)
+                || (contentType.startsWith(MIME_TEXT_PLAIN)) && hasJsonExtension;
     }
 
     private static Map<String, Object> fromJson(DataSource dataSource, boolean isExplodedDataModel) {
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 2f1dd69..c19f0b0 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
@@ -25,8 +25,8 @@
 
     // private static final String CMD = "-V";
     private static final String CMD =
-            "-t src/app/examples/templates/nginx/confluence/nginx-config-parser.ftl -s src/app/examples/data/nginx";
-            // "-t src/app/examples/templates/datasources.ftl";
+            "-t src/app/examples/templates/demo.ftl src/test/data/json"
+            ;
 
     @Override
     public String execute(String commandLine) throws IOException {
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 34745f2..32fa79b 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
@@ -184,9 +184,9 @@
         assertNotNull(model.get("post"));
     }
 
-    @Test
+    @Test(expected = RuntimeException.class)
     @Ignore("Requires internet access")
-    public void shouldResolveUrlToDataModelVariables() {
+    public void shouldThrowExceptionForUnresolvableUrl() {
         supplier("https://jsonplaceholder.typicode.com/posts/does-not-exist").get();
     }