这几天接到项目组一个需求,要求把某一目录下的某一类文件进行Base64编码,考虑到该项目用ANT进行打包发布,于是乎想到了用自定义的Ant Task来实现Base64,以减少操作步骤。花几个小时看了一下Ant的Task,拼凑出一个类,基本能满足要求,就先贴出来,省得下次遇到同样问题再到处找。
仅供自己备忘及跟我一样的新手参考,方家勿笑。
实现类如下,其中Base64实现代码就不贴了
/**
*
*/
package com.pansky.etax.invoice.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.taskdefs.condition.Condition;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import cn.com.XXX.YYY.ZZZ.util.Base64;
/**
*
* @author BrokenStone
* http://sheng.iteye.com
* @email: wdmsyf@yahoo.com
* @Since 2010-12-29
*/
public class JspEncodeTask extends MatchingTask implements Condition {
private File file = null;
private File todir = null;
private String fileext;
private Vector filesets = new Vector();
private Path classpath = null;
private Hashtable includeFileMap = new Hashtable();
private boolean verbose=false;
private boolean forceOverwrite = false;
private String base64Chars = null;
private String base64Pad = null;
public String getBase64Pad() {
return new StringBuffer(Base64.getB64Pad()).toString();
}
public void setBase64Pad(String base64Pad) {
Base64.setB64Pad( base64Pad.charAt(0) );
}
public String getBase64Chars() {
return Base64.getB64Chars();
}
public void setBase64Chars(String base64Chars) {
Base64.setB64Chars(base64Chars);
}
public void setFile(File file) {
this.file = file;
}
public void setTodir(File todir) {
this.todir = todir;
}
public void setFileext(String fileext) {
this.fileext = fileext;
}
public void addFileset(FileSet set) {
this.filesets.addElement(set);
}
public Path getClasspath() {
return classpath;
}
public void setClasspath(Path classpath) {
this.classpath = classpath;
}
public boolean isForceOverwrite() {
return forceOverwrite;
}
public void setForceOverwrite(boolean forceOverwrite) {
this.forceOverwrite = forceOverwrite;
}
public Path createClasspath(){
if(this.classpath ==null){
this.classpath = new Path(getProject());
}
return this.classpath.createPath();
}
public void setClasspathRef(Reference ref){
createClasspath().setRefid(ref);
}
public void execute() throws BuildException {
AntClassLoader loader = null;
try{
// if(this.classpath!=null){
// this.createClasspath();
// }
boolean value = validateAndExecute();
}catch(Throwable ex){
throw new BuildException(ex);
}finally{
if(loader!=null){
loader.resetThreadContextLoader();
loader.cleanup();
}
}
}
public boolean eval() throws BuildException {
return validateAndExecute();
}
private boolean validateAndExecute() throws BuildException {
String savedFileExt = this.fileext;
FileSet fs = null;
if ((this.file == null) && (this.filesets.size() == 0)) {
throw new BuildException("Specify at least one source - a file or a fileset.");
}
if ((this.file != null) && (this.file.exists()) && (this.file.isDirectory())) {
throw new BuildException("Checksum cannot be generated for directories");
}
if (this.fileext == null)
this.fileext = (".jspe");
else if (this.fileext.trim().length() == 0) {
throw new BuildException("File extension when specified must not be an empty string");
}
String baseDir = getProject().getBaseDir().getAbsolutePath();
try {
int sizeofFileSet = this.filesets.size();
for (int i = 0; i < sizeofFileSet; i++) {
fs = (FileSet) this.filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String[] srcFiles = ds.getIncludedFiles();
for (int j = 0; j < srcFiles.length; j++) {
File src = new File(fs.getDir(getProject()), srcFiles[j]);
if(src ==null || !src.exists()) continue;
if ( this.todir != null ) {
String absPath = this.todir + File.separator + srcFiles[j] + "." + this.fileext;
absPath = absPath.replace(File.separatorChar, '/');
this.includeFileMap.put(src, absPath);
}else{
String absPath = src.getAbsolutePath() + "." + this.fileext;
absPath = absPath.replace(File.separatorChar, '/');
this.includeFileMap.put(src, absPath);
}
}
}
if(this.file != null && this.file.exists()){
if ( this.todir != null ) {
String relativePath = this.file.getAbsolutePath().replace(baseDir, "");
String absPath = this.todir + File.separator + relativePath + "." + this.fileext;
absPath = absPath.replace(File.separatorChar, '/');
this.includeFileMap.put(this.file, absPath);
}else{
String absPath = this.file.getAbsolutePath() + "." + this.fileext;
absPath = absPath.replace(File.separatorChar, '/');
this.includeFileMap.put(this.file, absPath);
}
}
return doEncodeOrDecode();
} finally {
this.fileext = savedFileExt;
this.includeFileMap.clear();
}
}
private boolean doEncodeOrDecode() throws BuildException {
boolean checksumMatches = true;
FileInputStream fis = null;
FileOutputStream fos = null;
try {
for (Enumeration e = this.includeFileMap.keys(); e.hasMoreElements();) {
File src = (File) e.nextElement();
if(this.verbose)
log("Processing file: " + src.getName());
Object destination = this.includeFileMap.get(src);
fis = new FileInputStream(src);
File dest = new File((String)destination);
if(!dest.getParentFile().exists()){
dest.getParentFile().mkdirs();
}
if(!this.forceOverwrite){
if(dest.exists()){
throw new BuildException("File ["+dest.getAbsolutePath()+"] exist.", getLocation());
}
}
fos = new FileOutputStream(dest);
Base64.encode(fis, fos);
fos.flush();
fos.close();
fos = null;
}
} catch (Exception e) {
throw new BuildException(e, getLocation());
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e) {
}
if (fos != null)
try {
fos.close();
} catch (IOException e) {
}
}
return checksumMatches;
}
}
Build.xml如下:
<project name="MyJSPConvertor" default="encode_jsp" basedir="."> <property name="app.dir" value="app"/> <property name="web.dir" value="${app.dir}/web"/> <property name="lib.dir" value="${app.dir}/web"/> <property name="server.dir" value="server"/> <property name="server.admin.dir" value="${server.dir}/admin"/> <property name="server.common.dir" value="${server.dir}/common"/> <property name="server.lib.dir" value="${server.dir}/lib"/> <property name="encode.src.dir" value="${web.dir}"/> <property name="encode.dest.dir" value="${app.dir}/web_bak"/> <taskdef name="EncodeJsp" classname="com.XXX.YYY.ZZZ.util.JspEncodeTask"/> <target name="encode_jsp" description="encode jsp"> <echo message="创建目标路径" /> <mkdir dir="${encode.dest.dir}" /> <echo message="加密JSP……" /> <EncodeJsp forceOverwrite="yes" todir="${encode.dest.dir}" fileext="jspe" base64Chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" base64Pad="=" > <classpath refid="classpath" /> <fileset dir="${encode.src.dir}"> <include name="**/*.jsp"/> </fileset> </EncodeJsp> </target> </project>