package nebula.simpletemplate;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.Token;
import org.stringtemplate.v4.compiler.STException;
/**
* A directory or directory tree full of templates and/or group files. We load
* files on-demand. Dir search path: current working dir then CLASSPATH (as a
* resource). Do not look for templates outside of this dir subtree (except via
* imports).
*/
public class STGroupDir extends STGroup {
public String groupDirName;
public URL root;
public STGroupDir(String dirName) {
this(dirName, '<', '>');
}
public STGroupDir(String dirName, char delimiterStartChar, char delimiterStopChar) {
super(delimiterStartChar, delimiterStopChar);
this.groupDirName = dirName;
File dir = new File(dirName);
if (dir.exists() && dir.isDirectory()) {
// we found the directory and it'll be file based
try {
root = dir.toURI().toURL();
} catch (MalformedURLException e) {
throw new STException("can't load dir " + dirName, e);
}
if (verbose) System.out.println("STGroupDir(" + dirName + ") found at " + root);
} else {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
root = cl.getResource(dirName);
if (root == null) {
cl = this.getClass().getClassLoader();
root = cl.getResource(dirName);
}
if (verbose) System.out.println("STGroupDir(" + dirName + ") found via CLASSPATH at " + root);
if (root == null) {
throw new IllegalArgumentException("No such directory: " + dirName);
}
}
}
public STGroupDir(String dirName, String encoding) {
this(dirName, encoding, '<', '>');
}
public STGroupDir(String dirName, String encoding, char delimiterStartChar, char delimiterStopChar) {
this(dirName, delimiterStartChar, delimiterStopChar);
this.encoding = encoding;
}
public STGroupDir(URL root, String encoding, char delimiterStartChar, char delimiterStopChar) {
super(delimiterStartChar, delimiterStopChar);
this.groupDirName = new File(root.getFile()).getName();
this.root = root;
this.encoding = encoding;
}
@Override
public void importTemplates(Token fileNameToken) {
String msg = "import illegal in group files embedded in STGroupDirs; " + "import " + fileNameToken.getText() + " in STGroupDir " + this.getName();
throw new UnsupportedOperationException(msg);
}
/**
* Load a template from directory or group file. Group file is given
* precedence over directory with same name. {@code name} is always
* fully-qualified.
*/
@Override
protected CompiledST load(String name) {
if (verbose) System.out.println("STGroupDir.load(" + name + ")");
String parent = Misc.getParent(name); // must have parent; it's
// fully-qualified
String prefix = Misc.getPrefix(name);
// if (parent.isEmpty()) {
// // no need to check for a group file as name has no parent
// return loadTemplateFile("/", name+TEMPLATE_FILE_EXTENSION); // load
// t.st file
// }
URL groupFileURL = null;
try { // see if parent of template name is a group file
groupFileURL = new URL(root + parent + GROUP_FILE_EXTENSION);
} catch (MalformedURLException e) {
errMgr.internalError(null, "bad URL: " + root + parent + GROUP_FILE_EXTENSION, e);
return null;
}
InputStream is = null;
try {
is = groupFileURL.openStream();
} catch (IOException ioe) {
// must not be in a group file
String unqualifiedName = Misc.getFileName(name);
return loadTemplateFile(prefix, unqualifiedName + TEMPLATE_FILE_EXTENSION); // load
// t.st
// file
} finally { // clean up
try {
if (is != null) is.close();
} catch (IOException ioe) {
errMgr.internalError(null, "can't close template file stream " + name, ioe);
}
}
loadGroupFile(prefix, root + parent + GROUP_FILE_EXTENSION);
return rawGetTemplate(name);
}
/** Load .st as relative file name relative to root by {@code prefix}. */
public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName) {
if (verbose) System.out.println("loadTemplateFile(" + unqualifiedFileName + ") in groupdir " + "from " + root + " prefix=" + prefix);
URL f = null;
try {
f = new URL(root + prefix + unqualifiedFileName);
} catch (MalformedURLException me) {
// errMgr.runTimeError(null, null, ErrorType.INVALID_TEMPLATE_NAME,
// me, root + unqualifiedFileName);
return null;
}
ANTLRInputStream fs;
try {
fs = new ANTLRInputStream(f.openStream(), encoding);
fs.name = unqualifiedFileName;
} catch (IOException ioe) {
if (verbose) System.out.println(root + "/" + unqualifiedFileName + " doesn't exist");
// errMgr.IOError(null, ErrorType.NO_SUCH_TEMPLATE, ioe,
// unqualifiedFileName);
return null;
}
return loadTemplateFile(prefix, unqualifiedFileName, fs);
}
@Override
public String getName() {
return groupDirName;
}
@Override
public String getFileName() {
return root.getFile();
}
@Override
public URL getRootDirURL() {
return root;
}
}