山寨一个js缩减comment的Maven Plugin

[b]background:[/b]
动手写一个去掉js comment的Maven Plugin, 用英文写练习练习,哈哈

[b]steps:[/b]

1. New a maven project, the pom is like below. At the beginning I do not add the maven project api to the project, it is exhausting to find the project strutcture, build path etc and filter the resources that i want. It is better to include it in my project, :wink:


<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0.9</version>
<scope>provided</scope>
</dependency>

</dependencies>


2. Js comment is deleted by using regular expression. the code maybe like as below. The single line comment as "//...." without existing in string literal is hard to match. And a big js file is loaded into memory at one time and is treated as a really string by regular expression may cause java fatal error. So it is not very prefect, but it is enough to be fullfill my situation.

package com.mycompany.mojo.jsmin;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;

public abstract class JsFileProcessor {

private static final int buffer_size = 512;

private static final Pattern block = Pattern.compile( "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)" );

private static final Pattern singleLine = Pattern.compile( "(?<=.*)//[^\"\\n\\r]*(?=[\r\n])" );

public static void process(File inputFile, File outputFile) throws IOException {

FileInputStream fis = null;
FileWriter fw = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream(buffer_size * 2);
try {

fis = new FileInputStream(inputFile);
fw = new FileWriter(outputFile);

int length = -1;
byte[] buffer = new byte[buffer_size];
while( (length = fis.read(buffer)) != -1) {

baos.write(buffer, 0, length);
}

} catch (IOException e) {
throw e;
} finally {
fis.close();
baos.flush();
baos.close();
}

String text = singleLine.matcher(
block.matcher(baos.toString()).replaceAll("")
).replaceAll("");

try {
fw.write(text);
} finally {
fw.flush();
fw.close();
}
}
}



3. Mojo is like as below, the annotation is required by Maven plugin to dependecy inject the parms value at runtime. It is really very convenient. :idea: to deal with resources. The plugin is binded to the life cycle: process-resources. When the war file is packaged, the comment-deleted js files may be overwritten. :cry:

package com.mycompany.mojo.jsmin;

import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.DirectoryScanner;

/**
* delete the js file comment
* @goal minify
* @phase process-resources
*/
public class JsCommentMojo extends AbstractMojo {

/**
* Single directory for extra files to include in the WAR.
*
* @parameter expression="${basedir}/src/main/webapp"
*/
private File warSourceDirectory;

/**
* The folder where the webapp is built.
*
* @parameter expression="${project.build.directory}/${project.build.finalName}"
*/
private File webappDirectory;

/**
* excludes file
*
* @parameter
*/
private List<String> excludes;

/**
* javascript file extension
*
* @parameter default-value=".js"
*/
private String extension;

/**
* Whether to skip execution.
*
* @parameter expression="${maven.jsmin.skip}" default-value="false"
*/
private boolean skip;

/**
* total count of processed javascript file
*
*/
private int executedCount;


public void execute() throws MojoExecutionException, MojoFailureException {

if(skip) {
getLog().info("Run of javascript files process skipped");
return;
}

getLog().info("Run of javascript files process is starting...");

DirectoryScanner directoryScanner = new DirectoryScanner();
directoryScanner.setBasedir(warSourceDirectory);
if ( excludes != null && !excludes.isEmpty() ) {
directoryScanner.setExcludes( excludes.toArray(new String[0]) );
}
directoryScanner.setIncludes(new String[]{"**/*" + extension});
directoryScanner.addDefaultExcludes();
directoryScanner.scan();
for(String relativePath : directoryScanner.getIncludedFiles() ) {

try {
processFile(
new File(warSourceDirectory, relativePath),
getTargetFile(relativePath));
} catch (IOException e) {
getLog().error(warSourceDirectory + relativePath + " failed to be processed");
getLog().error(e);
throw new MojoExecutionException(e.getMessage());
}
}

getLog().info("Total " + executedCount + " javascript files processed");
}

private File getTargetFile(String relativePath) throws MojoExecutionException {


File file = new File(webappDirectory.getPath() + File.separator +
relativePath);

file.getParentFile().mkdirs();

if(getLog().isDebugEnabled()) {
getLog().debug("src file [ " +
relativePath + " ] ==>> target [ " +
file.getPath() + " ]");
}

return file;
}

private void processFile(File inputFile, File outputFile) throws IOException {

JsFileProcessor.process(inputFile, outputFile);

executedCount++;

getLog().info("process file : " + inputFile.getPath() );

}

}


作为记录, 以资参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值