/**
* 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.File;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import cn.bran.japid.classmeta.AbstractTemplateClassMetaData;
import cn.bran.japid.util.DirUtil;
import cn.bran.japid.util.JapidFlags;
/**
* modeled after the JamonTask in the <a url = "http://www.jamon.org/>Jamon
* project</a>
*
* ensure you have the Japid task properly defined,
*
* <pre>
* <path id="JapidCP">
* <pathelement file="/path/to/japid.jar"/>
* </path>
* <taskdef name="japid"
* classname="bran.ant.TranslateTemplateTask"
* classpathref="${JapidCP}"/>
*
* To generate the Java sources, include the following target:
*
* <target name="trans-templates">
* <japid srcdir="templates" destdir="tempsrc" />
* </target>
* </pre>
*
* @author Bing Ran<bing_ran@hotmail.com>
*
*/
public class TranslateTemplateTask {
private List<Class<?>> staticImports = new ArrayList<Class<?>>();
private List<String> imports = new ArrayList<String>();
// changed html source files
private List<File> changedFiles;
// updated Java files
private List<File> changedTargetFiles = new LinkedList<File>();
public List<File> getChangedTargetFiles() {
return changedTargetFiles;
}
private boolean usePlay = true;
// public boolean isUsePlay() {
// return usePlay;
// }
public void setUsePlay(boolean usePlay) {
this.usePlay = usePlay;
}
/**
* get a list of changed files in the last task execution
*
* @return
*/
public List<File> getChangedFiles() {
return changedFiles;
}
public void setDestdir(File p_destDir) {
destDir = p_destDir;
}
public void setPackageRoot(File p_srcDir) {
packageRoot = p_srcDir;
}
public void setListFiles(boolean p_listFiles) {
listFiles = p_listFiles;
}
public void execute(){
// first off, make sure that we've got a srcdir
if (packageRoot == null) {
throw new RuntimeException("srcdir attribute must be set!");
}
if (destDir == null) {
destDir = packageRoot;
}
if (!packageRoot.exists() || !packageRoot.isDirectory()) {
throw new RuntimeException("source directory \"" + packageRoot + "\" does not exist or is not a directory");
}
destDir.mkdirs();
if (!destDir.exists() || !destDir.isDirectory()) {
throw new RuntimeException("destination directory \"" + destDir + "\" does not exist or is not a directory");
}
if(changedFiles == null)
changedFiles = DirUtil.findChangedSrcFiles(include);
if (changedFiles.size() > 0) {
// JapidFlags.log("[Japid] Processing " + changedFiles.size() + " template" + (changedFiles.size() == 1 ? "" : "s") + " in directory tree: " + destDir);
JapidTemplateTransformer tran = new JapidTemplateTransformer(packageRoot.getPath(), null);
tran.usePlay(this.usePlay);
for (Class<?> c : this.staticImports) {
tran.addImportStatic(c);
}
for (String c : this.imports) {
tran.addImportLine(c);
}
for (Class<? extends Annotation> a : this.typeAnnotations) {
tran.addAnnotation(a);
}
for (int i = 0; i < changedFiles.size(); i++) {
File templateFile = changedFiles.get(i);
JapidFlags.log("[Japid] Transforming template: " + templateFile.getPath() + " to: " + DirUtil.mapSrcToJava(templateFile.getName()));
if (listFiles) {
JapidFlags.log(templateFile.getAbsolutePath());
}
try {
String relativePath = DirUtil.getRelativePath(templateFile, packageRoot);
File generate = tran.generate(relativePath);
changedTargetFiles.add(generate);
} catch (JapidCompilationException e) {
// syntax error
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getClass().getName() + ":" + e.getMessage());
}
}
}
}
/**
* derived artifacts are kept in memory instead of file system
*
* @author Bing Ran (bing.ran@hotmail.com)
*/
public void executeInMemory(){
// first off, make sure that we've got a srcdir
if (packageRoot == null) {
throw new RuntimeException("srcdir attribute must be set!");
}
if (!packageRoot.exists() && !packageRoot.isDirectory()) {
throw new RuntimeException("source directory \"" + packageRoot + "\" does not exist or is not a directory");
}
if(changedFiles == null)
changedFiles = DirUtil.findChangedSrcFiles(include);
if (changedFiles.size() > 0) {
// JapidFlags.log("[Japid] Processing " + changedFiles.size() + " template" + (changedFiles.size() == 1 ? "" : "s") + " in directory tree: " + destDir);
JapidTemplateTransformer tran = new JapidTemplateTransformer(packageRoot.getPath(), null);
tran.usePlay(this.usePlay);
for (Class<?> c : this.staticImports) {
tran.addImportStatic(c);
}
for (String c : this.imports) {
tran.addImportLine(c);
}
for (Class<? extends Annotation> a : this.typeAnnotations) {
tran.addAnnotation(a);
}
for (int i = 0; i < changedFiles.size(); i++) {
File templateFile = changedFiles.get(i);
JapidFlags.log("[Japid] Transforming template: " + templateFile.getPath() + " to: " + DirUtil.mapSrcToJava(templateFile.getName()));
if (listFiles) {
JapidFlags.log(templateFile.getAbsolutePath());
}
try {
String relativePath = DirUtil.getRelativePath(templateFile, packageRoot);
File generate = tran.generate(relativePath);
changedTargetFiles.add(generate);
} catch (JapidCompilationException e) {
// syntax error
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getClass().getName() + ":" + e.getMessage());
}
}
}
}
/**
* add an import static entry to the template translator
*
* @param clz
*/
public void importStatic(Class<?> clz) {
this.staticImports.add(clz);
}
/**
*
* @param imp
* the package or class part of a full line of regular imports,
* such as java.util.*, java.util.Hashmap
*/
public void addImport(String imp) {
this.imports.add(imp);
}
public void addImport(Class<?> clz) {
this.imports.add(clz.getName().replace('$', '.'));
}
// private static class JapidFileNameMapper {
//
// static String mapFileName(String sourceName) {
// String targetFileName = sourceName;
// String suffix = ".html";
// if (targetFileName.endsWith(suffix)) {
// targetFileName = targetFileName.substring(0, targetFileName.length() - suffix.length());
// return targetFileName + ".java" ;
// } else {
// return null;
// }
// // return new String[0];
// }
// }
private File destDir = null;
private File packageRoot = null;
private boolean listFiles = false;
public void addAnnotation(Class<? extends Annotation> anno) {
typeAnnotations.add(anno);
}
List<Class<? extends Annotation>> typeAnnotations = new ArrayList<Class<? extends Annotation>>();
private File include;
// private ClassLoader m_classLoader = JamonTask.class.getClassLoader();
public void setUseStreaming(boolean streaming) {
AbstractTemplateClassMetaData.streaming = streaming;
}
/**
*
* @param file the sub dir in the root that contains the template tree
*/
public void setInclude(File file) {
this.include = file;
}
public void clearImports() {
staticImports.clear();
imports.clear();
AbstractTemplateClassMetaData.clearImports();
}
/**
* @param changedFiles the changedFiles to set. Each file starts with the package root.
*/
public void setChangedFiles(List<File> changedFiles) {
this.changedFiles = changedFiles;
}
}