From 743e874f7df6391e8e0025388aef2b38b6b172e2 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 29 Apr 2020 00:13:41 +0200 Subject: [PATCH 1/4] update to apache configurations2. load properties files with default utf-8 encoding --- gradle.properties | 3 +- jbake-core/build.gradle | 3 +- .../src/main/java/org/jbake/app/Asset.java | 4 +- .../src/main/java/org/jbake/app/Crawler.java | 8 +-- .../src/main/java/org/jbake/app/Oven.java | 6 +- .../src/main/java/org/jbake/app/Renderer.java | 4 +- .../jbake/app/configuration/ConfigUtil.java | 58 ++++++++++++++----- .../DefaultJBakeConfiguration.java | 18 +++--- .../JBakeConfigurationFactory.java | 5 +- .../java/org/jbake/launcher/BakeWatcher.java | 4 +- .../main/java/org/jbake/launcher/Baker.java | 2 +- .../main/java/org/jbake/launcher/Init.java | 4 +- .../main/java/org/jbake/launcher/Main.java | 2 +- .../java/org/jbake/parser/MarkupEngine.java | 4 +- .../java/org/jbake/parser/ParserEngine.java | 2 +- .../org/jbake/render/ArchiveRenderer.java | 4 +- .../org/jbake/render/DocumentsRenderer.java | 2 +- .../java/org/jbake/render/FeedRenderer.java | 4 +- .../java/org/jbake/render/IndexRenderer.java | 4 +- .../java/org/jbake/render/RenderingTool.java | 2 +- .../org/jbake/render/SitemapRenderer.java | 4 +- .../java/org/jbake/render/TagsRenderer.java | 4 +- .../template/AbstractTemplateEngine.java | 4 +- .../template/DelegatingTemplateEngine.java | 2 +- .../template/FreemarkerTemplateEngine.java | 2 +- .../template/GroovyMarkupTemplateEngine.java | 2 +- .../jbake/template/GroovyTemplateEngine.java | 2 +- .../jbake/template/JadeTemplateEngine.java | 6 +- .../template/ThymeleafTemplateEngine.java | 10 ++-- .../app/configuration/ConfigUtilTest.java | 24 +++++--- .../java/org/jbake/launcher/MainTest.java | 2 +- .../support/MockCompositeConfiguration.java | 3 +- .../test/resources/fixture/jbake.properties | 3 +- jbake-core/src/test/resources/logback.xml | 6 +- jbake-dist/src/dist/lib/logging/logback.xml | 3 + 35 files changed, 135 insertions(+), 85 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8733e3e09..4748188e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,8 @@ asciidoctorjVersion = 2.2.0 asciidoctorjDiagramVersion = 2.0.1 args4jVersion = 2.33 commonsIoVersion = 2.6 -commonsConfigurationVersion = 1.10 +commonsConfigurationVersion = 2.7 +commonsBeanutilsVersion = 1.9.4 commonsLangVersion = 3.10 commonsVfs2Version = 2.6.0 freemarkerVersion = 2.3.30 diff --git a/jbake-core/build.gradle b/jbake-core/build.gradle index d7f886ee7..c693e2849 100644 --- a/jbake-core/build.gradle +++ b/jbake-core/build.gradle @@ -8,7 +8,8 @@ description = "The core library of JBake" dependencies { implementation "commons-io:commons-io:$commonsIoVersion" - implementation "commons-configuration:commons-configuration:$commonsConfigurationVersion" + implementation "org.apache.commons:commons-configuration2:$commonsConfigurationVersion" + implementation "commons-beanutils:commons-beanutils:$commonsBeanutilsVersion" implementation "org.apache.commons:commons-vfs2:$commonsVfs2Version", optional implementation "org.apache.commons:commons-lang3:$commonsLangVersion" implementation("com.googlecode.json-simple:json-simple:$jsonSimpleVersion") { diff --git a/jbake-core/src/main/java/org/jbake/app/Asset.java b/jbake-core/src/main/java/org/jbake/app/Asset.java index cd9148cc0..d1c3de96d 100644 --- a/jbake-core/src/main/java/org/jbake/app/Asset.java +++ b/jbake-core/src/main/java/org/jbake/app/Asset.java @@ -1,6 +1,6 @@ package org.jbake.app; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.apache.commons.io.FileUtils; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; @@ -24,7 +24,7 @@ public class Asset { private static final Logger LOGGER = LoggerFactory.getLogger(Asset.class); private final List errors = new LinkedList<>(); - private JBakeConfiguration config; + private final JBakeConfiguration config; /** * @param source Source file for the asset diff --git a/jbake-core/src/main/java/org/jbake/app/Crawler.java b/jbake-core/src/main/java/org/jbake/app/Crawler.java index 764a3e035..1a8029822 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -1,7 +1,7 @@ package org.jbake.app; import com.orientechnologies.orient.core.record.impl.ODocument; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.apache.commons.io.FilenameUtils; import org.jbake.app.Crawler.Attributes.Status; import org.jbake.app.configuration.JBakeConfiguration; @@ -30,8 +30,8 @@ public class Crawler { private static final Logger LOGGER = LoggerFactory.getLogger(Crawler.class); private final ContentStore db; - private JBakeConfiguration config; - private Parser parser; + private final JBakeConfiguration config; + private final Parser parser; /** * @param db Database instance for content @@ -142,7 +142,7 @@ private String buildURI(final File sourceFile) { // strip off leading / to enable generating non-root based sites if (uri.startsWith(FileUtil.URI_SEPARATOR_CHAR)) { - uri = uri.substring(1, uri.length()); + uri = uri.substring(1); } return uri; diff --git a/jbake-core/src/main/java/org/jbake/app/Oven.java b/jbake-core/src/main/java/org/jbake/app/Oven.java index 07b391491..723582b36 100644 --- a/jbake-core/src/main/java/org/jbake/app/Oven.java +++ b/jbake-core/src/main/java/org/jbake/app/Oven.java @@ -1,6 +1,6 @@ package org.jbake.app; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; @@ -29,8 +29,8 @@ public class Oven { private static final Logger LOGGER = LoggerFactory.getLogger(Oven.class); - private Utensils utensils; - private List errors = new LinkedList<>(); + private final Utensils utensils; + private final List errors = new LinkedList<>(); private int renderedCount = 0; /** diff --git a/jbake-core/src/main/java/org/jbake/app/Renderer.java b/jbake-core/src/main/java/org/jbake/app/Renderer.java index abc5018ad..beb097a04 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -1,6 +1,6 @@ package org.jbake.app; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; @@ -276,7 +276,7 @@ public int renderTags(String tagPath) throws Exception { File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + tag + config.getOutputExtension()); map.put(Attributes.ROOTPATH, FileUtil.getUriPathToDestinationRoot(config, path)); - + render(new ModelRenderingConfig(path, Attributes.TAG, model, findTemplateName(Attributes.TAG))); renderedCount++; diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java index de36efc78..e426f5a4b 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java @@ -1,17 +1,18 @@ package org.jbake.app.configuration; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; +import org.apache.commons.configuration2.PropertiesConfiguration; +import org.apache.commons.configuration2.SystemConfiguration; +import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; +import org.apache.commons.configuration2.builder.fluent.Parameters; +import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler; +import org.apache.commons.configuration2.ex.ConfigurationException; import org.jbake.app.JBakeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; /** * Provides Configuration related functions. @@ -20,6 +21,8 @@ */ public class ConfigUtil { + public static final char LIST_DELIMITER = ','; + public static final String DEFAULT_ENCODING = "UTF-8"; private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); private static final String LEGACY_CONFIG_FILE = "custom.properties"; private static final String CONFIG_FILE = "jbake.properties"; @@ -34,23 +37,52 @@ private CompositeConfiguration load(File source) throws ConfigurationException { throw new JBakeException("The given source folder is not a directory."); } + File legacyConfigFile = new File(source, LEGACY_CONFIG_FILE); + File customConfigFile = new File(source, CONFIG_FILE); + CompositeConfiguration config = new CompositeConfiguration(); - config.setListDelimiter(','); - File customConfigFile = new File(source, LEGACY_CONFIG_FILE); - if (customConfigFile.exists()) { + config.setListDelimiterHandler(new DefaultListDelimiterHandler(LIST_DELIMITER)); + + if (legacyConfigFile.exists()) { displayLegacyConfigFileWarningIfRequired(); - config.addConfiguration(new PropertiesConfiguration(customConfigFile)); + config.addConfiguration(getFileBasedPropertiesConfiguration(legacyConfigFile)); } - customConfigFile = new File(source, CONFIG_FILE); if (customConfigFile.exists()) { - config.addConfiguration(new PropertiesConfiguration(customConfigFile)); + config.addConfiguration(getFileBasedPropertiesConfiguration(customConfigFile)); } URL defaultPropertiesLocation = this.getClass().getClassLoader().getResource(DEFAULT_CONFIG_FILE); - config.addConfiguration(new PropertiesConfiguration(defaultPropertiesLocation)); + if (defaultPropertiesLocation != null) { + config.addConfiguration(getFileBasedPropertiesConfiguration(defaultPropertiesLocation)); + } + config.addConfiguration(new SystemConfiguration()); return config; } + private PropertiesConfiguration getFileBasedPropertiesConfiguration(File propertiesFile) throws ConfigurationException { + FileBasedConfigurationBuilder builder = + new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class) + .configure(new Parameters().properties() + .setFile(propertiesFile) + .setEncoding(DEFAULT_ENCODING) + .setThrowExceptionOnMissing(true) + .setListDelimiterHandler(new DefaultListDelimiterHandler(LIST_DELIMITER)) + .setIncludesAllowed(false)); + return builder.getConfiguration(); + } + + private PropertiesConfiguration getFileBasedPropertiesConfiguration(URL propertiesFile) throws ConfigurationException { + FileBasedConfigurationBuilder builder = + new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class) + .configure(new Parameters().properties() + .setURL(propertiesFile) + .setEncoding(DEFAULT_ENCODING) + .setThrowExceptionOnMissing(true) + .setListDelimiterHandler(new DefaultListDelimiterHandler(LIST_DELIMITER)) + .setIncludesAllowed(false)); + return builder.getConfiguration(); + } + private void displayLegacyConfigFileWarningIfRequired() { LOGGER.warn("You have defined a part of your JBake configuration in {}", LEGACY_CONFIG_FILE); LOGGER.warn("Usage of this file is being deprecated, please rename this file to: {} to remove this warning", CONFIG_FILE); diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java index e28af05de..6110aa8a1 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java @@ -1,7 +1,7 @@ package org.jbake.app.configuration; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration2.CompositeConfiguration; +import org.apache.commons.configuration2.Configuration; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,7 +10,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; @@ -74,7 +73,7 @@ private int getAsInt(String key, int defaultValue) { } private List getAsList(String key) { - return Arrays.asList(compositeConfiguration.getStringArray(key)); + return compositeConfiguration.getList(String.class, key); } private String getAsString(String key) { @@ -90,15 +89,15 @@ public List getAsciidoctorAttributes() { return getAsList(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES); } - public Object getAsciidoctorOption(String optionKey) { + public List getAsciidoctorOption(String optionKey) { Configuration subConfig = compositeConfiguration.subset(JBakeProperty.ASCIIDOCTOR_OPTION); - Object value = subConfig.getProperty(optionKey); - if (value == null) { + if (subConfig.containsKey(optionKey)) { + return subConfig.getList(String.class, optionKey); + } else { logger.warn("Cannot find asciidoctor option '{}.{}'", JBakeProperty.ASCIIDOCTOR_OPTION, optionKey); - return ""; + return new ArrayList<>(); } - return value; } @Override @@ -477,6 +476,7 @@ public void setExampleProject(String type, String fileName) { @Override public void setProperty(String key, Object value) { + compositeConfiguration.setProperty(key, value); } diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java index 06220e5fb..97634588c 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java @@ -1,7 +1,8 @@ package org.jbake.app.configuration; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; + +import org.apache.commons.configuration2.CompositeConfiguration; +import org.apache.commons.configuration2.ex.ConfigurationException; import java.io.File; diff --git a/jbake-core/src/main/java/org/jbake/launcher/BakeWatcher.java b/jbake-core/src/main/java/org/jbake/launcher/BakeWatcher.java index b6e2df1e8..34eb992c7 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/BakeWatcher.java +++ b/jbake-core/src/main/java/org/jbake/launcher/BakeWatcher.java @@ -1,6 +1,6 @@ package org.jbake.launcher; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemManager; @@ -18,7 +18,7 @@ */ public class BakeWatcher { - private Logger logger = LoggerFactory.getLogger(BakeWatcher.class); + private final Logger logger = LoggerFactory.getLogger(BakeWatcher.class); /** * Starts watching the file system for changes to trigger a bake. diff --git a/jbake-core/src/main/java/org/jbake/launcher/Baker.java b/jbake-core/src/main/java/org/jbake/launcher/Baker.java index a1dcb373e..44dcfdafe 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Baker.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Baker.java @@ -1,6 +1,6 @@ package org.jbake.launcher; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.JBakeException; import org.jbake.app.Oven; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/launcher/Init.java b/jbake-core/src/main/java/org/jbake/launcher/Init.java index 2a62f7875..ae1dd1bca 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Init.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Init.java @@ -1,6 +1,6 @@ package org.jbake.launcher; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ZipUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; @@ -16,7 +16,7 @@ */ public class Init { - private JBakeConfiguration config; + private final JBakeConfiguration config; /** * @param config The project configuration diff --git a/jbake-core/src/main/java/org/jbake/launcher/Main.java b/jbake-core/src/main/java/org/jbake/launcher/Main.java index ff643148c..fa94beac1 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -1,6 +1,6 @@ package org.jbake.launcher; -import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration2.ex.ConfigurationException; import org.jbake.app.FileUtil; import org.jbake.app.JBakeException; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java index 8e1cab76a..ecc7835ef 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -1,7 +1,7 @@ package org.jbake.parser; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration2.CompositeConfiguration; +import org.apache.commons.configuration2.Configuration; import org.apache.commons.io.IOUtils; import org.jbake.app.Crawler; import org.jbake.app.configuration.DefaultJBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java b/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java index dcd24f5cb..4be9d49ee 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java @@ -1,6 +1,6 @@ package org.jbake.parser; -import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration2.Configuration; import org.jbake.app.configuration.JBakeConfiguration; import java.io.File; diff --git a/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java b/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java index ba6eebcb3..397fa5bf1 100644 --- a/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; @@ -33,4 +33,4 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem return render(renderer, db, configuration); } -} \ No newline at end of file +} diff --git a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java index 78a4a4760..7d81c6e9a 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Crawler.Attributes; import org.jbake.app.DocumentList; diff --git a/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java b/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java index da956df33..cd4ffcbeb 100644 --- a/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; @@ -33,4 +33,4 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem return render(renderer, db, configuration); } -} \ No newline at end of file +} diff --git a/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java b/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java index bbdb7e4ae..b5b05a870 100644 --- a/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; @@ -37,4 +37,4 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem JBakeConfiguration configuration = new JBakeConfigurationFactory().createDefaultJbakeConfiguration(templatesPath.getParentFile(), config); return render(renderer, db, configuration); } -} \ No newline at end of file +} diff --git a/jbake-core/src/main/java/org/jbake/render/RenderingTool.java b/jbake-core/src/main/java/org/jbake/render/RenderingTool.java index 3b483ec7f..3417406b8 100644 --- a/jbake-core/src/main/java/org/jbake/render/RenderingTool.java +++ b/jbake-core/src/main/java/org/jbake/render/RenderingTool.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java b/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java index 71bb5756b..3d3525fa3 100644 --- a/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; @@ -33,4 +33,4 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem return render(renderer, db, configuration); } -} \ No newline at end of file +} diff --git a/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java b/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java index 2bb1f55df..41b70bc1b 100644 --- a/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java @@ -1,6 +1,6 @@ package org.jbake.render; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; @@ -32,4 +32,4 @@ public int render(Renderer renderer, ContentStore db, File destination, File tem return render(renderer, db, configuration); } -} \ No newline at end of file +} diff --git a/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java index aaa630032..eed4d3c8f 100644 --- a/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java @@ -1,7 +1,7 @@ package org.jbake.template; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration2.CompositeConfiguration; +import org.apache.commons.configuration2.Configuration; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; diff --git a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java index a006c51ab..9ba8336e6 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -1,6 +1,6 @@ package org.jbake.template; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.FileUtil; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java index 43c1e2158..ddfb942c0 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -15,7 +15,7 @@ import freemarker.template.TemplateHashModel; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java index f46b25ce5..083f61c83 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java @@ -5,7 +5,7 @@ import groovy.text.Template; import groovy.text.markup.MarkupTemplateEngine; import groovy.text.markup.TemplateConfiguration; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java index 58a166038..16e4702f9 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java @@ -7,7 +7,7 @@ import groovy.text.Template; import groovy.text.TemplateEngine; import groovy.text.XmlTemplateEngine; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.codehaus.groovy.runtime.MethodClosure; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java index c3c48bbfa..d6ecc5452 100644 --- a/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java @@ -11,7 +11,7 @@ import de.neuland.jade4j.template.FileTemplateLoader; import de.neuland.jade4j.template.JadeTemplate; import de.neuland.jade4j.template.TemplateLoader; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.apache.commons.lang.StringEscapeUtils; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; @@ -35,7 +35,7 @@ public class JadeTemplateEngine extends AbstractTemplateEngine { private static final String FILTER_STYLE = "css"; private static final String FILTER_SCRIPT = "js"; - private JadeConfiguration jadeConfiguration = new JadeConfiguration(); + private final JadeConfiguration jadeConfiguration = new JadeConfiguration(); @Deprecated public JadeTemplateEngine(final CompositeConfiguration config, final ContentStore db, final File destination, final File templatesPath) { @@ -90,7 +90,7 @@ public Object get(final Object property) { } public static class FormatHelper { - private Map formatters = new HashMap(); + private final Map formatters = new HashMap(); public String format(Date date, String pattern) { if(date!=null && pattern!=null) { diff --git a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java index e594e143e..fd49ac0d5 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -1,6 +1,6 @@ package org.jbake.template; -import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration2.CompositeConfiguration; import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ContentStore; import org.jbake.app.Crawler.Attributes; @@ -37,7 +37,7 @@ public class ThymeleafTemplateEngine extends AbstractTemplateEngine { private static final String DEFAULT_TEMPLATE_MODE = "HTML"; private final ReentrantLock lock = new ReentrantLock(); private TemplateEngine templateEngine; - private Context context; + private final Context context; private FileTemplateResolver templateResolver; /** @@ -122,9 +122,9 @@ private void initializeContext(Locale locale, Map model) { */ private class ContextVariable extends LazyContextVariable { - private ContentStore db; - private String key; - private Map model; + private final ContentStore db; + private final String key; + private final Map model; public ContextVariable(ContentStore db, String key, Map model) { this.db = db; diff --git a/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java b/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java index f1bae096e..60e560a50 100644 --- a/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java +++ b/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java @@ -23,6 +23,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; @@ -214,9 +215,9 @@ public void shouldReturnAnAsciidoctorOption() throws Exception { config.setProperty("asciidoctor.option.requires", "asciidoctor-diagram"); config.setProperty("asciidoctor.option.template_dirs", "src/template1,src/template2"); - Object option = config.getAsciidoctorOption("requires"); + List option = config.getAsciidoctorOption("requires"); - assertThat(String.valueOf(option)).contains("asciidoctor-diagram"); + assertThat(option).contains("asciidoctor-diagram"); } @Test @@ -226,20 +227,19 @@ public void shouldReturnAnAsciidoctorOptionWithAListValue() throws Exception { config.setProperty("asciidoctor.option.requires", "asciidoctor-diagram"); config.setProperty("asciidoctor.option.template_dirs", "src/template1,src/template2"); - Object option = config.getAsciidoctorOption("template_dirs"); + List option = config.getAsciidoctorOption("template_dirs"); - assertTrue(option instanceof List); - assertThat((List) option).contains("src/template1", "src/template2"); + assertThat(option).contains("src/template1", "src/template2"); } @Test - public void shouldReturnEmptyStringIfOptionNotAvailable() throws Exception { + public void shouldReturnEmptyListIfOptionNotAvailable() throws Exception { File sourceFolder = TestUtils.getTestResourcesAsSourceFolder(); DefaultJBakeConfiguration config = (DefaultJBakeConfiguration) util.loadConfig(sourceFolder); - Object option = config.getAsciidoctorOption("template_dirs"); + List options = config.getAsciidoctorOption("template_dirs"); - assertThat(String.valueOf(option)).isEmpty(); + assertThat(options).isEmpty(); } @Test @@ -329,6 +329,14 @@ void shouldSetCustomFoldersWithAbsolutePaths() throws Exception { assertThat(contentFolder).isEqualTo(expectedContentFolder.toFile()); } + @Test + void shouldLoadPropertiesWithUtf8Encoding() throws Exception { + File source = TestUtils.getTestResourcesAsSourceFolder(); + DefaultJBakeConfiguration config = (DefaultJBakeConfiguration) util.loadConfig(source); + + assertThat((String)config.get("site.about")).contains("中文属性使用默认Properties编码"); + } + private void assertDefaultPropertiesPresent(JBakeConfiguration config) throws IllegalAccessException { for (Field field : JBakeConfiguration.class.getFields()) { diff --git a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java index 827395051..c0dc310e3 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -1,7 +1,7 @@ package org.jbake.launcher; import ch.qos.logback.classic.spi.LoggingEvent; -import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration2.ex.ConfigurationException; import org.itsallcode.junit.sysextensions.ExitGuard; import org.jbake.TestUtils; import org.jbake.app.LoggingTest; diff --git a/jbake-core/src/test/java/org/jbake/render/support/MockCompositeConfiguration.java b/jbake-core/src/test/java/org/jbake/render/support/MockCompositeConfiguration.java index 1fb6de047..4a9d62fac 100644 --- a/jbake-core/src/test/java/org/jbake/render/support/MockCompositeConfiguration.java +++ b/jbake-core/src/test/java/org/jbake/render/support/MockCompositeConfiguration.java @@ -1,6 +1,7 @@ package org.jbake.render.support; -import org.apache.commons.configuration.CompositeConfiguration; + +import org.apache.commons.configuration2.CompositeConfiguration; public class MockCompositeConfiguration extends CompositeConfiguration { diff --git a/jbake-core/src/test/resources/fixture/jbake.properties b/jbake-core/src/test/resources/fixture/jbake.properties index ef678557d..2cbcab982 100644 --- a/jbake-core/src/test/resources/fixture/jbake.properties +++ b/jbake-core/src/test/resources/fixture/jbake.properties @@ -15,4 +15,5 @@ markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS site.host=http://www.jbake.org template.feed.thymeleaf.mode=XML template.sitemap.thymeleaf.mode=XML -template.allcontent.file=allcontent.ftl \ No newline at end of file +template.allcontent.file=allcontent.ftl +site.about=中文属性使用默认Properties编码(Property value in Chinese will let property `site.about` missing due to Apache Configuration implementation.) diff --git a/jbake-core/src/test/resources/logback.xml b/jbake-core/src/test/resources/logback.xml index 715728e0a..da72518ca 100644 --- a/jbake-core/src/test/resources/logback.xml +++ b/jbake-core/src/test/resources/logback.xml @@ -12,11 +12,13 @@ + + - - \ No newline at end of file + + diff --git a/jbake-dist/src/dist/lib/logging/logback.xml b/jbake-dist/src/dist/lib/logging/logback.xml index 22cd77f5a..12cd7dc19 100644 --- a/jbake-dist/src/dist/lib/logging/logback.xml +++ b/jbake-dist/src/dist/lib/logging/logback.xml @@ -14,6 +14,9 @@ + + + From 2781ff87fc9364044a54fcc869cb5fa38d90d7e4 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 29 Apr 2020 09:15:28 +0200 Subject: [PATCH 2/4] fix appveyor build by setting jvm parameter file.encoding to UTF-8 use java.io canonical name UTF8 to set encoding set file.encoding jvm parameter --- appveyor.yml | 6 ++++-- .../main/java/org/jbake/app/configuration/ConfigUtil.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cb865ccca..ca941ed5c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,9 +15,11 @@ environment: install: - SET PATH=%JAVA_HOME%\bin;%PATH% - echo %PATH% + - systeminfo - java -version - gradlew.bat --version + - file C:\projects\jbake\jbake-core\src\test\resources\fixture\jbake.properties build_script: - - gradlew.bat -i assemble + - gradlew.bat -Dfile.encoding=UTF-8 -i assemble test_script: - - gradlew.bat -i -S check + - gradlew.bat -Dfile.encoding=UTF-8 -i -S check diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java index e426f5a4b..c8cd87fbb 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java @@ -22,7 +22,7 @@ public class ConfigUtil { public static final char LIST_DELIMITER = ','; - public static final String DEFAULT_ENCODING = "UTF-8"; + public static final String DEFAULT_ENCODING = "UTF8"; private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); private static final String LEGACY_CONFIG_FILE = "custom.properties"; private static final String CONFIG_FILE = "jbake.properties"; From 9ab23dd4d2f5872126d1182564307d4d944370e1 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 1 May 2020 12:09:08 +0200 Subject: [PATCH 3/4] add cli option --prop-encoding to configure property encoding that should be used --- .../jbake/app/configuration/ConfigUtil.java | 21 ++++++++-- .../JBakeConfigurationFactory.java | 5 +++ .../org/jbake/launcher/LaunchOptions.java | 7 ++++ .../main/java/org/jbake/launcher/Main.java | 4 +- .../app/configuration/ConfigUtilTest.java | 37 +++++++++++++----- .../JBakeConfigurationFactoryTest.java | 38 +++++++++++++++---- .../org/jbake/launcher/LaunchOptionsTest.java | 21 ++++++++++ .../java/org/jbake/launcher/MainTest.java | 32 +++++++++++++--- .../resources/fixtureLatin1/jbake.properties | 19 ++++++++++ 9 files changed, 158 insertions(+), 26 deletions(-) create mode 100644 jbake-core/src/test/resources/fixtureLatin1/jbake.properties diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java index c8cd87fbb..e0c05ce1b 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/ConfigUtil.java @@ -13,6 +13,7 @@ import java.io.File; import java.net.URL; +import java.nio.charset.Charset; /** * Provides Configuration related functions. @@ -22,11 +23,12 @@ public class ConfigUtil { public static final char LIST_DELIMITER = ','; - public static final String DEFAULT_ENCODING = "UTF8"; + public static final String DEFAULT_ENCODING = "UTF-8"; private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); private static final String LEGACY_CONFIG_FILE = "custom.properties"; private static final String CONFIG_FILE = "jbake.properties"; private static final String DEFAULT_CONFIG_FILE = "default.properties"; + private String encoding = DEFAULT_ENCODING; private CompositeConfiguration load(File source) throws ConfigurationException { @@ -64,7 +66,7 @@ private PropertiesConfiguration getFileBasedPropertiesConfiguration(File propert new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class) .configure(new Parameters().properties() .setFile(propertiesFile) - .setEncoding(DEFAULT_ENCODING) + .setEncoding(encoding) .setThrowExceptionOnMissing(true) .setListDelimiterHandler(new DefaultListDelimiterHandler(LIST_DELIMITER)) .setIncludesAllowed(false)); @@ -76,7 +78,7 @@ private PropertiesConfiguration getFileBasedPropertiesConfiguration(URL properti new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class) .configure(new Parameters().properties() .setURL(propertiesFile) - .setEncoding(DEFAULT_ENCODING) + .setEncoding(encoding) .setThrowExceptionOnMissing(true) .setListDelimiterHandler(new DefaultListDelimiterHandler(LIST_DELIMITER)) .setIncludesAllowed(false)); @@ -93,4 +95,17 @@ public JBakeConfiguration loadConfig(File source) throws ConfigurationException return new DefaultJBakeConfiguration(source, configuration); } + public String getEncoding() { + return this.encoding; + } + + public ConfigUtil setEncoding(String encoding) { + if (Charset.isSupported(encoding)) { + this.encoding = encoding; + } else { + this.encoding = DEFAULT_ENCODING; + LOGGER.warn("Unsupported encoding '{}'. Using default encoding '{}'", encoding, this.encoding); + } + return this; + } } diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java index 97634588c..64a19c4b5 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationFactory.java @@ -106,4 +106,9 @@ public ConfigUtil getConfigUtil() { public void setConfigUtil(ConfigUtil configUtil) { this.configUtil = configUtil; } + + public JBakeConfigurationFactory setEncoding(String charset) { + this.configUtil.setEncoding(charset); + return this; + } } diff --git a/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java b/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java index d30bd5865..000b41016 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java +++ b/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java @@ -30,6 +30,9 @@ public class LaunchOptions { @Option(name = "--reset", usage = "clears the local cache, enforcing rendering from scratch") private boolean clearCache; + @Option(name = "--prop-encoding", usage = "use given encoding to load properties file. default: utf-8") + private String propertiesEncoding = "utf-8"; + public String getTemplate() { if (template != null) { return template; @@ -81,4 +84,8 @@ public boolean isClearCache() { public boolean isBake() { return bake || (source != null && destination != null); } + + public String getPropertiesEncoding() { + return propertiesEncoding; + } } diff --git a/jbake-core/src/main/java/org/jbake/launcher/Main.java b/jbake-core/src/main/java/org/jbake/launcher/Main.java index fa94beac1..9c8a1babf 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -77,9 +77,9 @@ protected void run(String[] args) { try { LaunchOptions res = parseArguments(args); if (res.isRunServer()) { - config = getJBakeConfigurationFactory().createJettyJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); + config = getJBakeConfigurationFactory().setEncoding(res.getPropertiesEncoding()).createJettyJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); } else { - config = getJBakeConfigurationFactory().createDefaultJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); + config = getJBakeConfigurationFactory().setEncoding(res.getPropertiesEncoding()).createDefaultJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); } run(res, config); } catch (final ConfigurationException e) { diff --git a/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java b/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java index 60e560a50..1d3c92b00 100644 --- a/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java +++ b/jbake-core/src/test/java/org/jbake/app/configuration/ConfigUtilTest.java @@ -16,15 +16,11 @@ import java.io.FileWriter; import java.lang.reflect.Field; import java.nio.file.Files; -import java.nio.file.OpenOption; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; import java.util.List; +import static ch.qos.logback.classic.Level.WARN; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -330,13 +326,36 @@ void shouldSetCustomFoldersWithAbsolutePaths() throws Exception { } @Test - void shouldLoadPropertiesWithUtf8Encoding() throws Exception { - File source = TestUtils.getTestResourcesAsSourceFolder(); - DefaultJBakeConfiguration config = (DefaultJBakeConfiguration) util.loadConfig(source); + public void shouldUseUtf8EncodingAsDefault() throws Exception{ + String unicodeString = "中文属性使用默认Properties编码"; + JBakeConfiguration config = util.loadConfig(TestUtils.getTestResourcesAsSourceFolder()); + + String siteAbout = (String) config.get("site.about"); + assertThat(util.getEncoding()).isEqualTo("UTF-8"); + assertThat(siteAbout).inUnicode().startsWith(unicodeString); + } + + @Test + public void shouldBePossibleToSetCustomEncoding() throws Exception { + String expected = "Latin1 encoded file äöü"; + JBakeConfiguration config = util.setEncoding("ISO8859_1").loadConfig(TestUtils.getTestResourcesAsSourceFolder("/fixtureLatin1")); - assertThat((String)config.get("site.about")).contains("中文属性使用默认Properties编码"); + String siteAbout = (String) config.get("site.about"); + assertThat(siteAbout).contains(expected); } + @Test + public void shouldLogAWarningAndFallbackToUTF8IfEncodingIsNotSupported() throws Exception { + JBakeConfiguration config = util.setEncoding("UNSUPPORTED_ENCODING").loadConfig(TestUtils.getTestResourcesAsSourceFolder("/fixtureLatin1")); + verify(mockAppender, times(1)).doAppend(captorLoggingEvent.capture()); + + LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel()).isEqualTo(WARN); + assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unsupported encoding 'UNSUPPORTED_ENCODING'. Using default encoding 'UTF-8'"); + } + + private void assertDefaultPropertiesPresent(JBakeConfiguration config) throws IllegalAccessException { for (Field field : JBakeConfiguration.class.getFields()) { diff --git a/jbake-core/src/test/java/org/jbake/app/configuration/JBakeConfigurationFactoryTest.java b/jbake-core/src/test/java/org/jbake/app/configuration/JBakeConfigurationFactoryTest.java index 0fb609a19..b81b24d5f 100644 --- a/jbake-core/src/test/java/org/jbake/app/configuration/JBakeConfigurationFactoryTest.java +++ b/jbake-core/src/test/java/org/jbake/app/configuration/JBakeConfigurationFactoryTest.java @@ -8,11 +8,14 @@ import java.io.File; import java.io.FileWriter; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; public class JBakeConfigurationFactoryTest { - @TempDir File root; + @TempDir + File root; @Test public void shouldReturnDefaultConfigurationWithDefaultFolders() throws Exception { @@ -33,7 +36,7 @@ public void shouldReturnDefaultConfigurationWithDefaultFolders() throws Exceptio @Test public void shouldReturnDefaultConfigurationWithCustomFolders() throws Exception { File sourceFolder = root; - File destinationFolder = TestUtils.newFolder(root,"output/custom"); + File destinationFolder = TestUtils.newFolder(root, "output/custom"); File templateFolder = TestUtils.newFolder(root, "templates/custom"); File assetFolder = TestUtils.newFolder(root, "assets/custom"); File contentFolder = TestUtils.newFolder(root, "content/custom"); @@ -63,12 +66,10 @@ public void shouldReturnDefaultConfigurationWithCustomFolders() throws Exception } - - @Test public void shouldReturnADefaultConfigurationWithSitehost() throws Exception { File sourceFolder = root; - File destinationFolder = TestUtils.newFolder(root,"output"); + File destinationFolder = TestUtils.newFolder(root, "output"); String siteHost = "http://www.jbake.org"; JBakeConfiguration configuration = new JBakeConfigurationFactory().createDefaultJbakeConfiguration(sourceFolder, destinationFolder, true); @@ -79,7 +80,7 @@ public void shouldReturnADefaultConfigurationWithSitehost() throws Exception { @Test public void shouldReturnAJettyConfiguration() throws Exception { File sourceFolder = root; - File destinationFolder = TestUtils.newFolder(root,"output"); + File destinationFolder = TestUtils.newFolder(root, "output"); String siteHost = "http://localhost:8820/"; JBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder, destinationFolder, true); @@ -87,4 +88,27 @@ public void shouldReturnAJettyConfiguration() throws Exception { assertThat(configuration.getSiteHost()).isEqualTo(siteHost); } + @Test + public void shouldUseDefaultEncodingUTF8() throws Exception { + File sourceFolder = root; + File destinationFolder = TestUtils.newFolder(root, "output"); + JBakeConfigurationFactory factory = new JBakeConfigurationFactory(); + JBakeConfiguration configuration = factory.createDefaultJbakeConfiguration(sourceFolder, destinationFolder, true); + + assertThat(factory.getConfigUtil().getEncoding()).isEqualTo("UTF-8"); + } + + @Test + public void shouldUseCustomEncoding() throws Exception { + + ConfigUtil util = spy(ConfigUtil.class); + File sourceFolder = root; + File destinationFolder = TestUtils.newFolder(root, "output"); + JBakeConfigurationFactory factory = new JBakeConfigurationFactory(); + factory.setConfigUtil(util); + JBakeConfiguration configuration = factory.setEncoding("latin1").createDefaultJbakeConfiguration(sourceFolder, destinationFolder, true); + + assertThat(factory.getConfigUtil().getEncoding()).isEqualTo("latin1"); + verify(util).loadConfig(sourceFolder); + } } diff --git a/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java b/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java index 78d8060f4..fbb9cb1b3 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java @@ -95,6 +95,27 @@ public void bake() throws Exception { assertThat(res.isBake()).isTrue(); } + @Test + public void customPropertiesEncoding() throws Exception { + String[] args = {"--prop-encoding", "utf-16"}; + LaunchOptions res = new LaunchOptions(); + CmdLineParser parser = new CmdLineParser(res); + parser.parseArgument(args); + + assertThat(res.getPropertiesEncoding()).isEqualTo("utf-16"); + } + + @Test + public void defaultEncodingIsUtf8() throws Exception { + String[] args = {}; + LaunchOptions res = new LaunchOptions(); + CmdLineParser parser = new CmdLineParser(res); + parser.parseArgument(args); + + assertThat(res.getPropertiesEncoding()).isEqualTo("utf-8"); + } + + @Test public void bakeNoArgs() throws Exception { String[] args = {}; diff --git a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java index c0dc310e3..a2ac2ca12 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -69,6 +69,28 @@ public void launchJetty(@TempDir Path source) throws Exception { verify(mockJetty).run(expectedOutput.getPath(),configuration); } + @Test + public void launchBakeWithCustomPropertiesEncoding(@TempDir Path source) throws Exception { + File currentWorkingdir = newFolder(source, "jbake"); + mockDefaultJbakeConfiguration(currentWorkingdir); + + String[] args = {"-b", "--prop-encoding", "latin1"}; + main.run(args); + + verify(factory).setEncoding("latin1"); + } + + @Test + public void launchBakeWithDefaultUtf8PropertiesEncoding(@TempDir Path source) throws Exception { + File currentWorkingdir = newFolder(source, "jbake"); + mockDefaultJbakeConfiguration(currentWorkingdir); + + String[] args = {"-b"}; + main.run(args); + + verify(factory).setEncoding("utf-8"); + } + @Test public void launchBakeAndJetty(@TempDir Path source) throws Exception { File sourceFolder = newFolder(source, "src/jbake"); @@ -83,7 +105,7 @@ public void launchBakeAndJetty(@TempDir Path source) throws Exception { @Test - public void launchBakeAndJettyWithCustomDirForJetty(@TempDir Path source) throws ConfigurationException, IOException { + public void launchBakeAndJettyWithCustomDirForJetty(@TempDir Path source) throws ConfigurationException { File sourceFolder = newFolder(source,"src/jbake"); String expectedRunPath = "src" + File.separator + "jbake" + File.separator + "output"; File output = newFolder(source,expectedRunPath); @@ -159,7 +181,7 @@ public void launchJettyWithCmdlineOverridingProperties(@TempDir Path source, @Te } @Test - public void shouldTellUserThatTemplateOptionRequiresInitOption() throws Exception { + public void shouldTellUserThatTemplateOptionRequiresInitOption() { String[] args = {"-t", "groovy-mte"}; @@ -188,14 +210,14 @@ private DefaultJBakeConfiguration stubConfig() throws ConfigurationException { private void mockDefaultJbakeConfiguration(File sourceFolder) throws ConfigurationException { DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder,null,false); System.setProperty("user.dir", sourceFolder.getPath()); - - when(factory.createJettyJbakeConfiguration(any(File.class),any(File.class),anyBoolean())).thenReturn( configuration ); + when(factory.setEncoding(any())).thenReturn(factory); + when(factory.createDefaultJbakeConfiguration(any(File.class),any(File.class),anyBoolean())).thenReturn( configuration ); } private JBakeConfiguration mockJettyConfiguration(File sourceFolder, File destinationFolder) throws ConfigurationException { DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder,destinationFolder,false); System.setProperty("user.dir", sourceFolder.getPath()); - + when(factory.setEncoding(any())).thenReturn(factory); when(factory.createJettyJbakeConfiguration(any(File.class),any(File.class),anyBoolean())).thenReturn( configuration ); return configuration; } diff --git a/jbake-core/src/test/resources/fixtureLatin1/jbake.properties b/jbake-core/src/test/resources/fixtureLatin1/jbake.properties new file mode 100644 index 000000000..3a4908f48 --- /dev/null +++ b/jbake-core/src/test/resources/fixtureLatin1/jbake.properties @@ -0,0 +1,19 @@ +template.folder=templates +content.folder=content +asset.folder=assets +render.index=true +index.file=index.html +render.feed=true +feed.file=feed.xml +render.archive=true +render.encoding=UTF-8 +archive.file=archive.html +render.tags=false +tag.path=tags +test.property=testing123 +markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS +site.host=http://www.jbake.org +template.feed.thymeleaf.mode=XML +template.sitemap.thymeleaf.mode=XML +template.allcontent.file=allcontent.ftl +site.about=Latin1 encoded file From 4d32d3842f0b47460c5f7e16ce8155dbad885000 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 2 May 2020 08:25:43 +0200 Subject: [PATCH 4/4] return empty immutable list if option attribute could not be found --- .../org/jbake/app/configuration/DefaultJBakeConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java index 6110aa8a1..be083cd2d 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java @@ -10,6 +10,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; @@ -96,7 +97,7 @@ public List getAsciidoctorOption(String optionKey) { return subConfig.getList(String.class, optionKey); } else { logger.warn("Cannot find asciidoctor option '{}.{}'", JBakeProperty.ASCIIDOCTOR_OPTION, optionKey); - return new ArrayList<>(); + return Collections.emptyList(); } }