/* * This software is distributed under the terms of the FSF * Gnu Lesser General Public License (see lgpl.txt). * * This program is distributed WITHOUT ANY WARRANTY. See the * GNU General Public License for more details. */ package com.scooterframework.tools.common; import java.io.File; import java.util.Map; import org.antlr.stringtemplate.StringTemplate; import com.scooterframework.common.util.Util; /** * The is the super class of all generator classes. * * @author (Fei) John Chen */ public abstract class GeneratorImpl implements Generator { public static final String DIRECTORY_NAME_SRC = "src"; public static final String DIRECTORY_NAME_TEST = "test"; public static final String FILE_EXTENSION_JAVA = ".java"; public static final String FILE_EXTENSION_JSP = ".jsp"; public static final String FILE_EXTENSION_PROPERTIES = ".properties"; public static final String FILE_EXTENSION_YAML = ".yaml"; public static final String UNIT_TEST = "unit"; public static final String FUNCTIONAL_TEST = "functional"; private static final String CHANGED_NO = "N"; private static final String CHANGED_YES = "Y"; protected String templateFilePath; private Map<String, String> props; public static final String linebreak = System.getProperty("line.separator", "\r\n"); public GeneratorImpl(Map<String, String> props) { this.props = props; } public GeneratorImpl(String templateFilePath, Map<String, String> props) { this.templateFilePath = templateFilePath; this.props = props; } protected String getProperty(String key) { return props.get(key); } protected String toString(Object o) { return (o != null)?o.toString():null; } protected String getTemplateFileContent(String templateFilePath) { String templateContent = ""; try { templateContent = GeneratorHelper.loadToStringFromFile(templateFilePath); } catch (Exception ex) { throw new IllegalArgumentException("Failed to load template file '" + templateFilePath + "': " + ex.getMessage()); } return templateContent; } /** * Generates code. If the code is already generated, overwrite it. */ public void generate() { generate(true); } /** * Generates code with an option if to overwrite the existing code. * * @param overwrite */ public void generate(boolean overwrite) { generate(getTemplateContent(), getTemplateProperties(), getRootPath(), getRelativePathToOutputFile(), getOutputFileName(), overwrite); } protected String getTemplateContent() { if (templateFilePath == null) throw new IllegalArgumentException( "Template file path is null. Please either provide template " + "file path or implement getTemplateContent() method."); return getTemplateFileContent(templateFilePath); } protected abstract Map<String, ?> getTemplateProperties(); protected abstract String getRootPath(); protected abstract String getRelativePathToOutputFile(); protected abstract String getOutputFileName(); protected void generate(String templateContent, Map<String, ?> props, String rootPath, String relativePathToFile, String outputFileName, boolean overwrite) { String outputFile = (relativePathToFile == null || "".equals(relativePathToFile))? outputFileName:(relativePathToFile + File.separatorChar + outputFileName); String fullPathToOutputFile = rootPath + File.separator + outputFile; generate(templateContent, props, fullPathToOutputFile, overwrite); } protected void generate(String templateContent, Map<String, ?> props, String fullPathToOutputFile, boolean overwrite) { int status = -1; if (templateContent == null) { status = -1; } else { String[] results = processTemplateContent(templateContent, props); String processStatus = results[0]; String processedContent = results[1]; try { status = GeneratorHelper.outputTo(processedContent, fullPathToOutputFile, overwrite); if (CHANGED_YES.equals(processStatus)) { log(Util.decode(status, "-1=exists, 0=create, 1=recreate", " ") + " " + fullPathToOutputFile.replace('\\', '/')); } } catch(Exception ex) { log("ERROR ERROR ERROR in creating file \"" + fullPathToOutputFile + "\": " + ex.getMessage()); } } } protected String[] processTemplateContent(String templateContent, Map<String, ?> props) { String[] results = new String[2]; results[0] = CHANGED_NO; results[1] = templateContent; if (props == null || props.size() == 0 || templateContent == null || "".equals(templateContent)) { return results; } String content = renderContent(templateContent, props); if (!templateContent.equals(content)) { results[0] = CHANGED_YES; } results[1] = content; return results; } protected String renderContent(String originalContent, Map<String, ?> props) { return ("Q".equals(props.get(Generator.TEMPLATE_PARSER_TYPE)))? renderContent_Q(originalContent, props) :renderContent_ST(originalContent, props); } private String renderContent_Q(String originalContent, Map<String, ?> props) { String newContent = originalContent; for (Map.Entry<String, ?> entry : props.entrySet()) { String key = entry.getKey(); String value = escape(entry.getValue()); newContent = newContent.replaceAll("\\Q{" + key + "}", value); } return newContent; } private String renderContent_ST(String originalContent, Map<String, ?> props) { StringTemplate st = new StringTemplate(originalContent); st.setAttributes(props); return st.toString(); } protected void log(String s) { System.out.println(s); } protected boolean isEmpty(String s) { return (s == null || "".equals(s.trim()))?true:false; } public static String escape(Object o) { if (o == null) return null; String s = o.toString(); if (s.indexOf('\\') == -1) return s; return s.replaceAll("\\\\", "\\\\\\\\"); } }