Package cn.org.rapid_framework.generator

Source Code of cn.org.rapid_framework.generator.Generator

package cn.org.rapid_framework.generator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;

import cn.org.rapid_framework.generator.util.FileHelper;
import cn.org.rapid_framework.generator.util.IOHelper;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
*
* @author badqiu
* @email badqiu(a)gmail.com
*/
public class Generator {
  private static final String GENERATOR_INSERT_LOCATION = "generator-insert-location";
  private List templateRootDirs = new ArrayList();
  private String outRootDir;

  String encoding = "UTF-8";
  public Generator() {
  }

  public void setTemplateRootDir(final File templateRootDir) {
    setTemplateRootDirs(new File[]{templateRootDir});
  }

  public void setTemplateRootDirs(final File[] templateRootDirs) {
    this.templateRootDirs = Arrays.asList(templateRootDirs);
  }

  public void addTemplateRootDir(final File f) {
    templateRootDirs.add(f);
  }

  public String getEncoding() {
    return encoding;
  }

  public void setEncoding(final String v) {
    if(v == null) throw new IllegalArgumentException("encoding must be not null");
    this.encoding = v;
  }

  public void setOutRootDir(final String v) {
    if(v == null) throw new IllegalArgumentException("outRootDir must be not null");
    this.outRootDir = v;
  }

  public void generateByModelProvider(final IGeneratorModelProvider modelProvider) throws Exception {
    if(templateRootDirs.size() == 0) throw new IllegalStateException("'templateRootDirs' is empty");

    System.out.println("***************************************************************");
    System.out.println("* BEGIN generate "+modelProvider.getDisaplyText());
    System.out.println("***************************************************************");
    for(int i = 0; i < this.templateRootDirs.size(); i++) {
      final File templateRootDir = (File)templateRootDirs.get(i);
      generateByModelProvider(templateRootDir,modelProvider);
    }
  }

  private void generateByModelProvider(final File templateRootDir, final IGeneratorModelProvider modelProvider) throws Exception {
    if(templateRootDir == null) throw new IllegalStateException("'templateRootDir' must be not null");
    System.out.println("-------------------load template from templateRootDir = '"+templateRootDir.getAbsolutePath()+"'");

    final List templateFiles = new ArrayList();
    FileHelper.listFiles(templateRootDir, templateFiles);

    for(int i = 0; i < templateFiles.size(); i++) {
      final File templateFile = (File)templateFiles.get(i);
      final String templateRelativePath = FileHelper.getRelativePath(templateRootDir, templateFile);
      String outputFilePath = templateRelativePath;
      if(templateFile.isDirectory() || templateFile.isHidden())
        continue;
      if(templateRelativePath.trim().equals(""))
        continue;
      if(templateFile.getName().toLowerCase().endsWith(".include")){
        System.out.println("[skip]\t\t endsWith '.include' template:"+templateRelativePath);
        continue;
      }
      int testExpressionIndex = -1;
      if((testExpressionIndex = templateRelativePath.indexOf('@')) != -1) {
        outputFilePath = templateRelativePath.substring(0, testExpressionIndex);
        final String testExpressionKey = templateRelativePath.substring(testExpressionIndex+1);
        final Map map = getFilePathDataModel(modelProvider);
        final Object expressionValue = map.get(testExpressionKey);
        if(expressionValue == null) {
          System.err.println("[not-generate] WARN: test expression is null by key:["+testExpressionKey+"] on template:["+templateRelativePath+"]");
          continue;
        }
        if(!"true".equals(String.valueOf(expressionValue))) {
          System.out.println("[not-generate]\t test expression '@"+testExpressionKey+"' is false,template:"+templateRelativePath);
          continue;
        }
      }
      try {
        generateNewFileOrInsertIntoFile(modelProvider, newFreeMarkerConfiguration(), templateRelativePath,outputFilePath);
      }catch(final Exception e) {
        throw new RuntimeException("generate '"+modelProvider.getDisaplyText()+"' oucur error,template is:"+templateRelativePath,e);
      }
    }
  }

