Package cn.bran.japid.compiler

Source Code of cn.bran.japid.compiler.JapidTemplateTransformer

/**
* Copyright 2010 Bing Ran<bing_ran@hotmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.bran.japid.compiler;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.regex.Pattern;

import cn.bran.japid.classmeta.AbstractTemplateClassMetaData;
import cn.bran.japid.template.JapidTemplate;
import cn.bran.japid.util.DirUtil;

/**
* compile html based template to java files
*
* The facade to all the compiler suite and configurations.
*
* @author Bing Ran<bing_ran@hotmail.com>
*
*/
public class JapidTemplateTransformer {

  private static final String HTML = ".html";
  private String sourceFolder;
  private String targetFolder;
  private boolean usePlay = true;

  // private MessageProvider messageProvider;
  // private UrlMapper urlMapper;

  /**
   * @param sourceFolder
   *            the folder containing the template source tree. It's the same
   *            concept as in eclipse. The root package for Java artifacts are
   *            the direct children of this
   * @param targetFolder
   *            the "source folder", in Eclipse term, that the generated Java
   *            artifacts will be placed. If it is null, the Java files will
   *            be placed in the sourceFolder.
   */
  public JapidTemplateTransformer(String sourceFolder, String targetFolder) {
    super();

    this.sourceFolder = sourceFolder;
    // this.messageProvider = messageProvider;
    // this.urlMapper = urlMapper;
    this.targetFolder = targetFolder;
    //   
    // BranTemplateBase.messageProvider = messageProvider;
    // BranTemplateBase.urlMapper = urlMapper;
  }

  /**
   *
   * @param importLine
   *            add an import to all the files generated. For examples:
   *            "my.package.*", "my.package.MyClass"
   */
  public void addImportLine(String importLine) {
    AbstractTemplateClassMetaData.addImportLineGlobal(importLine);
  }

  /**
   * effectively as in Java: "import static my.Tools.*;" if Tools.class is the
   * parameter.
   *
   * @param class1
   */
  public void addImportStatic(Class<?> class1) {
    AbstractTemplateClassMetaData.addImportStatic(class1);
  }

  static Pattern doLayoutTag = Pattern.compile(".*\\#\\{\\s*doLayout\\s*.*");
  static Pattern doLayoutDirective = Pattern.compile(".*`doLayout");
  static Pattern doLayoutDirective2 = Pattern.compile(".*`doLayout\\s?`.*");
  static Pattern getTag= Pattern.compile(".*\\#\\{\\s*get\\s*.*");
  static Pattern getDirective = Pattern.compile(".*`get\\s+\\w+\\s*");
 
  public static boolean looksLikeLayout(String src) {
    String[] split = src.split("[\r\n]");
    for (String line : split) {
      line = line.trim();
      if (doLayoutTag.matcher(line).matches()
          || doLayoutDirective.matcher(line).matches()
          || doLayoutDirective2.matcher(line).matches()
          || getTag.matcher(line).matches()
          || getDirective.matcher(line).matches()) {
        return true;
      }
    }
    return false;
  }
  /**
   *
   * @param fileName
   *            the relative path of the template file from the source folder,
   *            e.g., "my/path/mytemplate.html", which maps to
   *            my.path.mytemplate.java
   * @return
   * @throws Exception
   */
  public File generate(String fileName) throws Exception {
    String realSrcFile = sourceFolder == null ? fileName : sourceFolder + "/" + fileName;
    String src = readFileAsString(realSrcFile);
    JapidTemplate temp = new JapidTemplate(fileName, src);
    JapidAbstractCompiler c = null;
    // TODO: more robust way of determine layout file or view file
    if (looksLikeLayout(src)) {
      c = new JapidLayoutCompiler();
    } else {
      // regular template and tag are the same thing
      c = new JapidTemplateCompiler();
    }
    c.setUseWithPlay(usePlay);
    c.compile(temp);
    String jsrc = temp.javaSource;

//    String fileNameRoot = fileName;
//    if (fileName.endsWith(HTML)) {
//      fileNameRoot = fileName.substring(0, fileName.indexOf(HTML));
//    }

    String fileNameRoot = DirUtil.mapSrcToJava(fileName);

    String target = targetFolder == null ? sourceFolder : targetFolder;
    String realTargetFile = target == null ? fileNameRoot : target + "/" + fileNameRoot;
    File f = new File(realTargetFile);
    if (!f.exists()) {
      String parent = f.getParent();
      new File(parent).mkdirs();
    }
    BufferedOutputStream bf = new BufferedOutputStream(new FileOutputStream(f));
    bf.write(jsrc.getBytes("UTF-8"));
    bf.close();
    return f;

  }

  // this method is entirely safe ???
  private String readFileAsString(String filePath) throws Exception {
    // let're remove dependency on commons IO
//    return IOUtils.toString(new FileInputStream(filePath), "UTF-8");
    byte[] buffer = new byte[(int) new File(filePath).length()];
    BufferedInputStream f = new BufferedInputStream(new FileInputStream(filePath));
    // not sure if this is always safe assume it'll read all bytes in
    f.read(buffer);
    f.close();
    return new String(buffer, "UTF-8");

  }

  /**
   * a utility method. Should be somewhere else.
   *
   * @param srcDir
   * @param cf
   * @throws IOException
   */
  public static String getRelativePath(File child, File parent) throws IOException {
    String curPath = parent.getCanonicalPath();
    String childPath = child.getCanonicalPath();
    assert (childPath.startsWith(curPath));
    String srcRelative = childPath.substring(curPath.length());
    if (srcRelative.startsWith(File.separator)) {
      srcRelative = srcRelative.substring(File.separator.length());
    }
    return srcRelative;
  }

  /**
   * transform a source template to Java
   *
   * @param file
   *            the source file that must be a descendant of the source folder.
   * @return
   * @throws Exception
   */
  public File generate(File file) throws Exception {
    String rela = getRelativePath(file, new File("."));
    return generate(rela);
  }

  /**
   * add class level annotation for whatever purpose
   *
   * @param anno
   */
  public void addAnnotation(Class<? extends Annotation> anno) {
    AbstractTemplateClassMetaData.addAnnotation(anno);
    // typeAnnotations.add(anno);
  }

  public void usePlay(boolean b) {
    this.usePlay = b;
  }

  // List<Class<? extends Annotation>> typeAnnotations = new ArrayList<Class<?
  // extends Annotation>>();
}
TOP

Related Classes of cn.bran.japid.compiler.JapidTemplateTransformer

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.