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; } }