package com.github.mustachejava;
import java.io.*;
import java.util.
ArrayList;
import java.util.
List;
/**
* Mustache.java factory with a fallback mechanism for locating resources.
*
* (Some parts are based on DefaultMustacheFactory code that is Copyright 2010 RightTime, Inc.)
*
* @author gw0 [http://gw.tnode.com/] <gw.2012@tnode.com>
*/
public class
FallbackMustacheFactory extends
DefaultMustacheFactory {
/**
* List of fallback resource roots to search through.
*/
private
Object[]
resourceRoots;
/**
* Simple constructor for a fallback Mustache.java factory.
*
* @param resourceRoot normal resource root
* @param fallbackRoot fallback alternative root
*/
public
FallbackMustacheFactory(
String resourceRoot,
String fallbackRoot) {
this(new
Object[]{
resourceRoot,
fallbackRoot});
}
/**
* Simple constructor for a fallback Mustache.java factory.
*
* @param fileRoot normal resource root
* @param fallbackRoot fallback alternative root
*/
public
FallbackMustacheFactory(
File fileRoot,
File fallbackRoot) {
this(new
Object[]{
fileRoot,
fallbackRoot});
}
/**
* Generic constructor for a fallback Mustache.java factory.
*
* @param resourceRoots array of fallback resource roots as String or File
*/
@
SuppressWarnings("StatementWithEmptyBody")
public
FallbackMustacheFactory(
Object...
resourceRoots) {
super();
List<
Object>
newResourceRoots = new
ArrayList<>();
for (
Object resourceObj :
resourceRoots) {
if (
resourceObj instanceof
String) { // for String
String resourceRoot = (
String)
resourceObj;
if (!
resourceRoot.
endsWith("/"))
resourceRoot += "/";
newResourceRoots.
add(
resourceRoot);
} else if (
resourceObj instanceof
File) { // for File
File fileRoot = (
File)
resourceObj;
if (!
fileRoot.
exists()) {
throw new
MustacheException(
fileRoot + " does not exist");
}
if (!
fileRoot.
isDirectory()) {
throw new
MustacheException(
fileRoot + " is not a directory");
}
newResourceRoots.
add(
resourceObj);
} else if (
resourceObj == null) {
// for null
} else {
throw new
MustacheException("Invalid constructor parameter: " +
resourceObj.
toString());
}
}
this.
resourceRoots =
newResourceRoots.
toArray();
}
/**
* Return a reader for accessing resource files.
*
* @param resourceName resource name relative to one of the fallback resource roots
* @return resource file reader
*/
@
Override
public
Reader getReader(
String resourceName) {
Exception lastException = null;
for (
Object resourceObj : this.
resourceRoots) {
try {
InputStream is = null;
if (
resourceObj instanceof
String) { // class resource loader only for String
String resourceRoot = (
String)
resourceObj;
ClassLoader ccl =
Thread.
currentThread().
getContextClassLoader();
is =
ccl.
getResourceAsStream(
resourceRoot +
resourceName);
}
if (
is == null) {
File file;
if (
resourceObj instanceof
String) { // for String
file = new
File((
String)
resourceObj,
resourceName);
} else if (
resourceObj instanceof
File) { // for File
file = new
File((
File)
resourceObj,
resourceName);
} else { // for null
file = new
File(
resourceName);
}
if (
file.
exists() &&
file.
isFile()) {
try {
is = new
FileInputStream(
file);
} catch (
FileNotFoundException e) {
throw new
MustacheException("Found file, could not open: " +
file,
e);
}
}
}
if (
is == null) {
throw new
MustacheNotFoundException(
resourceName);
} else {
return new
BufferedReader(new
InputStreamReader(
is, "UTF-8"));
}
} catch (
Exception e) {
lastException =
e;
}
}
throw new
MustacheNotFoundException(
resourceName,
lastException);
}
}