diff --git a/build.gradle b/build.gradle
index 284f72f65..fffdd2509 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,33 +2,33 @@ plugins {
id "eclipse"
id "idea"
id "io.sdkman.vendors" version "1.1.1" apply false
- id "com.jfrog.bintray" version "1.7.3" apply false
- id "com.github.kt3k.coveralls" version "2.8.1" apply false
- id 'com.github.ben-manes.versions' version '0.15.0'
+ id "com.jfrog.bintray" version "1.8.0" apply false
+ id "com.github.kt3k.coveralls" version "2.8.2" apply false
+ id 'com.github.ben-manes.versions' version '0.17.0'
}
// common variables
ext {
asciidoctorjVersion = '1.5.6'
asciidoctorjDiagramVersion = '1.5.4.1'
- commonsIoVersion = '2.5'
+ commonsIoVersion = '2.6'
commonsConfigurationVersion = '1.10'
- commonsLangVersion = '3.6'
- commonsVfs2Version = '2.1'
+ commonsLangVersion = '3.7'
+ commonsVfs2Version = '2.2'
args4jVersion = '2.33'
- freemarkerVersion = '2.3.26-incubating'
+ freemarkerVersion = '2.3.27-incubating'
junit4Version = '4.12'
- flexmarkVersion = '0.27.0'
- jettyServerVersion = '9.2.22.v20170606'
- orientDbVersion = '2.2.28'
- groovyVersion = '2.4.12'
+ flexmarkVersion = '0.28.38'
+ jettyServerVersion = '9.2.24.v20180105'
+ orientDbVersion = '2.2.30'
+ groovyVersion = '2.4.13'
slf4jVersion = '1.7.25'
logbackVersion = '1.2.3'
- assertjCoreVersion = '2.8.0'
- thymeleafVersion = '3.0.7.RELEASE'
+ assertjCoreVersion = '2.9.0'
+ thymeleafVersion = '3.0.9.RELEASE'
jsonSimpleVersion = '1.1.1'
- jade4jVersion = '1.2.5'
- mockitoVersion = '2.10.0'
+ jade4jVersion = '1.2.7'
+ mockitoVersion = '2.13.0'
jsoupVersion = '1.10.3'
}
diff --git a/gradle.properties b/gradle.properties
index 574285fab..558cf5c16 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ website=http://jbake.org
issues=https://github.com/jbake-org/jbake/issues
vcs=https://github.com/jbake-org/jbake/
-jacocoVersion=0.7.9
+jacocoVersion=0.8.0
bintrayDryRun=false
bintrayOrg=jbake
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 60a3d06a1..4ea711dd5 100644
--- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java
+++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java
@@ -28,7 +28,6 @@
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.OPartitionedDatabasePool;
import com.orientechnologies.orient.core.db.OPartitionedDatabasePoolFactory;
-import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
@@ -41,11 +40,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* @author jdlee
@@ -63,7 +58,7 @@ public ContentStore(final String type, String name) {
pool.setAutoCreate(true);
db = pool.acquire();
- ODatabaseRecordThreadLocal.INSTANCE.set(db);
+ ODatabaseRecordThreadLocal.instance().set(db);
updateSchema();
}
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 c516c3826..62f45e9e6 100644
--- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java
+++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java
@@ -1,18 +1,5 @@
package org.jbake.parser;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.io.IOUtils;
import org.jbake.app.ConfigUtil.Keys;
@@ -21,10 +8,19 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
/**
* Base class for markup engine wrappers. A markup engine is responsible for rendering
* markup in a source file and exporting the result into the {@link ParserContext#getContents() contents} map.
- *
+ *
* This specific engine does nothing, meaning that the body is rendered as raw contents.
*
* @author Cédric Champeau
@@ -35,46 +31,50 @@ public abstract class MarkupEngine implements ParserEngine {
/**
* Tests if this markup engine can process the document.
+ *
* @param context the parser context
* @return true if this markup engine has enough context to process this document. false otherwise
*/
- public boolean validate(ParserContext context) { return true; }
+ public boolean validate(ParserContext context) {
+ return true;
+ }
/**
* Processes the document header. Usually subclasses will parse the document body and look for
* specific header metadata and export it into {@link ParserContext#getContents() contents} map.
+ *
* @param context the parser context
*/
- public void processHeader(final ParserContext context) {}
+ public void processHeader(final ParserContext context) {
+ }
/**
* Processes the body of the document. Usually subclasses will parse the document body and render
* it, exporting the result using the {@link org.jbake.parser.ParserContext#setBody(String)} method.
+ *
* @param context the parser context
*/
- public void processBody(final ParserContext context) {}
+ public void processBody(final ParserContext context) {
+ }
/**
* Parse given file to extract as much infos as possible
+ *
* @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(Configuration config, File file, String contentPath) {
-
- Map content = new HashMap();
- InputStream is = null;
+ public Map parse(Configuration config, File file, String contentPath) {
+
+ Map content = new HashMap();
List fileContents = null;
- try {
- is = new FileInputStream(file);
+ try (InputStream is = new FileInputStream(file)) {
+
fileContents = IOUtils.readLines(is, config.getString(Keys.RENDER_ENCODING));
} catch (IOException e) {
LOGGER.error("Error while opening file {}", file, e);
return null;
- } finally {
- IOUtils.closeQuietly(is);
}
-
boolean hasHeader = hasHeader(fileContents);
ParserContext context = new ParserContext(
file,
@@ -91,30 +91,30 @@ public Map parse(Configuration config, File file, String content
}
// then read engine specific headers
processHeader(context);
-
+
if (content.get(Crawler.Attributes.DATE) == null) {
- content.put(Crawler.Attributes.DATE, new Date(file.lastModified()));
+ content.put(Crawler.Attributes.DATE, new Date(file.lastModified()));
}
-
+
if (config.getString(Keys.DEFAULT_STATUS) != null) {
- // default status has been set
- if (content.get(Crawler.Attributes.STATUS) == null) {
- // file hasn't got status so use default
- content.put(Crawler.Attributes.STATUS, config.getString(Keys.DEFAULT_STATUS));
- }
+ // default status has been set
+ if (content.get(Crawler.Attributes.STATUS) == null) {
+ // file hasn't got status so use default
+ content.put(Crawler.Attributes.STATUS, config.getString(Keys.DEFAULT_STATUS));
+ }
}
if (config.getString(Keys.DEFAULT_TYPE) != null) {
- // default type has been set
+ // default type has been set
if (content.get(Crawler.Attributes.TYPE) == null) {
// file hasn't got type so use default
content.put(Crawler.Attributes.TYPE, config.getString(Keys.DEFAULT_TYPE));
}
}
- if (content.get(Crawler.Attributes.TYPE)==null||content.get(Crawler.Attributes.STATUS)==null) {
+ if (content.get(Crawler.Attributes.TYPE) == null || content.get(Crawler.Attributes.STATUS) == null) {
// output error
- LOGGER.warn("Error parsing meta data from header (missing type or status value) for file {}!", file);
+ LOGGER.warn("Error parsing meta data from header (missing type or status value) for file {}!", file);
return null;
}
@@ -129,21 +129,21 @@ public Map parse(Configuration config, File file, String content
return null;
}
- if (content.get(Crawler.Attributes.TAGS) != null) {
- String[] tags = (String[]) content.get(Crawler.Attributes.TAGS);
- for( int i=0; i contents) {
List header = new ArrayList();
for (String line : contents) {
- if (!line.isEmpty()){
- header.add(line);
- }
+ if (!line.isEmpty()) {
+ header.add(line);
+ }
if (line.contains("=")) {
if (line.startsWith("type=")) {
typeFound = true;
@@ -193,8 +193,8 @@ private boolean hasHeader(List contents) {
/**
* Process the header of the file.
- * @param config
*
+ * @param config
* @param contents Contents of file
* @param content
*/
@@ -205,10 +205,10 @@ private void processHeader(Configuration config, List contents, final Ma
}
if (line.isEmpty()) {
- continue;
+ continue;
}
-
- String[] parts = line.split("=",2);
+
+ String[] parts = line.split("=", 2);
if (parts.length != 2) {
continue;
}
@@ -216,9 +216,9 @@ private void processHeader(Configuration config, List contents, final Ma
String utf8BOM = "\uFEFF";
String key;
if (parts[0].contains(utf8BOM)) {
- key = parts[0].trim().replace(utf8BOM, "");
+ key = parts[0].trim().replace(utf8BOM, "");
} else {
- key = parts[0].trim();
+ key = parts[0].trim();
}
String value = parts[1].trim();
@@ -243,8 +243,8 @@ private void processHeader(Configuration config, List contents, final Ma
private String[] getTags(String tagsPart) {
String[] tags = tagsPart.split(",");
- for( int i=0; i contents, final Map conten
body.append(line).append("\n");
}
}
-
+
content.put(Crawler.Attributes.BODY, body.toString());
}
}
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 cb80f5df0..e9d04ee8d 100644
--- a/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/DelegatingTemplateEngine.java
@@ -4,10 +4,6 @@
import org.jbake.app.ConfigUtil.Keys;
import org.jbake.app.ContentStore;
import org.jbake.app.FileUtil;
-import org.jbake.model.DocumentTypeUtils;
-import org.jbake.model.DocumentTypes;
-import org.jbake.template.model.PublishedCustomExtractor;
-import org.jbake.template.model.TypedDocumentsExtractor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 5c1fcc223..a6d352bf9 100644
--- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java
@@ -1,6 +1,14 @@
package org.jbake.template;
+import freemarker.ext.beans.BeansWrapper;
+import freemarker.ext.beans.BeansWrapperBuilder;
+import freemarker.template.*;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.jbake.app.ConfigUtil.Keys;
+import org.jbake.app.ContentStore;
+import org.jbake.app.Crawler;
+
import java.io.File;
import java.io.IOException;
import java.io.Writer;
@@ -8,26 +16,6 @@
import java.util.Date;
import java.util.Map;
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.jbake.app.ConfigUtil.Keys;
-import org.jbake.app.ContentStore;
-import org.jbake.app.Crawler;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.beans.BeansWrapperBuilder;
-import freemarker.template.Configuration;
-import freemarker.template.DefaultObjectWrapper;
-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;
-
/**
* Renders pages using the Freemarker template engine.
*
@@ -43,21 +31,20 @@ public FreemarkerTemplateEngine(final CompositeConfiguration config, final Conte
}
private void createTemplateConfiguration(final CompositeConfiguration config, final File templatesPath) {
- templateCfg = new Configuration();
+ templateCfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
templateCfg.setDefaultEncoding(config.getString(Keys.RENDER_ENCODING));
try {
templateCfg.setDirectoryForTemplateLoading(templatesPath);
} catch (IOException e) {
e.printStackTrace();
}
- templateCfg.setObjectWrapper(new DefaultObjectWrapper());
}
@Override
public void renderDocument(final Map model, final String templateName, final Writer writer) throws RenderingException {
try {
Template template = templateCfg.getTemplate(templateName);
- template.process(new LazyLoadingModel(model, db), writer);
+ template.process(new LazyLoadingModel(templateCfg.getObjectWrapper(), model, db), writer);
} catch (IOException e) {
throw new RenderingException(e);
} catch (TemplateException e) {
@@ -69,12 +56,14 @@ public void renderDocument(final Map model, final String templat
* A custom Freemarker model that avoids loading the whole documents into memory if not necessary.
*/
public static class LazyLoadingModel implements TemplateHashModel {
+ private final ObjectWrapper wrapper;
private final SimpleHash eagerModel;
private final ContentStore db;
- public LazyLoadingModel(final Map eagerModel, final ContentStore db) {
- this.eagerModel = new SimpleHash(eagerModel);
+ public LazyLoadingModel(ObjectWrapper wrapper, Map eagerModel, final ContentStore db) {
+ this.eagerModel = new SimpleHash(eagerModel, wrapper);
this.db = db;
+ this.wrapper = wrapper;
}
@Override
@@ -96,12 +85,12 @@ public TemplateModel get(final String key) throws TemplateModelException {
@Override
public TemplateModel adapt(String key, Object extractedValue) {
if(key.equals(Crawler.Attributes.ALLTAGS)) {
- return new SimpleCollection((Collection) extractedValue);
+ return new SimpleCollection((Collection) extractedValue, wrapper);
} 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
- return new SimpleSequence((Collection) extractedValue);
+ return new SimpleSequence((Collection) extractedValue, wrapper);
}
}
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 61a184676..6c749c62e 100644
--- a/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/ThymeleafTemplateEngine.java
@@ -14,24 +14,20 @@
import java.io.File;
import java.io.Writer;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
/**
* A template engine which renders pages using Thymeleaf.
- *
+ *
*
This template engine is not recommended for large sites because the whole model
* is loaded into memory due to Thymeleaf internal limitations.
- *
+ *
*
The default rendering mode is "HTML", but it is possible to use another mode
* for each document type, by adding a key in the configuration, for example:
- *
+ *
*
- * template.feed.thymeleaf.mode=XML
+ * template.feed.thymeleaf.mode=XML
*
*
* @author Cédric Champeau
@@ -42,16 +38,16 @@ public class ThymeleafTemplateEngine extends AbstractTemplateEngine {
private TemplateEngine templateEngine;
private FileTemplateResolver templateResolver;
- private String templateMode;
+ private String templateMode;
public ThymeleafTemplateEngine(final CompositeConfiguration config, final ContentStore db, final File destination, final File templatesPath) {
super(config, db, destination, templatesPath);
}
private void initializeTemplateEngine(String mode) {
- if (mode.equals(templateMode)) {
- return;
- }
+ if (mode.equals(templateMode)) {
+ return;
+ }
templateMode = mode;
templateResolver = new FileTemplateResolver();
templateResolver.setPrefix(templatesPath.getAbsolutePath() + File.separatorChar);
@@ -92,42 +88,42 @@ private Map wrap(final Map model) {
}
private class JBakeMap extends HashMap {
- public JBakeMap(final Map model) {
- super(model);
- for(String key : extractors.keySet()) {
- try {
- put(key, extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter() {
- @Override
- public LazyContextVariable adapt(String key, final Object extractedValue) {
- if(key.equals(Crawler.Attributes.ALLTAGS)) {
- return new LazyContextVariable>() {
- @Override
- protected Set loadValue() {
- return (Set) extractedValue;
- }
- };
- } else if(key.equals(Crawler.Attributes.PUBLISHED_DATE)) {
- return new LazyContextVariable() {
- @Override
- protected Date loadValue() {
- return (Date) extractedValue;
- }
- };
- } else {
- // All other cases, as far as I know, are document collections
- return new LazyContextVariable() {
- @Override
- protected DocumentList loadValue() {
- return (DocumentList) extractedValue;
- }
- };
- }
- }
- }));
- } catch (NoModelExtractorException e) {
- // should never happen, as we iterate over existing extractors
- }
- }
- }
+ JBakeMap(final Map model) {
+ super(model);
+ for (String key : extractors.keySet()) {
+ try {
+ put(key, extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter() {
+ @Override
+ public LazyContextVariable adapt(String key, final Object extractedValue) {
+ if (key.equals(Crawler.Attributes.ALLTAGS)) {
+ return new LazyContextVariable>() {
+ @Override
+ protected Set> loadValue() {
+ return (Set>) extractedValue;
+ }
+ };
+ } else if (key.equals(Crawler.Attributes.PUBLISHED_DATE)) {
+ return new LazyContextVariable() {
+ @Override
+ protected Date loadValue() {
+ return (Date) extractedValue;
+ }
+ };
+ } else {
+ // All other cases, as far as I know, are document collections
+ return new LazyContextVariable() {
+ @Override
+ protected DocumentList loadValue() {
+ return (DocumentList) extractedValue;
+ }
+ };
+ }
+ }
+ }));
+ } catch (NoModelExtractorException e) {
+ // should never happen, as we iterate over existing extractors
+ }
+ }
+ }
}
}
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 e94c40276..f7abf00e0 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
@@ -14,7 +14,7 @@ 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");
+ Map, ?> config = (Map, ?>) model.get("config");
String tagPath = config.get(Keys.TAG_PATH.replace(".", "_")).toString();
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 8686ba689..1a448e888 100644
--- a/jbake-core/src/test/java/org/jbake/launcher/MainTest.java
+++ b/jbake-core/src/test/java/org/jbake/launcher/MainTest.java
@@ -7,7 +7,7 @@
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.util.HashMap;
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 fd67a5d54..2ba8e5c9d 100644
--- a/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java
+++ b/jbake-core/src/test/java/org/jbake/render/DocumentsRendererTest.java
@@ -2,9 +2,9 @@
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.Crawler.Attributes;
import org.jbake.model.DocumentTypes;
import org.jbake.template.RenderingException;
import org.junit.Before;
@@ -22,7 +22,7 @@
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
public class DocumentsRendererTest {
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 cc79a6fb9..951f167d3 100644
--- a/jbake-core/src/test/java/org/jbake/render/RendererTest.java
+++ b/jbake-core/src/test/java/org/jbake/render/RendererTest.java
@@ -1,26 +1,25 @@
package org.jbake.render;
-import java.io.File;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.vfs2.util.Os;
import org.jbake.app.ConfigUtil;
+import org.jbake.app.ConfigUtil.Keys;
import org.jbake.app.ContentStore;
import org.jbake.app.Crawler;
import org.jbake.app.Renderer;
-import org.jbake.app.ConfigUtil.Keys;
import org.jbake.template.DelegatingTemplateEngine;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
import static org.assertj.core.api.Assertions.assertThat;
@RunWith( MockitoJUnitRunner.class )