  private Configuration newFreeMarkerConfiguration() throws IOException {
    final Configuration config = new Configuration();

    final FileTemplateLoader[] templateLoaders = new FileTemplateLoader[templateRootDirs.size()];
    for(int i = 0; i < templateRootDirs.size(); i++) {
      templateLoaders[i] = new FileTemplateLoader((File)templateRootDirs.get(i));
    }
    final MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(templateLoaders);

    config.setTemplateLoader(multiTemplateLoader);
    config.setNumberFormat("###############");
    config.setBooleanFormat("true,false");
    config.setDefaultEncoding(encoding);
    return config;
  }

  private void generateNewFileOrInsertIntoFile(final IGeneratorModelProvider modelProvider, final Configuration config, final String templateFile,final String outputFilePath) throws Exception {
    final Template template = config.getTemplate(templateFile);
    template.setOutputEncoding(encoding);

    final String targetFilename = getTargetFilename(modelProvider, outputFilePath);

    final Map templateDataModel = getTemplateDataModel(modelProvider);
    final File absoluteOutputFilePath = getAbsoluteOutputFilePath(targetFilename);
    if(absoluteOutputFilePath.exists()) {
      final StringWriter newFileContentCollector = new StringWriter();
      if(isFoundInsertLocation(template, templateDataModel, absoluteOutputFilePath, newFileContentCollector)) {
        System.out.println("[insert]\t generate content into:"+targetFilename);
        IOHelper.saveFile(absoluteOutputFilePath, newFileContentCollector.toString());
        return;
      }
    }

    System.out.println("[generate]\t template:"+templateFile+" to "+targetFilename);
    saveNewOutputFileContent(template, templateDataModel, absoluteOutputFilePath);
  }

  private String getTargetFilename(final IGeneratorModelProvider modelProvider, final String templateFilepath) throws Exception {
    final Map fileModel = getFilePathDataModel(modelProvider);
    final StringWriter out = new StringWriter();
    final Template template = new Template("filePath",new StringReader(templateFilepath),newFreeMarkerConfiguration());
    try {
      template.process(fileModel, out);
      return out.toString();
    }catch(final Exception e) {
      throw new IllegalStateException("cannot generate filePath from templateFilepath:"+templateFilepath+" cause:"+e,e);
    }
  }
  /**
   * 得到生成"文件目录/文件路径"的Model
   **/
  private Map getFilePathDataModel(final IGeneratorModelProvider modelProvider) throws Exception {
    final Map model = new HashMap();
    model.putAll(GeneratorProperties.getProperties()); //generator.properties的内容
    modelProvider.mergeFilePathModel(model);
    return model;
  }
  /**
   * 得到FreeMarker的Model
   **/
  private Map getTemplateDataModel(final IGeneratorModelProvider modelProvider) throws Exception {
    final Map model = new HashMap();
    model.putAll(GeneratorProperties.getProperties()); //generator.properties的内容
    modelProvider.mergeTemplateModel(model);
    return model;
  }

  private File getAbsoluteOutputFilePath(final String targetFilename) {
    final String outRoot = getOutRootDir();
    final File outputFile = new File(outRoot,targetFilename);
    outputFile.getParentFile().mkdirs();
    return outputFile;
  }

  private boolean isFoundInsertLocation(final Template template, final Map model, final File outputFile, final StringWriter newFileContent) throws IOException, TemplateException {
    final LineNumberReader reader = new LineNumberReader(new FileReader(outputFile));
    String line = null;
    boolean isFoundInsertLocation = false;

    final PrintWriter writer = new PrintWriter(newFileContent);
    while((line = reader.readLine()) != null) {
      writer.println(line);
      // only insert once
      if(!isFoundInsertLocation && line.indexOf(GENERATOR_INSERT_LOCATION) >= 0) {
        template.process(model,writer);
        writer.println();
        isFoundInsertLocation = true;
      }
    }

    writer.close();
    reader.close();
    return isFoundInsertLocation;
  }

  private void saveNewOutputFileContent(final Template template, final Map model, final File outputFile) throws IOException, TemplateException {
    final Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile),encoding));
    template.process(model,out);
    out.close();
  }

  public void clean() throws IOException {
    final String outRoot = getOutRootDir();
    final File file = new File(outRoot);
    if (file.exists()) {
      FileUtils.deleteDirectory(file);
    }
    System.out.println("[Delete Dir]  "+outRoot);
  }

  private String getOutRootDir() {
    if(outRootDir == null) throw new IllegalStateException("'outRootDir' property must be not null.");
    return outRootDir;
  }

}
TOP

Related Classes of cn.org.rapid_framework.generator.Generator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.