From 741f7f0f844d992f8333bdf0d43d7aebb7322a64 Mon Sep 17 00:00:00 2001
From: Frank Becker
Date: Sat, 29 May 2021 02:24:06 +0200
Subject: [PATCH 1/7] cleanup and fix some sonarcloud issues
---
.../src/main/java/org/jbake/app/Asset.java | 26 ++--
.../main/java/org/jbake/app/ContentStore.java | 8 +-
.../src/main/java/org/jbake/app/Crawler.java | 20 ++-
.../src/main/java/org/jbake/app/FileUtil.java | 113 +++++----------
.../DefaultJBakeConfiguration.java | 10 +-
.../main/java/org/jbake/launcher/Main.java | 3 -
.../java/org/jbake/model/DocumentModel.java | 4 +-
.../org/jbake/parser/AsciidoctorEngine.java | 134 +++++++++++-------
.../main/java/org/jbake/parser/Engines.java | 21 +--
.../java/org/jbake/parser/MarkupEngine.java | 2 +-
.../org/jbake/render/ArchiveRenderer.java | 1 -
.../template/DelegatingTemplateEngine.java | 2 -
.../template/FreemarkerTemplateEngine.java | 40 +++---
.../template/GroovyMarkupTemplateEngine.java | 11 +-
.../jbake/template/JadeTemplateEngine.java | 2 +-
.../org/jbake/template/ModelExtractor.java | 5 +-
.../org/jbake/template/ModelExtractors.java | 58 ++++----
.../jbake/template/PebbleTemplateEngine.java | 9 +-
.../jbake/template/TemplateEngineAdapter.java | 2 +
.../org/jbake/template/TemplateEngines.java | 18 ++-
.../template/ThymeleafTemplateEngine.java | 49 +++----
.../template/model/AllContentExtractor.java | 9 +-
.../template/model/AllTagsExtractor.java | 5 +-
.../org/jbake/template/model/DBExtractor.java | 6 +-
.../jbake/template/model/DataExtractor.java | 15 +-
.../model/PublishedContentExtractor.java | 8 +-
.../model/PublishedCustomExtractor.java | 10 +-
.../model/PublishedDateExtractor.java | 5 +-
.../model/PublishedPagesExtractor.java | 9 +-
.../model/PublishedPostsExtractor.java | 9 +-
.../template/model/TagPostsExtractor.java | 13 +-
.../model/TaggedDocumentsExtractor.java | 14 +-
.../jbake/template/model/TagsExtractor.java | 20 +--
.../jbake/template/model/TemplateModel.java | 9 +-
.../model/TypedDocumentsExtractor.java | 12 +-
.../java/org/jbake/util/DataFileUtil.java | 11 +-
.../test/java/org/jbake/app/CrawlerTest.java | 6 +-
.../jbake/template/ModelExtractorsTest.java | 2 +-
.../java/org/jbake/BinaryRunner.java | 4 +-
39 files changed, 321 insertions(+), 384 deletions(-)
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 5bbc5d88e..1c76ac6ee 100644
--- a/jbake-core/src/main/java/org/jbake/app/Asset.java
+++ b/jbake-core/src/main/java/org/jbake/app/Asset.java
@@ -62,12 +62,7 @@ public void copy() {
* @param path The starting path
*/
public void copy(File path) {
- FileFilter filter = new FileFilter() {
- @Override
- public boolean accept(File file) {
- return (!config.getAssetIgnoreHidden() || !file.isHidden()) && (file.isFile() || FileUtil.directoryOnlyIfNotIgnored(file, config));
- }
- };
+ FileFilter filter = file -> (!config.getAssetIgnoreHidden() || !file.isHidden()) && (file.isFile() || FileUtil.directoryOnlyIfNotIgnored(file, config));
copy(path, config.getDestinationFolder(), filter);
}
@@ -96,21 +91,20 @@ public void copySingleFile(File asset) {
* @return true if the path provided points to a file in the asset folder.
*/
public boolean isAssetFile(File path) {
- boolean isAsset = false;
-
try {
- if(FileUtil.directoryOnlyIfNotIgnored(path.getParentFile(), config)) {
- if (FileUtil.isFileInDirectory(path, config.getAssetFolder())) {
- isAsset = true;
- } else if (FileUtil.isFileInDirectory(path, config.getContentFolder())
- && FileUtil.getNotContentFileFilter(config).accept(path)) {
- isAsset = true;
- }
+ if (FileUtil.directoryOnlyIfNotIgnored(path.getParentFile(), config)
+ && (FileUtil.isFileInDirectory(path, config.getAssetFolder()) || assetsInContentFolder(path))) {
+ return true;
}
} catch (IOException ioe) {
LOGGER.error("Unable to determine the path to asset file {}", path.getPath(), ioe);
}
- return isAsset;
+ return false;
+ }
+
+ private boolean assetsInContentFolder(File path) throws IOException {
+ return FileUtil.isFileInDirectory(path, config.getContentFolder())
+ && FileUtil.getNotContentFileFilter(config).accept(path);
}
/**
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 7dc71e887..589ae1005 100644
--- a/jbake-core/src/main/java/org/jbake/app/ContentStore.java
+++ b/jbake-core/src/main/java/org/jbake/app/ContentStore.java
@@ -34,8 +34,6 @@
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.executor.OResultSet;
-import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
-import org.jbake.launcher.SystemExit;
import org.jbake.model.DocumentModel;
import org.jbake.model.DocumentTypes;
import org.jbake.model.ModelAttributes;
@@ -149,8 +147,6 @@ public void close() {
}
public void shutdown() {
-
-// Orient.instance().shutdown();
}
private void startupIfEnginesAreMissing() {
@@ -169,8 +165,6 @@ private void startupIfEnginesAreMissing() {
public void drop() {
activateOnCurrentThread();
-// db.drop();
-
orient.drop(name);
}
@@ -178,7 +172,7 @@ private void activateOnCurrentThread() {
if (db != null) {
db.activateOnCurrentThread();
} else {
- System.out.println("db is null on activate");
+ logger.warn("db is null on activate");
}
}
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 0c3d8b9d6..0b117d3e8 100644
--- a/jbake-core/src/main/java/org/jbake/app/Crawler.java
+++ b/jbake-core/src/main/java/org/jbake/app/Crawler.java
@@ -1,10 +1,10 @@
package org.jbake.app;
-import com.orientechnologies.orient.core.record.impl.ODocument;
import org.apache.commons.configuration2.CompositeConfiguration;
import org.apache.commons.io.FilenameUtils;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
+import org.jbake.launcher.SystemExit;
import org.jbake.model.DocumentModel;
import org.jbake.model.DocumentStatus;
import org.jbake.model.DocumentTypes;
@@ -19,7 +19,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.
@@ -141,9 +140,8 @@ private void crawlDataFiles(File path) {
String sha1 = buildHash(sourceFile);
String uri = buildDataFileURI(sourceFile);
boolean process = true;
- DocumentStatus status = DocumentStatus.NEW;
String docType = config.getDataFileDocType();
- status = findDocumentStatus(uri, sha1);
+ DocumentStatus status = findDocumentStatus(uri, sha1);
if (status == DocumentStatus.UPDATED) {
sb.append(" : modified ");
db.deleteContent(uri);
@@ -156,8 +154,6 @@ private void crawlDataFiles(File path) {
}
if (DocumentStatus.NEW == status) {
sb.append(" : new ");
- }
- if (process) { // new or updated
crawlDataFile(sourceFile, sha1, uri, docType);
}
logger.info("{}", sb);
@@ -202,7 +198,7 @@ private String buildDataFileURI(final File sourceFile) {
String uri = FileUtil.asPath(sourceFile).replace(FileUtil.asPath(config.getDataFolder()), "");
// strip off leading /
if (uri.startsWith(FileUtil.URI_SEPARATOR_CHAR)) {
- uri = uri.substring(1, uri.length());
+ uri = uri.substring(1);
}
return uri;
}
@@ -216,7 +212,7 @@ private String createUri(String uri) {
+ URLEncoder.encode(FilenameUtils.getBaseName(uri), StandardCharsets.UTF_8.name())
+ config.getOutputExtension();
} catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Missing UTF-8 encoding??", e); // Won't happen unless JDK is broken.
+ throw new JBakeException(SystemExit.ERROR, "Missing UTF-8 encoding??", e); // Won't happen unless JDK is broken.
}
}
@@ -229,7 +225,7 @@ private String createNoExtensionUri(String uri) {
+ "index"
+ config.getOutputExtension();
} catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Missing UTF-8 encoding??", e); // Won't happen unless JDK is broken.
+ throw new JBakeException(SystemExit.ERROR, "Missing UTF-8 encoding??", e); // Won't happen unless JDK is broken.
}
}
@@ -258,7 +254,7 @@ private void crawlDataFile(final File sourceFile, final String sha1, final Strin
logger.warn("{} couldn't be parsed so it has been ignored!", sourceFile);
}
} catch (Exception ex) {
- throw new RuntimeException("Failed crawling file: " + sourceFile.getPath() + " " + ex.getMessage(), ex);
+ throw new JBakeException(SystemExit.ERROR, "Failed crawling file: " + sourceFile.getPath() + " " + ex.getMessage(), ex);
}
}
@@ -293,8 +289,8 @@ private void addAdditionalDocumentAttributes(DocumentModel document, File source
document.setCached(true);
if (document.getStatus().equals(ModelAttributes.Status.PUBLISHED_DATE)
- && (document.getDate() != null)
- && new Date().after(document.getDate())) {
+ && (document.getDate() != null)
+ && new Date().after(document.getDate())) {
document.setStatus(ModelAttributes.Status.PUBLISHED);
}
diff --git a/jbake-core/src/main/java/org/jbake/app/FileUtil.java b/jbake-core/src/main/java/org/jbake/app/FileUtil.java
index c80dbf9e2..2f928298a 100644
--- a/jbake-core/src/main/java/org/jbake/app/FileUtil.java
+++ b/jbake-core/src/main/java/org/jbake/app/FileUtil.java
@@ -1,6 +1,7 @@
package org.jbake.app;
import org.jbake.app.configuration.JBakeConfiguration;
+import org.jbake.launcher.SystemExit;
import org.jbake.parser.Engines;
import java.io.File;
@@ -9,10 +10,12 @@
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
/**
* Provides File related functions
@@ -30,15 +33,11 @@ public class FileUtil {
* @return Object for filtering files
*/
public static FileFilter getFileFilter(JBakeConfiguration config) {
- return new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- //Accept if input is a non-hidden file with registered extension
- //or if a non-hidden and not-ignored directory
- return !pathname.isHidden() && (pathname.isFile()
- && Engines.getRecognizedExtensions().contains(fileExt(pathname))) || (directoryOnlyIfNotIgnored(pathname, config));
- }
+ return pathname -> {
+ //Accept if input is a non-hidden file with registered extension
+ //or if a non-hidden and not-ignored directory
+ return !pathname.isHidden() && (pathname.isFile()
+ && Engines.getRecognizedExtensions().contains(fileExt(pathname))) || (directoryOnlyIfNotIgnored(pathname, config));
};
}
@@ -50,15 +49,11 @@ public boolean accept(File pathname) {
*/
@Deprecated
public static FileFilter getFileFilter() {
- return new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- //Accept if input is a non-hidden file with registered extension
- //or if a non-hidden and not-ignored directory
- return !pathname.isHidden() && (pathname.isFile()
- && Engines.getRecognizedExtensions().contains(fileExt(pathname))) || (directoryOnlyIfNotIgnored(pathname));
- }
+ return pathname -> {
+ //Accept if input is a non-hidden file with registered extension
+ //or if a non-hidden and not-ignored directory
+ return !pathname.isHidden() && (pathname.isFile()
+ && Engines.getRecognizedExtensions().contains(fileExt(pathname))) || (directoryOnlyIfNotIgnored(pathname));
};
}
@@ -68,13 +63,7 @@ public boolean accept(File pathname) {
* @return Object for filtering files
*/
public static FileFilter getDataFileFilter() {
- return new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- return "yaml".equalsIgnoreCase(fileExt(pathname)) || "yml".equalsIgnoreCase(fileExt(pathname));
- }
- };
+ return pathname -> "yaml".equalsIgnoreCase(fileExt(pathname)) || "yml".equalsIgnoreCase(fileExt(pathname));
}
/**
@@ -84,17 +73,13 @@ public boolean accept(File pathname) {
* @return FileFilter object
*/
public static FileFilter getNotContentFileFilter(JBakeConfiguration config) {
- return new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- //Accept if input is a non-hidden file with NOT-registered extension
- //or if a non-hidden and not-ignored directory
- return !pathname.isHidden() && (pathname.isFile()
- //extension should not be from registered content extensions
- && !Engines.getRecognizedExtensions().contains(fileExt(pathname)))
- || (directoryOnlyIfNotIgnored(pathname, config));
- }
+ return pathname -> {
+ //Accept if input is a non-hidden file with NOT-registered extension
+ //or if a non-hidden and not-ignored directory
+ return !pathname.isHidden() && (pathname.isFile()
+ //extension should not be from registered content extensions
+ && !Engines.getRecognizedExtensions().contains(fileExt(pathname)))
+ || (directoryOnlyIfNotIgnored(pathname, config));
};
}
@@ -106,17 +91,13 @@ public boolean accept(File pathname) {
*/
@Deprecated
public static FileFilter getNotContentFileFilter() {
- return new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- //Accept if input is a non-hidden file with NOT-registered extension
- //or if a non-hidden and not-ignored directory
- return !pathname.isHidden() && (pathname.isFile()
- //extension should not be from registered content extensions
- && !Engines.getRecognizedExtensions().contains(fileExt(pathname)))
- || (directoryOnlyIfNotIgnored(pathname));
- }
+ return pathname -> {
+ //Accept if input is a non-hidden file with NOT-registered extension
+ //or if a non-hidden and not-ignored directory
+ return !pathname.isHidden() && (pathname.isFile()
+ //extension should not be from registered content extensions
+ && !Engines.getRecognizedExtensions().contains(fileExt(pathname)))
+ || (directoryOnlyIfNotIgnored(pathname));
};
}
@@ -129,18 +110,9 @@ public boolean accept(File pathname) {
* @return true if file is directory and not ignored
*/
public static boolean directoryOnlyIfNotIgnored(File file, JBakeConfiguration config) {
- boolean accept = false;
-
- FilenameFilter ignoreFile = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.equalsIgnoreCase(config.getIgnoreFileName());
- }
- };
-
- accept = file.isDirectory() && (file.listFiles(ignoreFile).length == 0);
+ FilenameFilter ignoreFile = (dir, name) -> name.equalsIgnoreCase(config.getIgnoreFileName());
- return accept;
+ return file.isDirectory() && (file.listFiles(ignoreFile).length == 0);
}
/**
@@ -152,18 +124,9 @@ public boolean accept(File dir, String name) {
*/
@Deprecated
public static boolean directoryOnlyIfNotIgnored(File file) {
- boolean accept = false;
-
- FilenameFilter ignoreFile = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.equalsIgnoreCase(".jbakeignore");
- }
- };
-
- accept = file.isDirectory() && (file.listFiles(ignoreFile).length == 0);
+ FilenameFilter ignoreFile = (dir, name) -> name.equalsIgnoreCase(".jbakeignore");
- return accept;
+ return file.isDirectory() && (file.listFiles(ignoreFile).length == 0);
}
public static boolean isExistingFolder(File f) {
@@ -176,16 +139,16 @@ public static boolean isExistingFolder(File f) {
* @return File referencing folder JBake is running from
* @throws Exception when application is not able to work out where is JBake running from
*/
- public static File getRunningLocation() throws Exception {
+ public static File getRunningLocation() throws UnsupportedEncodingException {
String codePath = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(codePath, "UTF-8");
File codeFile = new File(decodedPath);
if (!codeFile.exists()) {
- throw new Exception("Cannot locate running location of JBake!");
+ throw new JBakeException(SystemExit.ERROR, "Cannot locate running location of JBake!");
}
File codeFolder = codeFile.getParentFile().getParentFile();
if (!codeFolder.exists()) {
- throw new Exception("Cannot locate running location of JBake!");
+ throw new JBakeException(SystemExit.ERROR, "Cannot locate running location of JBake!");
}
return codeFolder;
@@ -212,7 +175,7 @@ public static String fileExt(String name) {
* @return an hex string representing the SHA1 hash of the file or directory.
* @throws Exception if any IOException of SecurityException occured
*/
- public static String sha1(File sourceFile) throws Exception {
+ public static String sha1(File sourceFile) throws NoSuchAlgorithmException, IOException {
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance("SHA-1");
updateDigest(complete, sourceFile, buffer);
@@ -308,11 +271,11 @@ static public String getPathToRoot(JBakeConfiguration config, File rootPath, Fil
return sb.toString();
}
- static public String getUriPathToDestinationRoot(JBakeConfiguration config, File sourceFile) {
+ public static String getUriPathToDestinationRoot(JBakeConfiguration config, File sourceFile) {
return getPathToRoot(config, config.getDestinationFolder(), sourceFile);
}
- static public String getUriPathToContentRoot(JBakeConfiguration config, File sourceFile) {
+ public static String getUriPathToContentRoot(JBakeConfiguration config, File sourceFile) {
return getPathToRoot(config, config.getContentFolder(), sourceFile);
}
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 5de7d8e3c..49f5b9213 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
@@ -9,7 +9,13 @@
import org.slf4j.LoggerFactory;
import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -525,7 +531,6 @@ public void setExampleProject(String type, String fileName) {
@Override
public void setProperty(String key, Object value) {
-
compositeConfiguration.setProperty(key, value);
}
@@ -596,7 +601,6 @@ private void setupDefaultDestination() {
private void setupDefaultAssetFolder() {
String assetFolder = getAsString(ASSET_FOLDER.getKey());
-
File asset = new File(assetFolder);
if(asset.isAbsolute()) {
setAssetFolder(asset);
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 c244848f7..83d38a15d 100644
--- a/jbake-core/src/main/java/org/jbake/launcher/Main.java
+++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java
@@ -1,6 +1,5 @@
package org.jbake.launcher;
-import org.apache.commons.configuration2.ex.ConfigurationException;
import org.jbake.app.FileUtil;
import org.jbake.app.JBakeException;
import org.jbake.app.configuration.JBakeConfiguration;
@@ -21,8 +20,6 @@
*/
public class Main {
- 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;
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 99fd559cb..9af72bb86 100644
--- a/jbake-core/src/main/java/org/jbake/model/DocumentModel.java
+++ b/jbake-core/src/main/java/org/jbake/model/DocumentModel.java
@@ -84,8 +84,8 @@ public void setRootPath(String pathToRoot) {
put(ModelAttributes.ROOTPATH, pathToRoot);
}
- public Boolean getRendered() {
- return (Boolean) getOrDefault(ModelAttributes.RENDERED, false);
+ public boolean getRendered() {
+ return (boolean) getOrDefault(ModelAttributes.RENDERED, false);
}
public void setRendered(boolean rendered) {
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 a5b106895..9f24c6c6d 100644
--- a/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java
+++ b/jbake-core/src/main/java/org/jbake/parser/AsciidoctorEngine.java
@@ -6,14 +6,17 @@
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;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static org.asciidoctor.AttributesBuilder.attributes;
@@ -39,7 +42,7 @@ public class AsciidoctorEngine extends MarkupEngine {
private static final String OPT_REQUIRES = "requires";
public AsciidoctorEngine() {
- Class engineClass = Asciidoctor.class;
+ Class engineClass = Asciidoctor.class;
assert engineClass != null;
}
@@ -51,23 +54,7 @@ private Asciidoctor getEngine(Options options) {
try {
lock.writeLock().lock();
if (engine == null) {
- LOGGER.info("Initializing Asciidoctor engine...");
- if (options.map().containsKey(OPT_GEM_PATH)) {
- engine = AsciidoctorJRuby.Factory.create(String.valueOf(options.map().get(OPT_GEM_PATH)));
- } else {
- engine = Asciidoctor.Factory.create();
- }
-
- if (options.map().containsKey(OPT_REQUIRES)) {
- String[] requires = String.valueOf(options.map().get(OPT_REQUIRES)).split(",");
- if (requires.length != 0) {
- for (String require : requires) {
- engine.requireLibrary(require);
- }
- }
- }
-
- LOGGER.info("Asciidoctor engine initialized.");
+ initialize(options);
}
} finally {
lock.readLock().lock();
@@ -80,51 +67,96 @@ private Asciidoctor getEngine(Options options) {
return engine;
}
+ private void initialize(Options options) {
+ LOGGER.info("Initializing Asciidoctor engine...");
+ if (options.map().containsKey(OPT_GEM_PATH)) {
+ engine = AsciidoctorJRuby.Factory.create(String.valueOf(options.map().get(OPT_GEM_PATH)));
+ } else {
+ engine = Asciidoctor.Factory.create();
+ }
+
+ if (options.map().containsKey(OPT_REQUIRES)) {
+ String[] requires = String.valueOf(options.map().get(OPT_REQUIRES)).split(",");
+ if (requires.length != 0) {
+ for (String require : requires) {
+ engine.requireLibrary(require);
+ }
+ }
+ }
+
+ LOGGER.info("Asciidoctor engine initialized.");
+ }
+
@Override
public void processHeader(final ParserContext context) {
Options options = getAsciiDocOptionsAndAttributes(context);
final Asciidoctor asciidoctor = getEngine(options);
DocumentHeader header = asciidoctor.readDocumentHeader(context.getFile());
- DocumentModel documentModel = context.getDocumentModel();
- if (header.getDocumentTitle() != null) {
- documentModel.setTitle(header.getDocumentTitle().getCombined());
- }
+ setDocumentTitleIfNotPresentInHeader(context, header);
+ addAttributesToDocumentModel(context, header);
+ }
+
+ private void addAttributesToDocumentModel(ParserContext context, DocumentHeader header) {
Map attributes = header.getAttributes();
for (Map.Entry attribute : attributes.entrySet()) {
- String key = attribute.getKey();
- Object value = attribute.getValue();
-
- if (hasJBakePrefix(key)) {
- String pKey = key.substring(6);
- if(canCastToString(value)) {
- storeHeaderValue(pKey, (String) value, documentModel);
- } else {
- documentModel.put(pKey, value);
- }
- }
- if (hasRevdate(key) && canCastToString(value)) {
+ addIfKeyHasJbakePrefix(context, attribute);
+ convertAndSetIfDate(context, attribute);
+ addIfJbakeTagsOrDefault(context, attribute);
+ }
+ }
- String dateFormat = context.getConfig().getDateFormat();
- DateFormat df = new SimpleDateFormat(dateFormat);
- try {
- Date date = df.parse((String) value);
- context.setDate(date);
- } catch (ParseException e) {
- LOGGER.error("Unable to parse revdate. Expected {}", dateFormat, e);
- }
+ private void addIfJbakeTagsOrDefault(ParserContext context, Map.Entry attribute) {
+ String key = attribute.getKey();
+ Object value = attribute.getValue();
+
+ if (key.equals("jbake-tags")) {
+ if (canCastToString(value)) {
+ context.setTags(((String) value).split(","));
+ } else {
+ LOGGER.error("Wrong value of 'jbake-tags'. Expected a String got '{}'", getValueClassName(value));
}
- if (key.equals("jbake-tags")) {
- if (canCastToString(value)) {
- context.setTags(((String) value).split(","));
- } else {
- LOGGER.error("Wrong value of 'jbake-tags'. Expected a String got '{}'", getValueClassName(value));
- }
+ } else {
+ context.getDocumentModel().put(key, value);
+ }
+ }
+
+ private void addIfKeyHasJbakePrefix(ParserContext context, Map.Entry attribute) {
+ String key = attribute.getKey();
+ Object value = attribute.getValue();
+
+ if (hasJBakePrefix(key)) {
+ String pKey = key.substring(6);
+ if(canCastToString(value)) {
+ storeHeaderValue(pKey, (String) value, context.getDocumentModel());
} else {
- documentModel.put(key, attributes.get(key));
+ context.getDocumentModel().put(pKey, value);
}
}
}
+ private void convertAndSetIfDate(ParserContext context, Map.Entry attribute) {
+ String key = attribute.getKey();
+ Object value = attribute.getValue();
+
+ if (hasRevdate(key) && canCastToString(value)) {
+
+ String dateFormat = context.getConfig().getDateFormat();
+ DateFormat df = new SimpleDateFormat(dateFormat);
+ try {
+ Date date = df.parse((String) value);
+ context.setDate(date);
+ } catch (ParseException e) {
+ LOGGER.error("Unable to parse revdate. Expected {}", dateFormat, e);
+ }
+ }
+ }
+
+ private void setDocumentTitleIfNotPresentInHeader(ParserContext context, DocumentHeader header) {
+ if (header.getDocumentTitle() != null) {
+ context.getDocumentModel().setTitle(header.getDocumentTitle().getCombined());
+ }
+ }
+
private boolean canCastToString(Object value) {
return value instanceof String;
}
diff --git a/jbake-core/src/main/java/org/jbake/parser/Engines.java b/jbake-core/src/main/java/org/jbake/parser/Engines.java
index 4bccb245b..49e729cc0 100644
--- a/jbake-core/src/main/java/org/jbake/parser/Engines.java
+++ b/jbake-core/src/main/java/org/jbake/parser/Engines.java
@@ -4,6 +4,7 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Collections;
@@ -31,17 +32,17 @@
*
Markup engines are singletons, so are typically used to initialize the underlying renderning engines. They
* must not store specific information of a currently processed file (use {@link ParserContext the parser context}
* for that).
- *
+ *
* This class loads the engines only if they are found on classpath. If not, the engine is not registered. This allows
* JBake to support multiple rendering engines without the explicit need to have them on classpath. This is a better
* fit for embedding.
*
* @author Cédric Champeau
- *
*/
public class Engines {
private static final Logger LOGGER = LoggerFactory.getLogger(Engines.class);
private static final Engines INSTANCE;
+ public static final String PROPERTIES = "META-INF/org.jbake.parser.MarkupEngines.properties";
private final Map parsers;
@@ -105,15 +106,17 @@ private static ParserEngine tryLoadEngine(String engineClassName) {
private static void loadEngines() {
try {
ClassLoader cl = Engines.class.getClassLoader();
- Enumeration resources = cl.getResources("META-INF/org.jbake.parser.MarkupEngines.properties");
+ Enumeration resources = cl.getResources(PROPERTIES);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
- Properties props = new Properties();
- props.load(url.openStream());
- for (Map.Entry
*
The descriptor file must be found in META-INF directory and named
- * org.jbake.template.ModelExtractors.properties. The format of the file is easy:
+ * org.jbake.engine.ModelExtractors.properties. The format of the file is easy:
where the key is the class of the extractor (must implement {@link ModelExtractor} and the value is the key
* by which values are to be accessed in model.
@@ -27,7 +34,7 @@
*/
public class ModelExtractors extends DescriptorFileEngineLoader> {
- private static final String PROPERTIES = "META-INF/org.jbake.template.ModelExtractors.properties";
+ private static final String PROPERTIES = "META-INF/org.jbake.engine.ModelExtractors.properties";
private static class Loader {
private static final ModelExtractors INSTANCE = new ModelExtractors();
@@ -42,11 +49,21 @@ private ModelExtractors() {
loadEngines();
}
+ @Override
+ protected ModelExtractor> getErrorEngine(String engineClassName) {
+ return new UnknownModelExtractor(engineClassName);
+ }
+
@Override
protected String descriptorFile() {
return PROPERTIES;
}
+ @Override
+ protected @NotNull ModelExtractor> createInstance(Context context) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ return (ModelExtractor>) context.engineClass().getDeclaredConstructor().newInstance();
+ }
+
public T extractAndTransform(ContentStore db, String key, TemplateModel map, TemplateEngineAdapter adapter) throws NoModelExtractorException {
if (supportsExtension(key)) {
Object extractedValue = get(key).get(db, map, key);
@@ -59,7 +76,7 @@ public T extractAndTransform(ContentStore db, String key, TemplateModel map,
public void registerExtractorsForCustomTypes(String docType) {
String pluralizedDoctype = DocumentTypeUtils.pluralize(docType);
if (!supportsExtension(pluralizedDoctype)) {
- LOGGER.info("register new extractors for document type: {}", docType);
+ logger.info("register new extractors for document type: {}", docType);
registerEngine(pluralizedDoctype, new TypedDocumentsExtractor());
registerEngine("published_" + pluralizedDoctype, new PublishedCustomExtractor(docType));
}
diff --git a/jbake-core/src/main/java/org/jbake/engine/TemplateEngines.java b/jbake-core/src/main/java/org/jbake/engine/TemplateEngines.java
new file mode 100644
index 000000000..9d9fa1d09
--- /dev/null
+++ b/jbake-core/src/main/java/org/jbake/engine/TemplateEngines.java
@@ -0,0 +1,67 @@
+package org.jbake.engine;
+
+import org.jbake.app.ContentStore;
+import org.jbake.app.configuration.JBakeConfiguration;
+import org.jbake.template.AbstractTemplateEngine;
+import org.jbake.template.TemplateEngine;
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Set;
+
+
+/**
+ *
+ * A singleton class giving access to rendering engines. Rendering engines are loaded based on classpath. New
+ * rendering may be registered either at runtime (not recommanded) or by putting a descriptor file on classpath
+ * (recommanded).
+ *
The descriptor file must be found in META-INF directory and named
+ * org.jbake.engine.TemplateEngines.properties. The format of the file is easy:
where the key is the class of the engine (must extend {@link AbstractTemplateEngine} and have
+ * a 4-arg constructor and the value is a comma-separated list of file extensions that this engine is capable
+ * of proceeding.
+ *
Rendering engines are singletons, so are typically used to initialize the underlying template engines.
+ *
+ * This class loads the engines only if they are found on classpath. If not, the engine is not registered. This allows
+ * JBake to support multiple rendering engines without the explicit need to have them on classpath. This is a better fit
+ * for embedding.
+ *
+ *
+ * @author Cédric Champeau
+ */
+public class TemplateEngines extends DescriptorFileEngineLoader {
+
+ public static final String PROPERTIES = "META-INF/org.jbake.engine.TemplateEngines.properties";
+
+ public TemplateEngines(final JBakeConfiguration config, final ContentStore db) {
+ context.addConfig(config);
+ context.addDb(db);
+ loadEngines();
+ }
+
+ public Set getRecognizedExtensions() {
+ return keySet();
+ }
+
+ public TemplateEngine getEngine(String fileExtension) {
+ return get(fileExtension);
+ }
+
+ @Override
+ protected @NotNull TemplateEngine createInstance(Context context) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ Constructor> ctor = context.engineClass().getConstructor(JBakeConfiguration.class, ContentStore.class);
+ return (TemplateEngine) ctor.newInstance(context.config(), context.db());
+ }
+
+ @Override
+ protected TemplateEngine getErrorEngine(String engineClassName) {
+ return null;
+ }
+
+ @Override
+ protected String descriptorFile() {
+ return PROPERTIES;
+ }
+}
diff --git a/jbake-core/src/main/java/org/jbake/app/JBakeException.java b/jbake-core/src/main/java/org/jbake/exception/JBakeException.java
similarity index 96%
rename from jbake-core/src/main/java/org/jbake/app/JBakeException.java
rename to jbake-core/src/main/java/org/jbake/exception/JBakeException.java
index f3e858a4a..d87e49696 100644
--- a/jbake-core/src/main/java/org/jbake/app/JBakeException.java
+++ b/jbake-core/src/main/java/org/jbake/exception/JBakeException.java
@@ -1,4 +1,4 @@
-package org.jbake.app;
+package org.jbake.exception;
import org.jbake.launcher.SystemExit;
diff --git a/jbake-core/src/main/java/org/jbake/template/NoModelExtractorException.java b/jbake-core/src/main/java/org/jbake/exception/NoModelExtractorException.java
similarity index 92%
rename from jbake-core/src/main/java/org/jbake/template/NoModelExtractorException.java
rename to jbake-core/src/main/java/org/jbake/exception/NoModelExtractorException.java
index 51727a762..5dbcac429 100644
--- a/jbake-core/src/main/java/org/jbake/template/NoModelExtractorException.java
+++ b/jbake-core/src/main/java/org/jbake/exception/NoModelExtractorException.java
@@ -1,4 +1,4 @@
-package org.jbake.template;
+package org.jbake.exception;
public class NoModelExtractorException extends RenderingException {
diff --git a/jbake-core/src/main/java/org/jbake/template/RenderingException.java b/jbake-core/src/main/java/org/jbake/exception/RenderingException.java
similarity index 93%
rename from jbake-core/src/main/java/org/jbake/template/RenderingException.java
rename to jbake-core/src/main/java/org/jbake/exception/RenderingException.java
index 5b0bb3444..7a9ec6e48 100644
--- a/jbake-core/src/main/java/org/jbake/template/RenderingException.java
+++ b/jbake-core/src/main/java/org/jbake/exception/RenderingException.java
@@ -1,4 +1,4 @@
-package org.jbake.template;
+package org.jbake.exception;
/**
* Thrown if rendering of a document failed.
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 536625c98..ec2f5ac56 100644
--- a/jbake-core/src/main/java/org/jbake/launcher/Baker.java
+++ b/jbake-core/src/main/java/org/jbake/launcher/Baker.java
@@ -1,10 +1,10 @@
package org.jbake.launcher;
import org.apache.commons.configuration2.CompositeConfiguration;
-import org.jbake.app.JBakeException;
import org.jbake.app.Oven;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
+import org.jbake.exception.JBakeException;
import java.text.MessageFormat;
import java.util.List;
diff --git a/jbake-core/src/main/java/org/jbake/launcher/JettyServer.java b/jbake-core/src/main/java/org/jbake/launcher/JettyServer.java
index cff105932..a57627f0a 100644
--- a/jbake-core/src/main/java/org/jbake/launcher/JettyServer.java
+++ b/jbake-core/src/main/java/org/jbake/launcher/JettyServer.java
@@ -7,8 +7,8 @@
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
-import org.jbake.app.JBakeException;
import org.jbake.app.configuration.JBakeConfiguration;
+import org.jbake.exception.JBakeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 83d38a15d..0714bdd05 100644
--- a/jbake-core/src/main/java/org/jbake/launcher/Main.java
+++ b/jbake-core/src/main/java/org/jbake/launcher/Main.java
@@ -1,9 +1,9 @@
package org.jbake.launcher;
import org.jbake.app.FileUtil;
-import org.jbake.app.JBakeException;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
+import org.jbake.exception.JBakeException;
import org.jbake.util.ConfigurationPrinter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java b/jbake-core/src/main/java/org/jbake/model/TemplateModel.java
similarity index 94%
rename from jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java
rename to jbake-core/src/main/java/org/jbake/model/TemplateModel.java
index 87b6eb9e2..539b00d57 100644
--- a/jbake-core/src/main/java/org/jbake/template/model/TemplateModel.java
+++ b/jbake-core/src/main/java/org/jbake/model/TemplateModel.java
@@ -1,9 +1,6 @@
-package org.jbake.template.model;
+package org.jbake.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.io.Writer;
diff --git a/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java b/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java
index 36af41108..ed66d8685 100644
--- a/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/ArchiveRenderer.java
@@ -5,7 +5,7 @@
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java
index 742cc473b..f198bc41f 100644
--- a/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/DocumentsRenderer.java
@@ -5,9 +5,9 @@
import org.jbake.app.DocumentList;
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
+import org.jbake.exception.RenderingException;
import org.jbake.model.DocumentModel;
import org.jbake.model.ModelAttributes;
-import org.jbake.template.RenderingException;
import java.io.File;
import java.util.LinkedList;
diff --git a/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java b/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java
index fd2eb4a57..2b5e8ee6e 100644
--- a/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/Error404Renderer.java
@@ -1,13 +1,13 @@
package org.jbake.render;
-import java.io.File;
-
import org.apache.commons.configuration2.CompositeConfiguration;
import org.jbake.app.ContentStore;
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
+
+import java.io.File;
public class Error404Renderer implements RenderingTool {
diff --git a/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java b/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java
index cd4ffcbeb..d705b44eb 100644
--- a/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/FeedRenderer.java
@@ -5,7 +5,7 @@
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java b/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java
index b5b05a870..a3b435b0d 100644
--- a/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/IndexRenderer.java
@@ -5,7 +5,7 @@
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/render/RenderingTool.java b/jbake-core/src/main/java/org/jbake/render/RenderingTool.java
index 3417406b8..7a891de6e 100644
--- a/jbake-core/src/main/java/org/jbake/render/RenderingTool.java
+++ b/jbake-core/src/main/java/org/jbake/render/RenderingTool.java
@@ -4,7 +4,7 @@
import org.jbake.app.ContentStore;
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java b/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java
index 3d3525fa3..1471f99b2 100644
--- a/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/SitemapRenderer.java
@@ -5,7 +5,7 @@
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java b/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java
index 41b70bc1b..808763412 100644
--- a/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java
+++ b/jbake-core/src/main/java/org/jbake/render/TagsRenderer.java
@@ -5,7 +5,7 @@
import org.jbake.app.Renderer;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.RenderingException;
+import org.jbake.exception.RenderingException;
import java.io.File;
diff --git a/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/AbstractTemplateEngine.java
index 479f0a127..20be8ed47 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,8 @@
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
import org.jbake.app.configuration.JBakeConfigurationFactory;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.engine.ModelExtractors;
+import org.jbake.model.TemplateModel;
import java.io.File;
import java.io.Writer;
@@ -27,7 +28,7 @@
*
* @author Cédric Champeau
*/
-public abstract class AbstractTemplateEngine {
+public abstract class AbstractTemplateEngine implements TemplateEngine {
protected static ModelExtractors extractors = ModelExtractors.getInstance();
protected final JBakeConfiguration config;
@@ -46,5 +47,4 @@ protected AbstractTemplateEngine(final JBakeConfiguration config, final ContentS
this.db = db;
}
- 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 2ac880392..e9b4254ea 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,9 @@
import org.jbake.app.ContentStore;
import org.jbake.app.FileUtil;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.engine.TemplateEngines;
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +66,7 @@ public void renderDocument(final TemplateModel model, final String templateName,
}
}
String ext = FileUtil.fileExt(theTemplateName);
- AbstractTemplateEngine engine = renderers.getEngine(ext);
+ TemplateEngine engine = renderers.getEngine(ext);
if (engine != null) {
engine.renderDocument(model, theTemplateName, writer);
} else {
diff --git a/jbake-core/src/main/java/org/jbake/template/DescriptorFileEngineLoader.java b/jbake-core/src/main/java/org/jbake/template/DescriptorFileEngineLoader.java
deleted file mode 100644
index f0fc592fc..000000000
--- a/jbake-core/src/main/java/org/jbake/template/DescriptorFileEngineLoader.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.jbake.template;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeMap;
-
-public abstract class DescriptorFileEngineLoader {
- protected static final Logger LOGGER = LoggerFactory.getLogger(DescriptorFileEngineLoader.class);
- private final Map classes;
-
- protected DescriptorFileEngineLoader() {
- classes = new TreeMap<>();
- }
-
- /**
- * This method is used to search for a specific class, telling if loading the engine would succeed. This is
- * typically used to avoid loading optional modules.
- *
- * @param engineClassName engine class, used both as a hint to find it and to create the engine itself. @return null if the engine is not available, an instance of the engine otherwise
- */
- @SuppressWarnings("unchecked")
- protected T tryLoadEngine(String engineClassName) {
- try {
- Class> engineClass = Class.forName(engineClassName, false, DescriptorFileEngineLoader.class.getClassLoader());
- return (T) engineClass.getDeclaredConstructor().newInstance();
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoClassDefFoundError | NoSuchMethodException | InvocationTargetException e) {
- return null;
- } // a dependency of the engine may not be found on classpath
-
- }
-
- protected void registerEngine(String key, T extractor) {
- T old = classes.put(key, extractor);
- if (old != null) {
- LOGGER.warn("Override detected. Registered a model extractor for key [.{}] but another one was already defined: {}", key, old);
- }
- }
-
- /**
- * This method is used internally to load markup engines. Markup engines are found using descriptor files on
- * classpath, so adding an engine is as easy as adding a jar on classpath with the descriptor file included.
- */
- protected void loadEngines() {
- try {
- ClassLoader cl = DescriptorFileEngineLoader.class.getClassLoader();
- Enumeration resources = cl.getResources(descriptorFile());
- while (resources.hasMoreElements()) {
- URL url = resources.nextElement();
- try (InputStream is = url.openStream()) {
- Properties props = new Properties();
- props.load(is);
- for (Map.Entry entry : props.entrySet()) {
- String className = (String) entry.getKey();
- String[] extensions = ((String) entry.getValue()).split(",");
- loadAndRegisterEngine(className, extensions);
- }
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- protected void loadAndRegisterEngine(String className, String... extensions) {
- T engine = tryLoadEngine(className);
- if (engine != null) {
- for (String extension : extensions) {
- registerEngine(extension, engine);
- }
- }
- }
-
- protected abstract String descriptorFile();
-
- /**
- * @param key A key a {@link ModelExtractor} is registered with
- * @return true if key is registered
- * @see Map#containsKey(Object)
- */
- public boolean supportsExtension(String key) {
- return classes.containsKey(key);
- }
-
- /**
- * @return A @{@link Set} of all known keys a @{@link ModelExtractor} is registered with
- * @see Map#keySet()
- */
- public Set keySet() {
- return classes.keySet();
- }
-
- protected T get(String extension) {
- return classes.get(extension);
- }
-
- public void reset() {
- classes.clear();
- loadEngines();
- }
-}
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 8578999c4..253b79665 100644
--- a/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/FreemarkerTemplateEngine.java
@@ -17,8 +17,10 @@
import org.apache.commons.configuration2.CompositeConfiguration;
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
+import org.jbake.exception.NoModelExtractorException;
+import org.jbake.exception.RenderingException;
import org.jbake.model.ModelAttributes;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.model.TemplateModel;
import org.jbake.util.DataFileUtil;
import java.io.File;
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 f64094550..8e05a23e9 100644
--- a/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/GroovyMarkupTemplateEngine.java
@@ -7,7 +7,9 @@
import org.apache.commons.configuration2.CompositeConfiguration;
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.exception.NoModelExtractorException;
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
import java.io.File;
import java.io.Writer;
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 caad683e6..53f9a51b0 100644
--- a/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/GroovyTemplateEngine.java
@@ -10,7 +10,9 @@
import org.codehaus.groovy.runtime.MethodClosure;
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.exception.NoModelExtractorException;
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
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 4129f3f9e..9b855ad22 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,9 @@
import org.apache.commons.lang.StringEscapeUtils;
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.exception.NoModelExtractorException;
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
import java.io.File;
import java.io.IOException;
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 d684d4ee7..8cb3876e4 100644
--- a/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java
+++ b/jbake-core/src/main/java/org/jbake/template/PebbleTemplateEngine.java
@@ -7,7 +7,9 @@
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import org.jbake.app.ContentStore;
import org.jbake.app.configuration.JBakeConfiguration;
-import org.jbake.template.model.TemplateModel;
+import org.jbake.exception.NoModelExtractorException;
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
import java.io.IOException;
import java.io.Writer;
diff --git a/jbake-core/src/main/java/org/jbake/template/TemplateEngine.java b/jbake-core/src/main/java/org/jbake/template/TemplateEngine.java
new file mode 100644
index 000000000..0b4afdf41
--- /dev/null
+++ b/jbake-core/src/main/java/org/jbake/template/TemplateEngine.java
@@ -0,0 +1,10 @@
+package org.jbake.template;
+
+import org.jbake.exception.RenderingException;
+import org.jbake.model.TemplateModel;
+
+import java.io.Writer;
+
+public interface TemplateEngine {
+ void renderDocument(TemplateModel model, String templateName, Writer writer) throws RenderingException;
+}
diff --git a/jbake-core/src/main/java/org/jbake/template/TemplateEngines.java b/jbake-core/src/main/java/org/jbake/template/TemplateEngines.java
deleted file mode 100644
index d7c46864b..000000000
--- a/jbake-core/src/main/java/org/jbake/template/TemplateEngines.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.jbake.template;
-
-import org.jbake.app.ContentStore;
-import org.jbake.app.configuration.JBakeConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-
-/**
- *
- * A singleton class giving access to rendering engines. Rendering engines are loaded based on classpath. New
- * rendering may be registered either at runtime (not recommanded) or by putting a descriptor file on classpath
- * (recommanded).
- *
The descriptor file must be found in META-INF directory and named
- * org.jbake.template.TemplateEngines.properties. The format of the file is easy:
where the key is the class of the engine (must extend {@link AbstractTemplateEngine} and have
- * a 4-arg constructor and the value is a comma-separated list of file extensions that this engine is capable
- * of proceeding.
- *
Rendering engines are singletons, so are typically used to initialize the underlying template engines.
- *
- * This class loads the engines only if they are found on classpath. If not, the engine is not registered. This allows
- * JBake to support multiple rendering engines without the explicit need to have them on classpath. This is a better fit
- * for embedding.
- *