/** Create singleton template for use with dictionary values */
 public ST createSingleton(Token templateToken) {
   String template;
   if (templateToken.getType() == GroupParser.BIGSTRING) {
     template = Misc.strip(templateToken.getText(), 2);
   } else {
     template = Misc.strip(templateToken.getText(), 1);
   }
   CompiledST impl = compile(getFileName(), null, null, template, templateToken);
   ST st = createStringTemplateInternally(impl);
   st.groupThatCreatedThisInstance = this;
   st.impl.hasFormalArgs = false;
   st.impl.name = ST.UNKNOWN_NAME;
   st.impl.defineImplicitlyDefinedTemplates(this);
   return st;
 }
 @Override
 public void importTemplates(Token fileNameToken) {
   String fileName = fileNameToken.getText();
   // do nothing upon syntax error
   if (fileName == null || fileName.equals("<missing STRING>")) {
     return;
   }
   fileName = Misc.strip(fileName, 1);
   STGroup g = null;
   try {
     if (fProvider.templateExists(fileName)) {
       g = new STGroup();
       g.setListener(this.getListener());
       InputStream input = fProvider.getTemplate(fileName);
       ANTLRInputStream templateStream = new ANTLRInputStream(input);
       templateStream.name = fileName;
       CompiledST code = g.loadTemplateFile("", fileName, templateStream);
       if (code == null) {
         g = null;
       }
     }
   } catch (IOException ioe) {
     errMgr.internalError(null, "can't read from " + fileName, ioe);
     g = null;
   }
   if (g == null) {
     errMgr.compileTimeError(ErrorType.CANT_IMPORT, null, fileNameToken, fileName);
   } else {
     importTemplates(g);
   }
 }
  public CompiledST defineTemplate(
      String templateName,
      Token nameT,
      List<FormalArgument> args,
      String template,
      Token templateToken) {
    if (templateName == null || templateName.length() == 0) {
      throw new IllegalArgumentException("empty template name");
    }
    if (templateName.indexOf('.') >= 0) {
      throw new IllegalArgumentException("cannot have '.' in template names");
    }
    template = Misc.trimOneStartingNewline(template);
    template = Misc.trimOneTrailingNewline(template);
    // compile, passing in templateName as enclosing name for any embedded regions
    CompiledST code = compile(getFileName(), templateName, args, template, templateToken);
    code.name = templateName;
    rawDefineTemplate(templateName, code, nameT);
    code.defineArgDefaultValueTemplates(this);
    code.defineImplicitlyDefinedTemplates(this); // define any anonymous subtemplates

    return code;
  }
 /**
  * Load a template from dir or group file. Group file is given precedence over dir with same name.
  */
 @Override
 protected CompiledST load(String name) {
   String parent = Misc.getPrefix(name);
   try {
     if (fProvider.templateExists(parent + ".stg")) {
       loadGroupFile(parent, parent + ".stg");
     } else if (fProvider.templateExists(name + ".st")) {
       loadTemplateFile(parent, name + ".st");
     }
   } catch (IOException ioe) {
     errMgr.internalError(null, "can't load template file " + name, ioe);
   }
   return rawGetTemplate(name);
 }
 /** Load template stream into this group */
 public CompiledST loadTemplateFile(String prefix, String fileName, CharStream templateStream) {
   GroupLexer lexer = new GroupLexer(templateStream);
   CommonTokenStream tokens = new CommonTokenStream(lexer);
   GroupParser parser = new GroupParser(tokens);
   parser.group = this;
   lexer.group = this;
   try {
     parser.templateDef(prefix);
   } catch (RecognitionException re) {
     errMgr.groupSyntaxError(ErrorType.SYNTAX_ERROR, fileName, re, re.getMessage());
   }
   String templateName = Misc.getFileNameNoSuffix(fileName);
   if (prefix != null && prefix.length() > 0) templateName = prefix + "/" + templateName;
   return rawGetTemplate(templateName);
 }
  public CompiledST defineRegion(
      String enclosingTemplateName, Token regionT, String template, Token templateToken) {
    String name = regionT.getText();
    template = Misc.trimOneStartingNewline(template);
    template = Misc.trimOneTrailingNewline(template);
    CompiledST code = compile(getFileName(), enclosingTemplateName, null, template, templateToken);
    String mangled = getMangledRegionName(enclosingTemplateName, name);

    if (lookupTemplate(mangled) == null) {
      errMgr.compileTimeError(
          ErrorType.NO_SUCH_REGION, templateToken, regionT, enclosingTemplateName, name);
      return new CompiledST();
    }
    code.name = mangled;
    code.isRegion = true;
    code.regionDefType = ST.RegionType.EXPLICIT;
    code.templateDefStartToken = regionT;

    rawDefineTemplate(mangled, code, regionT);
    code.defineArgDefaultValueTemplates(this);
    code.defineImplicitlyDefinedTemplates(this);

    return code;
  }
 public String show() {
   StringBuilder buf = new StringBuilder();
   if (imports != null) buf.append(" : " + imports);
   for (String name : templates.keySet()) {
     CompiledST c = rawGetTemplate(name);
     if (c.isAnonSubtemplate || c == NOT_FOUND_ST) continue;
     int slash = name.lastIndexOf('/');
     name = name.substring(slash + 1, name.length());
     buf.append(name);
     buf.append('(');
     if (c.formalArguments != null)
       buf.append(Misc.join(c.formalArguments.values().iterator(), ","));
     buf.append(')');
     buf.append(" ::= <<" + Misc.newline);
     buf.append(c.template + Misc.newline);
     buf.append(">>" + Misc.newline);
   }
   return buf.toString();
 }
  /**
   * Import template files, directories, and group files. Priority is given to templates defined in
   * the current group; this, in effect, provides inheritance. Polymorphism is in effect so that if
   * an inherited template references template t() then we search for t() in the subgroup first.
   *
   * <p>If you specify an absolute file name or directory name, the import statement uses that
   * directly. If it is not an absolute path, we look that entity up in the directory holding the
   * group that initiates the import. If file or directory is not in that directory, then we load
   * using the classpath.
   *
   * <p>Templates are loaded on-demand from import dirs. Imported groups are loaded on-demand when
   * searching for a template.
   *
   * <p>The listener of this group is passed to the import group so errors found while loading
   * imported element are sent to listener of this group.
   */
  public void importTemplates(Token fileNameToken) {
    String fileName = fileNameToken.getText();
    // do nothing upon syntax error
    if (fileName == null || fileName.equals("<missing STRING>")) return;
    fileName = Misc.strip(fileName, 1);

    // System.out.println("import "+fileName);
    boolean isGroupFile = fileName.endsWith(".stg");
    boolean isTemplateFile = fileName.endsWith(".st");
    boolean isGroupDir = !(isGroupFile || isTemplateFile);

    STGroup g = null;

    File f = new File(fileName);
    if (f.isAbsolute()) { // load directly if absolute
      if (isTemplateFile) {
        g = new STGroup();
        g.setListener(this.getListener());
        g.loadAbsoluteTemplateFile(fileName);
      } else if (isGroupFile) {
        g = new STGroupFile(fileName, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      } else if (isGroupDir) {
        g = new STGroupDir(fileName, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      }
      importTemplates(g);
      return;
    }

    // it's a relative name; search path is working dir, g.stg's dir, CLASSPATH
    URL thisRoot = getRootDirURL();
    URL fileUnderRoot = null;
    //		System.out.println("thisRoot="+thisRoot);
    try {
      fileUnderRoot = new URL(thisRoot + "/" + fileName);
    } catch (MalformedURLException mfe) {
      errMgr.internalError(null, "can't build URL for " + thisRoot + "/" + fileName, mfe);
      return;
    }
    if (isTemplateFile) {
      g = new STGroup();
      g.setListener(this.getListener());
      URL fileURL;
      if (Misc.urlExists(fileUnderRoot)) fileURL = fileUnderRoot;
      else fileURL = getURL(fileName); // try CLASSPATH
      if (fileURL != null) {
        try {
          InputStream s = fileURL.openStream();
          ANTLRInputStream templateStream = new ANTLRInputStream(s);
          templateStream.name = fileName;
          CompiledST code = g.loadTemplateFile("", fileName, templateStream);
          if (code == null) g = null;
        } catch (IOException ioe) {
          errMgr.internalError(null, "can't read from " + fileURL, ioe);
          g = null;
        }
      } else {
        g = null;
      }
    } else if (isGroupFile) {
      // System.out.println("look for fileUnderRoot: "+fileUnderRoot);
      if (Misc.urlExists(fileUnderRoot)) {
        g = new STGroupFile(fileUnderRoot, encoding, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      } else {
        g = new STGroupFile(fileName, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      }
    } else if (isGroupDir) {
      //			System.out.println("try dir "+fileUnderRoot);
      if (Misc.urlExists(fileUnderRoot)) {
        g = new STGroupDir(fileUnderRoot, encoding, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      } else {
        // try in CLASSPATH
        //				System.out.println("try dir in CLASSPATH "+fileName);
        g = new STGroupDir(fileName, delimiterStartChar, delimiterStopChar);
        g.setListener(this.getListener());
      }
    }

    if (g == null) {
      errMgr.compileTimeError(ErrorType.CANT_IMPORT, null, fileNameToken, fileName);
    } else {
      importTemplates(g);
    }
  }