From 1911ffa05445b661fa0e55ea21a9fb0ea8a90ab0 Mon Sep 17 00:00:00 2001 From: rustamzh Date: Tue, 13 Feb 2018 13:33:05 +0600 Subject: [PATCH 01/27] add test on locale check --- .../src/main/java/org/jbake/launcher/Main.java | 18 +++++++++++++++++- .../test/java/org/jbake/launcher/MainTest.java | 17 +++++++++++++++++ .../test/resources/fixture/jbake.properties | 4 +++- 3 files changed, 37 insertions(+), 2 deletions(-) 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 001d2c76f..40bfe5ddb 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -14,6 +14,8 @@ import java.io.StringWriter; import java.text.MessageFormat; import java.util.List; +import java.util.Locale; +import java.util.NoSuchElementException; /** * Launcher for JBake. @@ -91,7 +93,7 @@ protected void run(LaunchOptions res, CompositeConfiguration config) { // Help was requested, so we are done here return; } - + setupLocale(config); if (res.isBake()) { ConfigUtil.displayLegacyConfigFileWarningIfRequired(); baker.bake(res, config); @@ -177,4 +179,18 @@ private void initStructure(CompositeConfiguration config, String type, String so } } + private void setupLocale(CompositeConfiguration config){ + String language; + String country; + try { + language = config.getString("jvm.language"); + country = config.getString("jvm.country"); + } catch (NoSuchElementException e) { + language = "en"; + country = "US"; + } + Locale newLocale = new Locale(language, country); + Locale.setDefault(newLocale); + } + } 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 1a448e888..723162edf 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -1,6 +1,9 @@ package org.jbake.launcher; import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; +import org.assertj.core.api.Assertions; +import org.jbake.app.ConfigUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,8 +14,10 @@ import java.io.File; import java.util.HashMap; +import java.util.Locale; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; @RunWith( MockitoJUnitRunner.class ) @@ -119,6 +124,18 @@ public void launchJettyWithCmdlineOverridingProperties() throws CmdLineException verify(mockJetty).run(buildPath,"8820"); } + @Test + public void localeConfiguration() throws Exception { + CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); + String language = config.getString("jvm.language"); + String country = config.getString("jvm.country"); + + String[] args = {"-s"}; + main.run(stubOptions(args), config); + + assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language, country), "language", "country"); + } + private LaunchOptions stubOptions(String[] args) throws CmdLineException { LaunchOptions res = new LaunchOptions(); CmdLineParser parser = new CmdLineParser(res); diff --git a/jbake-core/src/test/resources/fixture/jbake.properties b/jbake-core/src/test/resources/fixture/jbake.properties index ef678557d..84452e4d6 100644 --- a/jbake-core/src/test/resources/fixture/jbake.properties +++ b/jbake-core/src/test/resources/fixture/jbake.properties @@ -15,4 +15,6 @@ 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 +jvm.language=fr +jvm.country=Fr \ No newline at end of file From fadb09654e51d73ceba224aa1bb9a903770f721d Mon Sep 17 00:00:00 2001 From: rustamzh Date: Thu, 8 Mar 2018 22:53:15 +0600 Subject: [PATCH 02/27] implement setupLocale method --- .../src/main/java/org/jbake/launcher/Main.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) 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 40bfe5ddb..234cf1445 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -180,17 +180,11 @@ private void initStructure(CompositeConfiguration config, String type, String so } private void setupLocale(CompositeConfiguration config){ - String language; - String country; - try { - language = config.getString("jvm.language"); - country = config.getString("jvm.country"); - } catch (NoSuchElementException e) { - language = "en"; - country = "US"; + if (config.containsKey("jvm.language") && config.containsKey("jvm.country")){ + String language = config.getString("jvm.language"); + String country = config.getString("jvm.country"); + Locale newLocale = new Locale(language, country); + Locale.setDefault(newLocale); } - Locale newLocale = new Locale(language, country); - Locale.setDefault(newLocale); } - } From 3e72a6bb16b369d2d0c5f0d5cdeffce99e60f7cb Mon Sep 17 00:00:00 2001 From: rustamzh Date: Fri, 9 Mar 2018 03:11:58 +0600 Subject: [PATCH 03/27] keep up with upstream --- jbake-core/src/main/java/org/jbake/launcher/Main.java | 3 --- jbake-core/src/test/java/org/jbake/launcher/MainTest.java | 2 -- 2 files changed, 5 deletions(-) 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 234cf1445..fc5494567 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -12,10 +12,7 @@ import java.io.File; import java.io.StringWriter; -import java.text.MessageFormat; -import java.util.List; import java.util.Locale; -import java.util.NoSuchElementException; /** * Launcher for JBake. 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 723162edf..b4a736581 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -1,8 +1,6 @@ package org.jbake.launcher; import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.ConfigurationException; -import org.assertj.core.api.Assertions; import org.jbake.app.ConfigUtil; import org.junit.Before; import org.junit.Test; From cd317bcf188f78d60886a536e84c34bf7b202acc Mon Sep 17 00:00:00 2001 From: rustamzh Date: Mon, 12 Mar 2018 02:51:55 +0600 Subject: [PATCH 04/27] revise implementation --- .../src/main/java/org/jbake/app/ConfigUtil.java | 2 ++ .../src/main/java/org/jbake/launcher/Main.java | 10 ++++------ .../test/java/org/jbake/launcher/MainTest.java | 17 ++++++++++++++--- .../src/test/resources/fixture/jbake.properties | 3 +-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java b/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java index 712726500..fcdde3cd6 100644 --- a/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java @@ -216,6 +216,8 @@ public interface Keys { * The configured base URI for the hosted content */ String SITE_HOST = "site.host"; + + String JVM_LOCALE = "jvm.locale"; } private final static Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); 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 fc5494567..6279b11ee 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -2,6 +2,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ConfigUtil; import org.jbake.app.ConfigUtil.Keys; import org.jbake.app.FileUtil; @@ -177,11 +178,8 @@ private void initStructure(CompositeConfiguration config, String type, String so } private void setupLocale(CompositeConfiguration config){ - if (config.containsKey("jvm.language") && config.containsKey("jvm.country")){ - String language = config.getString("jvm.language"); - String country = config.getString("jvm.country"); - Locale newLocale = new Locale(language, country); - Locale.setDefault(newLocale); - } + String localeString = config.getString(Keys.JVM_LOCALE); + Locale locale = localeString != null ? LocaleUtils.toLocale(localeString) : Locale.getDefault(); + Locale.setDefault(locale); } } 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 b4a736581..efbdf4fb4 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -125,13 +125,24 @@ public void launchJettyWithCmdlineOverridingProperties() throws CmdLineException @Test public void localeConfiguration() throws Exception { CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); - String language = config.getString("jvm.language"); - String country = config.getString("jvm.country"); + String language = config.getString(ConfigUtil.Keys.JVM_LOCALE); String[] args = {"-s"}; main.run(stubOptions(args), config); - assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language, country), "language", "country"); + assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language), "language"); + } + + @Test + public void noLocaleConfiguration() throws Exception { + CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); + config.clearProperty(ConfigUtil.Keys.JVM_LOCALE); + + String[] args = {"-s"}; + String language = Locale.getDefault().getLanguage(); + main.run(stubOptions(args), config); + + assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language), "language"); } private LaunchOptions stubOptions(String[] args) throws CmdLineException { diff --git a/jbake-core/src/test/resources/fixture/jbake.properties b/jbake-core/src/test/resources/fixture/jbake.properties index 84452e4d6..32c3f4a76 100644 --- a/jbake-core/src/test/resources/fixture/jbake.properties +++ b/jbake-core/src/test/resources/fixture/jbake.properties @@ -16,5 +16,4 @@ site.host=http://www.jbake.org template.feed.thymeleaf.mode=XML template.sitemap.thymeleaf.mode=XML template.allcontent.file=allcontent.ftl -jvm.language=fr -jvm.country=Fr \ No newline at end of file +jvm.locale=fr \ No newline at end of file From e81e81ab95b8acb0888985010a33ee529581b0d9 Mon Sep 17 00:00:00 2001 From: rustamzh Date: Mon, 12 Mar 2018 03:13:24 +0600 Subject: [PATCH 05/27] move setupLocale to class Oven --- .../src/main/java/org/jbake/app/Oven.java | 7 ++++ .../main/java/org/jbake/launcher/Main.java | 9 +---- .../src/test/java/org/jbake/app/OvenTest.java | 37 ++++++++++++++++--- .../java/org/jbake/launcher/MainTest.java | 26 ------------- 4 files changed, 39 insertions(+), 40 deletions(-) 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 c62de212d..d5400d78d 100644 --- a/jbake-core/src/main/java/org/jbake/app/Oven.java +++ b/jbake-core/src/main/java/org/jbake/app/Oven.java @@ -3,6 +3,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ConfigUtil.Keys; import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentTypes; @@ -130,6 +131,7 @@ private File setupRequiredFolderFromConfig(final String key) { */ public void bake() { final ContentStore db = DBUtil.createDataStore(config.getString(Keys.DB_STORE), config.getString(Keys.DB_PATH)); + setupLocale(config); updateDocTypesFromConfiguration(); DBUtil.updateSchema(db); try { @@ -242,4 +244,9 @@ public List getErrors() { return new ArrayList(errors); } + private void setupLocale(CompositeConfiguration config){ + String localeString = config.getString(Keys.JVM_LOCALE); + Locale locale = localeString != null ? LocaleUtils.toLocale(localeString) : Locale.getDefault(); + Locale.setDefault(locale); + } } 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 6279b11ee..05fa6577e 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -2,7 +2,6 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ConfigUtil; import org.jbake.app.ConfigUtil.Keys; import org.jbake.app.FileUtil; @@ -13,7 +12,6 @@ import java.io.File; import java.io.StringWriter; -import java.util.Locale; /** * Launcher for JBake. @@ -91,7 +89,7 @@ protected void run(LaunchOptions res, CompositeConfiguration config) { // Help was requested, so we are done here return; } - setupLocale(config); + if (res.isBake()) { ConfigUtil.displayLegacyConfigFileWarningIfRequired(); baker.bake(res, config); @@ -177,9 +175,4 @@ private void initStructure(CompositeConfiguration config, String type, String so } } - private void setupLocale(CompositeConfiguration config){ - String localeString = config.getString(Keys.JVM_LOCALE); - Locale locale = localeString != null ? LocaleUtils.toLocale(localeString) : Locale.getDefault(); - Locale.setDefault(locale); - } } diff --git a/jbake-core/src/test/java/org/jbake/app/OvenTest.java b/jbake-core/src/test/java/org/jbake/app/OvenTest.java index e3da3e542..826efee25 100644 --- a/jbake-core/src/test/java/org/jbake/app/OvenTest.java +++ b/jbake-core/src/test/java/org/jbake/app/OvenTest.java @@ -1,11 +1,5 @@ package org.jbake.app; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.io.File; -import java.io.IOException; -import java.net.URL; - import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; @@ -16,6 +10,14 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Locale; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + public class OvenTest { @Rule @@ -61,6 +63,29 @@ public void bakeWithAbsolutePaths() throws IOException, ConfigurationException { assertThat("There shouldn't be any errors: " + oven.getErrors(), oven.getErrors().isEmpty()); } + @Test + public void localeConfiguration() throws Exception { + String language = config.getString(ConfigUtil.Keys.JVM_LOCALE); + + final Oven oven = new Oven(rootPath, outputPath, config, true); + oven.setupPaths(); + oven.bake(); + + assertThat(Locale.getDefault(), is(new Locale(language))); + } + + @Test + public void noLocaleConfiguration() throws Exception { + config.clearProperty(ConfigUtil.Keys.JVM_LOCALE); + + String language = Locale.getDefault().getLanguage(); + final Oven oven = new Oven(rootPath, outputPath, config, true); + oven.setupPaths(); + oven.bake(); + + assertThat(Locale.getDefault(), is(new Locale(language))); + } + private void makeAbsolute(Configuration configuration, File source, String key) { final File folder = new File(source, configuration.getString(key)); configuration.setProperty(key, folder.getAbsolutePath()); 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 efbdf4fb4..1a448e888 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,6 @@ package org.jbake.launcher; import org.apache.commons.configuration.CompositeConfiguration; -import org.jbake.app.ConfigUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -12,10 +11,8 @@ import java.io.File; import java.util.HashMap; -import java.util.Locale; import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; @RunWith( MockitoJUnitRunner.class ) @@ -122,29 +119,6 @@ public void launchJettyWithCmdlineOverridingProperties() throws CmdLineException verify(mockJetty).run(buildPath,"8820"); } - @Test - public void localeConfiguration() throws Exception { - CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); - String language = config.getString(ConfigUtil.Keys.JVM_LOCALE); - - String[] args = {"-s"}; - main.run(stubOptions(args), config); - - assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language), "language"); - } - - @Test - public void noLocaleConfiguration() throws Exception { - CompositeConfiguration config = ConfigUtil.load(new File(this.getClass().getResource("/fixture").getFile())); - config.clearProperty(ConfigUtil.Keys.JVM_LOCALE); - - String[] args = {"-s"}; - String language = Locale.getDefault().getLanguage(); - main.run(stubOptions(args), config); - - assertThat(Locale.getDefault()).isEqualToComparingOnlyGivenFields(new Locale(language), "language"); - } - private LaunchOptions stubOptions(String[] args) throws CmdLineException { LaunchOptions res = new LaunchOptions(); CmdLineParser parser = new CmdLineParser(res); From 9a6e41c165185c90670b5c04692cfc0fcbbf8c0c Mon Sep 17 00:00:00 2001 From: rustamzh Date: Sun, 15 Apr 2018 14:04:08 +0600 Subject: [PATCH 06/27] fix #365 issue: add default 404 file generation --- .../main/java/org/jbake/app/ConfigUtil.java | 8 ++ .../src/main/java/org/jbake/app/Renderer.java | 10 +++ .../org/jbake/render/Error404Renderer.java | 27 ++++++ .../services/org.jbake.render.RenderingTool | 3 +- .../src/main/resources/default.properties | 6 ++ .../jbake/render/Error404RendererTest.java | 90 +++++++++++++++++++ .../fixture/freemarkerTemplates/error404.ftl | 8 ++ .../groovyMarkupTemplates/error404.tpl | 7 ++ .../fixture/groovyTemplates/error404.gsp | 4 + .../fixture/jadeTemplates/error404.jade | 5 ++ .../test/resources/fixture/jbake.properties | 1 + .../fixture/thymeleafTemplates/error404.thyme | 13 +++ 12 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 jbake-core/src/main/java/org/jbake/render/Error404Renderer.java create mode 100644 jbake-core/src/test/java/org/jbake/render/Error404RendererTest.java create mode 100644 jbake-core/src/test/resources/fixture/freemarkerTemplates/error404.ftl create mode 100644 jbake-core/src/test/resources/fixture/groovyMarkupTemplates/error404.tpl create mode 100644 jbake-core/src/test/resources/fixture/groovyTemplates/error404.gsp create mode 100644 jbake-core/src/test/resources/fixture/jadeTemplates/error404.jade create mode 100644 jbake-core/src/test/resources/fixture/thymeleafTemplates/error404.thyme diff --git a/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java b/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java index 8ae065bcc..03a4ff70d 100644 --- a/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/ConfigUtil.java @@ -101,6 +101,10 @@ public interface Keys { * Output filename for index, is only used when {@link #RENDER_INDEX} is true */ String INDEX_FILE = "index.file"; + /** + * Output filename for error 404 file, is only used when {@link #RENDER_ERROR404} is true + */ + String ERROR404_FILE = "error404.file"; /** * File extension to be used for all output files */ @@ -133,6 +137,10 @@ public interface Keys { * Flag indicating if tag index file should be generated */ String RENDER_TAGS_INDEX = "render.tagsindex"; + /** + * Flag indicating if error 404 file should be generated + */ + String RENDER_ERROR404= "render.error404"; /** * String used to separate the header from the body. */ 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 4f89f98d0..77e3378d9 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -324,6 +324,16 @@ public void renderArchive(String archiveFile) throws Exception { render(new DefaultRenderingConfig(archiveFile, "archive")); } + /** + * Render an 404 file using the predefined template. + * + * @param errorFile The name of the output file + * @throws Exception if default rendering configuration is not loaded correctly + */ + public void renderError404(String errorFile) throws Exception { + render(new DefaultRenderingConfig(errorFile, "error404")); + } + /** * Render tag files using the supplied content. * diff --git a/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java b/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java new file mode 100644 index 000000000..44e09b1b2 --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java @@ -0,0 +1,27 @@ +package org.jbake.render; + +import java.io.File; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.jbake.app.ConfigUtil.Keys; +import org.jbake.app.ContentStore; +import org.jbake.app.Renderer; +import org.jbake.template.RenderingException; + + +public class Error404Renderer implements RenderingTool { + + @Override + public int render(Renderer renderer, ContentStore db, File destination, File templatesPath, CompositeConfiguration config) throws RenderingException { + if (config.getBoolean(Keys.RENDER_ERROR404)) { + try { + renderer.renderError404(config.getString(Keys.ERROR404_FILE)); + return 1; + } catch (Exception e) { + throw new RenderingException(e); + } + } else { + return 0; + } + } +} diff --git a/jbake-core/src/main/resources/META-INF/services/org.jbake.render.RenderingTool b/jbake-core/src/main/resources/META-INF/services/org.jbake.render.RenderingTool index ff03c55c7..59a5fa822 100644 --- a/jbake-core/src/main/resources/META-INF/services/org.jbake.render.RenderingTool +++ b/jbake-core/src/main/resources/META-INF/services/org.jbake.render.RenderingTool @@ -3,4 +3,5 @@ org.jbake.render.DocumentsRenderer org.jbake.render.FeedRenderer org.jbake.render.IndexRenderer org.jbake.render.SitemapRenderer -org.jbake.render.TagsRenderer \ No newline at end of file +org.jbake.render.TagsRenderer +org.jbake.render.Error404Renderer \ No newline at end of file diff --git a/jbake-core/src/main/resources/default.properties b/jbake-core/src/main/resources/default.properties index 01a45d96f..95074bd44 100644 --- a/jbake-core/src/main/resources/default.properties +++ b/jbake-core/src/main/resources/default.properties @@ -10,6 +10,8 @@ template.folder=templates template.masterindex.file=index.ftl # filename of feed template file template.feed.file=feed.ftl +# filename of 404 error template file +template.error404.file=error404.ftl # filename of archive template file template.archive.file=archive.ftl # filename of tag template file @@ -32,6 +34,8 @@ render.index=true index.file=index.html # render feed file? render.feed=true +#render 404 page? +render.error404=true # character encoding MIME name used for rendering. # use one of http://www.iana.org/assignments/character-sets/character-sets.xhtml render.encoding=UTF-8 @@ -40,6 +44,8 @@ render.encoding=UTF-8 template.encoding=UTF-8 # filename to use for feed feed.file=feed.xml +# filename to use for 404 error +error404.file=404.html # render archive file? render.archive=true # filename to use for archive file diff --git a/jbake-core/src/test/java/org/jbake/render/Error404RendererTest.java b/jbake-core/src/test/java/org/jbake/render/Error404RendererTest.java new file mode 100644 index 000000000..b3cec8165 --- /dev/null +++ b/jbake-core/src/test/java/org/jbake/render/Error404RendererTest.java @@ -0,0 +1,90 @@ +package org.jbake.render; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.jbake.app.ContentStore; +import org.jbake.app.Renderer; +import org.jbake.render.support.MockCompositeConfiguration; +import org.jbake.template.RenderingException; +import org.junit.Test; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.never; + +public class Error404RendererTest { + @Test + public void returnsZeroWhenConfigDoesNotRenderError404() throws RenderingException { + Error404Renderer renderer = new Error404Renderer(); + + CompositeConfiguration compositeConfiguration = new MockCompositeConfiguration().withDefaultBoolean(false); + ContentStore contentStore = mock(ContentStore.class); + + Renderer mockRenderer = mock(Renderer.class); + int renderResponse = renderer.render(mockRenderer, contentStore, + new File("fake"), new File("fake"), compositeConfiguration); + + assertThat(renderResponse).isEqualTo(0); + } + + @Test + public void doesNotRenderWhenConfigDoesNotRenderError404() throws Exception { + Error404Renderer renderer = new Error404Renderer(); + + CompositeConfiguration compositeConfiguration = new MockCompositeConfiguration().withDefaultBoolean(false); + ContentStore contentStore = mock(ContentStore.class); + Renderer mockRenderer = mock(Renderer.class); + + int renderResponse = renderer.render(mockRenderer, contentStore, + new File("fake"), new File("fake"), compositeConfiguration); + + verify(mockRenderer, never()).renderError404(anyString()); + } + + @Test + public void returnsOneWhenConfigRendersError404() throws RenderingException { + Error404Renderer renderer = new Error404Renderer(); + + CompositeConfiguration compositeConfiguration = new MockCompositeConfiguration().withDefaultBoolean(true); + ContentStore contentStore = mock(ContentStore.class); + + Renderer mockRenderer = mock(Renderer.class); + + int renderResponse = renderer.render(mockRenderer, contentStore, + new File("fake"), new File("fake"), compositeConfiguration); + + assertThat(renderResponse).isEqualTo(1); + } + + @Test + public void doesRenderWhenConfigDoesNotRenderError404() throws Exception { + Error404Renderer renderer = new Error404Renderer(); + + CompositeConfiguration compositeConfiguration = new MockCompositeConfiguration().withDefaultBoolean(true); + ContentStore contentStore = mock(ContentStore.class); + Renderer mockRenderer = mock(Renderer.class); + + int renderResponse = renderer.render(mockRenderer, contentStore, + new File("fake"), new File("fake"), compositeConfiguration); + + verify(mockRenderer, times(1)).renderError404("random string"); + } + + @Test(expected = RenderingException.class) + public void propogatesRenderingException() throws Exception { + Error404Renderer renderer = new Error404Renderer(); + + CompositeConfiguration compositeConfiguration = new MockCompositeConfiguration().withDefaultBoolean(true); + ContentStore contentStore = mock(ContentStore.class); + Renderer mockRenderer = mock(Renderer.class); + + doThrow(new Exception()).when(mockRenderer).renderError404(anyString()); + + int renderResponse = renderer.render(mockRenderer, contentStore, + new File("fake"), new File("fake"), compositeConfiguration); + + verify(mockRenderer, never()).renderError404("random string"); + } +} diff --git a/jbake-core/src/test/resources/fixture/freemarkerTemplates/error404.ftl b/jbake-core/src/test/resources/fixture/freemarkerTemplates/error404.ftl new file mode 100644 index 000000000..9fc79bae0 --- /dev/null +++ b/jbake-core/src/test/resources/fixture/freemarkerTemplates/error404.ftl @@ -0,0 +1,8 @@ +<#include "header.ftl"> + + <#include "menu.ftl"> + +

404 Not found

+

The requested page is not found.

+ +<#include "footer.ftl"> \ No newline at end of file diff --git a/jbake-core/src/test/resources/fixture/groovyMarkupTemplates/error404.tpl b/jbake-core/src/test/resources/fixture/groovyMarkupTemplates/error404.tpl new file mode 100644 index 000000000..b8af2e0a0 --- /dev/null +++ b/jbake-core/src/test/resources/fixture/groovyMarkupTemplates/error404.tpl @@ -0,0 +1,7 @@ +package fixture.groovyMarkupTemplates + +layout 'layout/main.tpl', + bodyContents: contents { + h1('404 Not found') + h2('The requested page is not found.') + } diff --git a/jbake-core/src/test/resources/fixture/groovyTemplates/error404.gsp b/jbake-core/src/test/resources/fixture/groovyTemplates/error404.gsp new file mode 100644 index 000000000..dc788c174 --- /dev/null +++ b/jbake-core/src/test/resources/fixture/groovyTemplates/error404.gsp @@ -0,0 +1,4 @@ +%include "header.gsp"%> +

404 Not found

+

The requested page is not found.

+<%include "footer.gsp"%> \ No newline at end of file diff --git a/jbake-core/src/test/resources/fixture/jadeTemplates/error404.jade b/jbake-core/src/test/resources/fixture/jadeTemplates/error404.jade new file mode 100644 index 000000000..133ba0107 --- /dev/null +++ b/jbake-core/src/test/resources/fixture/jadeTemplates/error404.jade @@ -0,0 +1,5 @@ +extends layout.jade + +block content + h1 404 Not found + h2 The requested page is not found. \ No newline at end of file diff --git a/jbake-core/src/test/resources/fixture/jbake.properties b/jbake-core/src/test/resources/fixture/jbake.properties index ef678557d..a316aa78b 100644 --- a/jbake-core/src/test/resources/fixture/jbake.properties +++ b/jbake-core/src/test/resources/fixture/jbake.properties @@ -4,6 +4,7 @@ asset.folder=assets render.index=true index.file=index.html render.feed=true +render.error404=true feed.file=feed.xml render.archive=true render.encoding=UTF-8 diff --git a/jbake-core/src/test/resources/fixture/thymeleafTemplates/error404.thyme b/jbake-core/src/test/resources/fixture/thymeleafTemplates/error404.thyme new file mode 100644 index 000000000..7173f8c78 --- /dev/null +++ b/jbake-core/src/test/resources/fixture/thymeleafTemplates/error404.thyme @@ -0,0 +1,13 @@ + + + + + +
+ +

404 Not found

+

The requested page is not found.

+
+ + \ No newline at end of file From fa50386f22089f4c624e214eaf8fff8b3f970d0b Mon Sep 17 00:00:00 2001 From: rustamzh Date: Mon, 16 Apr 2018 00:11:12 +0600 Subject: [PATCH 07/27] make error 404 non-default option --- jbake-core/src/main/resources/default.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jbake-core/src/main/resources/default.properties b/jbake-core/src/main/resources/default.properties index 95074bd44..9ed5b926e 100644 --- a/jbake-core/src/main/resources/default.properties +++ b/jbake-core/src/main/resources/default.properties @@ -35,7 +35,7 @@ index.file=index.html # render feed file? render.feed=true #render 404 page? -render.error404=true +render.error404=false # character encoding MIME name used for rendering. # use one of http://www.iana.org/assignments/character-sets/character-sets.xhtml render.encoding=UTF-8 From b7e65b3eb0ff0b7c5d9f633827f8c0fe14e20c04 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 25 Nov 2018 20:46:08 +0100 Subject: [PATCH 08/27] implemented ConfigurationPrinter to print configuration to a PrintStream --- .../DefaultJBakeConfiguration.java | 162 +++++---- .../app/configuration/JBakeConfiguration.java | 2 + .../JBakeConfigurationInspector.java | 7 +- .../app/configuration/JBakeProperty.java | 54 --- .../org/jbake/app/configuration/Property.java | 69 ++++ .../jbake/app/configuration/PropertyList.java | 326 ++++++++++++++++++ .../template/DelegatingTemplateEngine.java | 5 +- .../jbake/template/model/TagsExtractor.java | 8 +- .../org/jbake/util/ConfigurationPrinter.java | 64 ++++ .../org/jbake/app/AsciidocParserTest.java | 7 +- .../src/test/java/org/jbake/app/OvenTest.java | 11 +- .../test/java/org/jbake/app/ParserTest.java | 5 +- .../app/configuration/ConfigUtilTest.java | 7 +- .../app/configuration/PropertyListTest.java | 26 ++ .../jbake/util/ConfigurationPrinterTest.java | 47 +++ 15 files changed, 652 insertions(+), 148 deletions(-) delete mode 100644 jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java create mode 100644 jbake-core/src/main/java/org/jbake/app/configuration/Property.java create mode 100644 jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java create mode 100644 jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java create mode 100644 jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java create mode 100644 jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java 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..a08c4693f 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 @@ -2,20 +2,22 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.SystemConfiguration; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static org.jbake.app.configuration.PropertyList.*; + /** * The default implementation of a {@link JBakeConfiguration} */ @@ -58,7 +60,7 @@ public Object get(String key) { @Override public String getArchiveFileName() { - return getAsString(JBakeProperty.ARCHIVE_FILE); + return getAsString(PropertyList.ARCHIVE_FILE.getKey()); } private boolean getAsBoolean(String key) { @@ -87,15 +89,15 @@ private String getAsString(String key, String defaultValue) { @Override public List getAsciidoctorAttributes() { - return getAsList(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES); + return getAsList(ASCIIDOCTOR_ATTRIBUTES.getKey()); } public Object getAsciidoctorOption(String optionKey) { - Configuration subConfig = compositeConfiguration.subset(JBakeProperty.ASCIIDOCTOR_OPTION); + Configuration subConfig = compositeConfiguration.subset(ASCIIDOCTOR_OPTION.getKey()); Object value = subConfig.getProperty(optionKey); if (value == null) { - logger.warn("Cannot find asciidoctor option '{}.{}'", JBakeProperty.ASCIIDOCTOR_OPTION, optionKey); + logger.warn("Cannot find asciidoctor option '{}.{}'", ASCIIDOCTOR_OPTION.getKey(), optionKey); return ""; } return value; @@ -104,7 +106,7 @@ public Object getAsciidoctorOption(String optionKey) { @Override public List getAsciidoctorOptionKeys() { List options = new ArrayList<>(); - Configuration subConfig = compositeConfiguration.subset(JBakeProperty.ASCIIDOCTOR_OPTION); + Configuration subConfig = compositeConfiguration.subset(ASCIIDOCTOR_OPTION.getKey()); Iterator iterator = subConfig.getKeys(); while (iterator.hasNext()) { @@ -128,35 +130,35 @@ public void setAssetFolder(File assetFolder) { @Override public String getAssetFolderName() { - return getAsString(JBakeProperty.ASSET_FOLDER); + return getAsString(ASSET_FOLDER.getKey()); } @Override public boolean getAssetIgnoreHidden() { - return getAsBoolean(JBakeProperty.ASSET_IGNORE_HIDDEN); + return getAsBoolean(ASSET_IGNORE_HIDDEN.getKey()); } public void setAssetIgnoreHidden(boolean assetIgnoreHidden) { - setProperty(JBakeProperty.ASSET_IGNORE_HIDDEN, assetIgnoreHidden); + setProperty(ASSET_IGNORE_HIDDEN.getKey(), assetIgnoreHidden); } @Override public String getAttributesExportPrefixForAsciidoctor() { - return getAsString(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES_EXPORT_PREFIX, ""); + return getAsString(ASCIIDOCTOR_ATTRIBUTES_EXPORT_PREFIX.getKey(), ""); } @Override public String getBuildTimeStamp() { - return getAsString(JBakeProperty.BUILD_TIMESTAMP); + return getAsString(BUILD_TIMESTAMP.getKey()); } @Override public boolean getClearCache() { - return getAsBoolean(JBakeProperty.CLEAR_CACHE); + return getAsBoolean(CLEAR_CACHE.getKey()); } public void setClearCache(boolean clearCache) { - setProperty(JBakeProperty.CLEAR_CACHE, clearCache); + setProperty(CLEAR_CACHE.getKey(), clearCache); } public CompositeConfiguration getCompositeConfiguration() { @@ -180,48 +182,48 @@ public void setContentFolder(File contentFolder) { @Override public String getContentFolderName() { - return getAsString(JBakeProperty.CONTENT_FOLDER); + return getAsString(CONTENT_FOLDER.getKey()); } @Override public String getDatabasePath() { - return getAsString(JBakeProperty.DB_PATH); + return getAsString(DB_PATH.getKey()); } public void setDatabasePath(String path) { - setProperty(JBakeProperty.DB_PATH, path); + setProperty(DB_PATH.getKey(), path); } @Override public String getDatabaseStore() { - return getAsString(JBakeProperty.DB_STORE); + return getAsString(DB_STORE.getKey()); } public void setDatabaseStore(String storeType) { - setProperty(JBakeProperty.DB_STORE, storeType); + setProperty(DB_STORE.getKey(), storeType); } @Override public String getDateFormat() { - return getAsString(JBakeProperty.DATE_FORMAT); + return getAsString(DATE_FORMAT.getKey()); } @Override public String getDefaultStatus() { - return getAsString(JBakeProperty.DEFAULT_STATUS, ""); + return getAsString(DEFAULT_STATUS.getKey(), ""); } public void setDefaultStatus(String status) { - setProperty(JBakeProperty.DEFAULT_STATUS, status); + setProperty(DEFAULT_STATUS.getKey(), status); } @Override public String getDefaultType() { - return getAsString(JBakeProperty.DEFAULT_TYPE, ""); + return getAsString(DEFAULT_TYPE.getKey(), ""); } public void setDefaultType(String type) { - setProperty(JBakeProperty.DEFAULT_TYPE, type); + setProperty(DEFAULT_TYPE.getKey(), type); } @Override @@ -252,7 +254,7 @@ public List getDocumentTypes() { @Override public String getDraftSuffix() { - return getAsString(JBakeProperty.DRAFT_SUFFIX, ""); + return getAsString(DRAFT_SUFFIX.getKey(), ""); } @Override @@ -262,17 +264,17 @@ public String getExampleProjectByType(String templateType) { @Override public boolean getExportAsciidoctorAttributes() { - return getAsBoolean(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES_EXPORT); + return getAsBoolean(ASCIIDOCTOR_ATTRIBUTES_EXPORT.getKey()); } @Override public String getFeedFileName() { - return getAsString(JBakeProperty.FEED_FILE); + return getAsString(FEED_FILE.getKey()); } @Override public String getIndexFileName() { - return getAsString(JBakeProperty.INDEX_FILE); + return getAsString(INDEX_FILE.getKey()); } @Override @@ -282,20 +284,20 @@ public Iterator getKeys() { @Override public List getMarkdownExtensions() { - return getAsList(JBakeProperty.MARKDOWN_EXTENSIONS); + return getAsList(MARKDOWN_EXTENSIONS.getKey()); } public void setMarkdownExtensions(String... extensions) { - setProperty(JBakeProperty.MARKDOWN_EXTENSIONS, StringUtils.join(extensions, ",")); + setProperty(MARKDOWN_EXTENSIONS.getKey(), StringUtils.join(extensions, ",")); } @Override public String getOutputExtension() { - return getAsString(JBakeProperty.OUTPUT_EXTENSION); + return getAsString(OUTPUT_EXTENSION.getKey()); } public void setOutputExtension(String outputExtension) { - setProperty(JBakeProperty.OUTPUT_EXTENSION, outputExtension); + setProperty(OUTPUT_EXTENSION.getKey(), outputExtension); } @Override @@ -307,96 +309,96 @@ public String getOutputExtensionByDocType(String docType) { @Override public boolean getPaginateIndex() { - return getAsBoolean(JBakeProperty.PAGINATE_INDEX); + return getAsBoolean(PAGINATE_INDEX.getKey()); } public void setPaginateIndex(boolean paginateIndex) { - setProperty(JBakeProperty.PAGINATE_INDEX, paginateIndex); + setProperty(PAGINATE_INDEX.getKey(), paginateIndex); } @Override public int getPostsPerPage() { - return getAsInt(JBakeProperty.POSTS_PER_PAGE, 5); + return getAsInt(POSTS_PER_PAGE.getKey(), 5); } public void setPostsPerPage(int postsPerPage) { - setProperty(JBakeProperty.POSTS_PER_PAGE, postsPerPage); + setProperty(POSTS_PER_PAGE.getKey(), postsPerPage); } @Override public String getPrefixForUriWithoutExtension() { - return getAsString(JBakeProperty.URI_NO_EXTENSION_PREFIX); + return getAsString(URI_NO_EXTENSION_PREFIX.getKey()); } public void setPrefixForUriWithoutExtension(String prefix) { - setProperty(JBakeProperty.URI_NO_EXTENSION_PREFIX, prefix); + setProperty(URI_NO_EXTENSION_PREFIX.getKey(), prefix); } @Override public boolean getRenderArchive() { - return getAsBoolean(JBakeProperty.RENDER_ARCHIVE); + return getAsBoolean(RENDER_ARCHIVE.getKey()); } @Override public String getRenderEncoding() { - return getAsString(JBakeProperty.RENDER_ENCODING); + return getAsString(RENDER_ENCODING.getKey()); } @Override public boolean getRenderFeed() { - return getAsBoolean(JBakeProperty.RENDER_FEED); + return getAsBoolean(RENDER_FEED.getKey()); } @Override public boolean getRenderIndex() { - return getAsBoolean(JBakeProperty.RENDER_INDEX); + return getAsBoolean(RENDER_INDEX.getKey()); } @Override public boolean getRenderSiteMap() { - return getAsBoolean(JBakeProperty.RENDER_SITEMAP); + return getAsBoolean(RENDER_SITEMAP.getKey()); } @Override public boolean getRenderTags() { - return getAsBoolean(JBakeProperty.RENDER_TAGS); + return getAsBoolean(RENDER_TAGS.getKey()); } @Override public boolean getRenderTagsIndex() { - return compositeConfiguration.getBoolean(JBakeProperty.RENDER_TAGS_INDEX, false); + return compositeConfiguration.getBoolean(RENDER_TAGS_INDEX.getKey(), false); } public void setRenderTagsIndex(boolean enable) { - compositeConfiguration.setProperty(JBakeProperty.RENDER_TAGS_INDEX, enable); + compositeConfiguration.setProperty(RENDER_TAGS_INDEX.getKey(), enable); } @Override public boolean getSanitizeTag() { - return getAsBoolean(JBakeProperty.TAG_SANITIZE); + return getAsBoolean(TAG_SANITIZE.getKey()); } @Override public int getServerPort() { - return getAsInt(JBakeProperty.SERVER_PORT, 8080); + return getAsInt(SERVER_PORT.getKey(), 8080); } public void setServerPort(int port) { - setProperty(JBakeProperty.SERVER_PORT, port); + setProperty(SERVER_PORT.getKey(), port); } @Override public String getSiteHost() { - return getAsString(JBakeProperty.SITE_HOST, "http://www.jbake.org"); + return getAsString(SITE_HOST.getKey(), "http://www.jbake.org"); } public void setSiteHost(String siteHost) { - setProperty(JBakeProperty.SITE_HOST, siteHost); + setProperty(SITE_HOST.getKey(), siteHost); } @Override public String getSiteMapFileName() { - return getAsString(JBakeProperty.SITEMAP_FILE); + return getAsString(SITEMAP_FILE.getKey()); } @Override @@ -411,12 +413,12 @@ public void setSourceFolder(File sourceFolder) { @Override public String getTagPathName() { - return getAsString(JBakeProperty.TAG_PATH); + return getAsString(TAG_PATH.getKey()); } @Override public String getTemplateEncoding() { - return getAsString(JBakeProperty.TEMPLATE_ENCODING); + return getAsString(TEMPLATE_ENCODING.getKey()); } @Override @@ -443,30 +445,30 @@ public void setTemplateFolder(File templateFolder) { @Override public String getTemplateFolderName() { - return getAsString(JBakeProperty.TEMPLATE_FOLDER); + return getAsString(TEMPLATE_FOLDER.getKey()); } @Override public String getThymeleafLocale() { - return getAsString(JBakeProperty.THYMELEAF_LOCALE); + return getAsString(THYMELEAF_LOCALE.getKey()); } @Override public boolean getUriWithoutExtension() { - return getAsBoolean(JBakeProperty.URI_NO_EXTENSION); + return getAsBoolean(URI_NO_EXTENSION.getKey()); } public void setUriWithoutExtension(boolean withoutExtension) { - setProperty(JBakeProperty.URI_NO_EXTENSION, withoutExtension); + setProperty(URI_NO_EXTENSION.getKey(), withoutExtension); } @Override public String getVersion() { - return getAsString(JBakeProperty.VERSION); + return getAsString(VERSION.getKey()); } public void setDestinationFolderName(String folderName) { - setProperty(JBakeProperty.DESTINATION_FOLDER, folderName); + setProperty(DESTINATION_FOLDER.getKey(), folderName); setupDefaultDestination(); } @@ -482,12 +484,12 @@ public void setProperty(String key, Object value) { @Override public String getServerContextPath() { - return getAsString(JBakeProperty.SERVER_CONTEXT_PATH); + return getAsString(SERVER_CONTEXT_PATH.getKey()); } @Override public String getServerHostname() { - return getAsString(JBakeProperty.SERVER_HOSTNAME); + return getAsString(SERVER_HOSTNAME.getKey()); } public void setTemplateExtensionForDocType(String docType, String extension) { @@ -508,7 +510,7 @@ private void setupPaths() { } private void setupDefaultDestination() { - String destinationPath = getAsString(JBakeProperty.DESTINATION_FOLDER); + String destinationPath = getAsString(DESTINATION_FOLDER.getKey()); File destination = new File(destinationPath); if ( destination.isAbsolute() ) { @@ -519,7 +521,7 @@ private void setupDefaultDestination() { } private void setupDefaultAssetFolder() { - String assetFolder = getAsString(JBakeProperty.ASSET_FOLDER); + String assetFolder = getAsString(ASSET_FOLDER.getKey()); File asset = new File(assetFolder); @@ -531,7 +533,7 @@ private void setupDefaultAssetFolder() { } private void setupDefaultTemplateFolder() { - String templateFolder = getAsString(JBakeProperty.TEMPLATE_FOLDER); + String templateFolder = getAsString(TEMPLATE_FOLDER.getKey()); File template = new File(templateFolder); if(template.isAbsolute()) { @@ -547,28 +549,46 @@ private void setupDefaultContentFolder() { @Override public String getHeaderSeparator() { - return getAsString(JBakeProperty.HEADER_SEPARATOR); + return getAsString(HEADER_SEPARATOR.getKey()); } public void setHeaderSeparator(String headerSeparator) { - setProperty(JBakeProperty.HEADER_SEPARATOR, headerSeparator); + setProperty(HEADER_SEPARATOR.getKey(), headerSeparator); } @Override public boolean getImgPathPrependHost() { - return getAsBoolean(JBakeProperty.IMG_PATH_PREPEND_HOST); + return getAsBoolean(IMG_PATH_PREPEND_HOST.getKey()); } public void setImgPathPrependHost(boolean imgPathPrependHost) { - setProperty(JBakeProperty.IMG_PATH_PREPEND_HOST, imgPathPrependHost); + setProperty(IMG_PATH_PREPEND_HOST.getKey(), imgPathPrependHost); } @Override public boolean getImgPathUpdate() { - return getAsBoolean(JBakeProperty.IMG_PATH_UPDATE); + return getAsBoolean(IMG_PATH_UPDATE.getKey()); } public void setImgPathUPdate(boolean imgPathUpdate) { - setProperty(JBakeProperty.IMG_PATH_UPDATE, imgPathUpdate); + setProperty(IMG_PATH_UPDATE.getKey(), imgPathUpdate); + } + + public List getJbakeProperties() { + + List jbakeKeys = new ArrayList<>(); + + for (int i = 0; i < compositeConfiguration.getNumberOfConfigurations(); i++) { + Configuration configuration = compositeConfiguration.getConfiguration(i); + + if (!(configuration instanceof SystemConfiguration)) { + for (Iterator it = configuration.getKeys(); it.hasNext(); ) { + String key = it.next(); + jbakeKeys.add(PropertyList.getPropertyByKey(key)); + } + } + } + Collections.sort(jbakeKeys); + return jbakeKeys; } } diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java index 218c62177..33a7d1276 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java @@ -310,5 +310,7 @@ public interface JBakeConfiguration { String getServerContextPath(); String getServerHostname(); + + List getJbakeProperties(); } diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationInspector.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationInspector.java index 2fb214d96..9fdddf658 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationInspector.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfigurationInspector.java @@ -7,6 +7,9 @@ import java.io.File; +import static org.jbake.app.configuration.PropertyList.CONTENT_FOLDER; +import static org.jbake.app.configuration.PropertyList.TEMPLATE_FOLDER; + public class JBakeConfigurationInspector { private static final Logger LOGGER = LoggerFactory.getLogger(JBakeConfigurationInspector.class); @@ -37,12 +40,12 @@ private void ensureSource() throws JBakeException { private void ensureTemplateFolder() { File path = configuration.getTemplateFolder(); - checkRequiredFolderExists(JBakeProperty.TEMPLATE_FOLDER, path); + checkRequiredFolderExists(TEMPLATE_FOLDER.getKey(), path); } private void ensureContentFolder() { File path = configuration.getContentFolder(); - checkRequiredFolderExists(JBakeProperty.CONTENT_FOLDER, path); + checkRequiredFolderExists(CONTENT_FOLDER.getKey(), path); } private void ensureDestination() { diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java deleted file mode 100644 index 0c5159ccd..000000000 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.jbake.app.configuration; - -public class JBakeProperty { - - public static final String ARCHIVE_FILE = "archive.file"; - public static final String ASCIIDOCTOR_ATTRIBUTES = "asciidoctor.attributes"; - public static final String ASCIIDOCTOR_ATTRIBUTES_EXPORT = "asciidoctor.attributes.export"; - public static final String ASCIIDOCTOR_OPTION = "asciidoctor.option"; - public static final String ASCIIDOCTOR_ATTRIBUTES_EXPORT_PREFIX = "asciidoctor.attributes.export.prefix"; - public static final String ASSET_FOLDER = "asset.folder"; - public static final String ASSET_IGNORE_HIDDEN = "asset.ignore"; - public static final String BUILD_TIMESTAMP = "build.timestamp"; - public static final String CLEAR_CACHE = "db.clear.cache"; - public static final String CONTENT_FOLDER = "content.folder"; - public static final String DATE_FORMAT = "date.format"; - public static final String DB_STORE = "db.store"; - public static final String DB_PATH = "db.path"; - public static final String DEFAULT_STATUS = "default.status"; - public static final String DEFAULT_TYPE = "default.type"; - public static final String DESTINATION_FOLDER = "destination.folder"; - public static final String DRAFT_SUFFIX = "draft.suffix"; - public static final String FEED_FILE = "feed.file"; - public static final String HEADER_SEPARATOR = "header.separator"; - public static final String INDEX_FILE = "index.file"; - public static final String MARKDOWN_EXTENSIONS = "markdown.extensions"; - public static final String OUTPUT_EXTENSION = "output.extension"; - public static final String PAGINATE_INDEX = "index.paginate"; - public static final String POSTS_PER_PAGE = "index.posts_per_page"; - public static final String RENDER_ARCHIVE = "render.archive"; - public static final String RENDER_FEED = "render.feed"; - public static final String RENDER_INDEX = "render.index"; - public static final String RENDER_SITEMAP = "render.sitemap"; - public static final String RENDER_TAGS = "render.tags"; - public static final String RENDER_TAGS_INDEX = "render.tagsindex"; - public static final String RENDER_ENCODING = "render.encoding"; - public static final String SERVER_PORT = "server.port"; - public static final String SERVER_HOSTNAME = "server.hostname"; - public static final String SERVER_CONTEXT_PATH = "server.contextPath"; - public static final String SITE_HOST = "site.host"; - public static final String SITEMAP_FILE = "sitemap.file"; - public static final String TAG_SANITIZE = "tag.sanitize"; - public static final String TAG_PATH = "tag.path"; - public static final String TEMPLATE_FOLDER = "template.folder"; - public static final String TEMPLATE_ENCODING = "template.encoding"; - public static final String THYMELEAF_LOCALE = "thymeleaf.locale"; - public static final String URI_NO_EXTENSION = "uri.noExtension"; - public static final String URI_NO_EXTENSION_PREFIX = "uri.noExtension.prefix"; - public static final String IMG_PATH_UPDATE = "img.path.update"; - public static final String IMG_PATH_PREPEND_HOST = "img.path.prepend.host"; - public static final String VERSION = "version"; - - private JBakeProperty() {} - -} diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/Property.java b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java new file mode 100644 index 000000000..86ee0702b --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java @@ -0,0 +1,69 @@ +package org.jbake.app.configuration; + +import java.util.Objects; + +public class Property implements Comparable { + + private final String key; + private final String description; + private final Group group; + + public Property(String key, String description) { + this(key, description, Group.DEFAULT); + } + + public Property(String key, String description, Group group) { + this.key = key; + this.description = description; + this.group = group; + } + + public String getKey() { + return key; + } + + public String getDescription() { + return description; + } + + public Group getGroup() { + return group; + } + + @Override + public String toString() { + return getKey(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Property property = (Property) o; + return Objects.equals(key, property.key) && + Objects.equals(description, property.description) && + group == property.group; + } + + @Override + public int hashCode() { + return Objects.hash(key, description, group); + } + + @Override + public int compareTo(Object o) { + Property other = (Property) o; + return this.getGroup().compareTo(other.getGroup()); + } + + public enum Group { + DEFAULT, CUSTOM + } + + + +} diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java b/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java new file mode 100644 index 000000000..a2c5655db --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java @@ -0,0 +1,326 @@ +package org.jbake.app.configuration; + +import java.lang.reflect.Field; + +import static org.jbake.app.configuration.Property.Group.CUSTOM; + +public abstract class PropertyList { + + public static final Property ARCHIVE_FILE = new Property( + "archive.file", + "Output filename for archive file" + ); + + public static final Property ASCIIDOCTOR_ATTRIBUTES = new Property( + "asciidoctor.attributes", + "attributes to be set when processing input" + ); + + public static final Property ASCIIDOCTOR_ATTRIBUTES_EXPORT = new Property( + "asciidoctor.attributes.export", + "Prefix to be used when exporting JBake properties to Asciidoctor" + ); + + public static final Property ASCIIDOCTOR_ATTRIBUTES_EXPORT_PREFIX = new Property( + "asciidoctor.attributes.export.prefix", + "prefix that should be used when JBake config options are exported" + ); + + public static final Property ASCIIDOCTOR_OPTION = new Property( + "asciidoctor.option", + "default asciidoctor options" + ); + + public static final Property ASSET_FOLDER = new Property( + "asset.folder", + "folder that contains all asset files" + ); + + public static final Property ASSET_IGNORE_HIDDEN = new Property( + "asset.ignore", + "Flag indicating if hidden asset resources should be ignored" + ); + + public static final Property BUILD_TIMESTAMP = new Property( + "build.timestamp", + "timestamp jbake was build"); + + public static final Property CLEAR_CACHE = new Property( + "db.clear.cache", + "clear database cache" + ); + + public static final Property CONTENT_FOLDER = new Property( + "content.folder", + "folder that contains all content files" + ); + + public static final Property DATE_FORMAT = new Property( + "date.format", + "default date format used in content files" + ); + + public static final Property DB_STORE = new Property( + "db.store", + "database store (plocal, memory)" + ); + + public static final Property DB_PATH = new Property( + "db.path", + "database path for persistent storage" + ); + + public static final Property DEFAULT_STATUS = new Property( + "default.status", + "default document status" + ); + + public static final Property DEFAULT_TYPE = new Property( + "default.type", + "default document type" + ); + + public static final Property DESTINATION_FOLDER = new Property( + "destination.folder", + "path to destination folder by default" + ); + + public static final Property DRAFT_SUFFIX = new Property( + "draft.suffix", + "draft content suffix" + ); + + public static final Property FEED_FILE = new Property( + "feed.file", + "filename to use for feed" + ); + + public static final Property HEADER_SEPARATOR = new Property( + "header.separator", + "String used to separate the header from the body" + ); + + public static final Property IMG_PATH_UPDATE = new Property( + "img.path.update", + "update image path?" + ); + + public static final Property IMG_PATH_PREPEND_HOST = new Property( + "img.path.prepend.host", + "Prepend site.host to image paths" + ); + + public static final Property INDEX_FILE = new Property( + "index.file", + "filename to use for index file" + ); + + public static final Property MARKDOWN_EXTENSIONS = new Property( + "markdown.extensions", + "comma delimited default markdown extensions; for available extensions: http://www.decodified.com/pegdown/api/org/pegdown/Extensions.html" + ); + + public static final Property OUTPUT_EXTENSION = new Property( + "output.extension", + "file extension for output content files" + ); + + public static final Property PAGINATE_INDEX = new Property( + "index.paginate", + "paginate index?" + ); + + public static final Property POSTS_PER_PAGE = new Property( + "index.posts_per_page", + "number of post per page for pagination" + ); + + public static final Property RENDER_ARCHIVE = new Property( + "render.archive", + "render archive file?" + ); + + public static final Property RENDER_FEED = new Property( + "render.feed", + "render feed file?" + ); + + public static final Property RENDER_INDEX = new Property( + "render.index", + "render index file?" + ); + + public static final Property RENDER_SITEMAP = new Property( + "render.sitemap", + "render sitemap.xml file?" + ); + + public static final Property RENDER_TAGS = new Property( + "render.tags", + "render tag files?" + ); + + public static final Property RENDER_TAGS_INDEX = new Property( + "render.tagsindex", + "render tag index file?" + ); + + public static final Property RENDER_ENCODING = new Property( + "render.encoding", + "character encoding MIME name used in templates. use one of http://www.iana.org/assignments/character-sets/character-sets.xhtml" + ); + + public static final Property SERVER_PORT = new Property( + "server.port", + "default server port" + ); + + public static final Property SERVER_HOSTNAME = new Property( + "server.hostname", + "default server hostname" + ); + + public static final Property SERVER_CONTEXT_PATH = new Property( + "server.contextPath", + "default server context path" + ); + + public static final Property SITE_HOST = new Property( + "site.host", + "site host" + ); + + public static final Property SITEMAP_FILE = new Property( + "sitemap.file", + "filename to use for sitemap file" + ); + + public static final Property TAG_SANITIZE = new Property( + "tag.sanitize", + "sanitize tag value before it is used as filename (i.e. replace spaces with hyphens)" + ); + + public static final Property TAG_PATH = new Property( + "tag.path", + "folder name to use for tag files" + ); + + public static final Property TEMPLATE_FOLDER = new Property( + "template.folder", + "folder that contains all template files" + ); + + public static final Property TEMPLATE_ENCODING = new Property( + "template.encoding", + "character encoding MIME name used in templates. use one of http://www.iana.org/assignments/character-sets/character-sets.xhtml" + ); + + public static final Property TEMPLATE_MASTERINDEX_FILE = new Property( + "template.masterindex.file", + "filename of masterindex template file" + ); + + public static final Property TEMPLATE_FEED_FILE = new Property( + "template.feed.file", + "filename of feed template file" + ); + + public static final Property TEMPLATE_ARCHIVE_FILE = new Property( + "template.archive.file", + "filename of archive template file" + ); + + public static final Property TEMPLATE_TAG_FILE = new Property( + "template.tag.file", + "filename of tag template file" + ); + + public static final Property TEMPLATE_TAGSINDEX_FILE = new Property( + "template.tagsindex.file", + "filename of tag index template file" + ); + + public static final Property TEMPLATE_SITEMAP_FILE = new Property( + "template.sitemap.file", + "filename of sitemap template file" + ); + + public static final Property TEMPLATE_POST_FILE = new Property( + "template.post.file", + "filename of post template file" + ); + + public static final Property TEMPLATE_PAGE_FILE = new Property( + "template.page.file", + "filename of page template file" + ); + + public static final Property EXAMPLE_PROJECT_FREEMARKER = new Property( + "example.project.freemarker", + "zip file containing example project structure using freemarker templates" + ); + + public static final Property EXAMPLE_PROJECT_GROOVY = new Property( + "example.project.groovy", + "zip file containing example project structure using groovy templates" + ); + + public static final Property EXAMPLE_PROJECT_GROOVY_MTE = new Property( + "example.project.groovy-mte", + "zip file containing example project structure using groovy markup templates" + ); + + public static final Property EXAMPLE_PROJECT_THYMELEAF = new Property( + "example.project.thymeleaf", + "zip file containing example project structure using thymeleaf templates" + ); + + public static final Property EXAMPLE_PROJECT_JADE = new Property( + "example.project.jade", + "zip file containing example project structure using jade templates" + ); + + public static final Property MARKDOWN_MAX_PARSINGTIME = new Property( + "markdown.maxParsingTimeInMillis", + "millis to parse single markdown page. See PegDown Parse configuration for details" + ); + + public static final Property THYMELEAF_LOCALE = new Property( + "thymeleaf.locale", + "default thymeleafe locale" + ); + + public static final Property URI_NO_EXTENSION = new Property( + "uri.noExtension", + "enable extension-less URI option?" + ); + + public static final Property URI_NO_EXTENSION_PREFIX = new Property( + "uri.noExtension.prefix", + "Set to a prefix path (starting with a slash) for which to generate extension-less URI's (i.e. a folder with index.html in)" + ); + + public static final Property VERSION = new Property( + "version", + "jbake application version" + ); + + private PropertyList() { + } + + public static final Property getPropertyByKey(String key) { + + for (Field field : PropertyList.class.getFields()) { + try { + Property property = (Property) field.get(null); + + if (property.getKey().equals(key)) { + return property; + } + } catch (IllegalAccessException e) { + return new Property(key, "", CUSTOM); + } + } + return new Property(key, "", CUSTOM); + } +} 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..cd94f0856 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -4,7 +4,6 @@ import org.jbake.app.ContentStore; import org.jbake.app.FileUtil; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.app.configuration.JBakeProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +13,8 @@ import java.util.Iterator; import java.util.Map; +import static org.jbake.app.configuration.PropertyList.PAGINATE_INDEX; + /** * A template which is responsible for delegating to a supported template engine, * based on the file extension. @@ -55,7 +56,7 @@ public void renderDocument(final Map model, String templateName, String key = configKeys.next(); Object valueObject; - if ( key.equals(JBakeProperty.PAGINATE_INDEX) ){ + if (key.equals(PAGINATE_INDEX.getKey())) { valueObject = config.getPaginateIndex(); } else { valueObject = config.get(key); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java index 30b7c7f25..ef0e64e4f 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java @@ -8,8 +8,8 @@ import java.util.HashMap; import java.util.Map; -import static org.jbake.app.configuration.JBakeProperty.OUTPUT_EXTENSION; -import static org.jbake.app.configuration.JBakeProperty.TAG_PATH; +import static org.jbake.app.configuration.PropertyList.OUTPUT_EXTENSION; +import static org.jbake.app.configuration.PropertyList.TAG_PATH; public class TagsExtractor implements ModelExtractor { @@ -19,14 +19,14 @@ public DocumentList get(ContentStore db, Map model, String key) { DocumentList dl = new DocumentList(); Map config = (Map) model.get("config"); - String tagPath = config.get(TAG_PATH.replace(".", "_")).toString(); + String tagPath = config.get(TAG_PATH.getKey().replace(".", "_")).toString(); for (String tag : db.getAllTags()) { Map newTag = new HashMap<>(); String tagName = tag; newTag.put("name", tagName); - String uri = tagPath + FileUtil.URI_SEPARATOR_CHAR + tag + config.get(OUTPUT_EXTENSION.replace(".", "_")).toString(); + String uri = tagPath + FileUtil.URI_SEPARATOR_CHAR + tag + config.get(OUTPUT_EXTENSION.getKey().replace(".", "_")).toString(); newTag.put("uri", uri); newTag.put("tagged_posts", db.getPublishedPostsByTag(tagName)); diff --git a/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java b/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java new file mode 100644 index 000000000..f1610d53e --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java @@ -0,0 +1,64 @@ +package org.jbake.util; + +import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.app.configuration.Property; + +import java.io.PrintStream; +import java.util.List; + +public class ConfigurationPrinter { + + private PrintStream out; + private JBakeConfiguration configuration; + + public ConfigurationPrinter(JBakeConfiguration configuration, PrintStream out) { + this.out = out; + this.configuration = configuration; + } + + public void print() { + + List properties = configuration.getJbakeProperties(); + Property.Group lastGroup = null; + + for (Property property : properties) { + + if (lastGroup != property.getGroup()) { + printGroup(property); + this.printHeader(); + } + if (!property.getDescription().isEmpty()) { + printDescription(property); + } + printKeyAndValue(property); + + lastGroup = property.getGroup(); + } + } + + private void printHeader() { + out.printf("%1$-40s %2$-40s%n", "Key", "Value"); + out.println(String.format("%080d%n", 0).replace("0", "-")); + } + + private void printGroup(Property property) { + out.printf("##%n"); + out.printf("# GROUP: %s%n", property.getGroup()); + out.printf("##%n%n"); + } + + private void printDescription(Property property) { + out.printf("# %s%n", property.getDescription()); + } + + private void printKeyAndValue(Property property) { + String key = leftFillWithDots(property.getKey()); + Object value = configuration.get(property.getKey()); + out.printf("%1$s: %2$-40s%n%n", key, value); + } + + private String leftFillWithDots(String value) { + return String.format("%1$-40s", value).replace(' ', '.'); + } + +} diff --git a/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java b/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java index 642964998..0cbeb6613 100644 --- a/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java @@ -3,7 +3,7 @@ import org.jbake.TestUtils; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; -import org.jbake.app.configuration.JBakeProperty; +import org.jbake.app.configuration.PropertyList; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -15,6 +15,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.jbake.app.configuration.PropertyList.ASCIIDOCTOR_ATTRIBUTES; public class AsciidocParserTest { @@ -133,7 +134,7 @@ public void createSampleFile() throws Exception { @Test public void parseAsciidocFileWithPrettifyAttribute() { - config.setProperty(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES,"source-highlighter=prettify"); + config.setProperty(ASCIIDOCTOR_ATTRIBUTES.getKey(),"source-highlighter=prettify"); Map map = parser.processFile(asciidocWithSource); Assert.assertNotNull(map); Assert.assertEquals("draft", map.get("status")); @@ -150,7 +151,7 @@ public void parseAsciidocFileWithPrettifyAttribute() { @Test public void parseAsciidocFileWithCustomAttribute() { - config.setProperty(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES,"source-highlighter=prettify,testattribute=I Love Jbake"); + config.setProperty(ASCIIDOCTOR_ATTRIBUTES.getKey(),"source-highlighter=prettify,testattribute=I Love Jbake"); Map map = parser.processFile(asciidocWithSource); Assert.assertNotNull(map); Assert.assertEquals("draft", map.get("status")); diff --git a/jbake-core/src/test/java/org/jbake/app/OvenTest.java b/jbake-core/src/test/java/org/jbake/app/OvenTest.java index a945d2cb6..74b34500e 100644 --- a/jbake-core/src/test/java/org/jbake/app/OvenTest.java +++ b/jbake-core/src/test/java/org/jbake/app/OvenTest.java @@ -4,20 +4,17 @@ import org.jbake.TestUtils; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; -import org.jbake.app.configuration.JBakeProperty; +import org.jbake.app.configuration.PropertyList; import org.jbake.model.DocumentTypes; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; -import java.nio.Buffer; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -110,11 +107,11 @@ public void shouldBakeWithAbsoluteCustomPaths() throws Exception { BufferedWriter fw = Files.newBufferedWriter(properties); - fw.write(JBakeProperty.ASSET_FOLDER + "=" + TestUtils.getOsPath(expectedAssetFolder)); + fw.write(PropertyList.ASSET_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedAssetFolder)); fw.newLine(); - fw.write(JBakeProperty.TEMPLATE_FOLDER + "=" + TestUtils.getOsPath(expectedTemplateFolder)); + fw.write(PropertyList.TEMPLATE_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedTemplateFolder)); fw.newLine(); - fw.write(JBakeProperty.DESTINATION_FOLDER + "=" + TestUtils.getOsPath(expectedDestination)); + fw.write(PropertyList.DESTINATION_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedDestination)); fw.close(); configuration = (DefaultJBakeConfiguration) new ConfigUtil().loadConfig(source.toFile()); diff --git a/jbake-core/src/test/java/org/jbake/app/ParserTest.java b/jbake-core/src/test/java/org/jbake/app/ParserTest.java index d6d47eb32..9b6864df8 100644 --- a/jbake-core/src/test/java/org/jbake/app/ParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ParserTest.java @@ -3,7 +3,7 @@ import org.jbake.TestUtils; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; -import org.jbake.app.configuration.JBakeProperty; +import org.jbake.app.configuration.PropertyList; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.junit.Assert; @@ -21,6 +21,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.jbake.app.configuration.PropertyList.TAG_SANITIZE; public class ParserTest { @@ -298,7 +299,7 @@ public void sanitizeKeysAndValues() { @Test public void sanitizeTags() { - config.setProperty(JBakeProperty.TAG_SANITIZE, true); + config.setProperty(TAG_SANITIZE.getKey(), true); Map map = parser.processFile(validaAsciidocWithUnsanitizedHeader); assertThat(map.get("tags")).isEqualTo(Arrays.asList("jbake", "java", "tag-with-space").toArray()); 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 931cbccb5..f576a6587 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 @@ -21,6 +21,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.jbake.TestUtils.getTestResourcesAsSourceFolder; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; @@ -299,11 +300,11 @@ void shouldSetCustomFoldersWithAbsolutePaths() throws Exception { File properties = source.resolve("jbake.properties").toFile(); BufferedWriter fw = Files.newBufferedWriter(properties.toPath()); - fw.write(JBakeProperty.ASSET_FOLDER + "=" + TestUtils.getOsPath(expectedAssetFolder)); + fw.write(PropertyList.ASSET_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedAssetFolder)); fw.newLine(); - fw.write(JBakeProperty.TEMPLATE_FOLDER + "=" + TestUtils.getOsPath(expectedTemplateFolder)); + fw.write(PropertyList.TEMPLATE_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedTemplateFolder)); fw.newLine(); - fw.write(JBakeProperty.DESTINATION_FOLDER + "=" + TestUtils.getOsPath(expectedDestination)); + fw.write(PropertyList.DESTINATION_FOLDER.getKey() + "=" + TestUtils.getOsPath(expectedDestination)); fw.close(); // when diff --git a/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java b/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java new file mode 100644 index 000000000..fe7099a28 --- /dev/null +++ b/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java @@ -0,0 +1,26 @@ +package org.jbake.app.configuration; + +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class PropertyListTest { + + @Test + public void getPropertyByKey() { + + Property property = PropertyList.getPropertyByKey("archive.file"); + + assertThat(property, is(PropertyList.ARCHIVE_FILE)); + } + + @Test + public void getCustomProperty() { + + Property property = PropertyList.getPropertyByKey("unknown.option"); + + assertThat(property.getKey(), is("unknown.option")); + assertThat(property.getGroup(), is(Property.Group.CUSTOM)); + } +} \ No newline at end of file diff --git a/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java new file mode 100644 index 000000000..c0515e437 --- /dev/null +++ b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java @@ -0,0 +1,47 @@ +package org.jbake.util; + +import org.hamcrest.CoreMatchers; +import org.jbake.TestUtils; +import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.app.configuration.JBakeConfigurationFactory; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertThat; + +public class ConfigurationPrinterTest { + + @Test + public void shouldPrintHeader() throws Exception { + + JBakeConfiguration configuration = new JBakeConfigurationFactory().getConfigUtil().loadConfig(TestUtils.getTestResourcesAsSourceFolder()); + ByteArrayOutputStream data = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(data); + ConfigurationPrinter printer = new ConfigurationPrinter(configuration, out); + + printer.print(); + + assertThat(data.toString(), CoreMatchers.containsString("DEFAULT")); + assertThat(data.toString(), CoreMatchers.containsString("CUSTOM")); + assertThat(data.toString(), CoreMatchers.containsString("Key")); + assertThat(data.toString(), CoreMatchers.containsString("Value")); + + System.out.println(data.toString()); + } + + + @Test + public void shouldPrintKeyAndValue() throws Exception { + JBakeConfiguration configuration = new JBakeConfigurationFactory().getConfigUtil().loadConfig(TestUtils.getTestResourcesAsSourceFolder()); + ByteArrayOutputStream data = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(data); + ConfigurationPrinter printer = new ConfigurationPrinter(configuration, out); + + printer.print(); + + assertThat(data.toString(), CoreMatchers.containsString("site.host")); + assertThat(data.toString(), CoreMatchers.containsString("http://www.jbake.org")); + } +} \ No newline at end of file From a169bd4ffff59184bd32730ea5e0b686ab9d4864 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 26 Nov 2018 00:36:53 +0100 Subject: [PATCH 09/27] add -ls and alias --list-settings option to cli --- .../app/configuration/DefaultJBakeConfiguration.java | 5 ++++- .../java/org/jbake/app/configuration/Property.java | 7 ++++++- .../java/org/jbake/app/configuration/PropertyList.java | 2 +- .../main/java/org/jbake/launcher/LaunchOptions.java | 9 ++++++++- jbake-core/src/main/java/org/jbake/launcher/Main.java | 7 +++++++ .../main/java/org/jbake/util/ConfigurationPrinter.java | 10 ++++++---- .../java/org/jbake/util/ConfigurationPrinterTest.java | 6 ++---- 7 files changed, 34 insertions(+), 12 deletions(-) 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 a08c4693f..562802e38 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 @@ -584,7 +584,10 @@ public List getJbakeProperties() { if (!(configuration instanceof SystemConfiguration)) { for (Iterator it = configuration.getKeys(); it.hasNext(); ) { String key = it.next(); - jbakeKeys.add(PropertyList.getPropertyByKey(key)); + Property property = PropertyList.getPropertyByKey(key); + if (!jbakeKeys.contains(property)) { + jbakeKeys.add(property); + } } } } diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/Property.java b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java index 86ee0702b..18eedfeb5 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/Property.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java @@ -57,7 +57,12 @@ public int hashCode() { @Override public int compareTo(Object o) { Property other = (Property) o; - return this.getGroup().compareTo(other.getGroup()); + int result = this.getGroup().compareTo(other.getGroup()); + + if (result == 0) { + result = this.getKey().compareTo(other.getKey()); + } + return result; } public enum Group { diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java b/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java index a2c5655db..4991fce0f 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/PropertyList.java @@ -308,7 +308,7 @@ public abstract class PropertyList { private PropertyList() { } - public static final Property getPropertyByKey(String key) { + public static Property getPropertyByKey(String key) { for (Field field : PropertyList.class.getFields()) { try { 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..b484cd7ea 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 = "-ls", aliases = {"--list-settings"}, usage = "list configuration settings") + private boolean listConfig; + public String getTemplate() { if (template != null) { return template; @@ -63,7 +66,7 @@ public String getDestinationValue() { } public boolean isHelpNeeded() { - return helpNeeded || !(isBake() || isRunServer() || isInit() || source != null || destination != null); + return helpNeeded || !(isListConfig() || isBake() || isRunServer() || isInit() || source != null || destination != null); } public boolean isRunServer() { @@ -81,4 +84,8 @@ public boolean isClearCache() { public boolean isBake() { return bake || (source != null && destination != null); } + + public boolean isListConfig() { + return listConfig; + } } 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..bc1e5ce89 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -5,6 +5,7 @@ import org.jbake.app.JBakeException; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; +import org.jbake.util.ConfigurationPrinter; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.slf4j.Logger; @@ -97,6 +98,12 @@ protected void run(LaunchOptions res, JBakeConfiguration config) { return; } + if (res.isListConfig()) { + ConfigurationPrinter printer = new ConfigurationPrinter(config, System.out); + printer.print(); + return; + } + if (res.isBake()) { baker.bake(config); } diff --git a/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java b/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java index f1610d53e..1bbc127cb 100644 --- a/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java +++ b/jbake-core/src/main/java/org/jbake/util/ConfigurationPrinter.java @@ -38,13 +38,15 @@ public void print() { private void printHeader() { out.printf("%1$-40s %2$-40s%n", "Key", "Value"); - out.println(String.format("%080d%n", 0).replace("0", "-")); + out.println(getHorizontalLine()); + } + + private String getHorizontalLine() { + return String.format("%080d%n", 0).replace("0", "-"); } private void printGroup(Property property) { - out.printf("##%n"); - out.printf("# GROUP: %s%n", property.getGroup()); - out.printf("##%n%n"); + out.printf("%n%s - Settings%n%n", property.getGroup()); } private void printDescription(Property property) { diff --git a/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java index c0515e437..089f61fc4 100644 --- a/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java +++ b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java @@ -23,12 +23,10 @@ public void shouldPrintHeader() throws Exception { printer.print(); - assertThat(data.toString(), CoreMatchers.containsString("DEFAULT")); - assertThat(data.toString(), CoreMatchers.containsString("CUSTOM")); + assertThat(data.toString(), CoreMatchers.containsString("DEFAULT - Settings")); + assertThat(data.toString(), CoreMatchers.containsString("CUSTOM - Settings")); assertThat(data.toString(), CoreMatchers.containsString("Key")); assertThat(data.toString(), CoreMatchers.containsString("Value")); - - System.out.println(data.toString()); } From d68ddea7554653e7928d220f68a3af13bfb30cdb Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 8 May 2021 22:20:51 +0200 Subject: [PATCH 10/27] add tests for new launch option and cleanup some additional test and some cleanup based on sonarlint recommendations. fix deprecated method calls in CustomFSChangeListener. --- .../org/jbake/app/configuration/Property.java | 6 +- .../launcher/CustomFSChangeListener.java | 16 ++-- .../main/java/org/jbake/launcher/Main.java | 6 +- .../app/configuration/PropertyListTest.java | 13 +-- .../org/jbake/launcher/LaunchOptionsTest.java | 20 ++++ .../java/org/jbake/launcher/MainTest.java | 92 +++++++++++-------- .../jbake/util/ConfigurationPrinterTest.java | 26 +++--- 7 files changed, 106 insertions(+), 73 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/Property.java b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java index 18eedfeb5..3ea349763 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/Property.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/Property.java @@ -2,7 +2,7 @@ import java.util.Objects; -public class Property implements Comparable { +public class Property implements Comparable { private final String key; private final String description; @@ -55,8 +55,7 @@ public int hashCode() { } @Override - public int compareTo(Object o) { - Property other = (Property) o; + public int compareTo(Property other) { int result = this.getGroup().compareTo(other.getGroup()); if (result == 0) { @@ -70,5 +69,4 @@ public enum Group { } - } diff --git a/jbake-core/src/main/java/org/jbake/launcher/CustomFSChangeListener.java b/jbake-core/src/main/java/org/jbake/launcher/CustomFSChangeListener.java index bd8135b54..3c6006177 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/CustomFSChangeListener.java +++ b/jbake-core/src/main/java/org/jbake/launcher/CustomFSChangeListener.java @@ -12,9 +12,9 @@ public class CustomFSChangeListener implements FileListener { - private final static Logger LOGGER = LoggerFactory.getLogger(CustomFSChangeListener.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CustomFSChangeListener.class); - private JBakeConfiguration config; + private final JBakeConfiguration config; public CustomFSChangeListener(JBakeConfiguration config) { this.config = config; @@ -22,20 +22,20 @@ public CustomFSChangeListener(JBakeConfiguration config) { @Override public void fileCreated(FileChangeEvent event) throws Exception { - LOGGER.info("File created event detected: {}", event.getFile().getURL()); - exec(event.getFile()); + LOGGER.info("File created event detected: {}", event.getFileObject().getURL()); + exec(event.getFileObject()); } @Override public void fileDeleted(FileChangeEvent event) throws Exception { - LOGGER.info("File deleted event detected: {}", event.getFile().getURL()); - exec(event.getFile()); + LOGGER.info("File deleted event detected: {}", event.getFileObject().getURL()); + exec(event.getFileObject()); } @Override public void fileChanged(FileChangeEvent event) throws Exception { - LOGGER.info("File changed event detected: {}", event.getFile().getURL()); - exec(event.getFile()); + LOGGER.info("File changed event detected: {}", event.getFileObject().getURL()); + exec(event.getFileObject()); } private void exec(FileObject file) { 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 bc1e5ce89..c88ef3fcb 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -22,8 +22,8 @@ */ public class Main { - private final String USAGE_PREFIX = "Usage: jbake"; - private final String ALT_USAGE_PREFIX = " or jbake"; + private static final String USAGE_PREFIX = "Usage: jbake"; + private static final String ALT_USAGE_PREFIX = " or jbake"; private final Baker baker; private final JettyServer jettyServer; private final BakeWatcher watcher; @@ -155,7 +155,7 @@ private void printUsage(Object options) { sw.append(ALT_USAGE_PREFIX + " \n"); sw.append(ALT_USAGE_PREFIX + " [OPTION]... [...]\n\n"); sw.append("Options:"); - System.out.println(sw.toString()); + System.out.println(sw); parser.getProperties().withUsageWidth(100); parser.printUsage(System.out); } diff --git a/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java b/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java index fe7099a28..10190307e 100644 --- a/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java +++ b/jbake-core/src/test/java/org/jbake/app/configuration/PropertyListTest.java @@ -2,25 +2,22 @@ import org.junit.Test; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class PropertyListTest { @Test public void getPropertyByKey() { - Property property = PropertyList.getPropertyByKey("archive.file"); - assertThat(property, is(PropertyList.ARCHIVE_FILE)); + assertThat(property).isEqualTo(PropertyList.ARCHIVE_FILE); } @Test public void getCustomProperty() { - Property property = PropertyList.getPropertyByKey("unknown.option"); - assertThat(property.getKey(), is("unknown.option")); - assertThat(property.getGroup(), is(Property.Group.CUSTOM)); + assertThat(property.getKey()).isEqualTo("unknown.option"); + assertThat(property.getGroup()).isEqualTo(Property.Group.CUSTOM); } -} \ No newline at end of file +} 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..1285ee212 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,26 @@ public void bake() throws Exception { assertThat(res.isBake()).isTrue(); } + @Test + public void listConfig() throws Exception { + String[] args = {"-ls"}; + LaunchOptions res = new LaunchOptions(); + CmdLineParser parser = new CmdLineParser(res); + parser.parseArgument(args); + + assertThat(res.isListConfig()).isTrue(); + } + + @Test + public void listConfigLongOption() throws Exception { + String[] args = {"--list-settings"}; + LaunchOptions res = new LaunchOptions(); + CmdLineParser parser = new CmdLineParser(res); + parser.parseArgument(args); + + assertThat(res.isListConfig()).isTrue(); + } + @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 827395051..205d16b9c 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -18,8 +18,10 @@ import org.kohsuke.args4j.CmdLineParser; import org.mockito.Mock; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.PrintStream; import java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThat; @@ -31,46 +33,53 @@ import static org.mockito.Mockito.when; @ExtendWith(ExitGuard.class) -public class MainTest extends LoggingTest { +class MainTest extends LoggingTest { + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); private Main main; - - @Mock private Baker mockBaker; - @Mock private JettyServer mockJetty; - @Mock private BakeWatcher mockWatcher; - @Mock private ConfigUtil configUtil; - @Mock private JBakeConfigurationFactory factory; + @Mock + private Baker mockBaker; + @Mock + private JettyServer mockJetty; + @Mock + private BakeWatcher mockWatcher; + @Mock + private ConfigUtil configUtil; + @Mock + private JBakeConfigurationFactory factory; private String workingdir; @BeforeEach - public void setUp() { + void setUp() { this.main = new Main(mockBaker, mockJetty, mockWatcher); workingdir = System.getProperty("user.dir"); factory.setConfigUtil(configUtil); main.setJBakeConfigurationFactory(factory); + System.setOut(new PrintStream(outputStreamCaptor)); } @AfterEach - public void tearDown() { + void tearDown() { System.setProperty("user.dir", workingdir); + System.setOut(standardOut); } @Test - public void launchJetty(@TempDir Path source) throws Exception { - - File currentWorkingdir = newFolder(source,"src/jbake"); - File expectedOutput = new File(currentWorkingdir,"output"); - JBakeConfiguration configuration = mockJettyConfiguration(currentWorkingdir,expectedOutput); + void launchJetty(@TempDir Path source) throws Exception { + File currentWorkingdir = newFolder(source, "src/jbake"); + File expectedOutput = new File(currentWorkingdir, "output"); + JBakeConfiguration configuration = mockJettyConfiguration(currentWorkingdir, expectedOutput); String[] args = {"-s"}; main.run(args); - verify(mockJetty).run(expectedOutput.getPath(),configuration); + verify(mockJetty).run(expectedOutput.getPath(), configuration); } @Test - public void launchBakeAndJetty(@TempDir Path source) throws Exception { + void launchBakeAndJetty(@TempDir Path source) throws Exception { File sourceFolder = newFolder(source, "src/jbake"); File expectedOutput = newFolder(sourceFolder.toPath(), "output"); JBakeConfiguration configuration = mockJettyConfiguration(sourceFolder, expectedOutput); @@ -78,16 +87,16 @@ public void launchBakeAndJetty(@TempDir Path source) throws Exception { String[] args = {"-b", "-s"}; main.run(args); - verify(mockJetty).run(expectedOutput.getPath(),configuration); + verify(mockJetty).run(expectedOutput.getPath(), configuration); } @Test - public void launchBakeAndJettyWithCustomDirForJetty(@TempDir Path source) throws ConfigurationException, IOException { - File sourceFolder = newFolder(source,"src/jbake"); + void launchBakeAndJettyWithCustomDirForJetty(@TempDir Path source) throws ConfigurationException, IOException { + File sourceFolder = newFolder(source, "src/jbake"); String expectedRunPath = "src" + File.separator + "jbake" + File.separator + "output"; - File output = newFolder(source,expectedRunPath); - JBakeConfiguration configuration = mockJettyConfiguration(sourceFolder,output); + File output = newFolder(source, expectedRunPath); + JBakeConfiguration configuration = mockJettyConfiguration(sourceFolder, output); String[] args = {"-b", "-s", "src/jbake"}; main.run(args); @@ -96,8 +105,8 @@ public void launchBakeAndJettyWithCustomDirForJetty(@TempDir Path source) throws } @Test - public void launchJettyWithCustomServerSourceDir(@TempDir Path output) throws Exception { - File build = newFolder(output,"build/jbake"); + void launchJettyWithCustomServerSourceDir(@TempDir Path output) throws Exception { + File build = newFolder(output, "build/jbake"); JBakeConfiguration configuration = mockJettyConfiguration(build, build); String[] args = {build.getPath(), "-s"}; @@ -110,9 +119,9 @@ public void launchJettyWithCustomServerSourceDir(@TempDir Path output) throws Ex // ATTENTION // There ist no extra argument for -s option. you can call jbake -s /customsource or jbake /customsource -s @Test - public void launchJettyWithCustomDestinationDir(@TempDir Path source) throws Exception { + void launchJettyWithCustomDestinationDir(@TempDir Path source) throws Exception { File src = newFolder(source, "src/jbake"); - JBakeConfiguration configuration = mockJettyConfiguration(src,src); + JBakeConfiguration configuration = mockJettyConfiguration(src, src); String[] args = {"-s", src.getPath()}; main.run(args); @@ -121,10 +130,10 @@ public void launchJettyWithCustomDestinationDir(@TempDir Path source) throws Exc } @Test - public void launchJettyWithCustomSrcAndDestDir(@TempDir Path source, @TempDir Path output) throws Exception { + void launchJettyWithCustomSrcAndDestDir(@TempDir Path source, @TempDir Path output) throws Exception { File src = newFolder(source, "src/jbake"); File exampleOutput = output.resolve("build/jbake").toFile(); - JBakeConfiguration configuration = mockJettyConfiguration(src,exampleOutput); + JBakeConfiguration configuration = mockJettyConfiguration(src, exampleOutput); String[] args = {src.getPath(), exampleOutput.getPath(), "-s"}; main.run(args); @@ -133,7 +142,7 @@ public void launchJettyWithCustomSrcAndDestDir(@TempDir Path source, @TempDir Pa } @Test - public void launchJettyWithCustomDestViaConfig(@TempDir Path output) throws Exception { + void launchJettyWithCustomDestViaConfig(@TempDir Path output) throws Exception { String[] args = {"-s"}; final File exampleOutput = output.resolve("build/jbake").toFile(); DefaultJBakeConfiguration configuration = stubConfig(); @@ -145,7 +154,7 @@ public void launchJettyWithCustomDestViaConfig(@TempDir Path output) throws Exce } @Test - public void launchJettyWithCmdlineOverridingProperties(@TempDir Path source, @TempDir Path output, @TempDir Path target) throws Exception { + void launchJettyWithCmdlineOverridingProperties(@TempDir Path source, @TempDir Path output, @TempDir Path target) throws Exception { final File src = newFolder(source, "src/jbake"); final File expectedOutput = newFolder(output, "build/jbake"); final File configTarget = newFolder(target, "target/jbake"); @@ -159,11 +168,11 @@ public void launchJettyWithCmdlineOverridingProperties(@TempDir Path source, @Te } @Test - public void shouldTellUserThatTemplateOptionRequiresInitOption() throws Exception { + void shouldTellUserThatTemplateOptionRequiresInitOption() throws Exception { String[] args = {"-t", "groovy-mte"}; - assertExitWithStatus(1, ()->Main.main(args)); + assertExitWithStatus(1, () -> Main.main(args)); verify(mockAppender, times(1)).doAppend(captorLoggingEvent.capture()); @@ -171,6 +180,17 @@ public void shouldTellUserThatTemplateOptionRequiresInitOption() throws Exceptio assertThat(loggingEvent.getMessage()).isEqualTo("Invalid commandline arguments: option \"-t (--template)\" requires the option(s) [-i]"); } + @Test + void shouldListCurrentSettings(@TempDir Path source) throws ConfigurationException { + File src = newFolder(source, "src/jbake"); + mockDefaultJbakeConfiguration(src); + + String[] args = {"-ls"}; + main.run(args); + + assertThat(outputStreamCaptor.toString()).contains("DEFAULT - Settings"); + } + private LaunchOptions stubOptions(String[] args) throws CmdLineException { LaunchOptions res = new LaunchOptions(); CmdLineParser parser = new CmdLineParser(res); @@ -180,23 +200,23 @@ private LaunchOptions stubOptions(String[] args) throws CmdLineException { private DefaultJBakeConfiguration stubConfig() throws ConfigurationException { File sourceFolder = TestUtils.getTestResourcesAsSourceFolder(); - DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) new ConfigUtil().loadConfig( sourceFolder ); + DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) new ConfigUtil().loadConfig(sourceFolder); configuration.setServerPort(8820); return configuration; } private void mockDefaultJbakeConfiguration(File sourceFolder) throws ConfigurationException { - DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder,null,false); + 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.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); + DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder, destinationFolder, false); System.setProperty("user.dir", sourceFolder.getPath()); - when(factory.createJettyJbakeConfiguration(any(File.class),any(File.class),anyBoolean())).thenReturn( configuration ); + when(factory.createJettyJbakeConfiguration(any(File.class), any(File.class), anyBoolean())).thenReturn(configuration); return configuration; } diff --git a/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java index 089f61fc4..8d37c543b 100644 --- a/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java +++ b/jbake-core/src/test/java/org/jbake/util/ConfigurationPrinterTest.java @@ -1,21 +1,19 @@ package org.jbake.util; -import org.hamcrest.CoreMatchers; import org.jbake.TestUtils; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; -public class ConfigurationPrinterTest { +class ConfigurationPrinterTest { @Test - public void shouldPrintHeader() throws Exception { - + void shouldPrintHeader() throws Exception { JBakeConfiguration configuration = new JBakeConfigurationFactory().getConfigUtil().loadConfig(TestUtils.getTestResourcesAsSourceFolder()); ByteArrayOutputStream data = new ByteArrayOutputStream(); PrintStream out = new PrintStream(data); @@ -23,15 +21,15 @@ public void shouldPrintHeader() throws Exception { printer.print(); - assertThat(data.toString(), CoreMatchers.containsString("DEFAULT - Settings")); - assertThat(data.toString(), CoreMatchers.containsString("CUSTOM - Settings")); - assertThat(data.toString(), CoreMatchers.containsString("Key")); - assertThat(data.toString(), CoreMatchers.containsString("Value")); + assertThat(data.toString()).contains("DEFAULT - Settings"); + assertThat(data.toString()).contains("CUSTOM - Settings"); + assertThat(data.toString()).contains("Key"); + assertThat(data.toString()).contains("Value"); } @Test - public void shouldPrintKeyAndValue() throws Exception { + void shouldPrintKeyAndValue() throws Exception { JBakeConfiguration configuration = new JBakeConfigurationFactory().getConfigUtil().loadConfig(TestUtils.getTestResourcesAsSourceFolder()); ByteArrayOutputStream data = new ByteArrayOutputStream(); PrintStream out = new PrintStream(data); @@ -39,7 +37,7 @@ public void shouldPrintKeyAndValue() throws Exception { printer.print(); - assertThat(data.toString(), CoreMatchers.containsString("site.host")); - assertThat(data.toString(), CoreMatchers.containsString("http://www.jbake.org")); + assertThat(data.toString()).contains("site.host"); + assertThat(data.toString()).contains("http://www.jbake.org"); } -} \ No newline at end of file +} From c4d5a062c6e1b8a1759321b15a52548adb0b2cbb Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 17 Aug 2018 08:05:10 +0200 Subject: [PATCH 11/27] cleanup MarkupEngine --- jbake-core/src/main/java/org/jbake/parser/ParserContext.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java index 17a94f232..85eb48a3b 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java @@ -1,5 +1,6 @@ package org.jbake.parser; +import com.orientechnologies.orient.core.hook.ORecordHook; import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; From 9886f6a0c7fa5693392b83803d12bda3a1eb4d7e Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Fri, 17 Aug 2018 13:19:18 +0200 Subject: [PATCH 12/27] removed unused imports --- jbake-core/src/main/java/org/jbake/parser/ParserContext.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java index 85eb48a3b..17a94f232 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java @@ -1,6 +1,5 @@ package org.jbake.parser; -import com.orientechnologies.orient.core.hook.ORecordHook; import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; From 33f4a5fb08c7c777b80222a0af427c865217beea Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 18 Aug 2018 13:51:33 +0200 Subject: [PATCH 13/27] introduced DocumentModel --- .../main/java/org/jbake/app/ContentStore.java | 8 +- .../src/main/java/org/jbake/app/Crawler.java | 67 ++++------ .../src/main/java/org/jbake/app/Parser.java | 12 +- .../src/main/java/org/jbake/app/Renderer.java | 46 +++---- .../org/jbake/model/DocumentAttributes.java | 13 +- .../java/org/jbake/model/DocumentModel.java | 115 ++++++++++++++++++ .../java/org/jbake/parser/ErrorEngine.java | 16 ++- .../java/org/jbake/parser/MarkupEngine.java | 9 +- .../java/org/jbake/parser/ParserContext.java | 36 +++--- .../java/org/jbake/parser/ParserEngine.java | 10 +- .../org/jbake/render/DocumentsRenderer.java | 14 +-- .../template/ThymeleafTemplateEngine.java | 9 +- .../main/java/org/jbake/util/HtmlUtil.java | 18 ++- .../java/org/jbake/FakeDocumentBuilder.java | 27 ++-- .../java/org/jbake/app/ContentStoreTest.java | 72 +++++------ .../test/java/org/jbake/app/CrawlerTest.java | 7 +- .../AbstractTemplateEngineRenderingTest.java | 15 +-- ...oovyMarkupTemplateEngineRenderingTest.java | 6 +- .../jbake/render/DocumentsRendererTest.java | 18 ++- .../java/org/jbake/render/RendererTest.java | 12 +- .../java/org/jbake/util/HtmlUtilTest.java | 113 ++++++++--------- 21 files changed, 372 insertions(+), 271 deletions(-) create mode 100644 jbake-core/src/main/java/org/jbake/model/DocumentModel.java diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 7ebce3433..04fb5ef95 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -48,7 +48,6 @@ import java.util.Map; import java.util.Set; - /** * @author jdlee */ @@ -189,6 +188,7 @@ private void activateOnCurrentThread() { /** * Get a document by sourceUri and update it from the given map. + * * @param incomingDocMap The document's db columns. * @return The saved document. * @throws IllegalArgumentException if sourceUri or docType are null, or if the document doesn't exist. @@ -200,7 +200,7 @@ public ODocument mergeDocument(Map incomingDocMap) { throw new IllegalArgumentException("Document sourceUri is null."); } - String docType = (String) incomingDocMap.get(Crawler.Attributes.TYPE); + String docType = (String) incomingDocMap.get(DocumentAttributes.TYPE.toString()); if (null == docType) { throw new IllegalArgumentException("Document docType is null."); @@ -356,7 +356,7 @@ public Set getTags() { DocumentList docs = this.getAllTagsFromPublishedPosts(); Set result = new HashSet<>(); for (Map document : docs) { - String[] tags = DBUtil.toStringArray(document.get(Crawler.Attributes.TAGS)); + String[] tags = DBUtil.toStringArray(document.get(DocumentAttributes.TAGS.toString())); Collections.addAll(result, tags); } return result; @@ -368,7 +368,7 @@ public Set getAllTags() { String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, quoteIdentifier(docType)); DocumentList docs = query(statement); for (Map document : docs) { - String[] tags = DBUtil.toStringArray(document.get(Crawler.Attributes.TAGS)); + String[] tags = DBUtil.toStringArray(document.get(DocumentAttributes.TAGS.toString())); Collections.addAll(result, tags); } } 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..e1a0dc5a4 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -7,6 +7,7 @@ import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentStatus; import org.jbake.model.DocumentTypes; import org.jbake.util.HtmlUtil; @@ -186,42 +187,17 @@ private boolean useNoExtensionUri(String uri) { private void crawlSourceFile(final File sourceFile, final String sha1, final String uri) { try { - Map fileContents = parser.processFile(sourceFile); + DocumentModel fileContents = parser.processFile(sourceFile); if (fileContents != null) { - fileContents.put(Attributes.ROOTPATH, getPathToRoot(sourceFile)); - fileContents.put(String.valueOf(DocumentAttributes.SHA1), sha1); - fileContents.put(String.valueOf(DocumentAttributes.RENDERED), false); - if (fileContents.get(Attributes.TAGS) != null) { - // store them as a String[] - String[] tags = (String[]) fileContents.get(Attributes.TAGS); - fileContents.put(Attributes.TAGS, tags); - } - fileContents.put(Attributes.FILE, sourceFile.getPath()); - fileContents.put(String.valueOf(DocumentAttributes.SOURCE_URI), uri); - fileContents.put(Attributes.URI, uri); - - String documentType = (String) fileContents.get(Attributes.TYPE); - if (fileContents.get(Attributes.STATUS).equals(Status.PUBLISHED_DATE)) { - if (fileContents.get(Attributes.DATE) != null && (fileContents.get(Attributes.DATE) instanceof Date)) { - if (new Date().after((Date) fileContents.get(Attributes.DATE))) { - fileContents.put(Attributes.STATUS, Status.PUBLISHED); - } - } - } - - if (config.getUriWithoutExtension()) { - fileContents.put(Attributes.NO_EXTENSION_URI, uri.replace("/index.html", "/")); - } + addAdditionalDocumentAttributes(fileContents, sourceFile, sha1, uri); if (config.getImgPathUpdate()) { // Prevent image source url's from breaking HtmlUtil.fixImageSourceUrls(fileContents, config); } - ODocument doc = new ODocument(documentType); + ODocument doc = new ODocument(fileContents.getType()); doc.fromMap(fileContents); - boolean cached = fileContents.get(String.valueOf(DocumentAttributes.CACHED)) != null ? Boolean.valueOf((String) fileContents.get(String.valueOf(DocumentAttributes.CACHED))) : true; - doc.field(String.valueOf(DocumentAttributes.CACHED), cached); doc.save(); } else { LOGGER.warn("{} has an invalid header, it has been ignored!", sourceFile); @@ -229,6 +205,28 @@ private void crawlSourceFile(final File sourceFile, final String sha1, final Str } catch (Exception ex) { throw new RuntimeException("Failed crawling file: " + sourceFile.getPath() + " " + ex.getMessage(), ex); } + + } + + private void addAdditionalDocumentAttributes(DocumentModel documentModel, File sourceFile, String sha1, String uri) { + documentModel.setRootPath(getPathToRoot(sourceFile)); + documentModel.setSha1(sha1); + documentModel.setRendered(false); + documentModel.setFile(sourceFile.getPath()); + documentModel.setSourceUri(uri); + documentModel.setUri(uri); + + if (documentModel.getStatus().equals(Status.PUBLISHED_DATE)) { + if (documentModel.getDate() != null) { + if (new Date().after(documentModel.getDate())) { + documentModel.setStatus(Status.PUBLISHED); + } + } + } + + if (config.getUriWithoutExtension()) { + documentModel.setNoExtensionUri(uri.replace("/index.html", "/")); + } } private String getPathToRoot(File sourceFile) { @@ -252,27 +250,16 @@ private DocumentStatus findDocumentStatus(String docType, String uri, String sha public abstract static class Attributes { - public static final String DATE = "date"; - public static final String STATUS = "status"; - public static final String TYPE = "type"; - public static final String TITLE = "title"; - public static final String URI = "uri"; - public static final String FILE = "file"; - public static final String TAGS = "tags"; public static final String TAG = "tag"; - public static final String ROOTPATH = "rootpath"; - public static final String ID = "id"; - public static final String NO_EXTENSION_URI = "noExtensionUri"; public static final String ALLTAGS = "alltags"; public static final String PUBLISHED_DATE = "published_date"; - public static final String BODY = "body"; public static final String DB = "db"; private Attributes() { } /** - * Possible values of the {@link Attributes#STATUS} property + * Possible values of the {@link DocumentAttributes#STATUS} property * * @author ndx */ diff --git a/jbake-core/src/main/java/org/jbake/app/Parser.java b/jbake-core/src/main/java/org/jbake/app/Parser.java index d2da80ee9..129b01abf 100644 --- a/jbake-core/src/main/java/org/jbake/app/Parser.java +++ b/jbake-core/src/main/java/org/jbake/app/Parser.java @@ -1,13 +1,13 @@ package org.jbake.app; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import org.jbake.parser.Engines; import org.jbake.parser.ParserEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.util.Map; /** * Parses a File for content. @@ -31,13 +31,13 @@ public Parser(JBakeConfiguration config) { /** * Process the file by parsing the contents. * - * @param file File input for parsing - * @return The contents of the file + * @param file File input for parsing + * @return The contents of the file */ - public Map processFile(File file) { + public DocumentModel processFile(File file) { ParserEngine engine = Engines.get(FileUtil.fileExt(file)); - if (engine==null) { - LOGGER.error("Unable to find suitable markup engine for {}",file); + if (engine == null) { + LOGGER.error("Unable to find suitable markup engine for {}", file); return null; } 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 696569ec2..74af6f14a 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -5,16 +5,14 @@ import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; +import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.jbake.template.DelegatingTemplateEngine; import org.jbake.util.PagingHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; +import java.io.*; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -107,8 +105,8 @@ private String findTemplateName(String docType) { * @throws Exception if IOException or SecurityException are raised */ public void render(Map content) throws Exception { - String docType = (String) content.get(Crawler.Attributes.TYPE); - String outputFilename = config.getDestinationFolder().getPath() + File.separatorChar + content.get(Attributes.URI); + String docType = (String) content.get(DocumentAttributes.TYPE.toString()); + String outputFilename = config.getDestinationFolder().getPath() + File.separatorChar + content.get(DocumentAttributes.URI.toString()); if (outputFilename.lastIndexOf('.') > outputFilename.lastIndexOf(File.separatorChar)) { outputFilename = outputFilename.substring(0, outputFilename.lastIndexOf('.')); } @@ -125,7 +123,7 @@ public void render(Map content) throws Exception { publishedFile.delete(); } - if (content.get(Crawler.Attributes.STATUS).equals(Crawler.Attributes.Status.DRAFT)) { + if (content.get(DocumentAttributes.STATUS.toString()).equals(Crawler.Attributes.Status.DRAFT)) { outputFilename = outputFilename + config.getDraftSuffix(); } @@ -204,10 +202,10 @@ public void renderIndexPaging(String indexFile) throws Exception { String nextFileName = pagingHelper.getNextFileName(page); model.put("nextFileName", nextFileName); - Map contentModel = buildSimpleModel(MASTERINDEX_TEMPLATE_NAME); + DocumentModel contentModel = buildSimpleModel(MASTERINDEX_TEMPLATE_NAME); - if(page > 1){ - contentModel.put(Attributes.ROOTPATH, "../"); + if (page > 1) { + contentModel.setRootPath("../"); } model.put("content", contentModel); @@ -268,14 +266,16 @@ public int renderTags(String tagPath) throws Exception { for (String tag : db.getAllTags()) { try { + Map model = new HashMap<>(); + File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + tag + config.getOutputExtension()); + model.put("renderer", renderingEngine); model.put(Attributes.TAG, tag); - Map map = buildSimpleModel(Attributes.TAG); + DocumentModel map = buildSimpleModel(Attributes.TAG); + map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); model.put("content", map); - 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))); @@ -291,12 +291,14 @@ public int renderTags(String tagPath) throws Exception { // This will prevent directory listing and also provide an option to // display all tags page. Map model = new HashMap(); + File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + "index" + config.getOutputExtension()); + model.put("renderer", renderingEngine); - Map map = buildSimpleModel(Attributes.TAGS); + DocumentModel map = buildSimpleModel(DocumentAttributes.TAGS.toString()); + map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); model.put("content", map); - File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + "index" + config.getOutputExtension()); - map.put(Attributes.ROOTPATH, FileUtil.getUriPathToDestinationRoot(config, path)); + render(new ModelRenderingConfig(path, "tagindex", model, findTemplateName("tagsindex"))); renderedCount++; } catch (Exception e) { @@ -320,12 +322,12 @@ public int renderTags(String tagPath) throws Exception { * Builds simple map of values, which are exposed when rendering index/archive/sitemap/feed/tags. * * @param type - * @return + * @return a basic {@link DocumentModel} */ - private Map buildSimpleModel(String type) { - Map content = new HashMap(); - content.put(Attributes.TYPE, type); - content.put(Attributes.ROOTPATH, ""); + private DocumentModel buildSimpleModel(String type) { + DocumentModel content = new DocumentModel(); + content.setType(type); + content.setRootPath(""); // add any more keys here that need to have a default value to prevent need to perform null check in templates return content; } diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java b/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java index ae698fb1c..a715584a1 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java @@ -4,9 +4,18 @@ public enum DocumentAttributes { SHA1("sha1"), SOURCE_URI("sourceuri"), RENDERED("rendered"), - CACHED("cached"), + CACHED("cached"), //TODO: Do we need this? STATUS("status"), - NAME("name"); + NAME("name"), + BODY("body"), + DATE("date"), + TYPE("type"), + TAGS("tags"), + URI("uri"), + ROOTPATH("rootpath"), + FILE("file"), + NO_EXTENSION_URI("noExtensionUri"), + TITLE("title"); private String label; diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java new file mode 100644 index 000000000..a47b1fe00 --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -0,0 +1,115 @@ +package org.jbake.model; + +import java.util.Date; +import java.util.HashMap; + +public class DocumentModel extends HashMap { + + + public DocumentModel() { + super(); + } + + public String getBody() { + return get(DocumentAttributes.BODY.toString()).toString(); + } + + public void setBody(String body) { + put(DocumentAttributes.BODY.toString(), body); + } + + public Date getDate() { + return (Date) get(DocumentAttributes.DATE.toString()); + } + + public void setDate(Date date) { + put(DocumentAttributes.DATE.toString(), date); + } + + public String getStatus() { + if (containsKey(DocumentAttributes.STATUS.toString())) { + return get(DocumentAttributes.STATUS.toString()).toString(); + } + return ""; + + } + + public void setStatus(String status) { + put(DocumentAttributes.STATUS.toString(), status); + } + + public String getType() { + if (containsKey(DocumentAttributes.TYPE.toString())) { + return get(DocumentAttributes.TYPE.toString()).toString(); + } + return ""; + } + + public void setType(String type) { + put(DocumentAttributes.TYPE.toString(), type); + } + + public String[] getTags() { + return (String[]) get(DocumentAttributes.TAGS.toString()); + } + + public void setTags(String[] tags) { + put(DocumentAttributes.TAGS.toString(), tags); + } + + public String getSha1() { + return (String) get(DocumentAttributes.SHA1.toString()); + } + + public void setSha1(String sha1) { + put(DocumentAttributes.SHA1.toString(), sha1); + } + + public String getUri() { + return (String) get(DocumentAttributes.URI.toString()); + } + + public void setUri(String uri) { + put(DocumentAttributes.URI.toString(), uri); + } + + public void setSourceUri(String uri) { + put(DocumentAttributes.SOURCE_URI.toString(), uri); + } + + public void setRootPath(String pathToRoot) { + put(DocumentAttributes.ROOTPATH.toString(), pathToRoot); + } + + public void setRendered(boolean rendered) { + put(DocumentAttributes.RENDERED.toString(), rendered); + } + + public void setFile(String path) { + put(DocumentAttributes.FILE.toString(), path); + } + + public String getNoExtensionUri() { + return (String) get(DocumentAttributes.NO_EXTENSION_URI.toString()); + } + + public void setNoExtensionUri(String noExtensionUri) { + put(DocumentAttributes.NO_EXTENSION_URI.toString(), noExtensionUri); + } + + public void setTitle(String title) { + put(DocumentAttributes.TITLE.toString(), title); + } + + public void setName(String name) { + put(DocumentAttributes.NAME.toString(), name); + } + + public void setCached(boolean cached) { + put(DocumentAttributes.CACHED.toString(), cached); + } + + public boolean getCached() { + return (boolean) get(DocumentAttributes.CACHED.toString()); + } +} diff --git a/jbake-core/src/main/java/org/jbake/parser/ErrorEngine.java b/jbake-core/src/main/java/org/jbake/parser/ErrorEngine.java index bf654f6c8..b4d6051b2 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ErrorEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/ErrorEngine.java @@ -1,9 +1,8 @@ package org.jbake.parser; -import org.jbake.app.Crawler.Attributes; +import org.jbake.model.DocumentModel; import java.util.Date; -import java.util.Map; /** * An internal rendering engine used to notify the user that the markup format he used requires an engine that couldn't @@ -24,13 +23,12 @@ public ErrorEngine(final String name) { @Override public void processHeader(final ParserContext context) { - Map contents = context.getDocumentModel(); - contents.put(Attributes.TYPE, "post"); - contents.put(Attributes.STATUS, "published"); - contents.put(Attributes.TITLE, "Rendering engine missing"); - contents.put(Attributes.DATE, new Date()); - contents.put(Attributes.TAGS, new String[0]); - contents.put(Attributes.ID, context.getFile().getName()); + DocumentModel documentModel = context.getDocumentModel(); + documentModel.setType("post"); + documentModel.setStatus("published"); + documentModel.setTitle("Rendering engine missing"); + documentModel.setDate(new Date()); + documentModel.setTags(new String[0]); } @Override 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..2acf66ef5 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -3,9 +3,10 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.io.IOUtils; -import org.jbake.app.Crawler; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.json.simple.JSONValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,7 +76,7 @@ public Map parse(Configuration config, File file, String content * @param file file to process * @return a map containing all infos. Returning null indicates an error, even if an exception would be better. */ - public Map parse(JBakeConfiguration config, File file) { + public DocumentModel parse(JBakeConfiguration config, File file) { this.configuration = config; List fileContent = getFileContent(file, config.getRenderEncoding()); @@ -276,7 +277,7 @@ void storeHeaderValue(String inputKey, String inputValue, Map co String key = sanitize(inputKey); String value = sanitize(inputValue); - if (key.equalsIgnoreCase(Crawler.Attributes.DATE)) { + if (key.equalsIgnoreCase(DocumentAttributes.DATE.toString())) { DateFormat df = new SimpleDateFormat(configuration.getDateFormat()); try { Date date = df.parse(value); @@ -284,7 +285,7 @@ void storeHeaderValue(String inputKey, String inputValue, Map co } catch (ParseException e) { LOGGER.error("unable to parse date {}", value); } - } else if (key.equalsIgnoreCase(Crawler.Attributes.TAGS)) { + } else if (key.equalsIgnoreCase(DocumentAttributes.TAGS.toString())) { content.put(key, getTags(value)); } else if (isJson(value)) { content.put(key, JSONValue.parse(value)); diff --git a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java index 17a94f232..5a8fc3edc 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java @@ -1,20 +1,18 @@ package org.jbake.parser; -import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.File; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class ParserContext { private final File file; private final List fileLines; private final JBakeConfiguration config; private final boolean hasHeader; - private final Map documentModel; + private final DocumentModel documentModel; public ParserContext( File file, @@ -25,7 +23,7 @@ public ParserContext( this.fileLines = fileLines; this.config = config; this.hasHeader = hasHeader; - this.documentModel = new HashMap<>(); + this.documentModel = new DocumentModel(); } public File getFile() { @@ -40,7 +38,7 @@ public JBakeConfiguration getConfig() { return config; } - public Map getDocumentModel() { + public DocumentModel getDocumentModel() { return documentModel; } @@ -50,48 +48,48 @@ public boolean hasHeader() { // short methods for common use public String getBody() { - return documentModel.get(Crawler.Attributes.BODY).toString(); + return documentModel.getBody(); } public void setBody(String str) { - documentModel.put(Crawler.Attributes.BODY, str); + documentModel.setBody(str); } - public Object getDate() { - return getDocumentModel().get(Crawler.Attributes.DATE); + public Date getDate() { + return getDocumentModel().getDate(); } public void setDate(Date date) { - getDocumentModel().put(Crawler.Attributes.DATE, date); + getDocumentModel().setDate(date); } public String getStatus() { - if (getDocumentModel().containsKey(Crawler.Attributes.STATUS)) { - return getDocumentModel().get(Crawler.Attributes.STATUS).toString(); + if (getDocumentModel().getStatus() != null) { + return getDocumentModel().getStatus(); } return ""; } public void setDefaultStatus() { - getDocumentModel().put(Crawler.Attributes.STATUS, getConfig().getDefaultStatus()); + getDocumentModel().setStatus(getConfig().getDefaultStatus()); } public String getType() { - if (getDocumentModel().containsKey(Crawler.Attributes.TYPE)) { - return getDocumentModel().get(Crawler.Attributes.TYPE).toString(); + if (getDocumentModel().getType() != null) { + return getDocumentModel().getType(); } return ""; } public void setDefaultType() { - getDocumentModel().put(Crawler.Attributes.TYPE, getConfig().getDefaultType()); + getDocumentModel().setType(getConfig().getDefaultType()); } public Object getTags() { - return getDocumentModel().get(Crawler.Attributes.TAGS); + return getDocumentModel().getTags(); } public void setTags(String[] tags) { - getDocumentModel().put(Crawler.Attributes.TAGS, tags); + getDocumentModel().setTags(tags); } } 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..1c1193832 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserEngine.java @@ -2,6 +2,7 @@ import org.apache.commons.configuration.Configuration; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.File; import java.util.Map; @@ -11,15 +12,16 @@ public interface ParserEngine { /** * Parse a given file and transform to a model representation used by {@link MarkdownEngine} implementations * to render the file content. + * * @param config The project configuration - * @param file The file to be parsed + * @param file The file to be parsed * @return A model representation of the given file */ - Map parse(JBakeConfiguration config, File file); + DocumentModel parse(JBakeConfiguration config, File file); /** - * @param config The project configuration - * @param file The file to be parsed + * @param config The project configuration + * @param file The file to be parsed * @param contentPath unknown * @return A model representation of the given file * @deprecated use {@link #parse(JBakeConfiguration, File)} instead 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..f2be3114f 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -2,15 +2,15 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; import java.io.File; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -79,11 +79,11 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) * @param document * @return */ - private Map getContentForNav(Map document) { - Map navDocument = new HashMap<>(); - navDocument.put(Attributes.NO_EXTENSION_URI, document.get(Attributes.NO_EXTENSION_URI)); - navDocument.put(Attributes.URI, document.get(Attributes.URI)); - navDocument.put(Attributes.TITLE, document.get(Attributes.TITLE)); + private DocumentModel getContentForNav(Map document) { + DocumentModel navDocument = new DocumentModel(); + navDocument.setNoExtensionUri((String) document.get(DocumentAttributes.NO_EXTENSION_URI.toString())); + navDocument.setUri((String) document.get(DocumentAttributes.URI.toString())); + navDocument.setTitle((String) document.get(DocumentAttributes.TITLE.toString())); return navDocument; } 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..d0d870afc 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -5,6 +5,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentAttributes; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.LazyContextVariable; @@ -81,7 +82,7 @@ private String getTemplateModeByModel(Map model) { @SuppressWarnings("unchecked") Map content = (Map) model.get("content"); if (config != null && content != null) { - String key = "template_" + content.get(Attributes.TYPE) + "_thymeleaf_mode"; + String key = "template_" + content.get(DocumentAttributes.TYPE.toString()) + "_thymeleaf_mode"; String configMode = (String) config.get(key); if (configMode != null) { return configMode; @@ -99,7 +100,7 @@ public void renderDocument(Map model, String templateName, Write lock.lock(); try { - initializeContext(locale,model); + initializeContext(locale, model); updateTemplateMode(model); templateEngine.process(templateName, context, writer); } finally { @@ -113,7 +114,7 @@ private void initializeContext(Locale locale, Map model) { context.setVariables(model); for (String key : extractors.keySet()) { - context.setVariable(key, new ContextVariable(db,key,model)); + context.setVariable(key, new ContextVariable(db, key, model)); } } @@ -124,7 +125,7 @@ private class ContextVariable extends LazyContextVariable { private ContentStore db; private String key; - private Map model; + private Map model; public ContextVariable(ContentStore db, String key, Map model) { this.db = db; diff --git a/jbake-core/src/main/java/org/jbake/util/HtmlUtil.java b/jbake-core/src/main/java/org/jbake/util/HtmlUtil.java index cbafe6674..3794286dd 100644 --- a/jbake-core/src/main/java/org/jbake/util/HtmlUtil.java +++ b/jbake-core/src/main/java/org/jbake/util/HtmlUtil.java @@ -1,14 +1,12 @@ package org.jbake.util; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; -import java.util.Map; - /** * @author Manik Magar */ @@ -26,8 +24,8 @@ private HtmlUtil() { * @param fileContents Map representing file contents * @param configuration Configuration object */ - public static void fixImageSourceUrls(Map fileContents, JBakeConfiguration configuration) { - String htmlContent = fileContents.get(Attributes.BODY).toString(); + public static void fixImageSourceUrls(DocumentModel fileContents, JBakeConfiguration configuration) { + String htmlContent = fileContents.getBody(); boolean prependSiteHost = configuration.getImgPathPrependHost(); String siteHost = configuration.getSiteHost(); String uri = getDocumentUri(fileContents); @@ -40,14 +38,14 @@ public static void fixImageSourceUrls(Map fileContents, JBakeCon } //Use body().html() to prevent adding from parsed fragment. - fileContents.put(Attributes.BODY, document.body().html()); + fileContents.setBody(document.body().html()); } - private static String getDocumentUri(Map fileContents) { - String uri = fileContents.get(Attributes.URI).toString(); + private static String getDocumentUri(DocumentModel fileContents) { + String uri = fileContents.getUri(); - if (fileContents.get(Attributes.NO_EXTENSION_URI) != null) { - uri = fileContents.get(Attributes.NO_EXTENSION_URI).toString(); + if (fileContents.getNoExtensionUri() != null) { + uri = fileContents.getNoExtensionUri(); uri = removeTrailingSlash(uri); } diff --git a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java index 85c83be2f..0616bf2d5 100644 --- a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java +++ b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -1,20 +1,17 @@ package org.jbake; import com.orientechnologies.orient.core.record.impl.ODocument; -import org.jbake.app.Crawler; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; -import java.util.HashMap; -import java.util.Map; import java.util.Random; public class FakeDocumentBuilder { - Map fileModel = new HashMap(); + DocumentModel fileModel = new DocumentModel(); String type; private boolean hasSourceUri = false; private boolean hasSha1 = false; @@ -25,53 +22,53 @@ public FakeDocumentBuilder(String type) { } public FakeDocumentBuilder withName(String name) { - fileModel.put(DocumentAttributes.NAME.toString(), name); + fileModel.setName(name); return this; } public FakeDocumentBuilder withStatus(String status) { - fileModel.put(DocumentAttributes.STATUS.toString(), status); + fileModel.setStatus(status); return this; } public FakeDocumentBuilder withRandomSha1() throws NoSuchAlgorithmException { - fileModel.put(DocumentAttributes.SHA1.toString(), getRandomSha1()); + fileModel.setSha1(getRandomSha1()); hasSha1 = true; return this; } public FakeDocumentBuilder withDate(Date date) { - fileModel.put(Crawler.Attributes.DATE, date); + fileModel.setDate(date); hasDate = true; return this; } private FakeDocumentBuilder withCurrentDate() { - fileModel.put(Crawler.Attributes.DATE, new Date() ); + fileModel.setDate(new Date()); return this; } private FakeDocumentBuilder withRandomSourceUri() throws NoSuchAlgorithmException { String path = "/tmp/" + getRandomSha1() + ".txt"; - fileModel.put(DocumentAttributes.SOURCE_URI.toString(), path); + fileModel.setSourceUri(path); return this; } public FakeDocumentBuilder withCached(boolean cached) { - fileModel.put(DocumentAttributes.CACHED.toString(), cached); + fileModel.setCached(cached); return this; } public void build() { try { - if ( ! hasSourceUri() ) { + if (!hasSourceUri()) { this.withRandomSourceUri(); } - if ( ! hasSha1() ) { + if (!hasSha1()) { this.withRandomSha1(); } - if ( ! hasDate() ) { + if (!hasDate()) { this.withCurrentDate(); } ODocument document = new ODocument(type).fromMap(fileModel); diff --git a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java index 77d171325..11ad5fcd0 100644 --- a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java @@ -1,19 +1,21 @@ package org.jbake.app; import com.orientechnologies.orient.core.record.impl.ODocument; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; import org.jbake.FakeDocumentBuilder; -import static org.jbake.app.ContentStore.quoteIdentifier; import org.jbake.app.Crawler.Attributes.Status; import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; +import org.junit.Test; + +import java.util.Collections; +import java.util.Date; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.jbake.app.ContentStore.quoteIdentifier; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import org.junit.Test; public class ContentStoreTest extends ContentStoreIntegrationTest { @@ -45,9 +47,9 @@ public void testMergeDocument() { final String uri = "test/testMergeDocument"; ODocument doc = new ODocument(DOC_TYPE_POST); - Map values = new HashMap(); - values.put(Crawler.Attributes.TYPE, DOC_TYPE_POST); - values.put(DocumentAttributes.SOURCE_URI.toString(), uri); + DocumentModel values = new DocumentModel(); + values.setType(DOC_TYPE_POST); + values.setSourceUri(uri); values.put("foo", "originalValue"); doc.fromMap(values); doc.save(); @@ -82,20 +84,18 @@ public void testStoreTypeWithSpecialCharacters() { final String tagWithHyphen = "tag-with-hyphen"; final String uri = "test/testMergeDocument"; - Map values = new HashMap(); - values.put(Crawler.Attributes.TYPE, typeWithHyphen); - values.put(Crawler.Attributes.TAG, tagWithHyphen); - values.put(Crawler.Attributes.TAGS, new String[]{tagWithHyphen}); - values.put(Crawler.Attributes.STATUS, Status.DRAFT); - values.put(Crawler.Attributes.DATE, new Date()); - values.put(DocumentAttributes.RENDERED.toString(), false); - values.put(DocumentAttributes.SOURCE_URI.toString(), uri); - values.put(DocumentAttributes.CACHED.toString(), true); - values.put(DocumentAttributes.RENDERED.toString(), false); - values.put("foo", "originalValue"); + DocumentModel model = new DocumentModel(); + model.setType(typeWithHyphen); + model.setTags(new String[]{tagWithHyphen}); + model.setStatus(Status.DRAFT); + model.setDate(new Date()); + model.setRendered(false); + model.setSourceUri(uri); + model.setCached(true); + model.put("foo", "originalValue"); ODocument doc = new ODocument(typeWithHyphen); - doc.fromMap(values); + doc.fromMap(model); doc.save(); DocumentList documentList1 = db.getAllContent(typeWithHyphen); @@ -117,22 +117,22 @@ public void testStoreTypeWithSpecialCharacters() { DocumentList documentList4 = db.getDocumentStatus(typeWithHyphen, uri); assertEquals(1, documentList4.size()); - assertEquals(Boolean.FALSE, documentList4.get(0).get(String.valueOf(DocumentAttributes.RENDERED))); + assertEquals(Boolean.FALSE, documentList4.get(0).get(DocumentAttributes.RENDERED.toString())); long documentCount2 = db.getPublishedCount(typeWithHyphen); assertEquals(0, documentCount2); - Map published = new HashMap<>(); - published.put(DocumentAttributes.SOURCE_URI.toString(), uri); - published.put(Crawler.Attributes.TYPE, typeWithHyphen); - published.put(Crawler.Attributes.STATUS, Status.PUBLISHED); + DocumentModel published = new DocumentModel(); + published.setSourceUri(uri); + published.setType(typeWithHyphen); + published.setStatus(Status.PUBLISHED); db.mergeDocument(published); DocumentList documentList5 = db.getUnrenderedContent(typeWithHyphen); assertEquals(1, documentList5.size()); - assertEquals(Boolean.FALSE, documentList5.get(0).get(String.valueOf(DocumentAttributes.RENDERED))); - assertEquals(typeWithHyphen, documentList5.get(0).get(Crawler.Attributes.TYPE)); - assertEquals(tagWithHyphen, documentList5.get(0).get(Crawler.Attributes.TAG)); + assertEquals(Boolean.FALSE, documentList5.get(0).get(DocumentAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList5.get(0).get(DocumentAttributes.TYPE.toString())); + assertThat((String[])documentList5.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); long documentCount3 = db.getPublishedCount(typeWithHyphen); assertEquals(1, documentCount3); @@ -141,15 +141,15 @@ public void testStoreTypeWithSpecialCharacters() { DocumentList documentList6 = db.getPublishedContent(typeWithHyphen); assertEquals(1, documentList6.size()); - assertEquals(Boolean.TRUE, documentList6.get(0).get(String.valueOf(DocumentAttributes.RENDERED))); - assertEquals(typeWithHyphen, documentList6.get(0).get(Crawler.Attributes.TYPE)); - assertEquals(tagWithHyphen, documentList6.get(0).get(Crawler.Attributes.TAG)); + assertEquals(Boolean.TRUE, documentList6.get(0).get(DocumentAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList6.get(0).get(DocumentAttributes.TYPE.toString())); + assertThat((String[])documentList6.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); DocumentList documentList7 = db.getPublishedDocumentsByTag(tagWithHyphen); assertEquals(1, documentList7.size()); - assertEquals(Boolean.TRUE, documentList7.get(0).get(String.valueOf(DocumentAttributes.RENDERED))); - assertEquals(typeWithHyphen, documentList7.get(0).get(Crawler.Attributes.TYPE)); - assertEquals(tagWithHyphen, documentList7.get(0).get(Crawler.Attributes.TAG)); + assertEquals(Boolean.TRUE, documentList7.get(0).get(DocumentAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList7.get(0).get(DocumentAttributes.TYPE.toString())); + assertThat((String[])documentList7.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); DocumentList documentList8 = db.getPublishedPostsByTag(tagWithHyphen); assertEquals(0, documentList8.size()); diff --git a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java index a08315679..9ce6548c6 100644 --- a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java +++ b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java @@ -3,6 +3,7 @@ import org.apache.commons.io.FilenameUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; +import org.jbake.model.DocumentAttributes; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -28,7 +29,7 @@ public void crawl() { for (Map content : results) { assertThat(content) - .containsKey(Crawler.Attributes.ROOTPATH) + .containsKey(DocumentAttributes.ROOTPATH.toString()) .containsValue("../../../"); } @@ -37,8 +38,8 @@ public void crawl() { assertThat(allPosts.size()).isEqualTo(4); for (Map content : allPosts) { - if (content.get(Crawler.Attributes.TITLE).equals("Draft Post")) { - assertThat(content).containsKey(Crawler.Attributes.DATE); + if (content.get(DocumentAttributes.TITLE.toString()).equals("Draft Post")) { + assertThat(content).containsKey(DocumentAttributes.DATE.toString()); } } diff --git a/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java b/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java index 3c88c8e41..88c269e24 100644 --- a/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java +++ b/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java @@ -28,6 +28,7 @@ import org.jbake.app.Crawler; import org.jbake.app.Parser; import org.jbake.app.Renderer; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.ModelExtractors; import org.jbake.template.ModelExtractorsDocumentTypeListener; @@ -40,11 +41,7 @@ import java.io.File; import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; @@ -161,8 +158,8 @@ public void renderPost() throws Exception { File sampleFile = new File(sourceFolder.getPath() + File.separator + "content" + File.separator + "blog" + File.separator + "2013" + File.separator + filename); - Map content = parser.processFile(sampleFile); - content.put(Crawler.Attributes.URI, "/" + filename); + DocumentModel content = parser.processFile(sampleFile); + content.setUri("/" + filename); renderer.render(content); File outputFile = new File(destinationFolder, filename); Assert.assertTrue(outputFile.exists()); @@ -180,8 +177,8 @@ public void renderPage() throws Exception { String filename = "about.html"; File sampleFile = new File(sourceFolder.getPath() + File.separator + "content" + File.separator + filename); - Map content = parser.processFile(sampleFile); - content.put(Crawler.Attributes.URI, "/" + filename); + DocumentModel content = parser.processFile(sampleFile); + content.setUri("/" + filename); renderer.render(content); File outputFile = new File(destinationFolder, filename); Assert.assertTrue(outputFile.exists()); diff --git a/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java b/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java index 091a03fbf..cda5e044e 100644 --- a/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java +++ b/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java @@ -5,6 +5,7 @@ import org.jbake.app.DBUtil; import org.jbake.app.Parser; import org.jbake.app.Renderer; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.junit.Assert; import org.junit.BeforeClass; @@ -13,7 +14,6 @@ import java.io.File; import java.nio.charset.Charset; import java.util.Arrays; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -75,8 +75,8 @@ public void renderCustomTypePaper() throws Exception { String filename = "published-paper.html"; File sampleFile = new File(sourceFolder.getPath() + File.separator + "content" + File.separator + "papers" + File.separator + filename); - Map content = parser.processFile(sampleFile); - content.put(Crawler.Attributes.URI, "/" + filename); + DocumentModel content = parser.processFile(sampleFile); + content.setUri("/" + filename); renderer.render(content); File outputFile = new File(destinationFolder, filename); Assert.assertTrue(outputFile.exists()); diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index cc57bab39..b61ca0093 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -1,10 +1,10 @@ package org.jbake.render; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.DocumentList; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; import org.junit.Before; @@ -22,11 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class DocumentsRendererTest { @@ -168,12 +164,12 @@ private HashMap emptyDocument() { return new HashMap<>(); } - private Map simpleDocument(String title) { - Map simpleDoc = new HashMap<>(); + private DocumentModel simpleDocument(String title) { + DocumentModel simpleDoc = new DocumentModel(); String uri = title.replace(" ", "_"); - simpleDoc.put(Attributes.NO_EXTENSION_URI, uri); - simpleDoc.put(Attributes.URI, uri); - simpleDoc.put(Attributes.TITLE, title); + simpleDoc.setNoExtensionUri(uri); + simpleDoc.setUri(uri); + simpleDoc.setTitle(title); return simpleDoc; } diff --git a/jbake-core/src/test/java/org/jbake/render/RendererTest.java b/jbake-core/src/test/java/org/jbake/render/RendererTest.java index a022bd73e..c1cd2f0ce 100644 --- a/jbake-core/src/test/java/org/jbake/render/RendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/RendererTest.java @@ -2,10 +2,10 @@ import org.jbake.TestUtils; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler; import org.jbake.app.Renderer; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; +import org.jbake.model.DocumentModel; import org.jbake.template.DelegatingTemplateEngine; import org.junit.Assume; import org.junit.Before; @@ -18,8 +18,6 @@ import java.io.File; import java.net.URL; -import java.util.HashMap; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -65,10 +63,10 @@ public void testRenderFileWorksWhenPathHasDotInButFileDoesNot() throws Exception config.setTemplateFolder(folder.newFolder("templates")); Renderer renderer = new Renderer(db, config, renderingEngine); - Map content = new HashMap<>(); - content.put(Crawler.Attributes.TYPE, "page"); - content.put(Crawler.Attributes.URI, "/" + FOLDER + "/" + FILENAME); - content.put(Crawler.Attributes.STATUS, "published"); + DocumentModel content = new DocumentModel(); + content.setType("page"); + content.setUri("/" + FOLDER + "/" + FILENAME); + content.setStatus("published"); renderer.render(content); diff --git a/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java b/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java index b4f43e5f3..bc9ffb8c9 100644 --- a/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java +++ b/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java @@ -4,12 +4,11 @@ import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; +import org.jbake.model.DocumentModel; import org.junit.Before; import org.junit.Test; import java.io.File; -import java.util.HashMap; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -25,14 +24,14 @@ public void setUp() throws Exception { @Test public void shouldNotAddBodyHTMLElement() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).doesNotContain(""); assertThat(body).doesNotContain(""); @@ -41,15 +40,15 @@ public void shouldNotAddBodyHTMLElement() { @Test public void shouldNotAddSiteHost() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); config.setImgPathPrependHost(false); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"blog/2017/05/first.jpg\""); @@ -57,29 +56,30 @@ public void shouldNotAddSiteHost() { @Test public void shouldAddSiteHostWithRelativeImageToDocument() { - Map fileContent = new HashMap<>(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); config.setImgPathPrependHost(true); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/img/deeper/underground.jpg\""); } @Test public void shouldAddContentPath() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); + config.setImgPathPrependHost(true); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/first.jpg\""); @@ -87,14 +87,15 @@ public void shouldAddContentPath() { @Test public void shouldAddContentPathForCurrentDirectory() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); + config.setImgPathPrependHost(true); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/first.jpg\""); @@ -102,14 +103,14 @@ public void shouldAddContentPathForCurrentDirectory() { @Test public void shouldNotAddRootPath() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/first.jpg\""); @@ -117,15 +118,15 @@ public void shouldNotAddRootPath() { @Test public void shouldNotAddRootPathForNoExtension() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setNoExtensionUri("blog/2017/05/first_post/"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/first.jpg\""); @@ -133,30 +134,30 @@ public void shouldNotAddRootPathForNoExtension() { @Test public void shouldAddContentPathForNoExtension() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setNoExtensionUri("blog/2017/05/first_post/"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://www.jbake.org/blog/2017/05/first.jpg\""); } @Test public void shouldNotChangeForHTTP() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setNoExtensionUri("blog/2017/05/first_post/"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"http://example.com/first.jpg\""); @@ -164,15 +165,15 @@ public void shouldNotChangeForHTTP() { @Test public void shouldNotChangeForHTTPS() { - Map fileContent = new HashMap(); - fileContent.put(Attributes.ROOTPATH, "../../../"); - fileContent.put(Attributes.URI, "blog/2017/05/first_post.html"); - fileContent.put(Attributes.NO_EXTENSION_URI, "blog/2017/05/first_post/"); - fileContent.put(Attributes.BODY, "
Test
"); + DocumentModel fileContent = new DocumentModel(); + fileContent.setRootPath("../../../"); + fileContent.setUri("blog/2017/05/first_post.html"); + fileContent.setNoExtensionUri("blog/2017/05/first_post/"); + fileContent.setBody("
Test
"); HtmlUtil.fixImageSourceUrls(fileContent, config); - String body = fileContent.get(Attributes.BODY).toString(); + String body = fileContent.getBody(); assertThat(body).contains("src=\"https://example.com/first.jpg\""); } From 3e0bc64d7d6d22ea213f349a307c87e393ca769c Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 18 Aug 2018 15:49:20 +0200 Subject: [PATCH 14/27] use DocumentModel --- .../main/java/org/jbake/app/ContentStore.java | 13 +-- .../src/main/java/org/jbake/app/Crawler.java | 18 ++--- .../src/main/java/org/jbake/app/DBUtil.java | 16 ++-- .../main/java/org/jbake/app/DocumentList.java | 5 +- .../src/main/java/org/jbake/app/Renderer.java | 79 +++++++++---------- .../DefaultJBakeConfiguration.java | 7 ++ .../app/configuration/JBakeConfiguration.java | 7 ++ .../org/jbake/model/DocumentAttributes.java | 14 +++- .../java/org/jbake/model/DocumentModel.java | 73 ++++++++++++++++- .../org/jbake/parser/AsciidoctorEngine.java | 3 +- .../java/org/jbake/parser/MarkupEngine.java | 9 ++- .../org/jbake/render/DocumentsRenderer.java | 26 +++--- .../template/AbstractTemplateEngine.java | 15 ++-- .../template/DelegatingTemplateEngine.java | 7 +- .../template/FreemarkerTemplateEngine.java | 28 ++----- .../template/GroovyMarkupTemplateEngine.java | 5 +- .../jbake/template/GroovyTemplateEngine.java | 14 ++-- .../jbake/template/JadeTemplateEngine.java | 14 ++-- .../org/jbake/template/ModelExtractor.java | 4 +- .../jbake/template/PebbleTemplateEngine.java | 3 +- .../template/ThymeleafTemplateEngine.java | 27 ++----- .../template/model/TagPostsExtractor.java | 5 +- .../model/TaggedDocumentsExtractor.java | 6 +- .../jbake/template/model/TagsExtractor.java | 12 +-- .../jbake/render/DocumentsRendererTest.java | 25 +++--- 25 files changed, 249 insertions(+), 186 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 04fb5ef95..828bcbc3e 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -37,6 +37,7 @@ import com.orientechnologies.orient.core.sql.executor.OResultSet; import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -355,8 +356,8 @@ private void executeCommand(String query, Object... args) { public Set getTags() { DocumentList docs = this.getAllTagsFromPublishedPosts(); Set result = new HashSet<>(); - for (Map document : docs) { - String[] tags = DBUtil.toStringArray(document.get(DocumentAttributes.TAGS.toString())); + for (DocumentModel document : docs) { + String[] tags = document.getTags(); Collections.addAll(result, tags); } return result; @@ -367,8 +368,8 @@ public Set getAllTags() { for (String docType : DocumentTypes.getDocumentTypes()) { String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, quoteIdentifier(docType)); DocumentList docs = query(statement); - for (Map document : docs) { - String[] tags = DBUtil.toStringArray(document.get(DocumentAttributes.TAGS.toString())); + for (DocumentModel document : docs) { + String[] tags = document.getTags(); Collections.addAll(result, tags); } } @@ -405,7 +406,7 @@ private void createDocType(final OSchema schema, final String docType) { private void createSignatureType(OSchema schema) { OClass signatures = schema.createClass("Signatures"); - signatures.createProperty(String.valueOf(DocumentAttributes.SHA1), OType.STRING).setNotNull(true); + signatures.createProperty(DocumentAttributes.SHA1.toString(), OType.STRING).setNotNull(true); signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, DocumentAttributes.SHA1.toString()); } @@ -434,7 +435,7 @@ private boolean updateTemplateSignatureIfChanged(File templateFolder) { currentTemplatesSignature = ""; } if (!docs.isEmpty()) { - String sha1 = (String) docs.get(0).get(String.valueOf(DocumentAttributes.SHA1)); + String sha1 = docs.get(0).getSha1(); if (!sha1.equals(currentTemplatesSignature)) { this.updateSignatures(currentTemplatesSignature); templateSignatureChanged = true; 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 e1a0dc5a4..9f649e86c 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -20,7 +20,6 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Date; -import java.util.Map; /** * Crawls a file system looking for content. @@ -216,12 +215,10 @@ private void addAdditionalDocumentAttributes(DocumentModel documentModel, File s documentModel.setSourceUri(uri); documentModel.setUri(uri); - if (documentModel.getStatus().equals(Status.PUBLISHED_DATE)) { - if (documentModel.getDate() != null) { - if (new Date().after(documentModel.getDate())) { - documentModel.setStatus(Status.PUBLISHED); - } - } + if (documentModel.getStatus().equals(Status.PUBLISHED_DATE) + && (documentModel.getDate() != null) + && new Date().after(documentModel.getDate())) { + documentModel.setStatus(Status.PUBLISHED); } if (config.getUriWithoutExtension()) { @@ -236,9 +233,9 @@ private String getPathToRoot(File sourceFile) { private DocumentStatus findDocumentStatus(String docType, String uri, String sha1) { DocumentList match = db.getDocumentStatus(docType, uri); if (!match.isEmpty()) { - Map entries = match.get(0); - String oldHash = (String) entries.get(String.valueOf(DocumentAttributes.SHA1)); - if (!(oldHash.equals(sha1)) || Boolean.FALSE.equals(entries.get(String.valueOf(DocumentAttributes.RENDERED)))) { + DocumentModel documentModel = match.get(0); + String oldHash = documentModel.getSha1(); + if (!(oldHash.equals(sha1)) || Boolean.FALSE.equals(documentModel.getRendered())) { return DocumentStatus.UPDATED; } else { return DocumentStatus.IDENTICAL; @@ -250,7 +247,6 @@ private DocumentStatus findDocumentStatus(String docType, String uri, String sha public abstract static class Attributes { - public static final String TAG = "tag"; public static final String ALLTAGS = "alltags"; public static final String PUBLISHED_DATE = "published_date"; public static final String DB = "db"; diff --git a/jbake-core/src/main/java/org/jbake/app/DBUtil.java b/jbake-core/src/main/java/org/jbake/app/DBUtil.java index 20355e4d3..73fce3fdb 100644 --- a/jbake-core/src/main/java/org/jbake/app/DBUtil.java +++ b/jbake-core/src/main/java/org/jbake/app/DBUtil.java @@ -4,10 +4,7 @@ import com.orientechnologies.orient.core.record.OElement; import com.orientechnologies.orient.core.sql.executor.OResult; import org.jbake.app.configuration.JBakeConfiguration; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import org.jbake.model.DocumentModel; public class DBUtil { private static ContentStore contentStore; @@ -37,12 +34,11 @@ public static void closeDataStore() { contentStore = null; } - public static Map documentToModel(OResult doc) { - Map result = new HashMap<>(); - Iterator fieldIterator = doc.getPropertyNames().iterator(); - while (fieldIterator.hasNext()) { - String entry = fieldIterator.next(); - result.put(entry, doc.getProperty(entry)); + public static DocumentModel documentToModel(OResult doc) { + DocumentModel result = new DocumentModel(); + + for (String key : doc.getPropertyNames()) { + result.put(key, doc.getProperty(key)); } return result; } diff --git a/jbake-core/src/main/java/org/jbake/app/DocumentList.java b/jbake-core/src/main/java/org/jbake/app/DocumentList.java index 9364db3ec..02bb1f97a 100644 --- a/jbake-core/src/main/java/org/jbake/app/DocumentList.java +++ b/jbake-core/src/main/java/org/jbake/app/DocumentList.java @@ -2,9 +2,10 @@ import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.executor.OResultSet; +import com.orientechnologies.orient.core.record.impl.ODocument; +import org.jbake.model.DocumentModel; import java.util.LinkedList; -import java.util.Map; /** * Wraps an OrientDB document iterator into a model usable by @@ -12,7 +13,7 @@ * * @author Cédric Champeau */ -public class DocumentList extends LinkedList> { +public class DocumentList extends LinkedList { public static DocumentList wrap(OResultSet docs) { DocumentList list = new DocumentList(); 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 74af6f14a..5d4c28855 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -1,7 +1,6 @@ package org.jbake.app; import org.apache.commons.configuration.CompositeConfiguration; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; @@ -13,10 +12,9 @@ import org.slf4j.LoggerFactory; import java.io.*; -import java.util.HashMap; +import java.nio.file.Files; import java.util.LinkedList; import java.util.List; -import java.util.Map; /** * Render output to a file. @@ -29,7 +27,7 @@ public class Renderer { private static final String FEED_TEMPLATE_NAME = "feed"; private static final String ARCHIVE_TEMPLATE_NAME = "archive"; - private final Logger LOGGER = LoggerFactory.getLogger(Renderer.class); + private final Logger logger = LoggerFactory.getLogger(Renderer.class); private final JBakeConfiguration config; private final DelegatingTemplateEngine renderingEngine; private final ContentStore db; @@ -104,9 +102,9 @@ private String findTemplateName(String docType) { * @param content The content to renderDocument * @throws Exception if IOException or SecurityException are raised */ - public void render(Map content) throws Exception { - String docType = (String) content.get(DocumentAttributes.TYPE.toString()); - String outputFilename = config.getDestinationFolder().getPath() + File.separatorChar + content.get(DocumentAttributes.URI.toString()); + public void render(DocumentModel content) throws Exception { + String docType = content.getType(); + String outputFilename = config.getDestinationFolder().getPath() + File.separatorChar + content.getUri(); if (outputFilename.lastIndexOf('.') > outputFilename.lastIndexOf(File.separatorChar)) { outputFilename = outputFilename.substring(0, outputFilename.lastIndexOf('.')); } @@ -115,30 +113,30 @@ public void render(Map content) throws Exception { String outputExtension = config.getOutputExtensionByDocType(docType); File draftFile = new File(outputFilename, config.getDraftSuffix() + outputExtension); if (draftFile.exists()) { - draftFile.delete(); + Files.delete(draftFile.toPath()); } File publishedFile = new File(outputFilename + outputExtension); if (publishedFile.exists()) { - publishedFile.delete(); + Files.delete(publishedFile.toPath()); } - if (content.get(DocumentAttributes.STATUS.toString()).equals(Crawler.Attributes.Status.DRAFT)) { + if (content.getStatus().equals(Crawler.Attributes.Status.DRAFT)) { outputFilename = outputFilename + config.getDraftSuffix(); } File outputFile = new File(outputFilename + outputExtension); - Map model = new HashMap(); - model.put("content", content); - model.put("renderer", renderingEngine); + DocumentModel model = new DocumentModel(); + model.setContent(content); + model.setRenderer(renderingEngine); try { try (Writer out = createWriter(outputFile)) { renderingEngine.renderDocument(model, findTemplateName(docType), out); } - LOGGER.info("Rendering [{}]... done!", outputFile); + logger.info("Rendering [{}]... done!", outputFile); } catch (Exception e) { - LOGGER.error("Rendering [{}]... failed!", outputFile, e); + logger.error("Rendering [{}]... failed!", outputFile, e); throw new Exception("Failed to render file " + outputFile.getAbsolutePath() + ". Cause: " + e.getMessage(), e); } } @@ -158,9 +156,9 @@ private void render(RenderingConfig renderConfig) throws Exception { try (Writer out = createWriter(outputFile)) { renderingEngine.renderDocument(renderConfig.getModel(), renderConfig.getTemplate(), out); } - LOGGER.info("Rendering {} [{}]... done!", renderConfig.getName(), outputFile); + logger.info("Rendering {} [{}]... done!", renderConfig.getName(), outputFile); } catch (Exception e) { - LOGGER.error("Rendering {} [{}]... failed!", renderConfig.getName(), outputFile, e); + logger.error("Rendering {} [{}]... failed!", renderConfig.getName(), outputFile, e); throw new Exception("Failed to render " + renderConfig.getName(), e); } } @@ -186,9 +184,9 @@ public void renderIndexPaging(String indexFile) throws Exception { } else { PagingHelper pagingHelper = new PagingHelper(totalPosts, postsPerPage); - Map model = new HashMap(); - model.put("renderer", renderingEngine); - model.put("numberOfPages", pagingHelper.getNumberOfPages()); + DocumentModel model = new DocumentModel(); + model.setRenderer(renderingEngine); + model.setNumberOfPages(pagingHelper.getNumberOfPages()); try { db.setLimit(postsPerPage); @@ -196,18 +194,18 @@ public void renderIndexPaging(String indexFile) throws Exception { String fileName = indexFile; db.setStart(pageStart); - model.put("currentPageNumber", page); + model.setCurrentPageNuber(page); String previous = pagingHelper.getPreviousFileName(page); - model.put("previousFileName", previous); + model.setPreviousFilename(previous); String nextFileName = pagingHelper.getNextFileName(page); - model.put("nextFileName", nextFileName); + model.setNextFileName(nextFileName); DocumentModel contentModel = buildSimpleModel(MASTERINDEX_TEMPLATE_NAME); if (page > 1) { contentModel.setRootPath("../"); } - model.put("content", contentModel); + model.setContent(contentModel); // Add page number to file name fileName = pagingHelper.getCurrentFileName(page, fileName); @@ -266,18 +264,15 @@ public int renderTags(String tagPath) throws Exception { for (String tag : db.getAllTags()) { try { - - Map model = new HashMap<>(); + DocumentModel model = new DocumentModel(); File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + tag + config.getOutputExtension()); - - model.put("renderer", renderingEngine); - model.put(Attributes.TAG, tag); - DocumentModel map = buildSimpleModel(Attributes.TAG); + model.setRenderer(renderingEngine); + model.setTag(tag); + DocumentModel map = buildSimpleModel(DocumentAttributes.TAG.toString()); map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); - model.put("content", map); - + model.setContent(map); - render(new ModelRenderingConfig(path, Attributes.TAG, model, findTemplateName(Attributes.TAG))); + render(new ModelRenderingConfig(path, DocumentAttributes.TAG.toString(), model, findTemplateName(DocumentAttributes.TAG.toString()))); renderedCount++; } catch (Exception e) { @@ -290,7 +285,7 @@ public int renderTags(String tagPath) throws Exception { // Add an index file at root folder of tags. // This will prevent directory listing and also provide an option to // display all tags page. - Map model = new HashMap(); + DocumentModel model = new DocumentModel(); File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + "index" + config.getOutputExtension()); model.put("renderer", renderingEngine); @@ -340,10 +335,10 @@ private interface RenderingConfig { String getTemplate(); - Map getModel(); + DocumentModel getModel(); } - private static abstract class AbstractRenderingConfig implements RenderingConfig { + private abstract static class AbstractRenderingConfig implements RenderingConfig { protected final File path; protected final String name; @@ -374,20 +369,20 @@ public String getTemplate() { } public class ModelRenderingConfig extends AbstractRenderingConfig { - private final Map model; + private final DocumentModel model; - public ModelRenderingConfig(String fileName, Map model, String templateType) { + public ModelRenderingConfig(String fileName, DocumentModel model, String templateType) { super(new File(config.getDestinationFolder(), fileName), fileName, findTemplateName(templateType)); this.model = model; } - public ModelRenderingConfig(File path, String name, Map model, String template) { + public ModelRenderingConfig(File path, String name, DocumentModel model, String template) { super(path, name, template); this.model = model; } @Override - public Map getModel() { + public DocumentModel getModel() { return model; } } @@ -417,8 +412,8 @@ public DefaultRenderingConfig(String allInOneName) { } @Override - public Map getModel() { - Map model = new HashMap(); + public DocumentModel getModel() { + DocumentModel model = new DocumentModel(); model.put("renderer", renderingEngine); model.put("content", content); 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..e1a3d4b1e 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 @@ -22,6 +22,7 @@ public class DefaultJBakeConfiguration implements JBakeConfiguration { + public static final String DEFAULT_TYHMELEAF_TEMPLATE_MODE = "HTML"; private static final String SOURCE_FOLDER_KEY = "sourceFolder"; private static final String DESTINATION_FOLDER_KEY = "destinationFolder"; private static final String ASSET_FOLDER_KEY = "assetFolder"; @@ -480,6 +481,12 @@ public void setProperty(String key, Object value) { compositeConfiguration.setProperty(key, value); } + @Override + public String getThymeleafModeByType(String type) { + String key = "template_" + type + "_thymeleaf_mode"; + return getAsString(key, DEFAULT_TYHMELEAF_TEMPLATE_MODE); + } + @Override public String getServerContextPath() { return getAsString(JBakeProperty.SERVER_CONTEXT_PATH); diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java index 218c62177..175897641 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java @@ -307,6 +307,13 @@ public interface JBakeConfiguration { */ void setProperty(String key, Object value); + /** + * + * @param type the documents type + * @return the the thymeleaf render mode ( defaults to {@link DefaultJBakeConfiguration#DEFAULT_TYHMELEAF_TEMPLATE_MODE} ) + */ + String getThymeleafModeByType(String type); + String getServerContextPath(); String getServerHostname(); diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java b/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java index a715584a1..e6a19ae77 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java @@ -15,7 +15,19 @@ public enum DocumentAttributes { ROOTPATH("rootpath"), FILE("file"), NO_EXTENSION_URI("noExtensionUri"), - TITLE("title"); + TITLE("title"), + TAGGED_POSTS("tagged_posts"), + TAGGED_DOCUMENTS("tagged_documents"), + NEXT_CONTENT("nextContent"), + PREVIOUS_CONTENT("previousContent"), + CONFIG("config"), + CONTENT("content"), + RENDERER("renderer"), + NUMBER_OF_PAGES("numberOfPages"), + CURRENT_PAGE_NUMBERS("currentPageNumber"), + PREVIOUS_FILENAME("previousFileName"), + NEXT_FILENAME("nextFileName"), + TAG("tag"); private String label; diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index a47b1fe00..70f72ebfa 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -1,7 +1,14 @@ package org.jbake.model; +import org.jbake.app.Crawler; +import org.jbake.app.DBUtil; +import org.jbake.app.DocumentList; +import org.jbake.template.DelegatingTemplateEngine; + +import javax.swing.text.Document; import java.util.Date; import java.util.HashMap; +import java.util.Map; public class DocumentModel extends HashMap { @@ -50,7 +57,7 @@ public void setType(String type) { } public String[] getTags() { - return (String[]) get(DocumentAttributes.TAGS.toString()); + return DBUtil.toStringArray(get(DocumentAttributes.TAGS.toString())); } public void setTags(String[] tags) { @@ -81,6 +88,10 @@ public void setRootPath(String pathToRoot) { put(DocumentAttributes.ROOTPATH.toString(), pathToRoot); } + public Boolean getRendered() { + return (Boolean) get(DocumentAttributes.RENDERED.toString()); + } + public void setRendered(boolean rendered) { put(DocumentAttributes.RENDERED.toString(), rendered); } @@ -97,6 +108,10 @@ public void setNoExtensionUri(String noExtensionUri) { put(DocumentAttributes.NO_EXTENSION_URI.toString(), noExtensionUri); } + public String getTitle() { + return (String) get(DocumentAttributes.TITLE.toString()); + } + public void setTitle(String title) { put(DocumentAttributes.TITLE.toString(), title); } @@ -112,4 +127,60 @@ public void setCached(boolean cached) { public boolean getCached() { return (boolean) get(DocumentAttributes.CACHED.toString()); } + + public void setTaggedPosts(DocumentList taggedPosts) { + put(DocumentAttributes.TAGGED_POSTS.toString(), taggedPosts); + } + + public void setTaggedDocuments(DocumentList taggedDocuments) { + put(DocumentAttributes.TAGGED_DOCUMENTS.toString(), taggedDocuments); + } + + public void setNextContent(DocumentModel nextDocumentModel) { + put(DocumentAttributes.NEXT_CONTENT.toString(), nextDocumentModel); + } + + public void setPreviousContent(DocumentModel previousDocumentModel) { + put(DocumentAttributes.PREVIOUS_CONTENT.toString(), previousDocumentModel); + } + + public Map getConfig() { + return (Map) get(DocumentAttributes.CONFIG.toString()); + } + + public void setConfig(Map configModel) { + put(DocumentAttributes.CONFIG.toString(), configModel); + } + + public void setContent(DocumentModel content) { + put(DocumentAttributes.CONTENT.toString(), content); + } + + public DocumentModel getContent() { + return (DocumentModel) get(DocumentAttributes.CONTENT.toString()); + } + + public void setRenderer(DelegatingTemplateEngine renderingEngine) { + put(DocumentAttributes.RENDERER.toString(), renderingEngine); + } + + public void setNumberOfPages(int numberOfPages) { + put(DocumentAttributes.NUMBER_OF_PAGES.toString(), numberOfPages); + } + + public void setCurrentPageNuber(int currentPageNumber) { + put(DocumentAttributes.CURRENT_PAGE_NUMBERS.toString(), currentPageNumber); + } + + public void setPreviousFilename(String previousFilename) { + put(DocumentAttributes.PREVIOUS_FILENAME.toString(), previousFilename); + } + + public void setNextFileName(String nextFilename) { + put(DocumentAttributes.NEXT_FILENAME.toString(), nextFilename); + } + + public void setTag(String tag) { + put(DocumentAttributes.TAG.toString(), tag); + } } diff --git a/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java b/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java index 176d403c7..26261dd65 100644 --- a/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java @@ -6,6 +6,7 @@ import org.asciidoctor.ast.DocumentHeader; import org.asciidoctor.jruby.AsciidoctorJRuby; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,7 +89,7 @@ public void processHeader(final ParserContext context) { Options options = getAsciiDocOptionsAndAttributes(context); final Asciidoctor asciidoctor = getEngine(options); DocumentHeader header = asciidoctor.readDocumentHeader(context.getFile()); - Map documentModel = context.getDocumentModel(); + DocumentModel documentModel = context.getDocumentModel(); if (header.getDocumentTitle() != null) { documentModel.put("title", header.getDocumentTitle().getCombined()); } 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 2acf66ef5..95155d856 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -266,14 +266,14 @@ private void processDefaultHeader(ParserContext context) { } } - private void processHeaderLine(String line, Map content) { + private void processHeaderLine(String line, DocumentModel content) { String[] parts = line.split("=", 2); if (!line.isEmpty() && parts.length == 2) { storeHeaderValue(parts[0], parts[1], content); } } - void storeHeaderValue(String inputKey, String inputValue, Map content) { + void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) { String key = sanitize(inputKey); String value = sanitize(inputValue); @@ -281,17 +281,18 @@ void storeHeaderValue(String inputKey, String inputValue, Map co DateFormat df = new SimpleDateFormat(configuration.getDateFormat()); try { Date date = df.parse(value); - content.put(key, date); + content.setDate(date); } catch (ParseException e) { LOGGER.error("unable to parse date {}", value); } } else if (key.equalsIgnoreCase(DocumentAttributes.TAGS.toString())) { - content.put(key, getTags(value)); + content.setTags(getTags(value)); } else if (isJson(value)) { content.put(key, JSONValue.parse(value)); } else { content.put(key, value); } + } private String sanitize(String part) { 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 f2be3114f..49fcd0ef4 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -5,7 +5,6 @@ import org.jbake.app.DocumentList; import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; @@ -13,7 +12,6 @@ import java.io.File; import java.util.LinkedList; import java.util.List; -import java.util.Map; public class DocumentsRenderer implements RenderingTool { @@ -30,21 +28,21 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) int index = 0; - Map nextDocument = null; + DocumentModel nextDocument = null; while (index < documentList.size()) { try { - Map document = documentList.get(index); - document.put("nextContent", null); - document.put("previousContent", null); + DocumentModel document = documentList.get(index); + document.setNextContent(null); + document.setPreviousContent(null); - if (index > 0) { - document.put("nextContent", getContentForNav(nextDocument)); + if (nextDocument != null && index > 0) { + document.setNextContent(getContentForNav(nextDocument)); } if (index < documentList.size() - 1) { - Map tempNext = documentList.get(index + 1); - document.put("previousContent", getContentForNav(tempNext)); + DocumentModel tempNext = documentList.get(index + 1); + document.setPreviousContent(getContentForNav(tempNext)); } nextDocument = document; @@ -79,11 +77,11 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) * @param document * @return */ - private DocumentModel getContentForNav(Map document) { + private DocumentModel getContentForNav(DocumentModel document) { DocumentModel navDocument = new DocumentModel(); - navDocument.setNoExtensionUri((String) document.get(DocumentAttributes.NO_EXTENSION_URI.toString())); - navDocument.setUri((String) document.get(DocumentAttributes.URI.toString())); - navDocument.setTitle((String) document.get(DocumentAttributes.TITLE.toString())); + navDocument.setNoExtensionUri(document.getNoExtensionUri()); + navDocument.setUri(document.getUri()); + navDocument.setTitle(document.getTitle()); return navDocument; } 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..c90f20989 100644 --- a/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java @@ -5,24 +5,24 @@ import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; +import org.jbake.model.DocumentModel; import java.io.File; import java.io.Writer; -import java.util.Map; /** * A template is responsible for converting a model into a rendered document. The model * consists of key/value pairs, some of them potentially converted from a markup language * to HTML already. - * + *

* An appropriate rendering engine will be chosen by JBake based on the template suffix. If * contents is not available in the supplied model, a template has access to the document * database in order to complete the model. It is in particular interesting to optimize * data access based on the underlying template engine capabilities. - * + *

* Note that some rendering engines may rely on a different rendering model than the one - * provided by the first argument of {@link #renderDocument(java.util.Map, String, java.io.Writer)}. + * provided by the first argument of {@link #renderDocument(DocumentModel, String, Writer)}. * In this case, it is the responsibility of the engine to convert it. * * @author Cédric Champeau @@ -33,9 +33,12 @@ public abstract class AbstractTemplateEngine { protected final JBakeConfiguration config; protected final ContentStore db; + /** + * @deprecated use {@link AbstractTemplateEngine(JBakeConfiguration,ContentStore)} instead + */ @Deprecated protected AbstractTemplateEngine(final Configuration config, final ContentStore db, final File destination, final File templatesPath) { - this(new JBakeConfigurationFactory().createDefaultJbakeConfiguration(templatesPath.getParentFile(),destination, (CompositeConfiguration) config),db); + this(new JBakeConfigurationFactory().createDefaultJbakeConfiguration(templatesPath.getParentFile(), destination, (CompositeConfiguration) config), db); } protected AbstractTemplateEngine(final JBakeConfiguration config, final ContentStore db) { @@ -43,5 +46,5 @@ protected AbstractTemplateEngine(final JBakeConfiguration config, final ContentS this.db = db; } - public abstract void renderDocument(Map model, String templateName, Writer writer) throws RenderingException; + public abstract void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException; } 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..4f5fe7574 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -5,6 +5,7 @@ import org.jbake.app.FileUtil; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeProperty; +import org.jbake.model.DocumentModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +46,7 @@ public DelegatingTemplateEngine(final ContentStore db, final JBakeConfiguration } @Override - public void renderDocument(final Map model, String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final DocumentModel model, String templateName, final Writer writer) throws RenderingException { model.put("version", config.getVersion()); // TODO: create config model from configuration @@ -55,7 +56,7 @@ public void renderDocument(final Map model, String templateName, String key = configKeys.next(); Object valueObject; - if ( key.equals(JBakeProperty.PAGINATE_INDEX) ){ + if (key.equals(JBakeProperty.PAGINATE_INDEX)) { valueObject = config.getPaginateIndex(); } else { valueObject = config.get(key); @@ -63,7 +64,7 @@ public void renderDocument(final Map model, String templateName, //replace "." in key so you can use dot notation in templates configModel.put(key.replace(".", "_"), valueObject); } - model.put("config", configModel); + model.setConfig(configModel); // if default template exists we will use it File templateFolder = config.getTemplateFolder(); File templateFile = new File(templateFolder, templateName); 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..b14b5b5e7 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -3,22 +3,12 @@ import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.BeansWrapperBuilder; -import freemarker.template.Configuration; -import freemarker.template.ObjectWrapper; -import freemarker.template.SimpleCollection; -import freemarker.template.SimpleDate; -import freemarker.template.SimpleHash; -import freemarker.template.SimpleSequence; -import freemarker.template.Template; -import freemarker.template.TemplateDateModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; +import freemarker.template.*; import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.File; import java.io.IOException; @@ -58,13 +48,11 @@ private void createTemplateConfiguration() { } @Override - public void renderDocument(final Map model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = templateCfg.getTemplate(templateName); template.process(new LazyLoadingModel(templateCfg.getObjectWrapper(), model, db), writer); - } catch (IOException e) { - throw new RenderingException(e); - } catch (TemplateException e) { + } catch (IOException | TemplateException e) { throw new RenderingException(e); } } @@ -90,7 +78,7 @@ public TemplateModel get(final String key) throws TemplateModelException { // GIT Issue#357: Accessing db in freemarker template throws exception // When content store is accessed with key "db" then wrap the ContentStore with BeansWrapper and return to template. // All methods on db are then accessible in template. Eg: ${db.getPublishedPostsByTag(tagName).size()} - if(key.equals(Crawler.Attributes.DB)) { + if (key.equals(Crawler.Attributes.DB)) { BeansWrapperBuilder bwb = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); BeansWrapper bw = bwb.build(); return bw.wrap(db); @@ -101,9 +89,9 @@ public TemplateModel get(final String key) throws TemplateModelException { @Override public TemplateModel adapt(String key, Object extractedValue) { - if(key.equals(Crawler.Attributes.ALLTAGS)) { + if (key.equals(Crawler.Attributes.ALLTAGS)) { return new SimpleCollection((Collection) extractedValue, wrapper); - } else if(key.equals(Crawler.Attributes.PUBLISHED_DATE)) { + } else if (key.equals(Crawler.Attributes.PUBLISHED_DATE)) { return new SimpleDate((Date) extractedValue, TemplateDateModel.UNKNOWN); } else { // All other cases, as far as I know, are document collections @@ -112,7 +100,7 @@ public TemplateModel adapt(String key, Object extractedValue) { } }); - } catch(NoModelExtractorException e) { + } catch (NoModelExtractorException e) { return eagerModel.get(key); } } 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..73d7f93df 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java @@ -8,6 +8,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.File; import java.io.Writer; @@ -59,7 +60,7 @@ private void initializeTemplateEngine() { } @Override - public void renderDocument(final Map model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = templateEngine.createTemplateByPath(templateName); Map wrappedModel = wrap(model); @@ -70,7 +71,7 @@ public void renderDocument(final Map model, final String templat } } - private Map wrap(final Map model) { + private Map wrap(final DocumentModel model) { return new HashMap(model) { @Override public Object get(final Object property) { 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..326764081 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java @@ -11,15 +11,11 @@ import org.codehaus.groovy.runtime.MethodClosure; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Writer; +import java.io.*; import java.util.HashMap; import java.util.Map; @@ -52,7 +48,7 @@ public GroovyTemplateEngine(final JBakeConfiguration config, final ContentStore } @Override - public void renderDocument(final Map model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = findTemplate(templateName); Writable writable = template.make(wrap(model)); @@ -97,7 +93,9 @@ public Object get(final Object property) { private void doInclude(Map model, String templateName) throws Exception { AbstractTemplateEngine engine = (AbstractTemplateEngine) model.get("renderer"); Writer out = (Writer) model.get("out"); - engine.renderDocument(model, templateName, out); + DocumentModel documentModel = new DocumentModel(); + documentModel.putAll(model); + engine.renderDocument(documentModel, templateName, out); model.put("out", out); } } 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..7e5ac95ab 100644 --- a/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java @@ -3,7 +3,6 @@ import de.neuland.jade4j.Jade4J; import de.neuland.jade4j.JadeConfiguration; -import de.neuland.jade4j.exceptions.JadeCompilerException; import de.neuland.jade4j.filter.CDATAFilter; import de.neuland.jade4j.filter.CssFilter; import de.neuland.jade4j.filter.JsFilter; @@ -15,6 +14,7 @@ import org.apache.commons.lang.StringEscapeUtils; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.File; import java.io.IOException; @@ -56,7 +56,7 @@ public JadeTemplateEngine(final JBakeConfiguration config, final ContentStore db } @Override - public void renderDocument(Map model, String templateName, Writer writer) throws RenderingException { + public void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException { try { JadeTemplate template = jadeConfiguration.getTemplate(templateName); @@ -66,7 +66,7 @@ public void renderDocument(Map model, String templateName, Write } } - public void renderTemplate(JadeTemplate template, Map model, Writer writer) throws JadeCompilerException { + public void renderTemplate(JadeTemplate template, Map model, Writer writer) { JadeModel jadeModel = wrap(jadeConfiguration.getSharedVariables()); jadeModel.putAll(model); template.process(jadeModel, writer); @@ -80,7 +80,7 @@ public Object get(final Object property) { String key = property.toString(); try { return extractors.extractAndTransform(db, key, this, new TemplateEngineAdapter.NoopAdapter()); - } catch(NoModelExtractorException e) { + } catch (NoModelExtractorException e) { // fallback to parent model } @@ -90,13 +90,13 @@ public Object get(final Object property) { } public static class FormatHelper { - private Map formatters = new HashMap(); + private Map formatters = new HashMap<>(); public String format(Date date, String pattern) { - if(date!=null && pattern!=null) { + if (date != null && pattern != null) { SimpleDateFormat df = formatters.get(pattern); - if(df==null) { + if (df == null) { df = new SimpleDateFormat(pattern); formatters.put(pattern, df); } diff --git a/jbake-core/src/main/java/org/jbake/template/ModelExtractor.java b/jbake-core/src/main/java/org/jbake/template/ModelExtractor.java index 16b13f07e..f15c620ec 100644 --- a/jbake-core/src/main/java/org/jbake/template/ModelExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/ModelExtractor.java @@ -6,10 +6,8 @@ /** - * - * @author ndx - * * @param the type of data returned by this model extractor + * @author ndx */ public interface ModelExtractor { diff --git a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java index 07819580e..b45772b99 100644 --- a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java @@ -8,6 +8,7 @@ import com.mitchellbosecke.pebble.template.PebbleTemplate; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.DocumentModel; import java.io.IOException; import java.io.Writer; @@ -42,7 +43,7 @@ private void initializeTemplateEngine() { } @Override - public void renderDocument(final Map model, final String templateName, final Writer writer) + public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { PebbleTemplate template; 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 d0d870afc..9599f94ce 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -4,8 +4,9 @@ import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ContentStore; import org.jbake.app.Crawler.Attributes; +import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.DocumentModel; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.LazyContextVariable; @@ -35,7 +36,6 @@ * @author Cédric Champeau */ 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; @@ -66,38 +66,27 @@ private void initializeTemplateEngine() { templateResolver = new FileTemplateResolver(); templateResolver.setPrefix(config.getTemplateFolder().getAbsolutePath() + File.separatorChar); templateResolver.setCharacterEncoding(config.getTemplateEncoding()); - templateResolver.setTemplateMode(DEFAULT_TEMPLATE_MODE); + templateResolver.setTemplateMode(DefaultJBakeConfiguration.DEFAULT_TYHMELEAF_TEMPLATE_MODE); templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(templateResolver); templateEngine.clearTemplateCache(); } - private void updateTemplateMode(Map model) { + private void updateTemplateMode(DocumentModel model) { templateResolver.setTemplateMode(getTemplateModeByModel(model)); } - private String getTemplateModeByModel(Map model) { - @SuppressWarnings("unchecked") - Map config = (Map) model.get("config"); - @SuppressWarnings("unchecked") - Map content = (Map) model.get("content"); - if (config != null && content != null) { - String key = "template_" + content.get(DocumentAttributes.TYPE.toString()) + "_thymeleaf_mode"; - String configMode = (String) config.get(key); - if (configMode != null) { - return configMode; - } - } - return DEFAULT_TEMPLATE_MODE; + private String getTemplateModeByModel(DocumentModel model) { + DocumentModel content = model.getContent(); + return config.getThymeleafModeByType(content.getType()); } @Override - public void renderDocument(Map model, String templateName, Writer writer) throws RenderingException { + public void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException { String localeString = config.getThymeleafLocale(); Locale locale = localeString != null ? LocaleUtils.toLocale(localeString) : Locale.getDefault(); - lock.lock(); try { initializeContext(locale, model); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java index 4470efacb..ac977bead 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java @@ -3,6 +3,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.Crawler; import org.jbake.app.DocumentList; +import org.jbake.model.DocumentAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -12,8 +13,8 @@ public class TagPostsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(Crawler.Attributes.TAG) != null) { - tag = model.get(Crawler.Attributes.TAG).toString(); + if (model.get(DocumentAttributes.TAG.toString()) != null) { + tag = model.get(DocumentAttributes.TAG.toString()).toString(); } // fetch the tag posts from db return db.getPublishedPostsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java index 3fbaff373..97169ab2b 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java @@ -1,8 +1,8 @@ package org.jbake.template.model; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler; import org.jbake.app.DocumentList; +import org.jbake.model.DocumentAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -12,8 +12,8 @@ public class TaggedDocumentsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(Crawler.Attributes.TAG) != null) { - tag = model.get(Crawler.Attributes.TAG).toString(); + if (model.get(DocumentAttributes.TAG.toString()) != null) { + tag = model.get(DocumentAttributes.TAG.toString()).toString(); } // fetch the tagged documents from db return db.getPublishedDocumentsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java index 30b7c7f25..41b32861c 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java @@ -3,9 +3,9 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; import org.jbake.app.FileUtil; +import org.jbake.model.DocumentModel; import org.jbake.template.ModelExtractor; -import java.util.HashMap; import java.util.Map; import static org.jbake.app.configuration.JBakeProperty.OUTPUT_EXTENSION; @@ -22,15 +22,15 @@ public DocumentList get(ContentStore db, Map model, String key) { String tagPath = config.get(TAG_PATH.replace(".", "_")).toString(); for (String tag : db.getAllTags()) { - Map newTag = new HashMap<>(); + DocumentModel newTag = new DocumentModel(); String tagName = tag; - newTag.put("name", tagName); + newTag.setName(tagName); String uri = tagPath + FileUtil.URI_SEPARATOR_CHAR + tag + config.get(OUTPUT_EXTENSION.replace(".", "_")).toString(); - newTag.put("uri", uri); - newTag.put("tagged_posts", db.getPublishedPostsByTag(tagName)); - newTag.put("tagged_documents", db.getPublishedDocumentsByTag(tagName)); + newTag.setUri(uri); + newTag.setTaggedPosts(db.getPublishedPostsByTag(tagName)); + newTag.setTaggedDocuments(db.getPublishedDocumentsByTag(tagName)); dl.push(newTag); } return dl; diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index b61ca0093..06d2c23cd 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -12,13 +12,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; import org.mockito.Captor; import org.mockito.MockitoAnnotations; -import java.util.HashMap; import java.util.List; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; @@ -35,7 +32,7 @@ public class DocumentsRendererTest { private DocumentList emptyDocumentList; @Captor - private ArgumentCaptor> argument; + private ArgumentCaptor argument; @Before public void setUp() { @@ -93,13 +90,13 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception DocumentTypes.addDocumentType("customType"); DocumentList documentList = new DocumentList(); - HashMap document = emptyDocument(); - HashMap document2 = emptyDocument(); + DocumentModel document = emptyDocument(); + DocumentModel document2 = emptyDocument(); documentList.add(document); documentList.add(document2); // throw an exception for every call of renderer's render method - doThrow(new Exception(fakeExceptionMessage)).when(renderer).render(ArgumentMatchers.anyMap()); + doThrow(new Exception(fakeExceptionMessage)).when(renderer).render(any(DocumentModel.class)); when(db.getUnrenderedContent(anyString())).thenReturn(emptyDocumentList); when(db.getUnrenderedContent("customType")).thenReturn(documentList); @@ -129,25 +126,25 @@ public void shouldContainPostNavigation() throws Exception { int renderResponse = documentsRenderer.render(renderer, db, configuration); - Map fourthDoc = simpleDocument(fourth); + DocumentModel fourthDoc = simpleDocument(fourth); fourthDoc.put("previousContent", simpleDocument(third)); fourthDoc.put("nextContent", null); - Map thirdDoc = simpleDocument(third); + DocumentModel thirdDoc = simpleDocument(third); thirdDoc.put("nextContent", simpleDocument(fourth)); thirdDoc.put("previousContent", simpleDocument(second)); - Map secondDoc = simpleDocument(second); + DocumentModel secondDoc = simpleDocument(second); secondDoc.put("nextContent", simpleDocument(third)); secondDoc.put("previousContent", simpleDocument(first)); - Map firstDoc = simpleDocument(first); + DocumentModel firstDoc = simpleDocument(first); firstDoc.put("nextContent", simpleDocument(second)); firstDoc.put("previousContent", null); verify(renderer, times(4)).render(argument.capture()); - List> maps = argument.getAllValues(); + List maps = argument.getAllValues(); assertThat(maps).contains(fourthDoc); @@ -160,8 +157,8 @@ public void shouldContainPostNavigation() throws Exception { assertThat(renderResponse).isEqualTo(4); } - private HashMap emptyDocument() { - return new HashMap<>(); + private DocumentModel emptyDocument() { + return new DocumentModel(); } private DocumentModel simpleDocument(String title) { From 124d60f572d5c2c4b80bb448f5cc6be3ae578905 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 18 Aug 2018 19:53:00 +0200 Subject: [PATCH 15/27] introduce TemplateModel --- .../main/java/org/jbake/app/ContentStore.java | 34 +++-- .../src/main/java/org/jbake/app/Crawler.java | 8 +- .../main/java/org/jbake/app/DocumentList.java | 6 +- .../src/main/java/org/jbake/app/Renderer.java | 42 +++--- .../main/java/org/jbake/model/BaseModel.java | 18 +++ .../java/org/jbake/model/DocumentModel.java | 128 ++++-------------- ...ntAttributes.java => ModelAttributes.java} | 7 +- .../java/org/jbake/parser/MarkupEngine.java | 6 +- .../org/jbake/render/DocumentsRenderer.java | 4 +- .../template/AbstractTemplateEngine.java | 6 +- .../template/DelegatingTemplateEngine.java | 6 +- .../template/FreemarkerTemplateEngine.java | 12 +- .../template/GroovyMarkupTemplateEngine.java | 6 +- .../jbake/template/GroovyTemplateEngine.java | 10 +- .../jbake/template/JadeTemplateEngine.java | 12 +- .../jbake/template/PebbleTemplateEngine.java | 3 +- .../template/ThymeleafTemplateEngine.java | 7 +- .../template/model/TagPostsExtractor.java | 7 +- .../model/TaggedDocumentsExtractor.java | 6 +- .../jbake/template/model/TagsExtractor.java | 7 +- .../jbake/template/model/TemplateModel.java | 64 +++++++++ .../java/org/jbake/FakeDocumentBuilder.java | 5 - .../java/org/jbake/app/ContentStoreTest.java | 29 ++-- .../test/java/org/jbake/app/CrawlerTest.java | 10 +- .../java/org/jbake/app/PaginationTest.java | 3 +- .../jbake/render/DocumentsRendererTest.java | 26 ++-- 26 files changed, 240 insertions(+), 232 deletions(-) create mode 100644 jbake-core/src/main/java/org/jbake/model/BaseModel.java rename jbake-core/src/main/java/org/jbake/model/{DocumentAttributes.java => ModelAttributes.java} (89%) create mode 100644 jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 828bcbc3e..f81a0c90e 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -36,9 +36,10 @@ import com.orientechnologies.orient.core.sql.OCommandSQL; import com.orientechnologies.orient.core.sql.executor.OResultSet; import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.BaseModel; import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; +import org.jbake.model.ModelAttributes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -195,14 +196,11 @@ private void activateOnCurrentThread() { * @throws IllegalArgumentException if sourceUri or docType are null, or if the document doesn't exist. */ public ODocument mergeDocument(Map incomingDocMap) { - String sourceUri = (String) incomingDocMap.get(DocumentAttributes.SOURCE_URI.toString()); - + String sourceUri = (String) incomingDocMap.get(ModelAttributes.SOURCE_URI.toString()); if (null == sourceUri) { throw new IllegalArgumentException("Document sourceUri is null."); } - - String docType = (String) incomingDocMap.get(DocumentAttributes.TYPE.toString()); - + String docType = (String) incomingDocMap.get(ModelAttributes.TYPE.toString()); if (null == docType) { throw new IllegalArgumentException("Document docType is null."); } @@ -356,8 +354,8 @@ private void executeCommand(String query, Object... args) { public Set getTags() { DocumentList docs = this.getAllTagsFromPublishedPosts(); Set result = new HashSet<>(); - for (DocumentModel document : docs) { - String[] tags = document.getTags(); + for (BaseModel document : docs) { + String[] tags = ((DocumentModel) document).getTags(); Collections.addAll(result, tags); } return result; @@ -368,8 +366,8 @@ public Set getAllTags() { for (String docType : DocumentTypes.getDocumentTypes()) { String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, quoteIdentifier(docType)); DocumentList docs = query(statement); - for (DocumentModel document : docs) { - String[] tags = document.getTags(); + for (BaseModel document : docs) { + String[] tags = ((DocumentModel) document).getTags(); Collections.addAll(result, tags); } } @@ -383,31 +381,31 @@ private void createDocType(final OSchema schema, final String docType) { OClass page = schema.createClass(docType); // Primary key - String attribName = DocumentAttributes.SOURCE_URI.toString(); + String attribName = ModelAttributes.SOURCE_URI.toString(); page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "sourceUriIndex", OClass.INDEX_TYPE.UNIQUE, attribName); - attribName = DocumentAttributes.SHA1.toString(); + attribName = ModelAttributes.SHA1.toString(); page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "sha1Index", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = DocumentAttributes.CACHED.toString(); + attribName = ModelAttributes.CACHED.toString(); page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); page.createIndex(docType + "cachedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = DocumentAttributes.RENDERED.toString(); + attribName = ModelAttributes.RENDERED.toString(); page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); page.createIndex(docType + "renderedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = DocumentAttributes.STATUS.toString(); + attribName = ModelAttributes.STATUS.toString(); page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "statusIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); } private void createSignatureType(OSchema schema) { OClass signatures = schema.createClass("Signatures"); - signatures.createProperty(DocumentAttributes.SHA1.toString(), OType.STRING).setNotNull(true); - signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, DocumentAttributes.SHA1.toString()); + signatures.createProperty(ModelAttributes.SHA1.toString(), OType.STRING).setNotNull(true); + signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, ModelAttributes.SHA1.toString()); } public void updateAndClearCacheIfNeeded(boolean needed, File templateFolder) { @@ -435,7 +433,7 @@ private boolean updateTemplateSignatureIfChanged(File templateFolder) { currentTemplatesSignature = ""; } if (!docs.isEmpty()) { - String sha1 = docs.get(0).getSha1(); + String sha1 = ((DocumentModel) docs.get(0)).getSha1(); if (!sha1.equals(currentTemplatesSignature)) { this.updateSignatures(currentTemplatesSignature); templateSignatureChanged = true; 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 9f649e86c..b987f790c 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -6,10 +6,10 @@ import org.jbake.app.Crawler.Attributes.Status; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; -import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentModel; import org.jbake.model.DocumentStatus; import org.jbake.model.DocumentTypes; +import org.jbake.model.ModelAttributes; import org.jbake.util.HtmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -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; @@ -233,7 +233,7 @@ private String getPathToRoot(File sourceFile) { private DocumentStatus findDocumentStatus(String docType, String uri, String sha1) { DocumentList match = db.getDocumentStatus(docType, uri); if (!match.isEmpty()) { - DocumentModel documentModel = match.get(0); + DocumentModel documentModel = match.getDocumentModel(0); String oldHash = documentModel.getSha1(); if (!(oldHash.equals(sha1)) || Boolean.FALSE.equals(documentModel.getRendered())) { return DocumentStatus.UPDATED; @@ -255,7 +255,7 @@ private Attributes() { } /** - * Possible values of the {@link DocumentAttributes#STATUS} property + * Possible values of the {@link ModelAttributes#STATUS} property * * @author ndx */ diff --git a/jbake-core/src/main/java/org/jbake/app/DocumentList.java b/jbake-core/src/main/java/org/jbake/app/DocumentList.java index 02bb1f97a..9d564442d 100644 --- a/jbake-core/src/main/java/org/jbake/app/DocumentList.java +++ b/jbake-core/src/main/java/org/jbake/app/DocumentList.java @@ -3,6 +3,7 @@ import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.executor.OResultSet; import com.orientechnologies.orient.core.record.impl.ODocument; +import org.jbake.model.BaseModel; import org.jbake.model.DocumentModel; import java.util.LinkedList; @@ -13,7 +14,7 @@ * * @author Cédric Champeau */ -public class DocumentList extends LinkedList { +public class DocumentList extends LinkedList { public static DocumentList wrap(OResultSet docs) { DocumentList list = new DocumentList(); @@ -25,4 +26,7 @@ public static DocumentList wrap(OResultSet docs) { return list; } + public DocumentModel getDocumentModel(int index) { + return (DocumentModel) get(index); + } } 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 5d4c28855..d1ae53001 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -4,9 +4,10 @@ import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; -import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentModel; +import org.jbake.model.ModelAttributes; import org.jbake.template.DelegatingTemplateEngine; +import org.jbake.template.model.TemplateModel; import org.jbake.util.PagingHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -126,7 +127,7 @@ public void render(DocumentModel content) throws Exception { } File outputFile = new File(outputFilename + outputExtension); - DocumentModel model = new DocumentModel(); + TemplateModel model = new TemplateModel(); model.setContent(content); model.setRenderer(renderingEngine); @@ -184,7 +185,7 @@ public void renderIndexPaging(String indexFile) throws Exception { } else { PagingHelper pagingHelper = new PagingHelper(totalPosts, postsPerPage); - DocumentModel model = new DocumentModel(); + TemplateModel model = new TemplateModel(); model.setRenderer(renderingEngine); model.setNumberOfPages(pagingHelper.getNumberOfPages()); @@ -264,15 +265,16 @@ public int renderTags(String tagPath) throws Exception { for (String tag : db.getAllTags()) { try { - DocumentModel model = new DocumentModel(); - File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + tag + config.getOutputExtension()); + TemplateModel model = new TemplateModel(); model.setRenderer(renderingEngine); model.setTag(tag); - DocumentModel map = buildSimpleModel(DocumentAttributes.TAG.toString()); + DocumentModel map = buildSimpleModel(ModelAttributes.TAG.toString()); + File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + tag + config.getOutputExtension()); + map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); model.setContent(map); - render(new ModelRenderingConfig(path, DocumentAttributes.TAG.toString(), model, findTemplateName(DocumentAttributes.TAG.toString()))); + render(new ModelRenderingConfig(path, ModelAttributes.TAG.toString(), model, findTemplateName(ModelAttributes.TAG.toString()))); renderedCount++; } catch (Exception e) { @@ -285,11 +287,11 @@ public int renderTags(String tagPath) throws Exception { // Add an index file at root folder of tags. // This will prevent directory listing and also provide an option to // display all tags page. - DocumentModel model = new DocumentModel(); + TemplateModel model = new TemplateModel(); + model.put("renderer", renderingEngine); + DocumentModel map = buildSimpleModel(ModelAttributes.TAGS.toString()); File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + "index" + config.getOutputExtension()); - model.put("renderer", renderingEngine); - DocumentModel map = buildSimpleModel(DocumentAttributes.TAGS.toString()); map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); model.put("content", map); @@ -335,7 +337,7 @@ private interface RenderingConfig { String getTemplate(); - DocumentModel getModel(); + TemplateModel getModel(); } private abstract static class AbstractRenderingConfig implements RenderingConfig { @@ -369,27 +371,27 @@ public String getTemplate() { } public class ModelRenderingConfig extends AbstractRenderingConfig { - private final DocumentModel model; + private final TemplateModel model; - public ModelRenderingConfig(String fileName, DocumentModel model, String templateType) { + public ModelRenderingConfig(String fileName, TemplateModel model, String templateType) { super(new File(config.getDestinationFolder(), fileName), fileName, findTemplateName(templateType)); this.model = model; } - public ModelRenderingConfig(File path, String name, DocumentModel model, String template) { + public ModelRenderingConfig(File path, String name, TemplateModel model, String template) { super(path, name, template); this.model = model; } @Override - public DocumentModel getModel() { + public TemplateModel getModel() { return model; } } class DefaultRenderingConfig extends AbstractRenderingConfig { - private final Object content; + private final DocumentModel content; private DefaultRenderingConfig(File path, String allInOneName) { super(path, allInOneName, findTemplateName(allInOneName)); @@ -412,10 +414,10 @@ public DefaultRenderingConfig(String allInOneName) { } @Override - public DocumentModel getModel() { - DocumentModel model = new DocumentModel(); - model.put("renderer", renderingEngine); - model.put("content", content); + public TemplateModel getModel() { + TemplateModel model = new TemplateModel(); + model.setRenderer(renderingEngine); + model.setContent(content); if (config.getPaginateIndex()) { model.put("numberOfPages", 0); diff --git a/jbake-core/src/main/java/org/jbake/model/BaseModel.java b/jbake-core/src/main/java/org/jbake/model/BaseModel.java new file mode 100644 index 000000000..a5f49014e --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/model/BaseModel.java @@ -0,0 +1,18 @@ +package org.jbake.model; + +import java.util.HashMap; + +public abstract class BaseModel extends HashMap { + + public String getUri() { + return (String) get(ModelAttributes.URI.toString()); + } + + public void setUri(String uri) { + put(ModelAttributes.URI.toString(), uri); + } + + public void setName(String name) { + put(ModelAttributes.NAME.toString(), name); + } +} diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index 70f72ebfa..df3d3cc2d 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -1,186 +1,112 @@ package org.jbake.model; -import org.jbake.app.Crawler; import org.jbake.app.DBUtil; import org.jbake.app.DocumentList; -import org.jbake.template.DelegatingTemplateEngine; -import javax.swing.text.Document; import java.util.Date; -import java.util.HashMap; -import java.util.Map; -public class DocumentModel extends HashMap { - - - public DocumentModel() { - super(); - } +public class DocumentModel extends BaseModel { public String getBody() { - return get(DocumentAttributes.BODY.toString()).toString(); + return get(ModelAttributes.BODY.toString()).toString(); } public void setBody(String body) { - put(DocumentAttributes.BODY.toString(), body); + put(ModelAttributes.BODY.toString(), body); } public Date getDate() { - return (Date) get(DocumentAttributes.DATE.toString()); + return (Date) get(ModelAttributes.DATE.toString()); } public void setDate(Date date) { - put(DocumentAttributes.DATE.toString(), date); + put(ModelAttributes.DATE.toString(), date); } public String getStatus() { - if (containsKey(DocumentAttributes.STATUS.toString())) { - return get(DocumentAttributes.STATUS.toString()).toString(); + if (containsKey(ModelAttributes.STATUS.toString())) { + return get(ModelAttributes.STATUS.toString()).toString(); } return ""; } public void setStatus(String status) { - put(DocumentAttributes.STATUS.toString(), status); + put(ModelAttributes.STATUS.toString(), status); } public String getType() { - if (containsKey(DocumentAttributes.TYPE.toString())) { - return get(DocumentAttributes.TYPE.toString()).toString(); + if (containsKey(ModelAttributes.TYPE.toString())) { + return get(ModelAttributes.TYPE.toString()).toString(); } return ""; } public void setType(String type) { - put(DocumentAttributes.TYPE.toString(), type); + put(ModelAttributes.TYPE.toString(), type); } public String[] getTags() { - return DBUtil.toStringArray(get(DocumentAttributes.TAGS.toString())); + return DBUtil.toStringArray(get(ModelAttributes.TAGS.toString())); } public void setTags(String[] tags) { - put(DocumentAttributes.TAGS.toString(), tags); + put(ModelAttributes.TAGS.toString(), tags); } public String getSha1() { - return (String) get(DocumentAttributes.SHA1.toString()); + return (String) get(ModelAttributes.SHA1.toString()); } public void setSha1(String sha1) { - put(DocumentAttributes.SHA1.toString(), sha1); - } - - public String getUri() { - return (String) get(DocumentAttributes.URI.toString()); - } - - public void setUri(String uri) { - put(DocumentAttributes.URI.toString(), uri); + put(ModelAttributes.SHA1.toString(), sha1); } public void setSourceUri(String uri) { - put(DocumentAttributes.SOURCE_URI.toString(), uri); + put(ModelAttributes.SOURCE_URI.toString(), uri); } public void setRootPath(String pathToRoot) { - put(DocumentAttributes.ROOTPATH.toString(), pathToRoot); + put(ModelAttributes.ROOTPATH.toString(), pathToRoot); } public Boolean getRendered() { - return (Boolean) get(DocumentAttributes.RENDERED.toString()); + return (Boolean) get(ModelAttributes.RENDERED.toString()); } public void setRendered(boolean rendered) { - put(DocumentAttributes.RENDERED.toString(), rendered); + put(ModelAttributes.RENDERED.toString(), rendered); } public void setFile(String path) { - put(DocumentAttributes.FILE.toString(), path); + put(ModelAttributes.FILE.toString(), path); } public String getNoExtensionUri() { - return (String) get(DocumentAttributes.NO_EXTENSION_URI.toString()); + return (String) get(ModelAttributes.NO_EXTENSION_URI.toString()); } public void setNoExtensionUri(String noExtensionUri) { - put(DocumentAttributes.NO_EXTENSION_URI.toString(), noExtensionUri); + put(ModelAttributes.NO_EXTENSION_URI.toString(), noExtensionUri); } public String getTitle() { - return (String) get(DocumentAttributes.TITLE.toString()); + return (String) get(ModelAttributes.TITLE.toString()); } public void setTitle(String title) { - put(DocumentAttributes.TITLE.toString(), title); - } - - public void setName(String name) { - put(DocumentAttributes.NAME.toString(), name); + put(ModelAttributes.TITLE.toString(), title); } public void setCached(boolean cached) { - put(DocumentAttributes.CACHED.toString(), cached); - } - - public boolean getCached() { - return (boolean) get(DocumentAttributes.CACHED.toString()); - } - - public void setTaggedPosts(DocumentList taggedPosts) { - put(DocumentAttributes.TAGGED_POSTS.toString(), taggedPosts); - } - - public void setTaggedDocuments(DocumentList taggedDocuments) { - put(DocumentAttributes.TAGGED_DOCUMENTS.toString(), taggedDocuments); + put(ModelAttributes.CACHED.toString(), cached); } public void setNextContent(DocumentModel nextDocumentModel) { - put(DocumentAttributes.NEXT_CONTENT.toString(), nextDocumentModel); + put(ModelAttributes.NEXT_CONTENT.toString(), nextDocumentModel); } public void setPreviousContent(DocumentModel previousDocumentModel) { - put(DocumentAttributes.PREVIOUS_CONTENT.toString(), previousDocumentModel); - } - - public Map getConfig() { - return (Map) get(DocumentAttributes.CONFIG.toString()); - } - - public void setConfig(Map configModel) { - put(DocumentAttributes.CONFIG.toString(), configModel); - } - - public void setContent(DocumentModel content) { - put(DocumentAttributes.CONTENT.toString(), content); - } - - public DocumentModel getContent() { - return (DocumentModel) get(DocumentAttributes.CONTENT.toString()); - } - - public void setRenderer(DelegatingTemplateEngine renderingEngine) { - put(DocumentAttributes.RENDERER.toString(), renderingEngine); - } - - public void setNumberOfPages(int numberOfPages) { - put(DocumentAttributes.NUMBER_OF_PAGES.toString(), numberOfPages); - } - - public void setCurrentPageNuber(int currentPageNumber) { - put(DocumentAttributes.CURRENT_PAGE_NUMBERS.toString(), currentPageNumber); - } - - public void setPreviousFilename(String previousFilename) { - put(DocumentAttributes.PREVIOUS_FILENAME.toString(), previousFilename); - } - - public void setNextFileName(String nextFilename) { - put(DocumentAttributes.NEXT_FILENAME.toString(), nextFilename); - } - - public void setTag(String tag) { - put(DocumentAttributes.TAG.toString(), tag); + put(ModelAttributes.PREVIOUS_CONTENT.toString(), previousDocumentModel); } } diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java similarity index 89% rename from jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java rename to jbake-core/src/main/java/org/jbake/model/ModelAttributes.java index e6a19ae77..5beea3ffb 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java @@ -1,6 +1,6 @@ package org.jbake.model; -public enum DocumentAttributes { +public enum ModelAttributes { SHA1("sha1"), SOURCE_URI("sourceuri"), RENDERED("rendered"), @@ -27,11 +27,12 @@ public enum DocumentAttributes { CURRENT_PAGE_NUMBERS("currentPageNumber"), PREVIOUS_FILENAME("previousFileName"), NEXT_FILENAME("nextFileName"), - TAG("tag"); + TAG("tag"), + VERSION("version"); private String label; - DocumentAttributes(String label) { + ModelAttributes(String label) { this.label = label; } 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 95155d856..8dadbf732 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -5,8 +5,8 @@ import org.apache.commons.io.IOUtils; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentModel; +import org.jbake.model.ModelAttributes; import org.json.simple.JSONValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -277,7 +277,7 @@ void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) String key = sanitize(inputKey); String value = sanitize(inputValue); - if (key.equalsIgnoreCase(DocumentAttributes.DATE.toString())) { + if (key.equalsIgnoreCase(ModelAttributes.DATE.toString())) { DateFormat df = new SimpleDateFormat(configuration.getDateFormat()); try { Date date = df.parse(value); @@ -285,7 +285,7 @@ void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) } catch (ParseException e) { LOGGER.error("unable to parse date {}", value); } - } else if (key.equalsIgnoreCase(DocumentAttributes.TAGS.toString())) { + } else if (key.equalsIgnoreCase(ModelAttributes.TAGS.toString())) { content.setTags(getTags(value)); } else if (isJson(value)) { content.put(key, JSONValue.parse(value)); 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 49fcd0ef4..5abc3f7fc 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -32,7 +32,7 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) while (index < documentList.size()) { try { - DocumentModel document = documentList.get(index); + DocumentModel document = documentList.getDocumentModel(index); document.setNextContent(null); document.setPreviousContent(null); @@ -41,7 +41,7 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) } if (index < documentList.size() - 1) { - DocumentModel tempNext = documentList.get(index + 1); + DocumentModel tempNext = (DocumentModel) documentList.get(index + 1); document.setPreviousContent(getContentForNav(tempNext)); } 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 c90f20989..e43d36861 100644 --- a/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java @@ -5,7 +5,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import java.io.File; import java.io.Writer; @@ -22,7 +22,7 @@ * data access based on the underlying template engine capabilities. *

* Note that some rendering engines may rely on a different rendering model than the one - * provided by the first argument of {@link #renderDocument(DocumentModel, String, Writer)}. + * provided by the first argument of {@link #renderDocument(TemplateModel, String, Writer)}. * In this case, it is the responsibility of the engine to convert it. * * @author Cédric Champeau @@ -46,5 +46,5 @@ protected AbstractTemplateEngine(final JBakeConfiguration config, final ContentS this.db = db; } - public abstract void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException; + public abstract void renderDocument(TemplateModel model, String templateName, Writer writer) throws RenderingException; } 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 4f5fe7574..6f57affa0 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -5,7 +5,7 @@ import org.jbake.app.FileUtil; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeProperty; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,8 +46,8 @@ public DelegatingTemplateEngine(final ContentStore db, final JBakeConfiguration } @Override - public void renderDocument(final DocumentModel model, String templateName, final Writer writer) throws RenderingException { - model.put("version", config.getVersion()); + public void renderDocument(final TemplateModel model, String templateName, final Writer writer) throws RenderingException { + model.setVersion(config.getVersion()); // TODO: create config model from configuration Map configModel = new HashMap<>(); 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 b14b5b5e7..f9162aa1e 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -8,7 +8,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import java.io.File; import java.io.IOException; @@ -48,7 +48,7 @@ private void createTemplateConfiguration() { } @Override - public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final TemplateModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = templateCfg.getTemplate(templateName); template.process(new LazyLoadingModel(templateCfg.getObjectWrapper(), model, db), writer); @@ -72,7 +72,7 @@ public LazyLoadingModel(ObjectWrapper wrapper, Map eagerModel, f } @Override - public TemplateModel get(final String key) throws TemplateModelException { + public freemarker.template.TemplateModel get(final String key) throws TemplateModelException { try { // GIT Issue#357: Accessing db in freemarker template throws exception @@ -85,10 +85,10 @@ public TemplateModel get(final String key) throws TemplateModelException { } - return extractors.extractAndTransform(db, key, eagerModel.toMap(), new TemplateEngineAdapter() { + return extractors.extractAndTransform(db, key, eagerModel.toMap(), new TemplateEngineAdapter() { @Override - public TemplateModel adapt(String key, Object extractedValue) { + public freemarker.template.TemplateModel adapt(String key, Object extractedValue) { if (key.equals(Crawler.Attributes.ALLTAGS)) { return new SimpleCollection((Collection) extractedValue, wrapper); } else if (key.equals(Crawler.Attributes.PUBLISHED_DATE)) { @@ -106,7 +106,7 @@ public TemplateModel adapt(String key, Object extractedValue) { } @Override - public boolean isEmpty() throws TemplateModelException { + public boolean isEmpty() { return false; } 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 73d7f93df..5ee13b419 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java @@ -8,7 +8,7 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import java.io.File; import java.io.Writer; @@ -60,7 +60,7 @@ private void initializeTemplateEngine() { } @Override - public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final TemplateModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = templateEngine.createTemplateByPath(templateName); Map wrappedModel = wrap(model); @@ -71,7 +71,7 @@ public void renderDocument(final DocumentModel model, final String templateName, } } - private Map wrap(final DocumentModel model) { + private Map wrap(final TemplateModel model) { return new HashMap(model) { @Override public Object get(final Object property) { 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 326764081..4df0ce9b1 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java @@ -11,7 +11,7 @@ import org.codehaus.groovy.runtime.MethodClosure; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; @@ -48,7 +48,7 @@ public GroovyTemplateEngine(final JBakeConfiguration config, final ContentStore } @Override - public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final TemplateModel model, final String templateName, final Writer writer) throws RenderingException { try { Template template = findTemplate(templateName); Writable writable = template.make(wrap(model)); @@ -93,9 +93,9 @@ public Object get(final Object property) { private void doInclude(Map model, String templateName) throws Exception { AbstractTemplateEngine engine = (AbstractTemplateEngine) model.get("renderer"); Writer out = (Writer) model.get("out"); - DocumentModel documentModel = new DocumentModel(); - documentModel.putAll(model); - engine.renderDocument(documentModel, templateName, out); + TemplateModel templateModel = new TemplateModel(); + templateModel.putAll(model); + engine.renderDocument(templateModel, templateName, out); model.put("out", out); } } 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 7e5ac95ab..06d3360a5 100644 --- a/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java @@ -14,7 +14,7 @@ import org.apache.commons.lang.StringEscapeUtils; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import java.io.File; import java.io.IOException; @@ -56,7 +56,7 @@ public JadeTemplateEngine(final JBakeConfiguration config, final ContentStore db } @Override - public void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException { + public void renderDocument(TemplateModel model, String templateName, Writer writer) throws RenderingException { try { JadeTemplate template = jadeConfiguration.getTemplate(templateName); @@ -66,13 +66,13 @@ public void renderDocument(DocumentModel model, String templateName, Writer writ } } - public void renderTemplate(JadeTemplate template, Map model, Writer writer) { - JadeModel jadeModel = wrap(jadeConfiguration.getSharedVariables()); - jadeModel.putAll(model); + public void renderTemplate(JadeTemplate template, TemplateModel model, Writer writer) { + JadeModel jadeModel = wrap(model); + jadeModel.putAll(jadeConfiguration.getSharedVariables()); template.process(jadeModel, writer); } - private JadeModel wrap(final Map model) { + private JadeModel wrap(final TemplateModel model) { return new JadeModel(model) { @Override diff --git a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java index b45772b99..e4ff63bcd 100644 --- a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java @@ -9,6 +9,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import java.io.IOException; import java.io.Writer; @@ -43,7 +44,7 @@ private void initializeTemplateEngine() { } @Override - public void renderDocument(final DocumentModel model, final String templateName, final Writer writer) + public void renderDocument(TemplateModel model, String templateName, Writer writer) throws RenderingException { PebbleTemplate template; 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 9599f94ce..62db5fa1e 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -7,6 +7,7 @@ import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.model.DocumentModel; +import org.jbake.template.model.TemplateModel; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.LazyContextVariable; @@ -72,17 +73,17 @@ private void initializeTemplateEngine() { templateEngine.clearTemplateCache(); } - private void updateTemplateMode(DocumentModel model) { + private void updateTemplateMode(TemplateModel model) { templateResolver.setTemplateMode(getTemplateModeByModel(model)); } - private String getTemplateModeByModel(DocumentModel model) { + private String getTemplateModeByModel(TemplateModel model) { DocumentModel content = model.getContent(); return config.getThymeleafModeByType(content.getType()); } @Override - public void renderDocument(DocumentModel model, String templateName, Writer writer) throws RenderingException { + public void renderDocument(TemplateModel model, String templateName, Writer writer) { String localeString = config.getThymeleafLocale(); Locale locale = localeString != null ? LocaleUtils.toLocale(localeString) : Locale.getDefault(); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java index ac977bead..a674363c5 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java @@ -1,9 +1,8 @@ package org.jbake.template.model; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler; import org.jbake.app.DocumentList; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.ModelAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -13,8 +12,8 @@ public class TagPostsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(DocumentAttributes.TAG.toString()) != null) { - tag = model.get(DocumentAttributes.TAG.toString()).toString(); + if (model.get(ModelAttributes.TAG.toString()) != null) { + tag = model.get(ModelAttributes.TAG.toString()).toString(); } // fetch the tag posts from db return db.getPublishedPostsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java index 97169ab2b..ce36d04f1 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java @@ -2,7 +2,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.ModelAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -12,8 +12,8 @@ public class TaggedDocumentsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(DocumentAttributes.TAG.toString()) != null) { - tag = model.get(DocumentAttributes.TAG.toString()).toString(); + if (model.get(ModelAttributes.TAG.toString()) != null) { + tag = model.get(ModelAttributes.TAG.toString()).toString(); } // fetch the tagged documents from db return db.getPublishedDocumentsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java index 41b32861c..ba3aa85e8 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java @@ -3,7 +3,6 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; import org.jbake.app.FileUtil; -import org.jbake.model.DocumentModel; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -17,12 +16,14 @@ public class TagsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { DocumentList dl = new DocumentList(); - Map config = (Map) model.get("config"); + TemplateModel templateModel = new TemplateModel(); + templateModel.putAll(model); + Map config = templateModel.getConfig(); String tagPath = config.get(TAG_PATH.replace(".", "_")).toString(); for (String tag : db.getAllTags()) { - DocumentModel newTag = new DocumentModel(); + TemplateModel newTag = new TemplateModel(); String tagName = tag; newTag.setName(tagName); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java new file mode 100644 index 000000000..ea5decb36 --- /dev/null +++ b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java @@ -0,0 +1,64 @@ +package org.jbake.template.model; + +import org.jbake.app.DocumentList; +import org.jbake.model.BaseModel; +import org.jbake.model.DocumentModel; +import org.jbake.model.ModelAttributes; +import org.jbake.template.DelegatingTemplateEngine; + +import java.util.Map; + +public class TemplateModel extends BaseModel { + + public Map getConfig() { + return (Map) get(ModelAttributes.CONFIG.toString()); + } + + public void setConfig(Map configModel) { + put(ModelAttributes.CONFIG.toString(), configModel); + } + + public void setContent(DocumentModel content) { + put(ModelAttributes.CONTENT.toString(), content); + } + + public DocumentModel getContent() { + return (DocumentModel) get(ModelAttributes.CONTENT.toString()); + } + + public void setRenderer(DelegatingTemplateEngine renderingEngine) { + put(ModelAttributes.RENDERER.toString(), renderingEngine); + } + + public void setNumberOfPages(int numberOfPages) { + put(ModelAttributes.NUMBER_OF_PAGES.toString(), numberOfPages); + } + + public void setCurrentPageNuber(int currentPageNumber) { + put(ModelAttributes.CURRENT_PAGE_NUMBERS.toString(), currentPageNumber); + } + + public void setPreviousFilename(String previousFilename) { + put(ModelAttributes.PREVIOUS_FILENAME.toString(), previousFilename); + } + + public void setNextFileName(String nextFilename) { + put(ModelAttributes.NEXT_FILENAME.toString(), nextFilename); + } + + public void setTag(String tag) { + put(ModelAttributes.TAG.toString(), tag); + } + + public void setTaggedPosts(DocumentList taggedPosts) { + put(ModelAttributes.TAGGED_POSTS.toString(), taggedPosts); + } + + public void setTaggedDocuments(DocumentList taggedDocuments) { + put(ModelAttributes.TAGGED_DOCUMENTS.toString(), taggedDocuments); + } + + public void setVersion(String version) { + put(ModelAttributes.VERSION.toString(), version); + } +} diff --git a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java index 0616bf2d5..c7a170023 100644 --- a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java +++ b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -21,11 +21,6 @@ public FakeDocumentBuilder(String type) { this.type = type; } - public FakeDocumentBuilder withName(String name) { - fileModel.setName(name); - return this; - } - public FakeDocumentBuilder withStatus(String status) { fileModel.setStatus(status); return this; diff --git a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java index 11ad5fcd0..d9a0ea1ea 100644 --- a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java @@ -3,9 +3,9 @@ import com.orientechnologies.orient.core.record.impl.ODocument; import org.jbake.FakeDocumentBuilder; import org.jbake.app.Crawler.Attributes.Status; -import org.jbake.model.DocumentAttributes; import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; +import org.jbake.model.ModelAttributes; import org.junit.Test; import java.util.Collections; @@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.jbake.app.ContentStore.quoteIdentifier; +import static org.jbake.model.ModelAttributes.RENDERED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -26,15 +27,13 @@ public void shouldGetCountForPublishedDocuments() throws Exception { for (int i = 0; i < 5; i++) { FakeDocumentBuilder builder = new FakeDocumentBuilder(DOC_TYPE_POST); - builder.withName("dummyfile" + i) - .withStatus("published") + builder.withStatus("published") .withRandomSha1() .build(); } FakeDocumentBuilder builder = new FakeDocumentBuilder(DOC_TYPE_POST); - builder.withName("draftdummy") - .withStatus("draft") + builder.withStatus("draft") .withRandomSha1() .build(); @@ -117,7 +116,7 @@ public void testStoreTypeWithSpecialCharacters() { DocumentList documentList4 = db.getDocumentStatus(typeWithHyphen, uri); assertEquals(1, documentList4.size()); - assertEquals(Boolean.FALSE, documentList4.get(0).get(DocumentAttributes.RENDERED.toString())); + assertEquals(Boolean.FALSE, documentList4.get(0).get(RENDERED.toString())); long documentCount2 = db.getPublishedCount(typeWithHyphen); assertEquals(0, documentCount2); @@ -130,9 +129,9 @@ public void testStoreTypeWithSpecialCharacters() { DocumentList documentList5 = db.getUnrenderedContent(typeWithHyphen); assertEquals(1, documentList5.size()); - assertEquals(Boolean.FALSE, documentList5.get(0).get(DocumentAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList5.get(0).get(DocumentAttributes.TYPE.toString())); - assertThat((String[])documentList5.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); + assertEquals(Boolean.FALSE, documentList5.get(0).get(ModelAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList5.get(0).get(ModelAttributes.TYPE.toString())); + assertThat((String[])documentList5.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); long documentCount3 = db.getPublishedCount(typeWithHyphen); assertEquals(1, documentCount3); @@ -141,15 +140,15 @@ public void testStoreTypeWithSpecialCharacters() { DocumentList documentList6 = db.getPublishedContent(typeWithHyphen); assertEquals(1, documentList6.size()); - assertEquals(Boolean.TRUE, documentList6.get(0).get(DocumentAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList6.get(0).get(DocumentAttributes.TYPE.toString())); - assertThat((String[])documentList6.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); + assertEquals(Boolean.TRUE, documentList6.get(0).get(ModelAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList6.get(0).get(ModelAttributes.TYPE.toString())); + assertThat((String[])documentList6.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); DocumentList documentList7 = db.getPublishedDocumentsByTag(tagWithHyphen); assertEquals(1, documentList7.size()); - assertEquals(Boolean.TRUE, documentList7.get(0).get(DocumentAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList7.get(0).get(DocumentAttributes.TYPE.toString())); - assertThat((String[])documentList7.get(0).get(DocumentAttributes.TAGS.toString())).contains(tagWithHyphen); + assertEquals(Boolean.TRUE, documentList7.get(0).get(ModelAttributes.RENDERED.toString())); + assertEquals(typeWithHyphen, documentList7.get(0).get(ModelAttributes.TYPE.toString())); + assertThat((String[])documentList7.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); DocumentList documentList8 = db.getPublishedPostsByTag(tagWithHyphen); assertEquals(0, documentList8.size()); diff --git a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java index 9ce6548c6..5e5178cda 100644 --- a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java +++ b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java @@ -3,7 +3,7 @@ import org.apache.commons.io.FilenameUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; -import org.jbake.model.DocumentAttributes; +import org.jbake.model.ModelAttributes; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -29,7 +29,7 @@ public void crawl() { for (Map content : results) { assertThat(content) - .containsKey(DocumentAttributes.ROOTPATH.toString()) + .containsKey(ModelAttributes.ROOTPATH.toString()) .containsValue("../../../"); } @@ -38,8 +38,8 @@ public void crawl() { assertThat(allPosts.size()).isEqualTo(4); for (Map content : allPosts) { - if (content.get(DocumentAttributes.TITLE.toString()).equals("Draft Post")) { - assertThat(content).containsKey(DocumentAttributes.DATE.toString()); + if (content.get(ModelAttributes.TITLE.toString()).equals("Draft Post")) { + assertThat(content).containsKey(ModelAttributes.DATE.toString()); } } @@ -49,7 +49,7 @@ public void crawl() { } @Test - public void renderWithPrettyUrls() throws Exception { + public void renderWithPrettyUrls() { config.setUriWithoutExtension(true); config.setPrefixForUriWithoutExtension("/blog"); diff --git a/jbake-core/src/test/java/org/jbake/app/PaginationTest.java b/jbake-core/src/test/java/org/jbake/app/PaginationTest.java index 90cb1095a..74fe52b59 100644 --- a/jbake-core/src/test/java/org/jbake/app/PaginationTest.java +++ b/jbake-core/src/test/java/org/jbake/app/PaginationTest.java @@ -63,8 +63,7 @@ public void testPagination() { for (int i = 1; i <= TOTAL_POSTS; i++) { cal.add(Calendar.SECOND, 5); FakeDocumentBuilder builder = new FakeDocumentBuilder("post"); - builder.withName("dummyfile" + i) - .withCached(true) + builder.withCached(true) .withStatus("published") .withDate(cal.getTime()) .build(); diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index 06d2c23cd..9937e7cf1 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -29,7 +29,7 @@ public class DocumentsRendererTest { private ContentStore db; private Renderer renderer; private JBakeConfiguration configuration; - private DocumentList emptyDocumentList; + private DocumentList emptyTemplateModelList; @Captor private ArgumentCaptor argument; @@ -44,13 +44,13 @@ public void setUp() { db = mock(ContentStore.class); renderer = mock(Renderer.class); configuration = mock(JBakeConfiguration.class); - emptyDocumentList = new DocumentList(); + emptyTemplateModelList = new DocumentList(); } @Test public void shouldReturnZeroIfNothingHasRendered() throws Exception { - when(db.getUnrenderedContent(anyString())).thenReturn(emptyDocumentList); + when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -63,14 +63,14 @@ public void shouldReturnCountOfProcessedDocuments() throws Exception { // given: DocumentTypes.addDocumentType("customType"); - DocumentList documentList = new DocumentList(); - documentList.add(emptyDocument()); - documentList.add(emptyDocument()); + DocumentList templateModelList = new DocumentList(); + templateModelList.add(emptyDocument()); + templateModelList.add(emptyDocument()); // return empty DocumentList independent from DocumentType - when(db.getUnrenderedContent(anyString())).thenReturn(emptyDocumentList); + when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); // return given DocumentList for DocumentType 'custom type' - when(db.getUnrenderedContent("customType")).thenReturn(documentList); + when(db.getUnrenderedContent("customType")).thenReturn(templateModelList); // when: int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -89,16 +89,16 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception // given DocumentTypes.addDocumentType("customType"); - DocumentList documentList = new DocumentList(); + DocumentList templateModelList = new DocumentList(); DocumentModel document = emptyDocument(); DocumentModel document2 = emptyDocument(); - documentList.add(document); - documentList.add(document2); + templateModelList.add(document); + templateModelList.add(document2); // throw an exception for every call of renderer's render method doThrow(new Exception(fakeExceptionMessage)).when(renderer).render(any(DocumentModel.class)); - when(db.getUnrenderedContent(anyString())).thenReturn(emptyDocumentList); - when(db.getUnrenderedContent("customType")).thenReturn(documentList); + when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); + when(db.getUnrenderedContent("customType")).thenReturn(templateModelList); // when int renderResponse = documentsRenderer.render(renderer, db, configuration); From 5f8cb2ad14162d36ebf86328dc0da2b1c72901a4 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 19 Aug 2018 11:43:29 +0200 Subject: [PATCH 16/27] cleanup and small refactoring to create a HashMap from configuration --- .../main/java/org/jbake/app/ContentStore.java | 4 +- .../src/main/java/org/jbake/app/Renderer.java | 12 +- .../DefaultJBakeConfiguration.java | 23 +- .../app/configuration/JBakeConfiguration.java | 3 + .../main/java/org/jbake/model/BaseModel.java | 6 +- .../java/org/jbake/model/DocumentModel.java | 60 +-- .../java/org/jbake/model/ModelAttributes.java | 70 ++-- .../org/jbake/parser/AsciidoctorEngine.java | 8 +- .../java/org/jbake/parser/MarkupEngine.java | 4 +- .../template/DelegatingTemplateEngine.java | 21 +- .../jbake/template/GroovyTemplateEngine.java | 5 +- .../template/model/TagPostsExtractor.java | 7 +- .../model/TaggedDocumentsExtractor.java | 7 +- .../jbake/template/model/TemplateModel.java | 41 +- .../org/jbake/app/AsciidocParserTest.java | 59 +-- .../test/java/org/jbake/app/CrawlerTest.java | 24 +- .../test/java/org/jbake/app/MdParserTest.java | 363 +++++++++--------- .../java/org/jbake/app/PaginationTest.java | 7 +- .../test/java/org/jbake/app/ParserTest.java | 85 ++-- .../jbake/render/DocumentsRendererTest.java | 16 +- 20 files changed, 421 insertions(+), 404 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index f81a0c90e..84640ed98 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -404,8 +404,8 @@ private void createDocType(final OSchema schema, final String docType) { private void createSignatureType(OSchema schema) { OClass signatures = schema.createClass("Signatures"); - signatures.createProperty(ModelAttributes.SHA1.toString(), OType.STRING).setNotNull(true); - signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, ModelAttributes.SHA1.toString()); + signatures.createProperty(ModelAttributes.SHA1, OType.STRING).setNotNull(true); + signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, ModelAttributes.SHA1); } public void updateAndClearCacheIfNeeded(boolean needed, File templateFolder) { 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 d1ae53001..88da336cb 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -288,12 +288,12 @@ public int renderTags(String tagPath) throws Exception { // This will prevent directory listing and also provide an option to // display all tags page. TemplateModel model = new TemplateModel(); - model.put("renderer", renderingEngine); + model.setRenderer(renderingEngine); DocumentModel map = buildSimpleModel(ModelAttributes.TAGS.toString()); File path = new File(config.getDestinationFolder() + File.separator + tagPath + File.separator + "index" + config.getOutputExtension()); map.setRootPath(FileUtil.getUriPathToDestinationRoot(config, path)); - model.put("content", map); + model.setContent(map); render(new ModelRenderingConfig(path, "tagindex", model, findTemplateName("tagsindex"))); @@ -420,10 +420,10 @@ public TemplateModel getModel() { model.setContent(content); if (config.getPaginateIndex()) { - model.put("numberOfPages", 0); - model.put("currentPageNumber", 0); - model.put("previousFileName", ""); - model.put("nextFileName", ""); + model.setNumberOfPages(0); + model.setCurrentPageNuber(0); + model.setPreviousFilename(""); + model.setNextFileName(""); } return model; 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 e1a3d4b1e..baaf611d1 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 @@ -7,12 +7,12 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -497,6 +497,25 @@ public String getServerHostname() { return getAsString(JBakeProperty.SERVER_HOSTNAME); } + @Override + public Map asHashMap() { + HashMap configModel = new HashMap<>(); + Iterator configKeys = this.getKeys(); + while (configKeys.hasNext()) { + String key = configKeys.next(); + Object valueObject; + + if (key.equals(JBakeProperty.PAGINATE_INDEX)) { + valueObject = this.getPaginateIndex(); + } else { + valueObject = this.get(key); + } + //replace "." in key so you can use dot notation in templates + configModel.put(key.replace(".", "_"), valueObject); + } + return configModel; + } + public void setTemplateExtensionForDocType(String docType, String extension) { String templateExtensionKey = DOCTYPE_TEMPLATE_PREFIX + docType + DOCTYPE_EXTENSION_POSTFIX; setProperty(templateExtensionKey, extension); diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java index 175897641..a7c11e3cd 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java @@ -3,6 +3,7 @@ import java.io.File; import java.util.Iterator; import java.util.List; +import java.util.Map; /** * JBakeConfiguration gives you access to the project configuration. Typically located in a file called jbake.properties. @@ -317,5 +318,7 @@ public interface JBakeConfiguration { String getServerContextPath(); String getServerHostname(); + + Map asHashMap(); } diff --git a/jbake-core/src/main/java/org/jbake/model/BaseModel.java b/jbake-core/src/main/java/org/jbake/model/BaseModel.java index a5f49014e..ebc246c97 100644 --- a/jbake-core/src/main/java/org/jbake/model/BaseModel.java +++ b/jbake-core/src/main/java/org/jbake/model/BaseModel.java @@ -5,14 +5,14 @@ public abstract class BaseModel extends HashMap { public String getUri() { - return (String) get(ModelAttributes.URI.toString()); + return (String) get(ModelAttributes.URI); } public void setUri(String uri) { - put(ModelAttributes.URI.toString(), uri); + put(ModelAttributes.URI, uri); } public void setName(String name) { - put(ModelAttributes.NAME.toString(), name); + put(ModelAttributes.NAME, name); } } diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index df3d3cc2d..6e74589a2 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -8,105 +8,113 @@ public class DocumentModel extends BaseModel { public String getBody() { - return get(ModelAttributes.BODY.toString()).toString(); + return (String) get(ModelAttributes.BODY); } public void setBody(String body) { - put(ModelAttributes.BODY.toString(), body); + put(ModelAttributes.BODY, body); } public Date getDate() { - return (Date) get(ModelAttributes.DATE.toString()); + return (Date) get(ModelAttributes.DATE); } public void setDate(Date date) { - put(ModelAttributes.DATE.toString(), date); + put(ModelAttributes.DATE, date); } public String getStatus() { - if (containsKey(ModelAttributes.STATUS.toString())) { - return get(ModelAttributes.STATUS.toString()).toString(); + if (containsKey(ModelAttributes.STATUS)) { + return (String) get(ModelAttributes.STATUS); } return ""; } public void setStatus(String status) { - put(ModelAttributes.STATUS.toString(), status); + put(ModelAttributes.STATUS, status); } public String getType() { - if (containsKey(ModelAttributes.TYPE.toString())) { - return get(ModelAttributes.TYPE.toString()).toString(); + if (containsKey(ModelAttributes.TYPE)) { + return (String) get(ModelAttributes.TYPE); } return ""; } public void setType(String type) { - put(ModelAttributes.TYPE.toString(), type); + put(ModelAttributes.TYPE, type); } public String[] getTags() { - return DBUtil.toStringArray(get(ModelAttributes.TAGS.toString())); + return DBUtil.toStringArray(get(ModelAttributes.TAGS)); } public void setTags(String[] tags) { - put(ModelAttributes.TAGS.toString(), tags); + put(ModelAttributes.TAGS, tags); } public String getSha1() { - return (String) get(ModelAttributes.SHA1.toString()); + return (String) get(ModelAttributes.SHA1); } public void setSha1(String sha1) { - put(ModelAttributes.SHA1.toString(), sha1); + put(ModelAttributes.SHA1, sha1); } public void setSourceUri(String uri) { - put(ModelAttributes.SOURCE_URI.toString(), uri); + put(ModelAttributes.SOURCE_URI, uri); + } + + public String getRootPath() { + return (String) get(ModelAttributes.ROOTPATH); } public void setRootPath(String pathToRoot) { - put(ModelAttributes.ROOTPATH.toString(), pathToRoot); + put(ModelAttributes.ROOTPATH, pathToRoot); } public Boolean getRendered() { - return (Boolean) get(ModelAttributes.RENDERED.toString()); + return (Boolean) get(ModelAttributes.RENDERED); } public void setRendered(boolean rendered) { - put(ModelAttributes.RENDERED.toString(), rendered); + put(ModelAttributes.RENDERED, rendered); + } + + public String getFile() { + return (String) get(ModelAttributes.FILE); } public void setFile(String path) { - put(ModelAttributes.FILE.toString(), path); + put(ModelAttributes.FILE, path); } public String getNoExtensionUri() { - return (String) get(ModelAttributes.NO_EXTENSION_URI.toString()); + return (String) get(ModelAttributes.NO_EXTENSION_URI); } public void setNoExtensionUri(String noExtensionUri) { - put(ModelAttributes.NO_EXTENSION_URI.toString(), noExtensionUri); + put(ModelAttributes.NO_EXTENSION_URI, noExtensionUri); } public String getTitle() { - return (String) get(ModelAttributes.TITLE.toString()); + return (String) get(ModelAttributes.TITLE); } public void setTitle(String title) { - put(ModelAttributes.TITLE.toString(), title); + put(ModelAttributes.TITLE, title); } public void setCached(boolean cached) { - put(ModelAttributes.CACHED.toString(), cached); + put(ModelAttributes.CACHED, cached); } public void setNextContent(DocumentModel nextDocumentModel) { - put(ModelAttributes.NEXT_CONTENT.toString(), nextDocumentModel); + put(ModelAttributes.NEXT_CONTENT, nextDocumentModel); } public void setPreviousContent(DocumentModel previousDocumentModel) { - put(ModelAttributes.PREVIOUS_CONTENT.toString(), previousDocumentModel); + put(ModelAttributes.PREVIOUS_CONTENT, previousDocumentModel); } } diff --git a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java index 5beea3ffb..77e306605 100644 --- a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java @@ -1,43 +1,33 @@ package org.jbake.model; -public enum ModelAttributes { - SHA1("sha1"), - SOURCE_URI("sourceuri"), - RENDERED("rendered"), - CACHED("cached"), //TODO: Do we need this? - STATUS("status"), - NAME("name"), - BODY("body"), - DATE("date"), - TYPE("type"), - TAGS("tags"), - URI("uri"), - ROOTPATH("rootpath"), - FILE("file"), - NO_EXTENSION_URI("noExtensionUri"), - TITLE("title"), - TAGGED_POSTS("tagged_posts"), - TAGGED_DOCUMENTS("tagged_documents"), - NEXT_CONTENT("nextContent"), - PREVIOUS_CONTENT("previousContent"), - CONFIG("config"), - CONTENT("content"), - RENDERER("renderer"), - NUMBER_OF_PAGES("numberOfPages"), - CURRENT_PAGE_NUMBERS("currentPageNumber"), - PREVIOUS_FILENAME("previousFileName"), - NEXT_FILENAME("nextFileName"), - TAG("tag"), - VERSION("version"); - - private String label; - - ModelAttributes(String label) { - this.label = label; - } - - @Override - public String toString() { - return label; - } +public abstract class ModelAttributes { + public static final String SHA1 = "sha1"; + public static final String SOURCE_URI = "sourceuri"; + public static final String RENDERED = "rendered"; + public static final String CACHED = "cached"; //TODO: Do we need this? + public static final String STATUS = "status"; + public static final String NAME = "name"; + public static final String BODY = "body"; + public static final String DATE = "date"; + public static final String TYPE = "type"; + public static final String TAGS = "tags"; + public static final String URI = "uri"; + public static final String ROOTPATH = "rootpath"; + public static final String FILE = "file"; + public static final String NO_EXTENSION_URI = "noExtensionUri"; + public static final String TITLE = "title"; + public static final String TAGGED_POSTS = "tagged_posts"; + public static final String TAGGED_DOCUMENTS = "tagged_documents"; + public static final String NEXT_CONTENT = "nextContent"; + public static final String PREVIOUS_CONTENT = "previousContent"; + public static final String CONFIG = "config"; + public static final String CONTENT = "content"; + public static final String RENDERER = "renderer"; + public static final String NUMBER_OF_PAGES = "numberOfPages"; + public static final String CURRENT_PAGE_NUMBERS = "currentPageNumber"; + public static final String PREVIOUS_FILENAME = "previousFileName"; + public static final String NEXT_FILENAME = "nextFileName"; + public static final String TAG = "tag"; + public static final String VERSION = "version"; + public static final String OUT = "out"; } diff --git a/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java b/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java index 26261dd65..a5b106895 100644 --- a/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java @@ -13,11 +13,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.locks.ReentrantReadWriteLock; import static org.asciidoctor.AttributesBuilder.attributes; @@ -91,7 +87,7 @@ public void processHeader(final ParserContext context) { DocumentHeader header = asciidoctor.readDocumentHeader(context.getFile()); DocumentModel documentModel = context.getDocumentModel(); if (header.getDocumentTitle() != null) { - documentModel.put("title", header.getDocumentTitle().getCombined()); + documentModel.setTitle(header.getDocumentTitle().getCombined()); } Map attributes = header.getAttributes(); for (Map.Entry attribute : attributes.entrySet()) { 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 8dadbf732..ac1a93b81 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -277,7 +277,7 @@ void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) String key = sanitize(inputKey); String value = sanitize(inputValue); - if (key.equalsIgnoreCase(ModelAttributes.DATE.toString())) { + if (key.equalsIgnoreCase(ModelAttributes.DATE)) { DateFormat df = new SimpleDateFormat(configuration.getDateFormat()); try { Date date = df.parse(value); @@ -285,7 +285,7 @@ void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) } catch (ParseException e) { LOGGER.error("unable to parse date {}", value); } - } else if (key.equalsIgnoreCase(ModelAttributes.TAGS.toString())) { + } else if (key.equalsIgnoreCase(ModelAttributes.TAGS)) { content.setTags(getTags(value)); } else if (isJson(value)) { content.put(key, JSONValue.parse(value)); 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 6f57affa0..bea52842c 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -4,16 +4,12 @@ import org.jbake.app.ContentStore; import org.jbake.app.FileUtil; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.app.configuration.JBakeProperty; import org.jbake.template.model.TemplateModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.Writer; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; /** * A template which is responsible for delegating to a supported template engine, @@ -48,23 +44,8 @@ public DelegatingTemplateEngine(final ContentStore db, final JBakeConfiguration @Override public void renderDocument(final TemplateModel model, String templateName, final Writer writer) throws RenderingException { model.setVersion(config.getVersion()); + model.setConfig(config.asHashMap()); - // TODO: create config model from configuration - Map configModel = new HashMap<>(); - Iterator configKeys = config.getKeys(); - while (configKeys.hasNext()) { - String key = configKeys.next(); - Object valueObject; - - if (key.equals(JBakeProperty.PAGINATE_INDEX)) { - valueObject = config.getPaginateIndex(); - } else { - valueObject = config.get(key); - } - //replace "." in key so you can use dot notation in templates - configModel.put(key.replace(".", "_"), valueObject); - } - model.setConfig(configModel); // if default template exists we will use it File templateFolder = config.getTemplateFolder(); File templateFile = new File(templateFolder, templateName); 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 4df0ce9b1..dd4a1c69e 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java @@ -91,11 +91,10 @@ public Object get(final Object property) { } private void doInclude(Map model, String templateName) throws Exception { - AbstractTemplateEngine engine = (AbstractTemplateEngine) model.get("renderer"); - Writer out = (Writer) model.get("out"); TemplateModel templateModel = new TemplateModel(); templateModel.putAll(model); + AbstractTemplateEngine engine = templateModel.getRenderer(); + Writer out = templateModel.getWriter(); engine.renderDocument(templateModel, templateName, out); - model.put("out", out); } } diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java index a674363c5..39e42a5d7 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java @@ -2,7 +2,6 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; -import org.jbake.model.ModelAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -12,8 +11,10 @@ public class TagPostsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(ModelAttributes.TAG.toString()) != null) { - tag = model.get(ModelAttributes.TAG.toString()).toString(); + TemplateModel templateModel = new TemplateModel(); + templateModel.putAll(model); + if (templateModel.getTag() != null) { + tag = templateModel.getTag(); } // fetch the tag posts from db return db.getPublishedPostsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java index ce36d04f1..09402b2af 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TaggedDocumentsExtractor.java @@ -2,7 +2,6 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; -import org.jbake.model.ModelAttributes; import org.jbake.template.ModelExtractor; import java.util.Map; @@ -12,8 +11,10 @@ public class TaggedDocumentsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { String tag = null; - if (model.get(ModelAttributes.TAG.toString()) != null) { - tag = model.get(ModelAttributes.TAG.toString()).toString(); + TemplateModel templateModel = new TemplateModel(); + templateModel.putAll(model); + if (templateModel.getTag() != null) { + tag = templateModel.getTag(); } // fetch the tagged documents from db return db.getPublishedDocumentsByTag(tag); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java index ea5decb36..6d24d35d1 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java @@ -6,59 +6,72 @@ import org.jbake.model.ModelAttributes; import org.jbake.template.DelegatingTemplateEngine; +import java.io.Writer; import java.util.Map; public class TemplateModel extends BaseModel { public Map getConfig() { - return (Map) get(ModelAttributes.CONFIG.toString()); + return (Map) get(ModelAttributes.CONFIG); } public void setConfig(Map configModel) { - put(ModelAttributes.CONFIG.toString(), configModel); + put(ModelAttributes.CONFIG, configModel); + } + + public DocumentModel getContent() { + return (DocumentModel) get(ModelAttributes.CONTENT); } public void setContent(DocumentModel content) { - put(ModelAttributes.CONTENT.toString(), content); + put(ModelAttributes.CONTENT, content); } - public DocumentModel getContent() { - return (DocumentModel) get(ModelAttributes.CONTENT.toString()); + public DelegatingTemplateEngine getRenderer() { + return (DelegatingTemplateEngine) get(ModelAttributes.RENDERER); } public void setRenderer(DelegatingTemplateEngine renderingEngine) { - put(ModelAttributes.RENDERER.toString(), renderingEngine); + put(ModelAttributes.RENDERER, renderingEngine); } public void setNumberOfPages(int numberOfPages) { - put(ModelAttributes.NUMBER_OF_PAGES.toString(), numberOfPages); + put(ModelAttributes.NUMBER_OF_PAGES, numberOfPages); } public void setCurrentPageNuber(int currentPageNumber) { - put(ModelAttributes.CURRENT_PAGE_NUMBERS.toString(), currentPageNumber); + put(ModelAttributes.CURRENT_PAGE_NUMBERS, currentPageNumber); } public void setPreviousFilename(String previousFilename) { - put(ModelAttributes.PREVIOUS_FILENAME.toString(), previousFilename); + put(ModelAttributes.PREVIOUS_FILENAME, previousFilename); } public void setNextFileName(String nextFilename) { - put(ModelAttributes.NEXT_FILENAME.toString(), nextFilename); + put(ModelAttributes.NEXT_FILENAME, nextFilename); + } + + public String getTag() { + return (String) get(ModelAttributes.TAG); } public void setTag(String tag) { - put(ModelAttributes.TAG.toString(), tag); + put(ModelAttributes.TAG, tag); } public void setTaggedPosts(DocumentList taggedPosts) { - put(ModelAttributes.TAGGED_POSTS.toString(), taggedPosts); + put(ModelAttributes.TAGGED_POSTS, taggedPosts); } public void setTaggedDocuments(DocumentList taggedDocuments) { - put(ModelAttributes.TAGGED_DOCUMENTS.toString(), taggedDocuments); + put(ModelAttributes.TAGGED_DOCUMENTS, taggedDocuments); } public void setVersion(String version) { - put(ModelAttributes.VERSION.toString(), version); + put(ModelAttributes.VERSION, version); + } + + public Writer getWriter() { + return (Writer) get(ModelAttributes.OUT); } } diff --git a/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java b/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java index 642964998..fe4e38db0 100644 --- a/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/AsciidocParserTest.java @@ -4,6 +4,7 @@ import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeProperty; +import org.jbake.model.DocumentModel; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -134,76 +135,76 @@ public void createSampleFile() throws Exception { public void parseAsciidocFileWithPrettifyAttribute() { config.setProperty(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES,"source-highlighter=prettify"); - Map map = parser.processFile(asciidocWithSource); + DocumentModel map = parser.processFile(asciidocWithSource); Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("draft", map.getStatus()); + Assert.assertEquals("post", map.getType()); + assertThat(map.getBody()) .contains("class=\"paragraph\"") .contains("

JBake now supports AsciiDoc.

") .contains("class=\"prettyprint highlight\""); - assertThat(map.get("body").toString()).doesNotContain("I Love Jbake"); - System.out.println(map.get("body").toString()); + assertThat(map.getBody()).doesNotContain("I Love Jbake"); + System.out.println(map.getBody()); } @Test public void parseAsciidocFileWithCustomAttribute() { config.setProperty(JBakeProperty.ASCIIDOCTOR_ATTRIBUTES,"source-highlighter=prettify,testattribute=I Love Jbake"); - Map map = parser.processFile(asciidocWithSource); + DocumentModel map = parser.processFile(asciidocWithSource); Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("draft", map.getStatus()); + Assert.assertEquals("post", map.getType()); + assertThat(map.getBody()) .contains("I Love Jbake") .contains("class=\"prettyprint highlight\""); - System.out.println(map.get("body").toString()); + System.out.println(map.getBody()); } @Test public void parseValidAsciiDocFile() { - Map map = parser.processFile(validAsciidocFile); + DocumentModel map = parser.processFile(validAsciidocFile); Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("draft", map.getStatus()); + Assert.assertEquals("post", map.getType()); + assertThat(map.getBody()) .contains("class=\"paragraph\"") .contains("

JBake now supports AsciiDoc.

"); } @Test public void parseInvalidAsciiDocFile() { - Map map = parser.processFile(invalidAsciiDocFile); + DocumentModel map = parser.processFile(invalidAsciiDocFile); Assert.assertNull(map); } @Test public void parseValidAsciiDocFileWithoutHeader() { - Map map = parser.processFile(validAsciiDocFileWithoutHeader); + DocumentModel map = parser.processFile(validAsciiDocFileWithoutHeader); Assert.assertNotNull(map); Assert.assertEquals("Hello: AsciiDoc!", map.get("title")); - Assert.assertEquals("published", map.get("status")); - Assert.assertEquals("page", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("published", map.getStatus()); + Assert.assertEquals("page", map.getType()); + assertThat(map.getBody()) .contains("class=\"paragraph\"") .contains("

JBake now supports AsciiDoc.

"); } @Test public void parseInvalidAsciiDocFileWithoutHeader() { - Map map = parser.processFile(invalidAsciiDocFileWithoutHeader); + DocumentModel map = parser.processFile(invalidAsciiDocFileWithoutHeader); Assert.assertNull(map); } @Test public void parseValidAsciiDocFileWithExampleHeaderInContent() { - Map map = parser.processFile(validAsciiDocFileWithHeaderInContent); + DocumentModel map = parser.processFile(validAsciiDocFileWithHeaderInContent); Assert.assertNotNull(map); - Assert.assertEquals("published", map.get("status")); - Assert.assertEquals("page", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("published", map.getStatus()); + Assert.assertEquals("page", map.getType()); + assertThat(map.getBody()) .contains("class=\"paragraph\"") .contains("

JBake now supports AsciiDoc.

") .contains("class=\"listingblock\"") @@ -219,11 +220,11 @@ public void parseValidAsciiDocFileWithoutJBakeMetaDataUsingDefaultTypeAndStatus( config.setDefaultStatus("published"); config.setDefaultType("page"); Parser parser = new Parser(config); - Map map = parser.processFile(validAsciiDocFileWithoutJBakeMetaData); + DocumentModel map = parser.processFile(validAsciiDocFileWithoutJBakeMetaData); Assert.assertNotNull(map); - Assert.assertEquals("published", map.get("status")); - Assert.assertEquals("page", map.get("type")); - assertThat(map.get("body").toString()) + Assert.assertEquals("published", map.getStatus()); + Assert.assertEquals("page", map.getType()); + assertThat(map.getBody()) .contains("

JBake now supports AsciiDoc documents without JBake meta data.

"); } diff --git a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java index 5e5178cda..680e2d4c1 100644 --- a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java +++ b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java @@ -3,6 +3,8 @@ import org.apache.commons.io.FilenameUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; +import org.jbake.model.BaseModel; +import org.jbake.model.DocumentModel; import org.jbake.model.ModelAttributes; import org.junit.Assert; import org.junit.Before; @@ -12,6 +14,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.is; public class CrawlerTest extends ContentStoreIntegrationTest { @@ -29,7 +32,7 @@ public void crawl() { for (Map content : results) { assertThat(content) - .containsKey(ModelAttributes.ROOTPATH.toString()) + .containsKey(ModelAttributes.ROOTPATH) .containsValue("../../../"); } @@ -37,9 +40,10 @@ public void crawl() { assertThat(allPosts.size()).isEqualTo(4); - for (Map content : allPosts) { - if (content.get(ModelAttributes.TITLE.toString()).equals("Draft Post")) { - assertThat(content).containsKey(ModelAttributes.DATE.toString()); + for (BaseModel content : allPosts) { + DocumentModel documentModel = (DocumentModel) content; + if (documentModel.getTitle().equals("Draft Post")) { + assertThat(content).containsKey(ModelAttributes.DATE); } } @@ -62,13 +66,13 @@ public void renderWithPrettyUrls() { DocumentList documents = db.getPublishedPosts(); - for (Map model : documents) { - String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName((String) model.get("file")) + "/"; + for (BaseModel model : documents) { + DocumentModel documentModel = (DocumentModel) model; + String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName(documentModel.getFile()) + "/"; - Assert.assertThat(model.get("noExtensionUri"), RegexMatcher.matches(noExtensionUri)); - Assert.assertThat(model.get("uri"), RegexMatcher.matches(noExtensionUri + "index\\.html")); - - assertThat(model).containsEntry("rootpath", "../../../"); + Assert.assertThat(documentModel.getNoExtensionUri(), RegexMatcher.matches(noExtensionUri)); + Assert.assertThat(documentModel.getUri(), RegexMatcher.matches(noExtensionUri + "index\\.html")); + Assert.assertThat(documentModel.getRootPath(), is("../../../")); } } diff --git a/jbake-core/src/test/java/org/jbake/app/MdParserTest.java b/jbake-core/src/test/java/org/jbake/app/MdParserTest.java index f18a6c1bc..dfbd9d199 100644 --- a/jbake-core/src/test/java/org/jbake/app/MdParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/MdParserTest.java @@ -1,9 +1,9 @@ - package org.jbake.app; import org.jbake.TestUtils; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; +import org.jbake.model.DocumentModel; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -12,14 +12,13 @@ import java.io.File; import java.io.PrintWriter; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; /** * Tests basic Markdown syntax and the extensions supported by the Markdown * processor (Pegdown). - * + * * @author Jonathan Bullock * @author Kevin S. Clarke */ @@ -232,440 +231,440 @@ public void createSampleFile() throws Exception { } @Test - public void parseValidMarkdownFileBasic() throws Exception { + public void parseValidMarkdownFileBasic() { Parser parser = new Parser(config); - Map map = parser.processFile(validMdFileBasic); - Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - Assert.assertEquals("

This is a test

\n", map.get("body")); + DocumentModel documentModel = parser.processFile(validMdFileBasic); + Assert.assertNotNull(documentModel); + Assert.assertEquals("draft", documentModel.getStatus()); + Assert.assertEquals("post", documentModel.getType()); + Assert.assertEquals("

This is a test

\n", documentModel.getBody()); } @Test public void parseInvalidMarkdownFileBasic() { Parser parser = new Parser(config); - Map map = parser.processFile(invalidMdFileBasic); - Assert.assertNull(map); + DocumentModel documentModel = parser.processFile(invalidMdFileBasic); + Assert.assertNull(documentModel); } @Test - public void parseValidMdFileHardWraps() throws Exception { + public void parseValidMdFileHardWraps() { config.setMarkdownExtensions("HARDWRAPS"); // Test with HARDWRAPS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileHardWraps); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

First line
\nSecond line

\n"); + DocumentModel documentModel = parser.processFile(mdFileHardWraps); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

First line
\nSecond line

\n"); // Test without HARDWRAPS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileHardWraps); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

First line Second line

"); + documentModel = parser.processFile(mdFileHardWraps); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

First line Second line

"); } @Test - public void parseWithInvalidExtension() throws Exception { + public void parseWithInvalidExtension() { config.setMarkdownExtensions("HARDWRAPS,UNDEFINED_EXTENSION"); // Test with HARDWRAPS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileHardWraps); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

First line
\nSecond line

\n"); + DocumentModel documentModel = parser.processFile(mdFileHardWraps); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

First line
\nSecond line

\n"); } @Test - public void parseValidMdFileAbbreviations() throws Exception { + public void parseValidMdFileAbbreviations() { config.setMarkdownExtensions("ABBREVIATIONS"); // Test with ABBREVIATIONS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileAbbreviations); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileAbbreviations); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

HTML

" ); // Test without ABBREVIATIONS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileAbbreviations); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

*[HTML]: Hyper Text Markup Language HTML

"); + documentModel = parser.processFile(mdFileAbbreviations); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

*[HTML]: Hyper Text Markup Language HTML

"); } @Test - public void parseValidMdFileAutolinks() throws Exception { + public void parseValidMdFileAutolinks() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("AUTOLINKS"); // Test with AUTOLINKS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileAutolinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileAutolinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

http://github.com

" ); // Test without AUTOLINKS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileAutolinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

http://github.com

"); + documentModel = parser.processFile(mdFileAutolinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

http://github.com

"); } @Test - public void parseValidMdFileDefinitions() throws Exception { + public void parseValidMdFileDefinitions() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("DEFINITIONS"); // Test with DEFINITIONS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileDefinitions); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileDefinitions); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
\n
Apple
\n
Pomaceous fruit
\n
" ); // Test without DEFNITIONS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileDefinitions); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

Apple : Pomaceous fruit

"); + documentModel = parser.processFile(mdFileDefinitions); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

Apple : Pomaceous fruit

"); } @Test - public void parseValidMdFileFencedCodeBlocks() throws Exception { + public void parseValidMdFileFencedCodeBlocks() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("FENCED_CODE_BLOCKS"); // Test with FENCED_CODE_BLOCKS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileFencedCodeBlocks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileFencedCodeBlocks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
function test() {\n  console.log("!");\n}\n
" ); // Test without FENCED_CODE_BLOCKS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileFencedCodeBlocks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + documentModel = parser.processFile(mdFileFencedCodeBlocks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

function test() { console.log("!"); }

" ); } @Test - public void parseValidMdFileQuotes() throws Exception { + public void parseValidMdFileQuotes() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("QUOTES"); // Test with QUOTES Parser parser = new Parser(config); - Map map = parser.processFile(mdFileQuotes); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

“quotes”

"); + DocumentModel documentModel = parser.processFile(mdFileQuotes); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

“quotes”

"); // Test without QUOTES config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileQuotes); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

"quotes"

"); + documentModel = parser.processFile(mdFileQuotes); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

"quotes"

"); } @Test - public void parseValidMdFileSmarts() throws Exception { + public void parseValidMdFileSmarts() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("SMARTS"); // Test with SMARTS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileSmarts); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

"); + DocumentModel documentModel = parser.processFile(mdFileSmarts); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

"); // Test without SMARTS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileSmarts); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

...

"); + documentModel = parser.processFile(mdFileSmarts); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

...

"); } @Test - public void parseValidMdFileSmartypants() throws Exception { + public void parseValidMdFileSmartypants() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("SMARTYPANTS"); // Test with SMARTYPANTS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileSmartypants); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

“…”

"); + DocumentModel documentModel = parser.processFile(mdFileSmartypants); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

“…”

"); // Test without SMARTYPANTS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileSmartypants); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

"..."

"); + documentModel = parser.processFile(mdFileSmartypants); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

"..."

"); } @Test - public void parseValidMdFileSuppressAllHTML() throws Exception { + public void parseValidMdFileSuppressAllHTML() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("SUPPRESS_ALL_HTML"); // Test with SUPPRESS_ALL_HTML Parser parser = new Parser(config); - Map map = parser.processFile(mdFileSuppressAllHTML); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains(""); + DocumentModel documentModel = parser.processFile(mdFileSuppressAllHTML); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains(""); // Test without SUPPRESS_ALL_HTML config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileSuppressAllHTML); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("
!
!"); + documentModel = parser.processFile(mdFileSuppressAllHTML); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("
!
!"); } @Test - public void parseValidMdFileSuppressHTMLBlocks() throws Exception { + public void parseValidMdFileSuppressHTMLBlocks() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("SUPPRESS_HTML_BLOCKS"); // Test with SUPPRESS_HTML_BLOCKS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileSuppressHTMLBlocks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains(""); + DocumentModel documentModel = parser.processFile(mdFileSuppressHTMLBlocks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains(""); // Test without SUPPRESS_HTML_BLOCKS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileSuppressHTMLBlocks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("
!
!"); + documentModel = parser.processFile(mdFileSuppressHTMLBlocks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("
!
!"); } @Test - public void parseValidMdFileSuppressInlineHTML() throws Exception { + public void parseValidMdFileSuppressInlineHTML() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("SUPPRESS_INLINE_HTML"); // Test with SUPPRESS_INLINE_HTML Parser parser = new Parser(config); - Map map = parser.processFile(mdFileSuppressInlineHTML); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

This is the first paragraph. with inline html

"); + DocumentModel documentModel = parser.processFile(mdFileSuppressInlineHTML); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

This is the first paragraph. with inline html

"); // Test without SUPPRESS_INLINE_HTML config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileSuppressInlineHTML); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

This is the first paragraph. with inline html

"); + documentModel = parser.processFile(mdFileSuppressInlineHTML); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

This is the first paragraph. with inline html

"); } @Test - public void parseValidMdFileTables() throws Exception { + public void parseValidMdFileTables() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("TABLES"); // Test with TABLES Parser parser = new Parser(config); - Map map = parser.processFile(mdFileTables); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileTables); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
" + "\n" + + "First HeaderSecond Header\n" + + "\n" + + "\n" + + "Content CellContent Cell\n" + + "Content CellContent Cell\n" + + "\n" + + "" ); // Test without TABLES config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileTables); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + documentModel = parser.processFile(mdFileTables); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

First Header|Second Header -------------|------------- Content Cell|Content Cell Content Cell|Content Cell

" ); } @Test - public void parseValidMdFileWikilinks() throws Exception { + public void parseValidMdFileWikilinks() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("WIKILINKS"); // Test with WIKILINKS Parser parser = new Parser(config); - Map map = parser.processFile(mdFileWikilinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileWikilinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

Wiki-style links

" ); // Test without WIKILINKS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileWikilinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

[[Wiki-style links]]

"); + documentModel = parser.processFile(mdFileWikilinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

[[Wiki-style links]]

"); } @Test - public void parseValidMdFileAtxheaderspace() throws Exception { + public void parseValidMdFileAtxheaderspace() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("ATXHEADERSPACE"); // Test with ATXHEADERSPACE Parser parser = new Parser(config); - Map map = parser.processFile(mdFileAtxheaderspace); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

#Test

"); + DocumentModel documentModel = parser.processFile(mdFileAtxheaderspace); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

#Test

"); // Test without ATXHEADERSPACE config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileAtxheaderspace); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

Test

"); + documentModel = parser.processFile(mdFileAtxheaderspace); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

Test

"); } @Test - public void parseValidMdFileForcelistitempara() throws Exception { + public void parseValidMdFileForcelistitempara() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("FORCELISTITEMPARA"); // Test with FORCELISTITEMPARA Parser parser = new Parser(config); - Map map = parser.processFile(mdFileForcelistitempara); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileForcelistitempara); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
    \n" + - "
  1. \n" + - "

    Item 1 Item 1 lazy continuation

    \n" + - "

    Item 1 paragraph 1 Item 1 paragraph 1 lazy continuation Item 1 paragraph 1 continuation

    \n" + - "
  2. \n" + - "
"); + "
  • \n" + + "

    Item 1 Item 1 lazy continuation

    \n" + + "

    Item 1 paragraph 1 Item 1 paragraph 1 lazy continuation Item 1 paragraph 1 continuation

    \n" + + "
  • \n" + + ""); // Test without FORCELISTITEMPARA config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileForcelistitempara); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + documentModel = parser.processFile(mdFileForcelistitempara); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
      \n" + - "
    1. Item 1 Item 1 lazy continuation\n" + - "

      Item 1 paragraph 1 Item 1 paragraph 1 lazy continuation Item 1 paragraph 1 continuation

      \n" + - "
    2. \n" + - "
    " + "
  • Item 1 Item 1 lazy continuation\n" + + "

    Item 1 paragraph 1 Item 1 paragraph 1 lazy continuation Item 1 paragraph 1 continuation

    \n" + + "
  • \n" + + "" ); } @Test - public void parseValidMdFileRelaxedhrules() throws Exception { + public void parseValidMdFileRelaxedhrules() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("RELAXEDHRULES"); // Test with RELAXEDHRULES Parser parser = new Parser(config); - Map map = parser.processFile(mdFileRelaxedhrules); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdFileRelaxedhrules); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

    Hello World

    \n" + - "
    \n" + - "
    \n" + - "

    Hello World

    \n" + - "
    \n" + - "
    \n" + - "
    \n" + - "

    Hello World

    \n" + - "
    \n" + - "
    \n" + - "
    " + "
    \n" + + "
    \n" + + "

    Hello World

    \n" + + "
    \n" + + "
    \n" + + "
    \n" + + "

    Hello World

    \n" + + "
    \n" + + "
    \n" + + "
    " ); // Test without RELAXEDHRULES config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdFileRelaxedhrules); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + documentModel = parser.processFile(mdFileRelaxedhrules); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

    Hello World

    \n" + - "
    \n" + - "
    \n" + - "

    Hello World ***

    \n" + - "
    \n" + - "

    Hello World ___

    \n" + - "
    " + "
    \n" + + "
    \n" + + "

    Hello World ***

    \n" + + "
    \n" + + "

    Hello World ___

    \n" + + "
    " ); } @Test - public void parseValidMdFileTasklistitems() throws Exception { + public void parseValidMdFileTasklistitems() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("TASKLISTITEMS"); // Test with TASKLISTITEMS Parser parser = new Parser(config); - Map map = parser.processFile(mdTasklistitems); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdTasklistitems); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
      \n" + - "
    • loose bullet item 3
    • \n" + - "
    •  open task item
    • \n" + - "
    •  closed task item
    • \n" + - "
    " + "
  • loose bullet item 3
  • \n" + + "
  •  open task item
  • \n" + + "
  •  closed task item
  • \n" + + "" ); // Test without TASKLISTITEMS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdTasklistitems); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + documentModel = parser.processFile(mdTasklistitems); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "
      \n" + - "
    • loose bullet item 3
    • \n" + - "
    • [ ] open task item
    • \n" + - "
    • [x] closed task item
    • \n" + - "
    "); + "
  • loose bullet item 3
  • \n" + + "
  • [ ] open task item
  • \n" + + "
  • [x] closed task item
  • \n" + + ""); } @Test - public void parseValidMdFileExtanchorlinks() throws Exception { + public void parseValidMdFileExtanchorlinks() { config.setMarkdownExtensions(""); config.setMarkdownExtensions("EXTANCHORLINKS"); // Test with EXTANCHORLINKS Parser parser = new Parser(config); - Map map = parser.processFile(mdExtanchorlinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains( + DocumentModel documentModel = parser.processFile(mdExtanchorlinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains( "

    header & some formatting ~~chars~~

    " ); // Test without EXTANCHORLINKS config.setMarkdownExtensions(""); parser = new Parser(config); - map = parser.processFile(mdExtanchorlinks); - Assert.assertNotNull(map); - assertThat(map.get("body").toString()).contains("

    header & some formatting ~~chars~~

    "); + documentModel = parser.processFile(mdExtanchorlinks); + Assert.assertNotNull(documentModel); + assertThat(documentModel.getBody()).contains("

    header & some formatting ~~chars~~

    "); } diff --git a/jbake-core/src/test/java/org/jbake/app/PaginationTest.java b/jbake-core/src/test/java/org/jbake/app/PaginationTest.java index 74fe52b59..70fefa86a 100644 --- a/jbake-core/src/test/java/org/jbake/app/PaginationTest.java +++ b/jbake-core/src/test/java/org/jbake/app/PaginationTest.java @@ -24,6 +24,7 @@ package org.jbake.app; import org.jbake.FakeDocumentBuilder; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.junit.Assert; import org.junit.Before; @@ -31,7 +32,6 @@ import org.junit.BeforeClass; import java.util.Calendar; -import java.util.Date; import java.util.Locale; import static org.assertj.core.api.Assertions.assertThat; @@ -80,7 +80,10 @@ public void testPagination() { assertThat(posts.size()).isLessThanOrEqualTo(2); if (posts.size() > 1) { - assertThat((Date) posts.get(0).get("date")).isAfter((Date) posts.get(1).get("date")); + DocumentModel post = (DocumentModel) posts.get(0); + DocumentModel nextPost = (DocumentModel) posts.get(1); + + assertThat(post.getDate()).isAfter(nextPost.getDate()); } pageCount++; diff --git a/jbake-core/src/test/java/org/jbake/app/ParserTest.java b/jbake-core/src/test/java/org/jbake/app/ParserTest.java index d6d47eb32..726d85e4d 100644 --- a/jbake-core/src/test/java/org/jbake/app/ParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ParserTest.java @@ -4,6 +4,7 @@ import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeProperty; +import org.jbake.model.DocumentModel; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.junit.Assert; @@ -17,8 +18,6 @@ import java.util.AbstractMap.SimpleEntry; import java.util.Arrays; import java.util.Calendar; -import java.util.Date; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -209,14 +208,14 @@ public void createSampleFile() throws Exception { @Test public void parseValidHTMLFile() { - Map map = parser.processFile(validHTMLFile); - Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - Assert.assertEquals("This is a Title = This is a valid Title", map.get("title")); - Assert.assertNotNull(map.get("date")); + DocumentModel documentModel = parser.processFile(validHTMLFile); + Assert.assertNotNull(documentModel); + Assert.assertEquals("draft", documentModel.getStatus()); + Assert.assertEquals("post", documentModel.getType()); + Assert.assertEquals("This is a Title = This is a valid Title", documentModel.getTitle()); + Assert.assertNotNull(documentModel.getDate()); Calendar cal = Calendar.getInstance(); - cal.setTime((Date) map.get("date")); + cal.setTime(documentModel.getDate()); Assert.assertEquals(8, cal.get(Calendar.MONTH)); Assert.assertEquals(2, cal.get(Calendar.DAY_OF_MONTH)); Assert.assertEquals(2013, cal.get(Calendar.YEAR)); @@ -225,14 +224,14 @@ public void parseValidHTMLFile() { @Test public void parseInvalidHTMLFile() { - Map map = parser.processFile(invalidHTMLFile); - Assert.assertNull(map); + DocumentModel documentModel = parser.processFile(invalidHTMLFile); + Assert.assertNull(documentModel); } @Test public void parseInvalidExtension(){ - Map map = parser.processFile(invalidExtensionFile); - Assert.assertNull(map); + DocumentModel documentModel = parser.processFile(invalidExtensionFile); + Assert.assertNull(documentModel); } @@ -240,11 +239,11 @@ public void parseInvalidExtension(){ public void parseMarkdownFileWithCustomHeaderSeparator() { config.setHeaderSeparator(customHeaderSeparator); - Map map = parser.processFile(validMarkdownFileWithCustomHeader); - Assert.assertNotNull(map); - Assert.assertEquals("draft", map.get("status")); - Assert.assertEquals("post", map.get("type")); - assertThat(map.get("body").toString()) + DocumentModel documentModel = parser.processFile(validMarkdownFileWithCustomHeader); + Assert.assertNotNull(documentModel); + Assert.assertEquals("draft", documentModel.getStatus()); + Assert.assertEquals("post", documentModel.getType()); + assertThat(documentModel.getBody()) .contains("

    A paragraph

    "); } @@ -253,10 +252,10 @@ public void parseMarkdownFileWithCustomHeaderSeparator() { public void parseMarkdownFileWithDefaultStatus() { config.setDefaultStatus("published"); - Map map = parser.processFile(validMarkdownFileWithDefaultStatus); - Assert.assertNotNull(map); - Assert.assertEquals("published", map.get("status")); - Assert.assertEquals("post", map.get("type")); + DocumentModel documentModel = parser.processFile(validMarkdownFileWithDefaultStatus); + Assert.assertNotNull(documentModel); + Assert.assertEquals("published", documentModel.getStatus()); + Assert.assertEquals("post", documentModel.getType()); } @Test @@ -264,10 +263,10 @@ public void parseMarkdownFileWithDefaultTypeAndStatus() { config.setDefaultStatus("published"); config.setDefaultType("page"); - Map map = parser.processFile(validMarkdownFileWithDefaultTypeAndStatus); - Assert.assertNotNull(map); - Assert.assertEquals("published", map.get("status")); - Assert.assertEquals("page", map.get("type")); + DocumentModel documentModel = parser.processFile(validMarkdownFileWithDefaultTypeAndStatus); + Assert.assertNotNull(documentModel); + Assert.assertEquals("published", documentModel.getStatus()); + Assert.assertEquals("page", documentModel.getType()); } @Test @@ -275,52 +274,52 @@ public void parseInvalidMarkdownFileWithoutDefaultStatus() { config.setDefaultStatus(""); config.setDefaultType("page"); - Map map = parser.processFile(invalidMarkdownFileWithoutDefaultStatus); - Assert.assertNull(map); + DocumentModel documentModel = parser.processFile(invalidMarkdownFileWithoutDefaultStatus); + Assert.assertNull(documentModel); } @Test public void parseInvalidMarkdownFile() { - Map map = parser.processFile(invalidMDFile); - Assert.assertNull(map); + DocumentModel documentModel = parser.processFile(invalidMDFile); + Assert.assertNull(documentModel); } @Test public void sanitizeKeysAndValues() { - Map map = parser.processFile(validaAsciidocWithUnsanitizedHeader); + DocumentModel map = parser.processFile(validaAsciidocWithUnsanitizedHeader); - assertThat(map.get("status")).isEqualTo("draft"); - assertThat(map.get("title")).isEqualTo("Title"); - assertThat(map.get("type")).isEqualTo("post"); + assertThat(map.getStatus()).isEqualTo("draft"); + assertThat(map.getTitle()).isEqualTo("Title"); + assertThat(map.getType()).isEqualTo("post"); assertThat(map.get("custom")).isEqualTo("custom without bom's"); - assertThat(map.get("tags")).isEqualTo(Arrays.asList("jbake", "java", "tag with space").toArray()); + assertThat(map.getTags()).isEqualTo(Arrays.asList("jbake", "java", "tag with space").toArray()); } @Test public void sanitizeTags() { config.setProperty(JBakeProperty.TAG_SANITIZE, true); - Map map = parser.processFile(validaAsciidocWithUnsanitizedHeader); + DocumentModel map = parser.processFile(validaAsciidocWithUnsanitizedHeader); - assertThat(map.get("tags")).isEqualTo(Arrays.asList("jbake", "java", "tag-with-space").toArray()); + assertThat(map.getTags()).isEqualTo(Arrays.asList("jbake", "java", "tag-with-space").toArray()); } @Test public void parseValidHTMLWithJSONFile() { - Map map = parser.processFile(validHTMLWithJSONFile); - assertJSONExtracted(map.get("jsondata")); + DocumentModel documentModel = parser.processFile(validHTMLWithJSONFile); + assertJSONExtracted(documentModel.get("jsondata")); } @Test public void parseValidAsciiDocWithJSONFile() { - Map map = parser.processFile(validAsciiDocWithJSONFile); - assertJSONExtracted(map.get("jsondata")); + DocumentModel documentModel = parser.processFile(validAsciiDocWithJSONFile); + assertJSONExtracted(documentModel.get("jsondata")); } @Test public void testValidAsciiDocWithADHeaderJSONFile() { - Map map = parser.processFile(validAsciiDocWithADHeaderJSONFile); - assertJSONExtracted(map.get("jsondata")); + DocumentModel documentModel = parser.processFile(validAsciiDocWithADHeaderJSONFile); + assertJSONExtracted(documentModel.get("jsondata")); } private void assertJSONExtracted(Object jsonDataEntry) { diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index 9937e7cf1..4fae0be0c 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -127,20 +127,20 @@ public void shouldContainPostNavigation() throws Exception { int renderResponse = documentsRenderer.render(renderer, db, configuration); DocumentModel fourthDoc = simpleDocument(fourth); - fourthDoc.put("previousContent", simpleDocument(third)); - fourthDoc.put("nextContent", null); + fourthDoc.setPreviousContent(simpleDocument(third)); + fourthDoc.setNextContent(null); DocumentModel thirdDoc = simpleDocument(third); - thirdDoc.put("nextContent", simpleDocument(fourth)); - thirdDoc.put("previousContent", simpleDocument(second)); + thirdDoc.setNextContent(simpleDocument(fourth)); + thirdDoc.setPreviousContent(simpleDocument(second)); DocumentModel secondDoc = simpleDocument(second); - secondDoc.put("nextContent", simpleDocument(third)); - secondDoc.put("previousContent", simpleDocument(first)); + secondDoc.setNextContent(simpleDocument(third)); + secondDoc.setPreviousContent(simpleDocument(first)); DocumentModel firstDoc = simpleDocument(first); - firstDoc.put("nextContent", simpleDocument(second)); - firstDoc.put("previousContent", null); + firstDoc.setNextContent(simpleDocument(second)); + firstDoc.setPreviousContent(null); verify(renderer, times(4)).render(argument.capture()); From 8cf9a30c5e6846be88c292a3960b01baa8a77f04 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 19 Aug 2018 13:23:52 +0200 Subject: [PATCH 17/27] move Crawler Attributes to ModelAttributes --- .../src/main/java/org/jbake/app/Crawler.java | 101 +++++++----------- .../src/main/java/org/jbake/app/Renderer.java | 2 +- .../java/org/jbake/model/ModelAttributes.java | 20 ++++ .../template/FreemarkerTemplateEngine.java | 8 +- .../template/ThymeleafTemplateEngine.java | 6 +- .../java/org/jbake/util/HtmlUtilTest.java | 3 - 6 files changed, 66 insertions(+), 74 deletions(-) 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 b987f790c..333043c13 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -3,7 +3,6 @@ import com.orientechnologies.orient.core.record.impl.ODocument; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FilenameUtils; -import org.jbake.app.Crawler.Attributes.Status; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.app.configuration.JBakeConfigurationFactory; import org.jbake.model.DocumentModel; @@ -28,7 +27,7 @@ */ public class Crawler { - private static final Logger LOGGER = LoggerFactory.getLogger(Crawler.class); + private static final Logger logger = LoggerFactory.getLogger(Crawler.class); private final ContentStore db; private JBakeConfiguration config; private Parser parser; @@ -63,11 +62,11 @@ public Crawler(ContentStore db, JBakeConfiguration config) { public void crawl() { crawl(config.getContentFolder()); - LOGGER.info("Content detected:"); + logger.info("Content detected:"); for (String docType : DocumentTypes.getDocumentTypes()) { long count = db.getDocumentCount(docType); if (count > 0) { - LOGGER.info("Parsed {} files of type: {}", count, docType); + logger.info("Parsed {} files of type: {}", count, docType); } } @@ -84,47 +83,47 @@ private void crawl(File path) { Arrays.sort(contents); for (File sourceFile : contents) { if (sourceFile.isFile()) { - StringBuilder sb = new StringBuilder(); - sb.append("Processing [").append(sourceFile.getPath()).append("]... "); - String sha1 = buildHash(sourceFile); - String uri = buildURI(sourceFile); - boolean process = true; - DocumentStatus status = DocumentStatus.NEW; - for (String docType : DocumentTypes.getDocumentTypes()) { - status = findDocumentStatus(docType, uri, sha1); - if (status == DocumentStatus.UPDATED) { - sb.append(" : modified "); - db.deleteContent(docType, uri); - - } else if (status == DocumentStatus.IDENTICAL) { - sb.append(" : same "); - process = false; - } - if (!process) { - break; - } - } - if (DocumentStatus.NEW == status) { - sb.append(" : new "); - } - if (process) { // new or updated - crawlSourceFile(sourceFile, sha1, uri); - } - LOGGER.info("{}", sb); - } - if (sourceFile.isDirectory()) { + crawlFile(sourceFile); + } else if (sourceFile.isDirectory()) { crawl(sourceFile); } } } } + private void crawlFile(File sourceFile) { + StringBuilder sb = new StringBuilder(); + sb.append("Processing [").append(sourceFile.getPath()).append("]... "); + String sha1 = buildHash(sourceFile); + String uri = buildURI(sourceFile); + boolean process = true; + for (String docType : DocumentTypes.getDocumentTypes()) { + DocumentStatus status = findDocumentStatus(docType, uri, sha1); + if (status == DocumentStatus.UPDATED) { + sb.append(" : modified "); + db.deleteContent(docType, uri); + } else if (status == DocumentStatus.IDENTICAL) { + sb.append(" : same "); + process = false; + } else if (DocumentStatus.NEW == status) { + sb.append(" : new "); + } + if (!process || status != DocumentStatus.NEW) { + break; + } + } + if (process) { // new or updated + processSourceFile(sourceFile, sha1, uri); + } + logger.info("{}", sb); + } + private String buildHash(final File sourceFile) { String sha1; try { sha1 = FileUtil.sha1(sourceFile); } catch (Exception e) { - LOGGER.error("unable to build sha1 hash for source file '{}'", sourceFile); + logger.error("unable to build sha1 hash for source file '{}'", sourceFile); sha1 = ""; } return sha1; @@ -184,7 +183,7 @@ private boolean useNoExtensionUri(String uri) { && uri.startsWith(noExtensionUriPrefix); } - private void crawlSourceFile(final File sourceFile, final String sha1, final String uri) { + private void processSourceFile(final File sourceFile, final String sha1, final String uri) { try { DocumentModel fileContents = parser.processFile(sourceFile); if (fileContents != null) { @@ -199,7 +198,7 @@ private void crawlSourceFile(final File sourceFile, final String sha1, final Str doc.fromMap(fileContents); doc.save(); } else { - LOGGER.warn("{} has an invalid header, it has been ignored!", sourceFile); + logger.warn("{} has an invalid header, it has been ignored!", sourceFile); } } catch (Exception ex) { throw new RuntimeException("Failed crawling file: " + sourceFile.getPath() + " " + ex.getMessage(), ex); @@ -215,10 +214,10 @@ private void addAdditionalDocumentAttributes(DocumentModel documentModel, File s documentModel.setSourceUri(uri); documentModel.setUri(uri); - if (documentModel.getStatus().equals(Status.PUBLISHED_DATE) + if (documentModel.getStatus().equals(ModelAttributes.Status.PUBLISHED_DATE) && (documentModel.getDate() != null) && new Date().after(documentModel.getDate())) { - documentModel.setStatus(Status.PUBLISHED); + documentModel.setStatus(ModelAttributes.Status.PUBLISHED); } if (config.getUriWithoutExtension()) { @@ -235,7 +234,7 @@ private DocumentStatus findDocumentStatus(String docType, String uri, String sha if (!match.isEmpty()) { DocumentModel documentModel = match.getDocumentModel(0); String oldHash = documentModel.getSha1(); - if (!(oldHash.equals(sha1)) || Boolean.FALSE.equals(documentModel.getRendered())) { + if (!oldHash.equals(sha1) || !documentModel.getRendered()) { return DocumentStatus.UPDATED; } else { return DocumentStatus.IDENTICAL; @@ -245,28 +244,4 @@ private DocumentStatus findDocumentStatus(String docType, String uri, String sha } } - public abstract static class Attributes { - - public static final String ALLTAGS = "alltags"; - public static final String PUBLISHED_DATE = "published_date"; - public static final String DB = "db"; - - private Attributes() { - } - - /** - * Possible values of the {@link ModelAttributes#STATUS} property - * - * @author ndx - */ - public abstract static class Status { - public static final String PUBLISHED_DATE = "published-date"; - public static final String PUBLISHED = "published"; - public static final String DRAFT = "draft"; - - private Status() { - } - } - - } } 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 88da336cb..2bf49802f 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -122,7 +122,7 @@ public void render(DocumentModel content) throws Exception { Files.delete(publishedFile.toPath()); } - if (content.getStatus().equals(Crawler.Attributes.Status.DRAFT)) { + if (content.getStatus().equals(ModelAttributes.Status.DRAFT)) { outputFilename = outputFilename + config.getDraftSuffix(); } diff --git a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java index 77e306605..cf680e03f 100644 --- a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java @@ -30,4 +30,24 @@ public abstract class ModelAttributes { public static final String TAG = "tag"; public static final String VERSION = "version"; public static final String OUT = "out"; + public static final String ALLTAGS = "alltags"; + public static final String PUBLISHED_DATE = "published_date"; + public static final String DB = "db"; + + private ModelAttributes() { + } + + /** + * Possible values of the {@link ModelAttributes#STATUS} property + * + * @author ndx + */ + public abstract static class Status { + public static final String PUBLISHED_DATE = "published-date"; + public static final String PUBLISHED = "published"; + public static final String DRAFT = "draft"; + + private Status() { + } + } } 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 f9162aa1e..58c6aea96 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -6,8 +6,8 @@ import freemarker.template.*; import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler; import org.jbake.app.configuration.JBakeConfiguration; +import org.jbake.model.ModelAttributes; import org.jbake.template.model.TemplateModel; import java.io.File; @@ -78,7 +78,7 @@ public freemarker.template.TemplateModel get(final String key) throws TemplateMo // GIT Issue#357: Accessing db in freemarker template throws exception // When content store is accessed with key "db" then wrap the ContentStore with BeansWrapper and return to template. // All methods on db are then accessible in template. Eg: ${db.getPublishedPostsByTag(tagName).size()} - if (key.equals(Crawler.Attributes.DB)) { + if (key.equals(ModelAttributes.DB)) { BeansWrapperBuilder bwb = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); BeansWrapper bw = bwb.build(); return bw.wrap(db); @@ -89,9 +89,9 @@ public freemarker.template.TemplateModel get(final String key) throws TemplateMo @Override public freemarker.template.TemplateModel adapt(String key, Object extractedValue) { - if (key.equals(Crawler.Attributes.ALLTAGS)) { + if (key.equals(ModelAttributes.ALLTAGS)) { return new SimpleCollection((Collection) extractedValue, wrapper); - } else if (key.equals(Crawler.Attributes.PUBLISHED_DATE)) { + } else if (key.equals(ModelAttributes.PUBLISHED_DATE)) { return new SimpleDate((Date) extractedValue, TemplateDateModel.UNKNOWN); } else { // All other cases, as far as I know, are document collections 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 62db5fa1e..01b9e7d6b 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -3,10 +3,10 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.lang.LocaleUtils; import org.jbake.app.ContentStore; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.model.DocumentModel; +import org.jbake.model.ModelAttributes; import org.jbake.template.model.TemplateModel; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; @@ -130,14 +130,14 @@ protected Object loadValue() { return extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter() { @Override public LazyContextVariable adapt(String key, final Object extractedValue) { - if (key.equals(Attributes.ALLTAGS)) { + if (key.equals(ModelAttributes.ALLTAGS)) { return new LazyContextVariable>() { @Override protected Set loadValue() { return (Set) extractedValue; } }; - } else if (key.equals(Attributes.PUBLISHED_DATE)) { + } else if (key.equals(ModelAttributes.PUBLISHED_DATE)) { return new LazyContextVariable() { @Override protected Date loadValue() { diff --git a/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java b/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java index bc9ffb8c9..0d5c4f8cc 100644 --- a/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java +++ b/jbake-core/src/test/java/org/jbake/util/HtmlUtilTest.java @@ -1,15 +1,12 @@ package org.jbake.util; import org.jbake.TestUtils; -import org.jbake.app.Crawler.Attributes; import org.jbake.app.configuration.ConfigUtil; import org.jbake.app.configuration.DefaultJBakeConfiguration; import org.jbake.model.DocumentModel; import org.junit.Before; import org.junit.Test; -import java.io.File; - import static org.assertj.core.api.Assertions.assertThat; From 75154d40a5bbdfbfb35759c4f3025ac1f3ee15be Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 19 Aug 2018 19:21:49 +0200 Subject: [PATCH 18/27] fix codacy warnings --- .../org/jbake/template/DelegatingTemplateEngine.java | 11 ++++++----- .../org/jbake/template/FreemarkerTemplateEngine.java | 12 +++++++++++- .../src/test/java/org/jbake/FakeDocumentBuilder.java | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-) 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 bea52842c..0190f5b66 100644 --- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java @@ -42,13 +42,14 @@ public DelegatingTemplateEngine(final ContentStore db, final JBakeConfiguration } @Override - public void renderDocument(final TemplateModel model, String templateName, final Writer writer) throws RenderingException { + public void renderDocument(final TemplateModel model, final String templateName, final Writer writer) throws RenderingException { model.setVersion(config.getVersion()); model.setConfig(config.asHashMap()); // if default template exists we will use it File templateFolder = config.getTemplateFolder(); File templateFile = new File(templateFolder, templateName); + String theTemplateName = templateName; if (!templateFile.exists()) { LOGGER.info("Default template: {} was not found, searching for others...", templateName); // if default template does not exist then check if any alternative engine templates exist @@ -57,17 +58,17 @@ public void renderDocument(final TemplateModel model, String templateName, final templateFile = new File(templateFolder, templateNameWithoutExt + "." + extension); if (templateFile.exists()) { LOGGER.info("Found alternative template file: {} using this instead", templateFile.getName()); - templateName = templateFile.getName(); + theTemplateName = templateFile.getName(); break; } } } - String ext = FileUtil.fileExt(templateName); + String ext = FileUtil.fileExt(theTemplateName); AbstractTemplateEngine engine = renderers.getEngine(ext); if (engine != null) { - engine.renderDocument(model, templateName, writer); + engine.renderDocument(model, theTemplateName, writer); } else { - LOGGER.error("Warning - No template engine found for template: {}", templateName); + LOGGER.error("Warning - No template engine found for template: {}", theTemplateName); } } } 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 58c6aea96..29475b27d 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -3,7 +3,17 @@ import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.BeansWrapperBuilder; -import freemarker.template.*; +import freemarker.template.Configuration; +import freemarker.template.ObjectWrapper; +import freemarker.template.SimpleCollection; +import freemarker.template.SimpleDate; +import freemarker.template.SimpleHash; +import freemarker.template.SimpleSequence; +import freemarker.template.Template; +import freemarker.template.TemplateDateModel; +import freemarker.template.TemplateException; +import freemarker.template.TemplateHashModel; +import freemarker.template.TemplateModelException; import org.apache.commons.configuration.CompositeConfiguration; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; diff --git a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java index c7a170023..3962774bf 100644 --- a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java +++ b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -11,8 +11,8 @@ public class FakeDocumentBuilder { - DocumentModel fileModel = new DocumentModel(); - String type; + private DocumentModel fileModel = new DocumentModel(); + private String type; private boolean hasSourceUri = false; private boolean hasSha1 = false; private boolean hasDate = false; From c8b3301453398aae236fdf7ae19558fc75e84167 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 19 Aug 2018 23:55:25 +0200 Subject: [PATCH 19/27] handle document caching --- .../main/java/org/jbake/app/ContentStore.java | 10 +++++----- .../src/main/java/org/jbake/app/Crawler.java | 1 + .../main/java/org/jbake/model/DocumentModel.java | 16 ++++++++++++++++ .../java/org/jbake/model/ModelAttributes.java | 2 +- .../java/org/jbake/parser/ParserContext.java | 2 +- .../src/test/java/org/jbake/app/ParserTest.java | 11 +++++++++++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 84640ed98..650973904 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -381,23 +381,23 @@ private void createDocType(final OSchema schema, final String docType) { OClass page = schema.createClass(docType); // Primary key - String attribName = ModelAttributes.SOURCE_URI.toString(); + String attribName = ModelAttributes.SOURCE_URI; page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "sourceUriIndex", OClass.INDEX_TYPE.UNIQUE, attribName); - attribName = ModelAttributes.SHA1.toString(); + attribName = ModelAttributes.SHA1; page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "sha1Index", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = ModelAttributes.CACHED.toString(); + attribName = ModelAttributes.CACHED; page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); page.createIndex(docType + "cachedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = ModelAttributes.RENDERED.toString(); + attribName = ModelAttributes.RENDERED; page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); page.createIndex(docType + "renderedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - attribName = ModelAttributes.STATUS.toString(); + attribName = ModelAttributes.STATUS; page.createProperty(attribName, OType.STRING).setNotNull(true); page.createIndex(docType + "statusIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); } 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 333043c13..be3cd855d 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -213,6 +213,7 @@ private void addAdditionalDocumentAttributes(DocumentModel documentModel, File s documentModel.setFile(sourceFile.getPath()); documentModel.setSourceUri(uri); documentModel.setUri(uri); + documentModel.setCached(true); if (documentModel.getStatus().equals(ModelAttributes.Status.PUBLISHED_DATE) && (documentModel.getDate() != null) diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index 6e74589a2..3778a0362 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -7,6 +7,12 @@ public class DocumentModel extends BaseModel { + public static DocumentModel createDefaultDocumentModel() { + DocumentModel documentModel = new DocumentModel(); + documentModel.setCached(true); + return documentModel; + } + public String getBody() { return (String) get(ModelAttributes.BODY); } @@ -106,6 +112,16 @@ public void setTitle(String title) { put(ModelAttributes.TITLE, title); } + public Boolean getCached() { + + Object value = get(ModelAttributes.CACHED); + if ( value instanceof String ) { + return Boolean.valueOf((String) value); + } else { + return (Boolean) value; + } + } + public void setCached(boolean cached) { put(ModelAttributes.CACHED, cached); } diff --git a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java index cf680e03f..2dde1d0ff 100644 --- a/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java +++ b/jbake-core/src/main/java/org/jbake/model/ModelAttributes.java @@ -4,7 +4,7 @@ public abstract class ModelAttributes { public static final String SHA1 = "sha1"; public static final String SOURCE_URI = "sourceuri"; public static final String RENDERED = "rendered"; - public static final String CACHED = "cached"; //TODO: Do we need this? + public static final String CACHED = "cached"; public static final String STATUS = "status"; public static final String NAME = "name"; public static final String BODY = "body"; diff --git a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java index 5a8fc3edc..ce51d6412 100644 --- a/jbake-core/src/main/java/org/jbake/parser/ParserContext.java +++ b/jbake-core/src/main/java/org/jbake/parser/ParserContext.java @@ -23,7 +23,7 @@ public ParserContext( this.fileLines = fileLines; this.config = config; this.hasHeader = hasHeader; - this.documentModel = new DocumentModel(); + this.documentModel = DocumentModel.createDefaultDocumentModel(); } public File getFile() { diff --git a/jbake-core/src/test/java/org/jbake/app/ParserTest.java b/jbake-core/src/test/java/org/jbake/app/ParserTest.java index 726d85e4d..c82882def 100644 --- a/jbake-core/src/test/java/org/jbake/app/ParserTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ParserTest.java @@ -105,6 +105,7 @@ public void createSampleFile() throws Exception { out = new PrintWriter(validMarkdownFileWithDefaultTypeAndStatus); out.println("title=Custom Header separator"); + out.println("cached=false"); out.println(config.getHeaderSeparator()); out.println("# Hello Markdown!"); out.println(""); @@ -256,6 +257,7 @@ public void parseMarkdownFileWithDefaultStatus() { Assert.assertNotNull(documentModel); Assert.assertEquals("published", documentModel.getStatus()); Assert.assertEquals("post", documentModel.getType()); + Assert.assertEquals(true, documentModel.getCached()); } @Test @@ -269,6 +271,15 @@ public void parseMarkdownFileWithDefaultTypeAndStatus() { Assert.assertEquals("page", documentModel.getType()); } + @Test + public void parseMarkdownFileWithDisabledCache() { + config.setDefaultStatus("published"); + config.setDefaultType("page"); + + DocumentModel documentModel = parser.processFile(validMarkdownFileWithDefaultTypeAndStatus); + Assert.assertEquals(false, documentModel.getCached()); + } + @Test public void parseInvalidMarkdownFileWithoutDefaultStatus() { config.setDefaultStatus(""); From b26dbc632fef0a4afa85e5648c796a98e9d0aca2 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 22 Aug 2018 21:40:11 +0200 Subject: [PATCH 20/27] make DocumentList more generic --- .../main/java/org/jbake/app/ContentStore.java | 38 +++++++++---------- .../src/main/java/org/jbake/app/Crawler.java | 10 ++--- .../main/java/org/jbake/app/DocumentList.java | 11 ++---- .../org/jbake/render/DocumentsRenderer.java | 6 +-- .../jbake/template/PebbleTemplateEngine.java | 3 +- .../template/model/AllContentExtractor.java | 5 ++- .../model/PublishedContentExtractor.java | 5 ++- .../jbake/template/model/TagsExtractor.java | 2 +- .../java/org/jbake/app/ContentStoreTest.java | 6 +-- .../test/java/org/jbake/app/CrawlerTest.java | 25 ++++++------ .../jbake/render/DocumentsRendererTest.java | 10 ++--- 11 files changed, 57 insertions(+), 64 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 650973904..8b0c647a2 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -234,7 +234,7 @@ public long getPublishedCount(String docType) { /* * In fact, the URI should be the only input as there can only be one document at given URI; but the DB is split per document type for some reason. */ - public DocumentList getDocumentByUri(String docType, String uri) { + public DocumentList getDocumentByUri(String docType, String uri) { return query(String.format(STATEMENT_GET_POST_BY_TYPE_AND_URI, quoteIdentifier(docType)), uri); } @@ -243,20 +243,20 @@ public DocumentList getDocumentStatus(String docType, String uri) { return query(statement, uri); } - public DocumentList getPublishedPosts() { + public DocumentList getPublishedPosts() { return getPublishedContent("post"); } - public DocumentList getPublishedPosts(boolean applyPaging) { + public DocumentList getPublishedPosts(boolean applyPaging) { return getPublishedContent("post", applyPaging); } - public DocumentList getPublishedPostsByTag(String tag) { + public DocumentList getPublishedPostsByTag(String tag) { return query(STATEMENT_GET_PUBLISHED_POSTS_BY_TAG, tag); } - public DocumentList getPublishedDocumentsByTag(String tag) { - final DocumentList documents = new DocumentList(); + public DocumentList getPublishedDocumentsByTag(String tag) { + final DocumentList documents = new DocumentList<>(); for (final String docType : DocumentTypes.getDocumentTypes()) { String statement = String.format(STATEMENT_GET_PUBLISHED_POST_BY_TYPE_AND_TAG, quoteIdentifier(docType)); @@ -266,11 +266,11 @@ public DocumentList getPublishedDocumentsByTag(String tag) { return documents; } - public DocumentList getPublishedPages() { + public DocumentList getPublishedPages() { return getPublishedContent("page"); } - public DocumentList getPublishedContent(String docType) { + public DocumentList getPublishedContent(String docType) { return getPublishedContent(docType, false); } @@ -282,11 +282,11 @@ private DocumentList getPublishedContent(String docType, boolean applyPaging) { return query(query); } - public DocumentList getAllContent(String docType) { + public DocumentList getAllContent(String docType) { return getAllContent(docType, false); } - public DocumentList getAllContent(String docType, boolean applyPaging) { + public DocumentList getAllContent(String docType, boolean applyPaging) { String query = String.format(STATEMENT_GET_ALL_CONTENT_BY_DOCTYPE, quoteIdentifier(docType)); if (applyPaging && hasStartAndLimitBoundary()) { query += " SKIP " + start + " LIMIT " + limit; @@ -298,11 +298,11 @@ private boolean hasStartAndLimitBoundary() { return (start >= 0) && (limit > -1); } - private DocumentList getAllTagsFromPublishedPosts() { + private DocumentList getAllTagsFromPublishedPosts() { return query(STATEMENT_GET_TAGS_FROM_PUBLISHED_POSTS); } - private DocumentList getSignaturesForTemplates() { + private DocumentList getSignaturesForTemplates() { return query(STATEMENT_GET_SIGNATURE_FOR_TEMPLATES); } @@ -334,13 +334,13 @@ private void insertTemplatesSignature(String currentTemplatesSignature) { executeCommand(STATEMENT_INSERT_TEMPLATES_SIGNATURE, currentTemplatesSignature); } - private DocumentList query(String sql) { + private DocumentList query(String sql) { activateOnCurrentThread(); OResultSet results = db.query(sql); return DocumentList.wrap(results); } - private DocumentList query(String sql, Object... args) { + private DocumentList query(String sql, Object... args) { activateOnCurrentThread(); OResultSet results = db.command(sql, args); return DocumentList.wrap(results); @@ -352,10 +352,10 @@ private void executeCommand(String query, Object... args) { } public Set getTags() { - DocumentList docs = this.getAllTagsFromPublishedPosts(); + DocumentList docs = this.getAllTagsFromPublishedPosts(); Set result = new HashSet<>(); - for (BaseModel document : docs) { - String[] tags = ((DocumentModel) document).getTags(); + for (DocumentModel document : docs) { + String[] tags = document.getTags(); Collections.addAll(result, tags); } return result; @@ -365,8 +365,8 @@ public Set getAllTags() { Set result = new HashSet<>(); for (String docType : DocumentTypes.getDocumentTypes()) { String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, quoteIdentifier(docType)); - DocumentList docs = query(statement); - for (BaseModel document : docs) { + DocumentList docs = query(statement); + for (DocumentModel document : docs) { String[] tags = ((DocumentModel) document).getTags(); Collections.addAll(result, tags); } 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 be3cd855d..866efa145 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -230,12 +230,12 @@ private String getPathToRoot(File sourceFile) { return FileUtil.getUriPathToContentRoot(config, sourceFile); } - private DocumentStatus findDocumentStatus(String docType, String uri, String sha1) { - DocumentList match = db.getDocumentStatus(docType, uri); + private DocumentStatus findDocumentStatus(String documentType, String uri, String sha1) { + DocumentList match = db.getDocumentStatus(documentType, uri); if (!match.isEmpty()) { - DocumentModel documentModel = match.getDocumentModel(0); - String oldHash = documentModel.getSha1(); - if (!oldHash.equals(sha1) || !documentModel.getRendered()) { + DocumentModel document = match.get(0); + String oldHash = document.getSha1(); + if (!oldHash.equals(sha1) || !document.getRendered()) { return DocumentStatus.UPDATED; } else { return DocumentStatus.IDENTICAL; diff --git a/jbake-core/src/main/java/org/jbake/app/DocumentList.java b/jbake-core/src/main/java/org/jbake/app/DocumentList.java index 9d564442d..d297ff387 100644 --- a/jbake-core/src/main/java/org/jbake/app/DocumentList.java +++ b/jbake-core/src/main/java/org/jbake/app/DocumentList.java @@ -2,8 +2,6 @@ import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.executor.OResultSet; -import com.orientechnologies.orient.core.record.impl.ODocument; -import org.jbake.model.BaseModel; import org.jbake.model.DocumentModel; import java.util.LinkedList; @@ -14,10 +12,10 @@ * * @author Cédric Champeau */ -public class DocumentList extends LinkedList { +public class DocumentList extends LinkedList { - public static DocumentList wrap(OResultSet docs) { - DocumentList list = new DocumentList(); + public static DocumentList wrap(OResultSet docs) { + DocumentList list = new DocumentList<>(); while (docs.hasNext()) { OResult next = docs.next(); list.add(DBUtil.documentToModel(next)); @@ -26,7 +24,4 @@ public static DocumentList wrap(OResultSet docs) { return list; } - public DocumentModel getDocumentModel(int index) { - return (DocumentModel) get(index); - } } 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 5abc3f7fc..43d86933f 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -20,7 +20,7 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) int renderedCount = 0; final List errors = new LinkedList<>(); for (String docType : DocumentTypes.getDocumentTypes()) { - DocumentList documentList = db.getUnrenderedContent(docType); + DocumentList documentList = db.getUnrenderedContent(docType); if (documentList == null) { continue; @@ -32,7 +32,7 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) while (index < documentList.size()) { try { - DocumentModel document = documentList.getDocumentModel(index); + DocumentModel document = documentList.get(index); document.setNextContent(null); document.setPreviousContent(null); @@ -41,7 +41,7 @@ public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) } if (index < documentList.size() - 1) { - DocumentModel tempNext = (DocumentModel) documentList.get(index + 1); + DocumentModel tempNext = documentList.get(index + 1); document.setPreviousContent(getContentForNav(tempNext)); } diff --git a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java index e4ff63bcd..bd2531e22 100644 --- a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java @@ -8,7 +8,6 @@ import com.mitchellbosecke.pebble.template.PebbleTemplate; import org.jbake.app.ContentStore; import org.jbake.app.configuration.JBakeConfiguration; -import org.jbake.model.DocumentModel; import org.jbake.template.model.TemplateModel; import java.io.IOException; @@ -44,7 +43,7 @@ private void initializeTemplateEngine() { } @Override - public void renderDocument(TemplateModel model, String templateName, Writer writer) + public void renderDocument(final TemplateModel model, final String templateName, final Writer writer) throws RenderingException { PebbleTemplate template; diff --git a/jbake-core/src/main/java/org/jbake/template/model/AllContentExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/AllContentExtractor.java index db23bdd03..38faa7d05 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/AllContentExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/AllContentExtractor.java @@ -2,6 +2,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.ModelExtractor; @@ -11,10 +12,10 @@ public class AllContentExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { - DocumentList allContent = new DocumentList(); + DocumentList allContent = new DocumentList<>(); String[] documentTypes = DocumentTypes.getDocumentTypes(); for (String docType : documentTypes) { - DocumentList query = db.getAllContent(docType); + DocumentList query = db.getAllContent(docType); allContent.addAll(query); } return allContent; diff --git a/jbake-core/src/main/java/org/jbake/template/model/PublishedContentExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/PublishedContentExtractor.java index d0aa9a603..b9b4081ec 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/PublishedContentExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/PublishedContentExtractor.java @@ -2,6 +2,7 @@ import org.jbake.app.ContentStore; import org.jbake.app.DocumentList; +import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.template.ModelExtractor; @@ -11,10 +12,10 @@ public class PublishedContentExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { - DocumentList publishedContent = new DocumentList(); + DocumentList publishedContent = new DocumentList<>(); String[] documentTypes = DocumentTypes.getDocumentTypes(); for (String docType : documentTypes) { - DocumentList query = db.getPublishedContent(docType); + DocumentList query = db.getPublishedContent(docType); publishedContent.addAll(query); } return publishedContent; diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java index ba3aa85e8..44933e505 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagsExtractor.java @@ -15,7 +15,7 @@ public class TagsExtractor implements ModelExtractor { @Override public DocumentList get(ContentStore db, Map model, String key) { - DocumentList dl = new DocumentList(); + DocumentList dl = new DocumentList<>(); TemplateModel templateModel = new TemplateModel(); templateModel.putAll(model); Map config = templateModel.getConfig(); diff --git a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java index d9a0ea1ea..0601e2fb5 100644 --- a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java @@ -2,9 +2,9 @@ import com.orientechnologies.orient.core.record.impl.ODocument; import org.jbake.FakeDocumentBuilder; -import org.jbake.app.Crawler.Attributes.Status; +import static org.junit.Assert.assertEquals; + import org.jbake.model.DocumentModel; -import org.jbake.model.DocumentTypes; import org.jbake.model.ModelAttributes; import org.junit.Test; @@ -57,7 +57,7 @@ public void testMergeDocument() { values.put("foo", "newValue"); db.mergeDocument(values); - DocumentList docs = db.getDocumentByUri(DOC_TYPE_POST, uri); + DocumentList docs = db.getDocumentByUri(DOC_TYPE_POST, uri); assertEquals(1, docs.size()); assertEquals("newValue", docs.get(0).get("foo")); diff --git a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java index 680e2d4c1..c9ed5bafb 100644 --- a/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java +++ b/jbake-core/src/test/java/org/jbake/app/CrawlerTest.java @@ -3,7 +3,6 @@ import org.apache.commons.io.FilenameUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; -import org.jbake.model.BaseModel; import org.jbake.model.DocumentModel; import org.jbake.model.ModelAttributes; import org.junit.Assert; @@ -26,7 +25,7 @@ public void crawl() { Assert.assertEquals(4, db.getDocumentCount("post")); Assert.assertEquals(3, db.getDocumentCount("page")); - DocumentList results = db.getPublishedPosts(); + DocumentList results = db.getPublishedPosts(); assertThat(results.size()).isEqualTo(3); @@ -36,19 +35,18 @@ public void crawl() { .containsValue("../../../"); } - DocumentList allPosts = db.getAllContent("post"); + DocumentList allPosts = db.getAllContent("post"); assertThat(allPosts.size()).isEqualTo(4); - for (BaseModel content : allPosts) { - DocumentModel documentModel = (DocumentModel) content; - if (documentModel.getTitle().equals("Draft Post")) { + for (DocumentModel content : allPosts) { + if (content.getTitle().equals("Draft Post")) { assertThat(content).containsKey(ModelAttributes.DATE); } } // covers bug #213 - DocumentList publishedPostsByTag = db.getPublishedPostsByTag("blog"); + DocumentList publishedPostsByTag = db.getPublishedPostsByTag("blog"); Assert.assertEquals(3, publishedPostsByTag.size()); } @@ -64,15 +62,14 @@ public void renderWithPrettyUrls() { Assert.assertEquals(4, db.getDocumentCount("post")); Assert.assertEquals(3, db.getDocumentCount("page")); - DocumentList documents = db.getPublishedPosts(); + DocumentList documents = db.getPublishedPosts(); - for (BaseModel model : documents) { - DocumentModel documentModel = (DocumentModel) model; - String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName(documentModel.getFile()) + "/"; + for (DocumentModel model : documents) { + String noExtensionUri = "blog/\\d{4}/" + FilenameUtils.getBaseName(model.getFile()) + "/"; - Assert.assertThat(documentModel.getNoExtensionUri(), RegexMatcher.matches(noExtensionUri)); - Assert.assertThat(documentModel.getUri(), RegexMatcher.matches(noExtensionUri + "index\\.html")); - Assert.assertThat(documentModel.getRootPath(), is("../../../")); + Assert.assertThat(model.getNoExtensionUri(), RegexMatcher.matches(noExtensionUri)); + Assert.assertThat(model.getUri(), RegexMatcher.matches(noExtensionUri + "index\\.html")); + Assert.assertThat(model.getRootPath(), is("../../../")); } } diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index 4fae0be0c..ce8bddeb1 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -29,7 +29,7 @@ public class DocumentsRendererTest { private ContentStore db; private Renderer renderer; private JBakeConfiguration configuration; - private DocumentList emptyTemplateModelList; + private DocumentList emptyTemplateModelList; @Captor private ArgumentCaptor argument; @@ -44,7 +44,7 @@ public void setUp() { db = mock(ContentStore.class); renderer = mock(Renderer.class); configuration = mock(JBakeConfiguration.class); - emptyTemplateModelList = new DocumentList(); + emptyTemplateModelList = new DocumentList<>(); } @Test @@ -63,7 +63,7 @@ public void shouldReturnCountOfProcessedDocuments() throws Exception { // given: DocumentTypes.addDocumentType("customType"); - DocumentList templateModelList = new DocumentList(); + DocumentList templateModelList = new DocumentList<>(); templateModelList.add(emptyDocument()); templateModelList.add(emptyDocument()); @@ -89,7 +89,7 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception // given DocumentTypes.addDocumentType("customType"); - DocumentList templateModelList = new DocumentList(); + DocumentList templateModelList = new DocumentList<>(); DocumentModel document = emptyDocument(); DocumentModel document2 = emptyDocument(); templateModelList.add(document); @@ -116,7 +116,7 @@ public void shouldContainPostNavigation() throws Exception { String third = "Third Document"; String fourth = "Fourth Document"; - DocumentList documents = new DocumentList(); + DocumentList documents = new DocumentList<>(); documents.add(simpleDocument(fourth)); documents.add(simpleDocument(third)); documents.add(simpleDocument(second)); From 61253234c2986b533b2298e8b0527f15d5c66dee Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 14 Nov 2018 13:32:38 +0100 Subject: [PATCH 21/27] fix broken status concatenation --- jbake-core/src/main/java/org/jbake/app/Crawler.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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 866efa145..daaaa22d7 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -97,22 +97,27 @@ private void crawlFile(File sourceFile) { String sha1 = buildHash(sourceFile); String uri = buildURI(sourceFile); boolean process = true; + DocumentStatus status = DocumentStatus.NEW; + for (String docType : DocumentTypes.getDocumentTypes()) { - DocumentStatus status = findDocumentStatus(docType, uri, sha1); + status = findDocumentStatus(docType, uri, sha1); + if ( status == null ) continue; if (status == DocumentStatus.UPDATED) { sb.append(" : modified "); db.deleteContent(docType, uri); + break; } else if (status == DocumentStatus.IDENTICAL) { sb.append(" : same "); process = false; - } else if (DocumentStatus.NEW == status) { - sb.append(" : new "); } if (!process || status != DocumentStatus.NEW) { break; } } if (process) { // new or updated + if (status == DocumentStatus.NEW) { + sb.append(" : new "); + } processSourceFile(sourceFile, sha1, uri); } logger.info("{}", sb); From 6eb635bef8b94c721221dfa93272322065c16eb8 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sun, 28 Jul 2019 21:12:36 +0200 Subject: [PATCH 22/27] cleanup template engines --- .../java/org/jbake/model/DocumentModel.java | 1 - .../template/FreemarkerTemplateEngine.java | 3 +- .../template/GroovyMarkupTemplateEngine.java | 21 +++------ .../jbake/template/GroovyTemplateEngine.java | 43 +++++++++---------- .../jbake/template/JadeTemplateEngine.java | 7 +-- .../jbake/template/PebbleTemplateEngine.java | 17 +++----- .../template/ThymeleafTemplateEngine.java | 7 ++- .../jbake/template/model/TemplateModel.java | 7 +++ 8 files changed, 45 insertions(+), 61 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index 3778a0362..5f1f672ed 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -1,7 +1,6 @@ package org.jbake.model; import org.jbake.app.DBUtil; -import org.jbake.app.DocumentList; import java.util.Date; 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 29475b27d..25d844875 100644 --- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java @@ -25,7 +25,6 @@ import java.io.Writer; import java.util.Collection; import java.util.Date; -import java.util.Map; /** * Renders pages using the Freemarker template engine. @@ -75,7 +74,7 @@ public static class LazyLoadingModel implements TemplateHashModel { private final SimpleHash eagerModel; private final ContentStore db; - public LazyLoadingModel(ObjectWrapper wrapper, Map eagerModel, final ContentStore db) { + public LazyLoadingModel(ObjectWrapper wrapper, TemplateModel eagerModel, final ContentStore db) { this.eagerModel = new SimpleHash(eagerModel, wrapper); this.db = db; this.wrapper = wrapper; 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 5ee13b419..b1fbb39a8 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java @@ -1,6 +1,5 @@ package org.jbake.template; -import groovy.lang.GString; import groovy.lang.Writable; import groovy.text.Template; import groovy.text.markup.MarkupTemplateEngine; @@ -12,7 +11,6 @@ import java.io.File; import java.io.Writer; -import java.util.HashMap; import java.util.Map; /** @@ -71,20 +69,15 @@ public void renderDocument(final TemplateModel model, final String templateName, } } - private Map wrap(final TemplateModel model) { - return new HashMap(model) { + private TemplateModel wrap(final TemplateModel model) { + return new TemplateModel(model) { @Override - public Object get(final Object property) { - if (property instanceof String || property instanceof GString) { - String key = property.toString(); - try { - put(key, extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter.NoopAdapter())); - } catch (NoModelExtractorException e) { - // should never happen, as we iterate over existing extractors - } + public Object get(Object key) { + try { + return extractors.extractAndTransform(db, (String) key, model, new TemplateEngineAdapter.NoopAdapter()); + } catch (NoModelExtractorException e) { + return super.get(key); } - - return super.get(property); } }; } 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 dd4a1c69e..94659b261 100644 --- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java @@ -1,7 +1,6 @@ package org.jbake.template; -import groovy.lang.GString; import groovy.lang.Writable; import groovy.text.SimpleTemplateEngine; import groovy.text.Template; @@ -15,7 +14,12 @@ import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Writer; import java.util.HashMap; import java.util.Map; @@ -69,32 +73,25 @@ private Template findTemplate(final String templateName) throws SAXException, Pa return template; } - private Map wrap(final Map model) { - return new HashMap(model) { + private TemplateModel wrap(final TemplateModel model) { + return new TemplateModel(model) { @Override - public Object get(final Object property) { - if (property instanceof String || property instanceof GString) { - String key = property.toString(); - if ("include".equals(key)) { - return new MethodClosure(GroovyTemplateEngine.this, "doInclude").curry(this); - } - try { - return extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter.NoopAdapter()); - } catch (NoModelExtractorException e) { - // fallback to parent model - } + public Object get(Object key) { + if ("include".equals(key)) { + return new MethodClosure(GroovyTemplateEngine.this, "doInclude").curry(this); + } + try { + return extractors.extractAndTransform(db, (String) key, model, new TemplateEngineAdapter.NoopAdapter()); + } catch (NoModelExtractorException e) { + return super.get(key); } - - return super.get(property); } }; } - private void doInclude(Map model, String templateName) throws Exception { - TemplateModel templateModel = new TemplateModel(); - templateModel.putAll(model); - AbstractTemplateEngine engine = templateModel.getRenderer(); - Writer out = templateModel.getWriter(); - engine.renderDocument(templateModel, templateName, out); + private void doInclude(TemplateModel model, String templateName) throws Exception { + AbstractTemplateEngine engine = model.getRenderer(); + Writer out = model.getWriter(); + engine.renderDocument(model, templateName, out); } } 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 06d3360a5..b23366697 100644 --- a/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/JadeTemplateEngine.java @@ -77,14 +77,11 @@ private JadeModel wrap(final TemplateModel model) { @Override public Object get(final Object property) { - String key = property.toString(); try { - return extractors.extractAndTransform(db, key, this, new TemplateEngineAdapter.NoopAdapter()); + return extractors.extractAndTransform(db, (String) property, this, new TemplateEngineAdapter.NoopAdapter()); } catch (NoModelExtractorException e) { - // fallback to parent model + return super.get(property); } - - return super.get(property); } }; } diff --git a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java index bd2531e22..7a850043c 100644 --- a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java @@ -12,7 +12,6 @@ import java.io.IOException; import java.io.Writer; -import java.util.HashMap; import java.util.Map; /** @@ -50,32 +49,26 @@ public void renderDocument(final TemplateModel model, final String templateName, try { template = engine.getTemplate(templateName); template.evaluate(writer, wrap(model)); - } catch (PebbleException e) { - throw new RenderingException(e); - } catch (IOException e) { + } catch (PebbleException | IOException e) { throw new RenderingException(e); } } - private Map wrap(final Map model) { - Map result = new HashMap(model) { + private TemplateModel wrap(final TemplateModel model) { + return new TemplateModel(model) { private static final long serialVersionUID = -5489285491728950547L; @Override public Object get(final Object property) { - String key = property.toString(); try { - return extractors.extractAndTransform(db, key, this, new TemplateEngineAdapter.NoopAdapter()); + return extractors.extractAndTransform(db, (String) property, this, new TemplateEngineAdapter.NoopAdapter()); } catch(NoModelExtractorException e) { - // fallback to parent model + return super.get(property); } - - return super.get(property); } }; - return result; } } 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 01b9e7d6b..3a79af04e 100644 --- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java +++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java @@ -17,7 +17,6 @@ import java.io.Writer; import java.util.Date; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; @@ -98,7 +97,7 @@ public void renderDocument(TemplateModel model, String templateName, Writer writ } } - private void initializeContext(Locale locale, Map model) { + private void initializeContext(Locale locale, TemplateModel model) { context.clearVariables(); context.setLocale(locale); context.setVariables(model); @@ -115,9 +114,9 @@ private class ContextVariable extends LazyContextVariable { private ContentStore db; private String key; - private Map model; + private TemplateModel model; - public ContextVariable(ContentStore db, String key, Map model) { + public ContextVariable(ContentStore db, String key, TemplateModel model) { this.db = db; this.key = key; this.model = model; diff --git a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java index 6d24d35d1..8f4cd3cfc 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java @@ -11,6 +11,13 @@ public class TemplateModel extends BaseModel { + public TemplateModel() { + } + + public TemplateModel(TemplateModel model) { + putAll(model); + } + public Map getConfig() { return (Map) get(ModelAttributes.CONFIG); } From 1b5691ad2a7d734321d0382e71743a85835556b3 Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Sat, 18 Aug 2018 13:51:33 +0200 Subject: [PATCH 23/27] one document table for all types --- .../main/java/org/jbake/app/ContentStore.java | 185 +++++++----------- .../src/main/java/org/jbake/app/Crawler.java | 91 ++++----- .../src/main/java/org/jbake/app/Renderer.java | 7 +- .../java/org/jbake/model/DocumentModel.java | 7 +- .../java/org/jbake/model/DocumentTypes.java | 8 +- .../java/org/jbake/parser/MarkupEngine.java | 2 + .../org/jbake/render/DocumentsRenderer.java | 53 +++-- .../template/model/TagPostsExtractor.java | 2 +- .../java/org/jbake/FakeDocumentBuilder.java | 3 +- .../java/org/jbake/app/ContentStoreTest.java | 117 ++++------- .../src/test/java/org/jbake/app/OvenTest.java | 5 +- .../AbstractTemplateEngineRenderingTest.java | 6 + ...oovyMarkupTemplateEngineRenderingTest.java | 4 +- .../jbake/render/DocumentsRendererTest.java | 21 +- 14 files changed, 206 insertions(+), 305 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/ContentStore.java b/jbake-core/src/main/java/org/jbake/app/ContentStore.java index 8b0c647a2..2abeb3d77 100644 --- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java +++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java @@ -33,10 +33,7 @@ import com.orientechnologies.orient.core.metadata.schema.OSchema; import com.orientechnologies.orient.core.metadata.schema.OType; import com.orientechnologies.orient.core.record.impl.ODocument; -import com.orientechnologies.orient.core.sql.OCommandSQL; import com.orientechnologies.orient.core.sql.executor.OResultSet; -import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; -import org.jbake.model.BaseModel; import org.jbake.model.DocumentModel; import org.jbake.model.DocumentTypes; import org.jbake.model.ModelAttributes; @@ -46,8 +43,6 @@ import java.io.File; import java.util.Collections; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -55,22 +50,22 @@ */ public class ContentStore { - private static final String STATEMENT_GET_PUBLISHED_POST_BY_TYPE_AND_TAG = "select * from %s where status='published' and ? in tags order by date desc"; - private static final String STATEMENT_GET_POST_BY_TYPE_AND_URI = "select * from %s where sourceuri=?"; - private static final String STATEMENT_GET_DOCUMENT_STATUS_BY_DOCTYPE_AND_URI = "select sha1,rendered from %s where sourceuri=?"; - private static final String STATEMENT_GET_PUBLISHED_COUNT = "select count(*) as count from %s where status='published'"; - private static final String STATEMENT_MARK_CONTENT_AS_RENDERD = "update %s set rendered=true where rendered=false and cached=true"; - private static final String STATEMENT_DELETE_DOCTYPE_BY_SOURCEURI = "delete from %s where sourceuri=?"; - private static final String STATEMENT_GET_UNDRENDERED_CONTENT = "select * from %s where rendered=false order by date desc"; + private static final String STATEMENT_GET_PUBLISHED_POST_BY_TYPE_AND_TAG = "select * from Documents where status='published' and type='%s' and ? in tags order by date desc"; + private static final String STATEMENT_GET_DOCUMENT_STATUS_BY_DOCTYPE_AND_URI = "select sha1,rendered from Documents where sourceuri=?"; + private static final String STATEMENT_GET_PUBLISHED_COUNT = "select count(*) as count from Documents where status='published' and type='%s'"; + private static final String STATEMENT_MARK_CONTENT_AS_RENDERD = "update Documents set rendered=true where rendered=false and type='%s' and sourceuri='%s' and cached=true"; + private static final String STATEMENT_DELETE_DOCTYPE_BY_SOURCEURI = "delete from Documents where sourceuri=?"; + private static final String STATEMENT_GET_UNDRENDERED_CONTENT = "select * from Documents where rendered=false order by date desc"; private static final String STATEMENT_GET_SIGNATURE_FOR_TEMPLATES = "select sha1 from Signatures where key='templates'"; - private static final String STATEMENT_GET_TAGS_FROM_PUBLISHED_POSTS = "select tags from post where status='published'"; - private static final String STATEMENT_GET_ALL_CONTENT_BY_DOCTYPE = "select * from %s order by date desc"; - private static final String STATEMENT_GET_PUBLISHED_CONTENT_BY_DOCTYPE = "select * from %s where status='published' order by date desc"; - private static final String STATEMENT_GET_PUBLISHED_POSTS_BY_TAG = "select * from post where status='published' and ? in tags order by date desc"; - private static final String STATEMENT_GET_TAGS_BY_DOCTYPE = "select tags from %s where status='published'"; + private static final String STATEMENT_GET_TAGS_FROM_PUBLISHED_POSTS = "select tags from Documents where status='published' and type='post'"; + private static final String STATEMENT_GET_ALL_CONTENT_BY_DOCTYPE = "select * from Documents where type='%s' order by date desc"; + private static final String STATEMENT_GET_PUBLISHED_CONTENT_BY_DOCTYPE = "select * from Documents where status='published' and type='%s' order by date desc"; + private static final String STATEMENT_GET_PUBLISHED_POSTS_BY_TAG = "select * from Documents where status='published' and type='post' and ? in tags order by date desc"; + private static final String STATEMENT_GET_TAGS_BY_DOCTYPE = "select tags from Documents where status='published' and type='%s'"; private static final String STATEMENT_INSERT_TEMPLATES_SIGNATURE = "insert into Signatures(key,sha1) values('templates',?)"; - private static final String STATEMENT_DELETE_ALL = "delete from %s"; + private static final String STATEMENT_DELETE_ALL = "delete from Documents where type='%s'"; private static final String STATEMENT_UPDATE_TEMPLATE_SIGNATURE = "update Signatures set sha1=? where key='templates'"; + private static final String STATEMENT_GET_DOCUMENT_COUNT_BY_TYPE = "select count(*) as count from Documents where type='%s'"; private final Logger logger = LoggerFactory.getLogger(ContentStore.class); private final String type; @@ -131,12 +126,10 @@ public final void updateSchema() { OSchema schema = db.getMetadata().getSchema(); - for (String docType : DocumentTypes.getDocumentTypes()) { - if (!schema.existsClass(docType)) { - createDocType(schema, docType); - } + if (!schema.existsClass(Schema.DOCUMENTS)) { + createDocType(schema); } - if (!schema.existsClass("Signatures")) { + if (!schema.existsClass(Schema.SIGNATURES)) { createSignatureType(schema); } } @@ -187,60 +180,23 @@ private void activateOnCurrentThread() { } } - - /** - * Get a document by sourceUri and update it from the given map. - * - * @param incomingDocMap The document's db columns. - * @return The saved document. - * @throws IllegalArgumentException if sourceUri or docType are null, or if the document doesn't exist. - */ - public ODocument mergeDocument(Map incomingDocMap) { - String sourceUri = (String) incomingDocMap.get(ModelAttributes.SOURCE_URI.toString()); - if (null == sourceUri) { - throw new IllegalArgumentException("Document sourceUri is null."); - } - String docType = (String) incomingDocMap.get(ModelAttributes.TYPE.toString()); - if (null == docType) { - throw new IllegalArgumentException("Document docType is null."); - } - - // Get a document by sourceUri - String sql = String.format(STATEMENT_GET_POST_BY_TYPE_AND_URI, quoteIdentifier(docType)); - activateOnCurrentThread(); - List results = db.command(new OSQLSynchQuery(sql)).execute(sourceUri); - if (results.isEmpty()) { - throw new JBakeException("No document with sourceUri '" + sourceUri + "'."); - } - - // Update it from the given map. - ODocument incomingDoc = new ODocument(docType); - incomingDoc.fromMap(incomingDocMap); - ODocument merged = results.get(0).merge(incomingDoc, true, false); - return merged; - } - - public long getDocumentCount(String docType) { activateOnCurrentThread(); - return db.countClass(docType); + String statement = String.format(STATEMENT_GET_DOCUMENT_COUNT_BY_TYPE, docType); + return (long) query(statement).get(0).get("count"); } public long getPublishedCount(String docType) { - String statement = String.format(STATEMENT_GET_PUBLISHED_COUNT, quoteIdentifier(docType)); - return (Long) query(statement).get(0).get("count"); + String statement = String.format(STATEMENT_GET_PUBLISHED_COUNT, docType); + return (long) query(statement).get(0).get("count"); } - /* - * In fact, the URI should be the only input as there can only be one document at given URI; but the DB is split per document type for some reason. - */ - public DocumentList getDocumentByUri(String docType, String uri) { - return query(String.format(STATEMENT_GET_POST_BY_TYPE_AND_URI, quoteIdentifier(docType)), uri); + public DocumentList getDocumentByUri(String uri) { + return query("select * from Documents where sourceuri=?", uri); } - public DocumentList getDocumentStatus(String docType, String uri) { - String statement = String.format(STATEMENT_GET_DOCUMENT_STATUS_BY_DOCTYPE_AND_URI, quoteIdentifier(docType)); - return query(statement, uri); + public DocumentList getDocumentStatus(String uri) { + return query(STATEMENT_GET_DOCUMENT_STATUS_BY_DOCTYPE_AND_URI, uri); } public DocumentList getPublishedPosts() { @@ -259,8 +215,8 @@ public DocumentList getPublishedDocumentsByTag(String tag) { final DocumentList documents = new DocumentList<>(); for (final String docType : DocumentTypes.getDocumentTypes()) { - String statement = String.format(STATEMENT_GET_PUBLISHED_POST_BY_TYPE_AND_TAG, quoteIdentifier(docType)); - DocumentList documentsByTag = query(statement, tag); + String statement = String.format(STATEMENT_GET_PUBLISHED_POST_BY_TYPE_AND_TAG, docType); + DocumentList documentsByTag = query(statement, tag); documents.addAll(documentsByTag); } return documents; @@ -274,8 +230,8 @@ public DocumentList getPublishedContent(String docType) { return getPublishedContent(docType, false); } - private DocumentList getPublishedContent(String docType, boolean applyPaging) { - String query = String.format(STATEMENT_GET_PUBLISHED_CONTENT_BY_DOCTYPE, quoteIdentifier(docType)); + private DocumentList getPublishedContent(String docType, boolean applyPaging) { + String query = String.format(STATEMENT_GET_PUBLISHED_CONTENT_BY_DOCTYPE, docType); if (applyPaging && hasStartAndLimitBoundary()) { query += " SKIP " + start + " LIMIT " + limit; } @@ -287,7 +243,7 @@ public DocumentList getAllContent(String docType) { } public DocumentList getAllContent(String docType, boolean applyPaging) { - String query = String.format(STATEMENT_GET_ALL_CONTENT_BY_DOCTYPE, quoteIdentifier(docType)); + String query = String.format(STATEMENT_GET_ALL_CONTENT_BY_DOCTYPE, docType); if (applyPaging && hasStartAndLimitBoundary()) { query += " SKIP " + start + " LIMIT " + limit; } @@ -306,18 +262,16 @@ private DocumentList getSignaturesForTemplates() { return query(STATEMENT_GET_SIGNATURE_FOR_TEMPLATES); } - public DocumentList getUnrenderedContent(String docType) { - String statement = String.format(STATEMENT_GET_UNDRENDERED_CONTENT, quoteIdentifier(docType)); - return query(statement); + public DocumentList getUnrenderedContent() { + return query(STATEMENT_GET_UNDRENDERED_CONTENT); } - public void deleteContent(String docType, String uri) { - String statement = String.format(STATEMENT_DELETE_DOCTYPE_BY_SOURCEURI, quoteIdentifier(docType)); - executeCommand(statement, uri); + public void deleteContent(String uri) { + executeCommand(STATEMENT_DELETE_DOCTYPE_BY_SOURCEURI, uri); } - public void markContentAsRendered(String docType) { - String statement = String.format(STATEMENT_MARK_CONTENT_AS_RENDERD, quoteIdentifier(docType)); + public void markContentAsRendered(DocumentModel document) { + String statement = String.format(STATEMENT_MARK_CONTENT_AS_RENDERD, document.getType(), document.getSourceuri()); executeCommand(statement); } @@ -326,7 +280,7 @@ private void updateSignatures(String currentTemplatesSignature) { } public void deleteAllByDocType(String docType) { - String statement = String.format(STATEMENT_DELETE_ALL, quoteIdentifier(docType)); + String statement = String.format(STATEMENT_DELETE_ALL, docType); executeCommand(statement); } @@ -348,7 +302,7 @@ private DocumentList query(String sql, Object... args) { private void executeCommand(String query, Object... args) { activateOnCurrentThread(); - db.command(new OCommandSQL(query)).execute(args); + db.command(query, args); } public Set getTags() { @@ -364,46 +318,37 @@ public Set getTags() { public Set getAllTags() { Set result = new HashSet<>(); for (String docType : DocumentTypes.getDocumentTypes()) { - String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, quoteIdentifier(docType)); + String statement = String.format(STATEMENT_GET_TAGS_BY_DOCTYPE, docType); DocumentList docs = query(statement); for (DocumentModel document : docs) { - String[] tags = ((DocumentModel) document).getTags(); + String[] tags = document.getTags(); Collections.addAll(result, tags); } } return result; } - private void createDocType(final OSchema schema, final String docType) { - logger.debug("Create document class '{}'", docType); - - - OClass page = schema.createClass(docType); - - // Primary key - String attribName = ModelAttributes.SOURCE_URI; - page.createProperty(attribName, OType.STRING).setNotNull(true); - page.createIndex(docType + "sourceUriIndex", OClass.INDEX_TYPE.UNIQUE, attribName); - - attribName = ModelAttributes.SHA1; - page.createProperty(attribName, OType.STRING).setNotNull(true); - page.createIndex(docType + "sha1Index", OClass.INDEX_TYPE.NOTUNIQUE, attribName); - - attribName = ModelAttributes.CACHED; - page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); - page.createIndex(docType + "cachedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); + private void createDocType(final OSchema schema) { + logger.debug("Create document class"); - attribName = ModelAttributes.RENDERED; - page.createProperty(attribName, OType.BOOLEAN).setNotNull(true); - page.createIndex(docType + "renderedIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); + OClass page = schema.createClass(Schema.DOCUMENTS); + page.createProperty(ModelAttributes.SHA1, OType.STRING).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "sha1Index", OClass.INDEX_TYPE.NOTUNIQUE, ModelAttributes.SHA1); + page.createProperty(ModelAttributes.SOURCE_URI, OType.STRING).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "sourceUriIndex", OClass.INDEX_TYPE.UNIQUE, ModelAttributes.SOURCE_URI); + page.createProperty(ModelAttributes.CACHED, OType.BOOLEAN).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "cachedIndex", OClass.INDEX_TYPE.NOTUNIQUE, ModelAttributes.CACHED); + page.createProperty(ModelAttributes.RENDERED, OType.BOOLEAN).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "renderedIndex", OClass.INDEX_TYPE.NOTUNIQUE, ModelAttributes.RENDERED); + page.createProperty(ModelAttributes.STATUS, OType.STRING).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "statusIndex", OClass.INDEX_TYPE.NOTUNIQUE, ModelAttributes.STATUS); + page.createProperty(ModelAttributes.TYPE, OType.STRING).setNotNull(true); + page.createIndex(Schema.DOCUMENTS + "typeIndex", OClass.INDEX_TYPE.NOTUNIQUE, ModelAttributes.TYPE); - attribName = ModelAttributes.STATUS; - page.createProperty(attribName, OType.STRING).setNotNull(true); - page.createIndex(docType + "statusIndex", OClass.INDEX_TYPE.NOTUNIQUE, attribName); } private void createSignatureType(OSchema schema) { - OClass signatures = schema.createClass("Signatures"); + OClass signatures = schema.createClass(Schema.SIGNATURES); signatures.createProperty(ModelAttributes.SHA1, OType.STRING).setNotNull(true); signatures.createIndex("sha1Idx", OClass.INDEX_TYPE.UNIQUE, ModelAttributes.SHA1); } @@ -425,7 +370,7 @@ public void updateAndClearCacheIfNeeded(boolean needed, File templateFolder) { private boolean updateTemplateSignatureIfChanged(File templateFolder) { boolean templateSignatureChanged = false; - DocumentList docs = this.getSignaturesForTemplates(); + DocumentList docs = this.getSignaturesForTemplates(); String currentTemplatesSignature; try { currentTemplatesSignature = FileUtil.sha1(templateFolder); @@ -433,7 +378,7 @@ private boolean updateTemplateSignatureIfChanged(File templateFolder) { currentTemplatesSignature = ""; } if (!docs.isEmpty()) { - String sha1 = ((DocumentModel) docs.get(0)).getSha1(); + String sha1 = docs.get(0).getSha1(); if (!sha1.equals(currentTemplatesSignature)) { this.updateSignatures(currentTemplatesSignature); templateSignatureChanged = true; @@ -460,11 +405,15 @@ public boolean isActive() { return db.isActiveOnCurrentThread(); } - static String quoteIdentifier(String input) { - if(input == null) { - return input; - } else { - return "`" + input.replaceAll("([\\\\`])", "\\\\$1") + "`"; - } + public void addDocument(DocumentModel document) { + ODocument doc = new ODocument(Schema.DOCUMENTS); + doc.fromMap(document); + doc.save(); } + + protected abstract class Schema { + static final String DOCUMENTS = "Documents"; + static final String SIGNATURES = "Signatures"; + } + } 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 daaaa22d7..b12336db0 100644 --- a/jbake-core/src/main/java/org/jbake/app/Crawler.java +++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java @@ -1,6 +1,5 @@ package org.jbake.app; -import com.orientechnologies.orient.core.record.impl.ODocument; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FilenameUtils; import org.jbake.app.configuration.JBakeConfiguration; @@ -69,7 +68,6 @@ public void crawl() { logger.info("Parsed {} files of type: {}", count, docType); } } - } /** @@ -92,35 +90,26 @@ private void crawl(File path) { } private void crawlFile(File sourceFile) { + StringBuilder sb = new StringBuilder(); sb.append("Processing [").append(sourceFile.getPath()).append("]... "); String sha1 = buildHash(sourceFile); String uri = buildURI(sourceFile); - boolean process = true; - DocumentStatus status = DocumentStatus.NEW; - - for (String docType : DocumentTypes.getDocumentTypes()) { - status = findDocumentStatus(docType, uri, sha1); - if ( status == null ) continue; - if (status == DocumentStatus.UPDATED) { - sb.append(" : modified "); - db.deleteContent(docType, uri); - break; - } else if (status == DocumentStatus.IDENTICAL) { - sb.append(" : same "); - process = false; - } - if (!process || status != DocumentStatus.NEW) { - break; - } + DocumentStatus status = findDocumentStatus(uri, sha1); + if (status == DocumentStatus.UPDATED) { + sb.append(" : modified "); + db.deleteContent(uri); + } else if (status == DocumentStatus.IDENTICAL) { + sb.append(" : same "); + } else if (DocumentStatus.NEW == status) { + sb.append(" : new "); } - if (process) { // new or updated - if (status == DocumentStatus.NEW) { - sb.append(" : new "); - } + + logger.info("{}", sb); + + if (status != DocumentStatus.IDENTICAL) { processSourceFile(sourceFile, sha1, uri); } - logger.info("{}", sb); } private String buildHash(final File sourceFile) { @@ -189,45 +178,43 @@ private boolean useNoExtensionUri(String uri) { } private void processSourceFile(final File sourceFile, final String sha1, final String uri) { - try { - DocumentModel fileContents = parser.processFile(sourceFile); - if (fileContents != null) { - addAdditionalDocumentAttributes(fileContents, sourceFile, sha1, uri); + DocumentModel document = parser.processFile(sourceFile); + + if (document != null) { + if (DocumentTypes.contains(document.getType())) { + addAdditionalDocumentAttributes(document, sourceFile, sha1, uri); if (config.getImgPathUpdate()) { // Prevent image source url's from breaking - HtmlUtil.fixImageSourceUrls(fileContents, config); + HtmlUtil.fixImageSourceUrls(document, config); } - ODocument doc = new ODocument(fileContents.getType()); - doc.fromMap(fileContents); - doc.save(); + db.addDocument(document); } else { - logger.warn("{} has an invalid header, it has been ignored!", sourceFile); + logger.warn("{} has an unknown document type '{}' and has been ignored!", sourceFile, document.getType()); } - } catch (Exception ex) { - throw new RuntimeException("Failed crawling file: " + sourceFile.getPath() + " " + ex.getMessage(), ex); + } else { + logger.warn("{} has an invalid header, it has been ignored!", sourceFile); } - } - private void addAdditionalDocumentAttributes(DocumentModel documentModel, File sourceFile, String sha1, String uri) { - documentModel.setRootPath(getPathToRoot(sourceFile)); - documentModel.setSha1(sha1); - documentModel.setRendered(false); - documentModel.setFile(sourceFile.getPath()); - documentModel.setSourceUri(uri); - documentModel.setUri(uri); - documentModel.setCached(true); - - if (documentModel.getStatus().equals(ModelAttributes.Status.PUBLISHED_DATE) - && (documentModel.getDate() != null) - && new Date().after(documentModel.getDate())) { - documentModel.setStatus(ModelAttributes.Status.PUBLISHED); + private void addAdditionalDocumentAttributes(DocumentModel document, File sourceFile, String sha1, String uri) { + document.setRootPath(getPathToRoot(sourceFile)); + document.setSha1(sha1); + document.setRendered(false); + document.setFile(sourceFile.getPath()); + document.setSourceUri(uri); + document.setUri(uri); + document.setCached(true); + + if (document.getStatus().equals(ModelAttributes.Status.PUBLISHED_DATE) + && (document.getDate() != null) + && new Date().after(document.getDate())) { + document.setStatus(ModelAttributes.Status.PUBLISHED); } if (config.getUriWithoutExtension()) { - documentModel.setNoExtensionUri(uri.replace("/index.html", "/")); + document.setNoExtensionUri(uri.replace("/index.html", "/")); } } @@ -235,8 +222,8 @@ private String getPathToRoot(File sourceFile) { return FileUtil.getUriPathToContentRoot(config, sourceFile); } - private DocumentStatus findDocumentStatus(String documentType, String uri, String sha1) { - DocumentList match = db.getDocumentStatus(documentType, uri); + private DocumentStatus findDocumentStatus(String uri, String sha1) { + DocumentList match = db.getDocumentStatus(uri); if (!match.isEmpty()) { DocumentModel document = match.get(0); String oldHash = document.getSha1(); 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 2bf49802f..da02a7ee1 100644 --- a/jbake-core/src/main/java/org/jbake/app/Renderer.java +++ b/jbake-core/src/main/java/org/jbake/app/Renderer.java @@ -12,8 +12,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.nio.file.Files; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java index 5f1f672ed..99fd559cb 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java @@ -9,6 +9,7 @@ public class DocumentModel extends BaseModel { public static DocumentModel createDefaultDocumentModel() { DocumentModel documentModel = new DocumentModel(); documentModel.setCached(true); + documentModel.setRendered(false); return documentModel; } @@ -67,6 +68,10 @@ public void setSha1(String sha1) { put(ModelAttributes.SHA1, sha1); } + public String getSourceuri() { + return (String) get(ModelAttributes.SOURCE_URI); + } + public void setSourceUri(String uri) { put(ModelAttributes.SOURCE_URI, uri); } @@ -80,7 +85,7 @@ public void setRootPath(String pathToRoot) { } public Boolean getRendered() { - return (Boolean) get(ModelAttributes.RENDERED); + return (Boolean) getOrDefault(ModelAttributes.RENDERED, false); } public void setRendered(boolean rendered) { diff --git a/jbake-core/src/main/java/org/jbake/model/DocumentTypes.java b/jbake-core/src/main/java/org/jbake/model/DocumentTypes.java index ff821a7e2..0ecc975ec 100644 --- a/jbake-core/src/main/java/org/jbake/model/DocumentTypes.java +++ b/jbake-core/src/main/java/org/jbake/model/DocumentTypes.java @@ -23,7 +23,8 @@ public class DocumentTypes { resetDocumentTypes(); } - private DocumentTypes() {} + private DocumentTypes() { + } public static void resetDocumentTypes() { DEFAULT_DOC_TYPES.clear(); @@ -37,17 +38,18 @@ public static void addDocumentType(String docType) { } private static void notifyListener(String docType) { - for ( DocumentTypeListener listener : LISTENERS) { + for (DocumentTypeListener listener : LISTENERS) { listener.added(docType); } } - public static void addListener( DocumentTypeListener listener ) { + public static void addListener(DocumentTypeListener listener) { LISTENERS.add(listener); } /** * Notice additional document types are added automagically before returning them + * * @return all supported document types */ public static String[] getDocumentTypes() { 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 ac1a93b81..71d915e5e 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -287,6 +287,8 @@ void storeHeaderValue(String inputKey, String inputValue, DocumentModel content) } } else if (key.equalsIgnoreCase(ModelAttributes.TAGS)) { content.setTags(getTags(value)); + } else if (key.equalsIgnoreCase(ModelAttributes.CACHED)) { + content.setCached(Boolean.valueOf(value)); } else if (isJson(value)) { content.put(key, JSONValue.parse(value)); } else { 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 43d86933f..e36ddee64 100644 --- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java +++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java @@ -6,7 +6,6 @@ import org.jbake.app.Renderer; import org.jbake.app.configuration.JBakeConfiguration; import org.jbake.model.DocumentModel; -import org.jbake.model.DocumentTypes; import org.jbake.template.RenderingException; import java.io.File; @@ -18,47 +17,39 @@ public class DocumentsRenderer implements RenderingTool { @Override public int render(Renderer renderer, ContentStore db, JBakeConfiguration config) throws RenderingException { int renderedCount = 0; + int index = 0; final List errors = new LinkedList<>(); - for (String docType : DocumentTypes.getDocumentTypes()) { - DocumentList documentList = db.getUnrenderedContent(docType); + DocumentModel nextDocument = null; - if (documentList == null) { - continue; - } - - int index = 0; - - DocumentModel nextDocument = null; - - while (index < documentList.size()) { - try { - DocumentModel document = documentList.get(index); - document.setNextContent(null); - document.setPreviousContent(null); + DocumentList documentList = db.getUnrenderedContent(); - if (nextDocument != null && index > 0) { - document.setNextContent(getContentForNav(nextDocument)); - } + for (DocumentModel document : documentList) { + try { + document.setNextContent(null); + document.setPreviousContent(null); - if (index < documentList.size() - 1) { - DocumentModel tempNext = documentList.get(index + 1); - document.setPreviousContent(getContentForNav(tempNext)); - } + if (nextDocument != null && index > 0) { + document.setNextContent(getContentForNav(nextDocument)); + } - nextDocument = document; + if (index < documentList.size() - 1) { + DocumentModel tempNext = documentList.get(index + 1); + document.setPreviousContent(getContentForNav(tempNext)); + } - renderer.render(document); - renderedCount++; + nextDocument = document; - } catch (Exception e) { - errors.add(e.getMessage()); - } + renderer.render(document); + db.markContentAsRendered(document); + renderedCount++; - index++; + } catch (Exception e) { + errors.add(e.getMessage()); } - db.markContentAsRendered(docType); + index++; } + if (!errors.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("Failed to render documents. Cause(s):"); diff --git a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java index 39e42a5d7..b502fd6e5 100644 --- a/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java +++ b/jbake-core/src/main/java/org/jbake/template/model/TagPostsExtractor.java @@ -20,4 +20,4 @@ public DocumentList get(ContentStore db, Map model, String key) { return db.getPublishedPostsByTag(tag); } -} \ No newline at end of file +} diff --git a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java index 3962774bf..c72898db4 100644 --- a/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java +++ b/jbake-core/src/test/java/org/jbake/FakeDocumentBuilder.java @@ -19,6 +19,7 @@ public class FakeDocumentBuilder { public FakeDocumentBuilder(String type) { this.type = type; + fileModel.setType(type); } public FakeDocumentBuilder withStatus(String status) { @@ -66,7 +67,7 @@ public void build() { if (!hasDate()) { this.withCurrentDate(); } - ODocument document = new ODocument(type).fromMap(fileModel); + ODocument document = new ODocument("Documents").fromMap(fileModel); document.save(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); diff --git a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java index 0601e2fb5..567ced0c0 100644 --- a/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java +++ b/jbake-core/src/test/java/org/jbake/app/ContentStoreTest.java @@ -1,11 +1,9 @@ package org.jbake.app; -import com.orientechnologies.orient.core.record.impl.ODocument; import org.jbake.FakeDocumentBuilder; -import static org.junit.Assert.assertEquals; - import org.jbake.model.DocumentModel; -import org.jbake.model.ModelAttributes; +import org.jbake.model.DocumentTypes; +import org.jbake.model.ModelAttributes.Status; import org.junit.Test; import java.util.Collections; @@ -13,10 +11,7 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; -import static org.jbake.app.ContentStore.quoteIdentifier; -import static org.jbake.model.ModelAttributes.RENDERED; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; public class ContentStoreTest extends ContentStoreIntegrationTest { @@ -41,71 +36,33 @@ public void shouldGetCountForPublishedDocuments() throws Exception { assertEquals(5, db.getPublishedCount(DOC_TYPE_POST)); } - @Test - public void testMergeDocument() { - final String uri = "test/testMergeDocument"; - - ODocument doc = new ODocument(DOC_TYPE_POST); - DocumentModel values = new DocumentModel(); - values.setType(DOC_TYPE_POST); - values.setSourceUri(uri); - values.put("foo", "originalValue"); - doc.fromMap(values); - doc.save(); - - // 1st - values.put("foo", "newValue"); - db.mergeDocument(values); - - DocumentList docs = db.getDocumentByUri(DOC_TYPE_POST, uri); - assertEquals(1, docs.size()); - assertEquals("newValue", docs.get(0).get("foo")); - - // 2nd - values.put("foo", "anotherValue"); - db.mergeDocument(values); - - docs = db.getDocumentByUri(DOC_TYPE_POST, uri); - assertEquals(1, docs.size()); - assertEquals("anotherValue", docs.get(0).get("foo")); - - db.deleteContent(DOC_TYPE_POST, uri); - docs = db.getDocumentByUri(DOC_TYPE_POST, uri); - assertEquals(0, docs.size()); - } - @Test public void testStoreTypeWithSpecialCharacters() { final String typeWithHyphen = "type-with-hyphen"; DocumentTypes.addDocumentType(typeWithHyphen); - final String tagWithHyphen = "tag-with-hyphen"; + final String tagWithHyphenBackslashAndBacktick = "identifier-with\\`backtick"; final String uri = "test/testMergeDocument"; - DocumentModel model = new DocumentModel(); + DocumentModel model = DocumentModel.createDefaultDocumentModel(); model.setType(typeWithHyphen); - model.setTags(new String[]{tagWithHyphen}); - model.setStatus(Status.DRAFT); + model.setTags(new String[]{tagWithHyphenBackslashAndBacktick}); model.setDate(new Date()); - model.setRendered(false); model.setSourceUri(uri); - model.setCached(true); model.put("foo", "originalValue"); - ODocument doc = new ODocument(typeWithHyphen); - doc.fromMap(model); - doc.save(); + db.addDocument(model); - DocumentList documentList1 = db.getAllContent(typeWithHyphen); + DocumentList documentList1 = db.getAllContent(typeWithHyphen); assertEquals(1, documentList1.size()); - DocumentList documentList2 = db.getAllContent(typeWithHyphen, true); + DocumentList documentList2 = db.getAllContent(typeWithHyphen, true); assertEquals(1, documentList2.size()); - DocumentList documentList3 = db.getDocumentByUri(typeWithHyphen, uri); + DocumentList documentList3 = db.getDocumentByUri(uri); assertEquals(1, documentList3.size()); @@ -113,63 +70,59 @@ public void testStoreTypeWithSpecialCharacters() { assertEquals(1L, documentCount1); - DocumentList documentList4 = db.getDocumentStatus(typeWithHyphen, uri); + DocumentList documentList4 = db.getDocumentStatus(uri); assertEquals(1, documentList4.size()); - assertEquals(Boolean.FALSE, documentList4.get(0).get(RENDERED.toString())); + assertEquals(Boolean.FALSE, documentList4.get(0).getRendered()); long documentCount2 = db.getPublishedCount(typeWithHyphen); assertEquals(0, documentCount2); DocumentModel published = new DocumentModel(); - published.setSourceUri(uri); + published.setSourceUri("test/another-testdocument.adoc"); + published.setTags(new String[]{tagWithHyphenBackslashAndBacktick}); published.setType(typeWithHyphen); published.setStatus(Status.PUBLISHED); - db.mergeDocument(published); + published.setCached(true); + published.setRendered(false); + + db.addDocument(published); - DocumentList documentList5 = db.getUnrenderedContent(typeWithHyphen); - assertEquals(1, documentList5.size()); - assertEquals(Boolean.FALSE, documentList5.get(0).get(ModelAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList5.get(0).get(ModelAttributes.TYPE.toString())); - assertThat((String[])documentList5.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); + DocumentList documentList5 = db.getUnrenderedContent(); + assertEquals(2, documentList5.size()); + assertEquals(Boolean.FALSE, documentList5.get(0).getRendered()); + assertEquals(typeWithHyphen, documentList5.get(0).getType()); + assertThat(documentList5.get(0).getTags()).contains(tagWithHyphenBackslashAndBacktick); long documentCount3 = db.getPublishedCount(typeWithHyphen); assertEquals(1, documentCount3); - db.markContentAsRendered(typeWithHyphen); + db.markContentAsRendered(published); - DocumentList documentList6 = db.getPublishedContent(typeWithHyphen); + DocumentList documentList6 = db.getPublishedContent(typeWithHyphen); assertEquals(1, documentList6.size()); - assertEquals(Boolean.TRUE, documentList6.get(0).get(ModelAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList6.get(0).get(ModelAttributes.TYPE.toString())); - assertThat((String[])documentList6.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); + assertEquals(Boolean.TRUE, documentList6.get(0).getRendered()); + assertEquals(typeWithHyphen, documentList6.get(0).getType()); + assertThat(documentList6.get(0).getTags()).contains(tagWithHyphenBackslashAndBacktick); - DocumentList documentList7 = db.getPublishedDocumentsByTag(tagWithHyphen); + DocumentList documentList7 = db.getPublishedDocumentsByTag(tagWithHyphenBackslashAndBacktick); assertEquals(1, documentList7.size()); - assertEquals(Boolean.TRUE, documentList7.get(0).get(ModelAttributes.RENDERED.toString())); - assertEquals(typeWithHyphen, documentList7.get(0).get(ModelAttributes.TYPE.toString())); - assertThat((String[])documentList7.get(0).get(ModelAttributes.TAGS.toString())).contains(tagWithHyphen); + assertEquals(Boolean.TRUE, documentList7.get(0).getRendered()); + assertEquals(typeWithHyphen, documentList7.get(0).getType()); + assertThat(documentList7.get(0).getTags()).contains(tagWithHyphenBackslashAndBacktick); - DocumentList documentList8 = db.getPublishedPostsByTag(tagWithHyphen); + DocumentList documentList8 = db.getPublishedPostsByTag(tagWithHyphenBackslashAndBacktick); assertEquals(0, documentList8.size()); Set tags = db.getAllTags(); - assertEquals(Collections.singleton(tagWithHyphen), tags); + assertEquals(Collections.singleton(tagWithHyphenBackslashAndBacktick), tags); - db.deleteContent(typeWithHyphen, uri); + db.deleteContent(uri); long documentCount4 = db.getDocumentCount(typeWithHyphen); - assertEquals(0, documentCount4); + assertEquals(1, documentCount4); db.deleteAllByDocType(typeWithHyphen); } - @Test - public void testIdentifierQuoting() { - assertNull(quoteIdentifier(null)); - assertEquals("`normalIdentifier`", quoteIdentifier("normalIdentifier")); - assertEquals("`identifier-with-hyphen`", quoteIdentifier("identifier-with-hyphen")); - assertEquals("`identifier-with\\\\backslash`", quoteIdentifier("identifier-with\\backslash")); - assertEquals("`identifier-with\\`backtick`", quoteIdentifier("identifier-with`backtick")); - } } diff --git a/jbake-core/src/test/java/org/jbake/app/OvenTest.java b/jbake-core/src/test/java/org/jbake/app/OvenTest.java index a945d2cb6..a104f09a4 100644 --- a/jbake-core/src/test/java/org/jbake/app/OvenTest.java +++ b/jbake-core/src/test/java/org/jbake/app/OvenTest.java @@ -45,7 +45,8 @@ public void setUp() throws Exception { sourceFolder = TestUtils.getTestResourcesAsSourceFolder(); configuration = (DefaultJBakeConfiguration) new ConfigUtil().loadConfig(sourceFolder); configuration.setDestinationFolder(output); - configuration.setTemplateFolder(new File(sourceFolder, "freemarkerTemplates")); + configuration.setTemplateFolder(new File(sourceFolder, "groovyMarkupTemplate")); + configuration.setProperty("template.paper.file", "paper.tpl"); } @AfterEach @@ -58,7 +59,7 @@ public void tearDown() { @Test public void bakeWithAbsolutePaths() { - configuration.setTemplateFolder(new File(sourceFolder, "freemarkerTemplates")); + configuration.setTemplateFolder(new File(sourceFolder, "groovyMarkupTemplates")); configuration.setContentFolder(new File(sourceFolder, "content")); configuration.setAssetFolder(new File(sourceFolder, "assets")); diff --git a/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java b/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java index 88c269e24..69ee1cab4 100644 --- a/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java +++ b/jbake-core/src/test/java/org/jbake/app/template/AbstractTemplateEngineRenderingTest.java @@ -82,6 +82,7 @@ public void setup() throws Exception { config.setDestinationFolder(destinationFolder); config.setTemplateFolder(templateFolder); + for (String docType : DocumentTypes.getDocumentTypes()) { File templateFile = config.getTemplateFileByDocType(docType); @@ -91,6 +92,11 @@ public void setup() throws Exception { config.setTemplateFileNameForDocType(docType, fileBaseName + "." + templateExtension); } } + + config.setTemplateFileNameForDocType("paper", "paper." + templateExtension); + DocumentTypes.addDocumentType("paper"); + db.updateSchema(); + Assert.assertEquals(".html", config.getOutputExtension()); Crawler crawler = new Crawler(db, config); diff --git a/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java b/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java index cda5e044e..cbc52455b 100644 --- a/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java +++ b/jbake-core/src/test/java/org/jbake/app/template/GroovyMarkupTemplateEngineRenderingTest.java @@ -64,9 +64,7 @@ public GroovyMarkupTemplateEngineRenderingTest() { @Test public void renderCustomTypePaper() throws Exception { // setup - config.setTemplateFileNameForDocType("paper", "paper." + templateExtension); - DocumentTypes.addDocumentType("paper"); - db.updateSchema(); + Crawler crawler = new Crawler(db, config); crawler.crawl(); diff --git a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java index ce8bddeb1..769f1997b 100644 --- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java +++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java @@ -18,8 +18,12 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class DocumentsRendererTest { @@ -50,7 +54,7 @@ public void setUp() { @Test public void shouldReturnZeroIfNothingHasRendered() throws Exception { - when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); + when(db.getUnrenderedContent()).thenReturn(emptyTemplateModelList); int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -67,10 +71,8 @@ public void shouldReturnCountOfProcessedDocuments() throws Exception { templateModelList.add(emptyDocument()); templateModelList.add(emptyDocument()); - // return empty DocumentList independent from DocumentType - when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); // return given DocumentList for DocumentType 'custom type' - when(db.getUnrenderedContent("customType")).thenReturn(templateModelList); + when(db.getUnrenderedContent()).thenReturn(templateModelList); // when: int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -97,8 +99,7 @@ public void shouldThrowAnExceptionWithCollectedErrorMessages() throws Exception // throw an exception for every call of renderer's render method doThrow(new Exception(fakeExceptionMessage)).when(renderer).render(any(DocumentModel.class)); - when(db.getUnrenderedContent(anyString())).thenReturn(emptyTemplateModelList); - when(db.getUnrenderedContent("customType")).thenReturn(templateModelList); + when(db.getUnrenderedContent()).thenReturn(templateModelList); // when int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -122,7 +123,7 @@ public void shouldContainPostNavigation() throws Exception { documents.add(simpleDocument(second)); documents.add(simpleDocument(first)); - when(db.getUnrenderedContent("customType")).thenReturn(documents); + when(db.getUnrenderedContent()).thenReturn(documents); int renderResponse = documentsRenderer.render(renderer, db, configuration); @@ -170,4 +171,4 @@ private DocumentModel simpleDocument(String title) { return simpleDoc; } -} \ No newline at end of file +} From 06668688a3669254cc1232fa57bae1f1f33b8c23 Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Thu, 20 May 2021 13:45:25 +0100 Subject: [PATCH 24/27] Updated tests following #450 --- .../test/java/org/jbake/app/configuration/ConfigUtilTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 76006498c..491672799 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 @@ -188,7 +188,7 @@ public void shouldReturnConfiguredDocTypes() throws Exception { List docTypes = config.getDocumentTypes(); - assertThat(docTypes).containsExactly("allcontent", "masterindex", "feed", "archive", "tag", "tagsindex", "sitemap", "post", "page"); + assertThat(docTypes).containsExactly("allcontent", "masterindex", "feed", "error404", "archive", "tag", "tagsindex", "sitemap", "post", "page"); } From d589a3336bca3707b49cb7baa5902d509ddf45fe Mon Sep 17 00:00:00 2001 From: Jonathan Bullock Date: Thu, 20 May 2021 15:36:32 +0100 Subject: [PATCH 25/27] Merged in #647 --- .../jbake/app/configuration/ConfigUtil.java | 34 +++++++++++++---- .../JBakeConfigurationFactory.java | 37 +++++++++++++++++-- .../org/jbake/launcher/LaunchOptions.java | 16 ++++++++ .../main/java/org/jbake/launcher/Main.java | 4 +- .../org/jbake/launcher/LaunchOptionsTest.java | 10 +++++ .../java/org/jbake/launcher/MainTest.java | 8 ++-- 6 files changed, 93 insertions(+), 16 deletions(-) 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 c55befaf5..75cbf1450 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 @@ -20,11 +20,11 @@ public class ConfigUtil { 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"; + public static final String LEGACY_CONFIG_FILE = "custom.properties"; + public static final String CONFIG_FILE = "jbake.properties"; + public static final String DEFAULT_CONFIG_FILE = "default.properties"; - private CompositeConfiguration load(File source) throws ConfigurationException { + private CompositeConfiguration load(File source, File propertiesFile) throws ConfigurationException { if (!source.exists()) { throw new JBakeException(SystemExit.CONFIGURATION_ERROR, "The given source folder '" + source.getAbsolutePath() + "' does not exist."); @@ -39,7 +39,7 @@ private CompositeConfiguration load(File source) throws ConfigurationException { displayLegacyConfigFileWarningIfRequired(); config.addConfiguration(new PropertiesConfiguration(customConfigFile)); } - customConfigFile = new File(source, CONFIG_FILE); + customConfigFile = propertiesFile != null ? propertiesFile : new File(source, CONFIG_FILE); if (customConfigFile.exists()) { config.addConfiguration(new PropertiesConfiguration(customConfigFile)); } @@ -54,9 +54,29 @@ private void displayLegacyConfigFileWarningIfRequired() { LOGGER.warn("Usage of this file is being deprecated, please rename this file to: {} to remove this warning", CONFIG_FILE); } - public JBakeConfiguration loadConfig(File source) throws ConfigurationException { - CompositeConfiguration configuration = load(source); + /** + * Load a configuration. + * + * @param source the source directory of the project + * @param propertiesFile the properties file for the project + * @return the configuration + * @throws ConfigurationException if unable to configure + */ + public JBakeConfiguration loadConfig(File source, File propertiesFile) throws ConfigurationException { + CompositeConfiguration configuration = load(source, propertiesFile); return new DefaultJBakeConfiguration(source, configuration); } + /** + * Load a configuration. + * + * @param source the source directory of the project + * @return the configuration + * @throws ConfigurationException if unable to configure + * @deprecated use {@link #loadConfig(File, File)} instead + */ + @Deprecated + public JBakeConfiguration loadConfig(File source) throws ConfigurationException { + return loadConfig(source, null); + } } 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..976ec6e22 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 @@ -23,13 +23,26 @@ public JBakeConfigurationFactory() { * @param isClearCache Whether to clear database cache or not * @return A configuration by given parameters * @throws ConfigurationException if loading the configuration fails + * @deprecated use {@link #createDefaultJbakeConfiguration(File, File, File, boolean)} instead */ + @Deprecated public DefaultJBakeConfiguration createDefaultJbakeConfiguration(File sourceFolder, File destination, boolean isClearCache) throws ConfigurationException { + return createDefaultJbakeConfiguration(sourceFolder, destination, (File) null, isClearCache); + } - DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) getConfigUtil().loadConfig(sourceFolder); + /** + * Creates a {@link DefaultJBakeConfiguration} + * @param sourceFolder The source folder of the project + * @param destination The destination folder to render and copy files to + * @param propertiesFile The properties file for the project + * @param isClearCache Whether to clear database cache or not + * @return A configuration by given parameters + * @throws ConfigurationException if loading the configuration fails + */ + public DefaultJBakeConfiguration createDefaultJbakeConfiguration(File sourceFolder, File destination, File propertiesFile, boolean isClearCache) throws ConfigurationException { + DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) getConfigUtil().loadConfig(sourceFolder, propertiesFile); configuration.setDestinationFolder(destination); configuration.setClearCache(isClearCache); - return configuration; } @@ -89,9 +102,27 @@ public DefaultJBakeConfiguration createDefaultJbakeConfiguration(File sourceFold * @param isClearCache Whether to clear database cache or not * @return A configuration by given parameters * @throws ConfigurationException if loading the configuration fails + * @deprecated use {@link #createJettyJbakeConfiguration(File, File, File, boolean)} instead */ + @Deprecated public DefaultJBakeConfiguration createJettyJbakeConfiguration(File sourceFolder, File destinationFolder, boolean isClearCache) throws ConfigurationException { - DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) getConfigUtil().loadConfig(sourceFolder); + return createJettyJbakeConfiguration(sourceFolder, destinationFolder, (File)null, isClearCache); + } + + /** + * Creates a {@link DefaultJBakeConfiguration} with value site.host replaced + * by http://localhost:[server.port]. + * The server.port is read from the project properties file. + * + * @param sourceFolder The source folder of the project + * @param destinationFolder The destination folder to render and copy files to + * @param propertiesFile The properties file for the project + * @param isClearCache Whether to clear database cache or not + * @return A configuration by given parameters + * @throws ConfigurationException if loading the configuration fails + */ + public DefaultJBakeConfiguration createJettyJbakeConfiguration(File sourceFolder, File destinationFolder, File propertiesFile, boolean isClearCache) throws ConfigurationException { + DefaultJBakeConfiguration configuration = (DefaultJBakeConfiguration) getConfigUtil().loadConfig(sourceFolder, propertiesFile); configuration.setDestinationFolder(destinationFolder); configuration.setClearCache(isClearCache); configuration.setSiteHost("http://" + configuration.getServerHostname() + ":" +configuration.getServerPort() + configuration.getServerContextPath()); 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 5f3b1914f..4a9ff5c2a 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java +++ b/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java @@ -1,5 +1,6 @@ package org.jbake.launcher; +import org.jbake.app.configuration.ConfigUtil; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -37,6 +38,9 @@ static class InitOptions { @Option(names = {"-s", "--server"}, description = "runs HTTP server to serve out baked site, if no is supplied will default to a folder called \"output\" in the current directory") private boolean runServer; + @Option(names = {"-c", "--config"}, description = "use specified file for configuration (defaults to " + ConfigUtil.CONFIG_FILE +" in the source folder if not supplied)") + private String config; + @Option(names = {"-h", "--help"}, description = "prints this message", usageHelp = true) private boolean helpRequested; @@ -71,6 +75,18 @@ public String getDestinationValue() { return destination; } + public File getConfig() { + if (config != null) { + return new File(config); + } else { + return new File(getSource(), "jbake.properties"); + } + } + + public String getConfigValue() { + return config; + } + public boolean isHelpNeeded() { return helpRequested || !(isBake() || isRunServer() || isInit() || source != null || destination != null); } 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 c96dd93dd..75565d88f 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/Main.java +++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java @@ -76,9 +76,9 @@ public void run(String[] args) throws JBakeException { LaunchOptions res = parseArguments(args); if (res.isRunServer()) { - config = getJBakeConfigurationFactory().createJettyJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); + config = getJBakeConfigurationFactory().createJettyJbakeConfiguration(res.getSource(), res.getDestination(), res.getConfig(), res.isClearCache()); } else { - config = getJBakeConfigurationFactory().createDefaultJbakeConfiguration(res.getSource(), res.getDestination(), res.isClearCache()); + config = getJBakeConfigurationFactory().createDefaultJbakeConfiguration(res.getSource(), res.getDestination(), res.getConfig(), res.isClearCache()); } run(res, config); } catch (final ConfigurationException e) { 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 f080214fa..7714220ae 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/LaunchOptionsTest.java @@ -1,5 +1,6 @@ package org.jbake.launcher; +import org.jbake.app.configuration.ConfigUtil; import org.junit.Test; import picocli.CommandLine; import picocli.CommandLine.MissingParameterException; @@ -100,6 +101,7 @@ public void bakeNoArgs() { assertThat(res.isBake()).isFalse(); assertThat(res.getSource().getPath()).isEqualTo(System.getProperty("user.dir")); assertThat(res.getDestination().getPath()).isEqualTo(System.getProperty("user.dir") + File.separator + "output"); + assertThat(res.getConfig().getPath()).isEqualTo(System.getProperty("user.dir") + File.separator + ConfigUtil.CONFIG_FILE); } @Test @@ -115,6 +117,14 @@ public void bakeWithArgs() { assertThat(res.getDestination()).isEqualTo(new File("/tmp/destination")); } + @Test + public void configArg() { + String[] args = {"-c", "foo"}; + LaunchOptions res = parseArgs(args); + assertThat(res.getConfig().getAbsoluteFile().toString()).isEqualTo(System.getProperty("user.dir")+ File.separator + "foo"); + + } + private LaunchOptions parseArgs(String[] args) { return CommandLine.populateCommand(new LaunchOptions(), 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 af93fca21..de95bf7b2 100644 --- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java +++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java @@ -198,17 +198,17 @@ private DefaultJBakeConfiguration stubConfig() throws ConfigurationException { } private void mockDefaultJbakeConfiguration(File sourceFolder) throws ConfigurationException { - DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder, null, false); + DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder, null, null, false); System.setProperty("user.dir", sourceFolder.getPath()); - when(factory.createJettyJbakeConfiguration(any(File.class), any(File.class), anyBoolean())).thenReturn(configuration); + when(factory.createJettyJbakeConfiguration(any(File.class), 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); + DefaultJBakeConfiguration configuration = new JBakeConfigurationFactory().createJettyJbakeConfiguration(sourceFolder, destinationFolder, null, false); System.setProperty("user.dir", sourceFolder.getPath()); - when(factory.createJettyJbakeConfiguration(any(File.class), any(File.class), anyBoolean())).thenReturn(configuration); + when(factory.createJettyJbakeConfiguration(any(File.class), any(File.class), any(File.class), anyBoolean())).thenReturn(configuration); return configuration; } From 011b89949c44f534081417f20cc8e0e0886800df Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Wed, 29 Apr 2020 00:13:41 +0200 Subject: [PATCH 26/27] update to apache configurations2. load properties files with default utf-8 encoding 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 add cli option --prop-encoding to configure property encoding that should be used --- appveyor.yml | 4 +- 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 | 2 +- .../jbake/app/configuration/ConfigUtil.java | 72 ++++++++++++++++--- .../DefaultJBakeConfiguration.java | 21 +++--- .../JBakeConfigurationFactory.java | 10 ++- .../java/org/jbake/launcher/BakeWatcher.java | 4 +- .../main/java/org/jbake/launcher/Baker.java | 2 +- .../main/java/org/jbake/launcher/Init.java | 4 +- .../org/jbake/launcher/LaunchOptions.java | 36 +++++----- .../main/java/org/jbake/launcher/Main.java | 6 +- .../java/org/jbake/parser/MarkupEngine.java | 4 +- .../java/org/jbake/parser/ParserEngine.java | 2 +- .../org/jbake/render/ArchiveRenderer.java | 2 +- .../org/jbake/render/DocumentsRenderer.java | 2 +- .../java/org/jbake/render/FeedRenderer.java | 2 +- .../java/org/jbake/render/IndexRenderer.java | 2 +- .../java/org/jbake/render/RenderingTool.java | 2 +- .../org/jbake/render/SitemapRenderer.java | 2 +- .../java/org/jbake/render/TagsRenderer.java | 2 +- .../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 | 51 +++++++++---- .../JBakeConfigurationFactoryTest.java | 38 ++++++++-- .../org/jbake/launcher/LaunchOptionsTest.java | 16 +++++ .../java/org/jbake/launcher/MainTest.java | 40 ++++++++--- .../support/MockCompositeConfiguration.java | 3 +- .../test/resources/fixture/jbake.properties | 1 + .../resources/fixtureLatin1/jbake.properties | 19 +++++ jbake-core/src/test/resources/logback.xml | 2 + jbake-dist/src/dist/lib/logging/logback.xml | 3 + 40 files changed, 292 insertions(+), 114 deletions(-) create mode 100644 jbake-core/src/test/resources/fixtureLatin1/jbake.properties diff --git a/appveyor.yml b/appveyor.yml index b6ef6ed20..65894fc34 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,6 +20,6 @@ install: - 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/gradle.properties b/gradle.properties index 1d8892d22..13d0e3eeb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,8 @@ asciidoctorjVersion = 2.4.3 asciidoctorjDiagramVersion = 2.1.0 args4jVersion = 2.33 commonsIoVersion = 2.8.0 -commonsConfigurationVersion = 1.10 +commonsConfigurationVersion = 2.7 +commonsBeanutilsVersion = 1.9.4 commonsLangVersion = 3.12.0 commonsVfs2Version = 2.7.0 freemarkerVersion = 2.3.31 diff --git a/jbake-core/build.gradle b/jbake-core/build.gradle index d4780c06d..3e41caa41 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 f11e9f5ac..5bbc5d88e 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 f5a01c8cc..63e00875d 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 @@ -197,7 +197,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 242784b53..74d91332f 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 696569ec2..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; 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 c55befaf5..c35e921a2 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,9 +1,12 @@ 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.jbake.launcher.SystemExit; import org.slf4j.Logger; @@ -11,6 +14,7 @@ import java.io.File; import java.net.URL; +import java.nio.charset.Charset; /** * Provides Configuration related functions. @@ -19,10 +23,13 @@ */ 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"; private static final String DEFAULT_CONFIG_FILE = "default.properties"; + private String encoding = DEFAULT_ENCODING; private CompositeConfiguration load(File source) throws ConfigurationException { @@ -32,23 +39,53 @@ private CompositeConfiguration load(File source) throws ConfigurationException { if (!source.isDirectory()) { throw new JBakeException(SystemExit.CONFIGURATION_ERROR,"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(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(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); @@ -59,4 +96,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/DefaultJBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java index 7b4988677..d61025089 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,16 +1,14 @@ 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; import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; @@ -75,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) { @@ -91,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 Collections.emptyList(); } - return value; } @Override @@ -515,6 +513,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..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 @@ -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; @@ -105,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/BakeWatcher.java b/jbake-core/src/main/java/org/jbake/launcher/BakeWatcher.java index 7643b33fc..3512cb83d 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 17d17f8f4..536625c98 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/LaunchOptions.java b/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java index 5f3b1914f..150b442f7 100644 --- a/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java +++ b/jbake-core/src/main/java/org/jbake/launcher/LaunchOptions.java @@ -8,9 +8,9 @@ import java.io.File; @Command( - description = "JBake is a Java based, open source, static site/blog generator for developers & designers", - name = "jbake", - usageHelpAutoWidth = true + description = "JBake is a Java based, open source, static site/blog generator for developers & designers", + name = "jbake", + usageHelpAutoWidth = true ) public class LaunchOptions { @Parameters(index = "0", description = "source folder of site content (with templates and assets), if not supplied will default to current directory", arity = "0..1") @@ -24,24 +24,15 @@ public class LaunchOptions { @ArgGroup(exclusive = false, heading = "%n%nJBake initialization%n%n") private InitOptions initGroup; - - static class InitOptions { - - @Option(names = {"-i", "--init"}, paramLabel = "", description = "initialises required folder structure with default templates (defaults to current directory if is not supplied)", required = true) - private boolean init; - - @Option(names = {"-t", "--template"}, defaultValue = "freemarker", fallbackValue = "freemarker", description = "use specified template engine for default templates (uses Freemarker if