import com.swift.web.resource.handler.FileEntity;
import com.swift.web.resource.handler.FileScanner;
/*******************************************
* 压缩jsp,html中的代码,去掉所有空白符、换行符
*
*******************************************/
@SuppressWarnings("nls")
public class HtmlCompressor {
private static String tempPreBlock = "%%%HTMLCOMPRESS~PRE&&&";
private static String tempTextAreaBlock = "%%%HTMLCOMPRESS~TEXTAREA&&&";
private static String tempScriptBlock = "%%%HTMLCOMPRESS~SCRIPT&&&";
private static String tempStyleBlock = "%%%HTMLCOMPRESS~STYLE&&&";
private static String tempJspBlock = "%%%HTMLCOMPRESS~JSP&&&";
private static Pattern commentPattern = Pattern.compile("<!--\\s*[^\\[].*?-->", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static Pattern itsPattern = Pattern.compile(">\\s+?<", Pattern.DOTALL | Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE);
private static Pattern prePattern = Pattern.compile("<pre[^>]*?>.*?</pre>", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static Pattern taPattern = Pattern.compile("<textarea[^>]*?>.*?</textarea>", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static Pattern jspPattern = Pattern.compile("<%([^-@][\\w\\W]*?)%>", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
// <script></script>
private static Pattern scriptPattern = Pattern.compile(
"(?:<script\\s*>|<script type=['\"]text/javascript['\"]\\s*>)(.*?)</script>", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static Pattern stylePattern = Pattern.compile("<style[^>()]*?>(.+)</style>", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
// 单行注释,
private static Pattern signleCommentPattern = Pattern.compile("//.*");
// 字符串匹配
private static Pattern stringPattern = Pattern.compile("(\"[^\"\\n]*?\"|'[^'\\n]*?')");
// trim去空格和换行符
private static Pattern trimPattern = Pattern.compile("\\n\\s*", Pattern.MULTILINE);
private static Pattern trimPattern2 = Pattern.compile("\\s*\\r", Pattern.MULTILINE);
// 多行注释
private static Pattern multiCommentPattern = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static String tempSingleCommentBlock = "%%%HTMLCOMPRESS~SINGLECOMMENT&&&"; // //占位符
private static String tempMulitCommentBlock1 = "%%%HTMLCOMPRESS~MULITCOMMENT1&&&"; // /*占位符
private static String tempMulitCommentBlock2 = "%%%HTMLCOMPRESS~MULITCOMMENT2&&&"; // */占位符
public static String compress(String html) throws Exception {
if (html == null || html.length() == 0) {
return html;
}
List<String> preBlocks = new ArrayList<String>();
List<String> taBlocks = new ArrayList<String>();
List<String> scriptBlocks = new ArrayList<String>();
List<String> styleBlocks = new ArrayList<String>();
List<String> jspBlocks = new ArrayList<String>();
String result = html;
// preserve inline java code
Matcher jspMatcher = jspPattern.matcher(result);
while (jspMatcher.find()) {
jspBlocks.add(jspMatcher.group(0));
}
result = jspMatcher.replaceAll(tempJspBlock);
// preserve PRE tags
Matcher preMatcher = prePattern.matcher(result);
while (preMatcher.find()) {
preBlocks.add(preMatcher.group(0));
}
result = preMatcher.replaceAll(tempPreBlock);
// preserve TEXTAREA tags
/*Matcher taMatcher = taPattern.matcher(result);
while (taMatcher.find()) {
taBlocks.add(taMatcher.group(0));
}
result = taMatcher.replaceAll(tempTextAreaBlock);*/
// preserve SCRIPT tags
Matcher scriptMatcher = scriptPattern.matcher(result);
while (scriptMatcher.find()) {
scriptBlocks.add(scriptMatcher.group(0));
}
result = scriptMatcher.replaceAll(tempScriptBlock);
// don't process inline css
Matcher styleMatcher = stylePattern.matcher(result);
while (styleMatcher.find()) {
styleBlocks.add(styleMatcher.group(0));
}
result = styleMatcher.replaceAll(tempStyleBlock);
// process pure html
result = processHtml(result);
// process preserved blocks
result = processPreBlocks(result, preBlocks);
//result = processTextareaBlocks(result, taBlocks);
result = processScriptBlocks(result, scriptBlocks);
result = processStyleBlocks(result, styleBlocks);
result = processJspBlocks(result, jspBlocks);
preBlocks = taBlocks = scriptBlocks = styleBlocks = jspBlocks = null;
return result.trim();
}
private static String processHtml(String html) {
String result = html;
// remove comments
// if(removeComments) {
result = commentPattern.matcher(result).replaceAll("");
// }
// remove inter-tag spaces
// if(removeIntertagSpaces) {
result = itsPattern.matcher(result).replaceAll("><");
// }
// remove multi whitespace characters
// if(removeMultiSpaces) {
result = result.replaceAll("\\s{2,}", " ");
// }
return result;
}
private static String processJspBlocks(String html, List<String> blocks) {
String result = html;
for (int i = 0; i < blocks.size(); i++) {
blocks.set(i, compressJsp(blocks.get(i)));
}
// put preserved blocks back
while (result.contains(tempJspBlock)) {
result = result.replaceFirst(tempJspBlock, Matcher.quoteReplacement(blocks.remove(0)));
}
return result;
}
private static String processPreBlocks(String html, List<String> blocks) throws Exception {
String result = html;
// put preserved blocks back
while (result.contains(tempPreBlock)) {
result = result.replaceFirst(tempPreBlock, Matcher.quoteReplacement(blocks.remove(0)));
}
return result;
}
private static String processTextareaBlocks(String html, List<String> blocks) throws Exception {
String result = html;
// put preserved blocks back
while (result.contains(tempTextAreaBlock)) {
result = result.replaceFirst(tempTextAreaBlock, Matcher.quoteReplacement(blocks.remove(0)));
}
return result;
}
private static String processScriptBlocks(String html, List<String> blocks) throws Exception {
String result = html;
// if(compressJavaScript) {
for (int i = 0; i < blocks.size(); i++) {
blocks.set(i, compressJavaScript(blocks.get(i)));
}
// }
// put preserved blocks back
while (result.contains(tempScriptBlock)) {
result = result.replaceFirst(tempScriptBlock, Matcher.quoteReplacement(blocks.remove(0)));
}
return result;
}
private static String processStyleBlocks(String html, List<String> blocks) throws Exception {
String result = html;
// if(compressCss) {
for (int i = 0; i < blocks.size(); i++) {
blocks.set(i, compressCssStyles(blocks.get(i)));
}
// }
// put preserved blocks back
while (result.contains(tempStyleBlock)) {
result = result.replaceFirst(tempStyleBlock, Matcher.quoteReplacement(blocks.remove(0)));
}
return result;
}
private static String compressJsp(String source) {
// check if block is not empty
Matcher jspMatcher = jspPattern.matcher(source);
if (jspMatcher.find()) {
String result = compressJspJs(jspMatcher.group(1));
return (new StringBuilder(source.substring(0, jspMatcher.start(1))).append(result).append(source
.substring(jspMatcher.end(1)))).toString();
} else {
return source;
}
}
private static String compressJavaScript(String source) {
// check if block is not empty
Matcher scriptMatcher = scriptPattern.matcher(source);
if (scriptMatcher.find()) {
String result = compressJspJs(scriptMatcher.group(1));
return (new StringBuilder(source.substring(0, scriptMatcher.start(1))).append(result).append(source
.substring(scriptMatcher.end(1)))).toString();
} else {
return source;
}
}
private static String compressCssStyles(String source) {
// check if block is not empty
Matcher styleMatcher = stylePattern.matcher(source);
if (styleMatcher.find()) {
// 去掉注释,换行
String result = multiCommentPattern.matcher(styleMatcher.group(1)).replaceAll("");
result = trimPattern.matcher(result).replaceAll("");
result = trimPattern2.matcher(result).replaceAll("");
return (new StringBuilder(source.substring(0, styleMatcher.start(1))).append(result).append(source
.substring(styleMatcher.end(1)))).toString();
} else {
return source;
}
}
private static String compressJspJs(String source) {
String result = source;
// 因注释符合有可能出现在字符串中,所以要先把字符串中的特殊符好去掉
Matcher stringMatcher = stringPattern.matcher(result);
while (stringMatcher.find()) {
String tmpStr = stringMatcher.group(0);
if (tmpStr.indexOf("//") != -1 || tmpStr.indexOf("/*") != -1 || tmpStr.indexOf("*/") != -1) {
String blockStr = tmpStr.replaceAll("//", tempSingleCommentBlock).replaceAll("/\\*",
tempMulitCommentBlock1).replaceAll("\\*/", tempMulitCommentBlock2);
result = result.replace(tmpStr, blockStr);
}
}
// 去掉注释
result = signleCommentPattern.matcher(result).replaceAll("");
result = multiCommentPattern.matcher(result).replaceAll("");
result = trimPattern2.matcher(result).replaceAll("");
result = trimPattern.matcher(result).replaceAll(" ");
// 恢复替换掉的字符串
result = result.replaceAll(tempSingleCommentBlock, "//").replaceAll(tempMulitCommentBlock1, "/*").replaceAll(
tempMulitCommentBlock2, "*/");
return result;
}
public static List<FileEntity> compressAll(String rootPath) {
List entities = new ArrayList();
//FileScanner.scan(rootPath, new String[] { "jsp", "html" }, new HtmlScanBack(rootPath, entities));
FileScanner.scan(rootPath, new String[] {"jsp"}, new HtmlScanBack(rootPath, entities));
return entities;
}
static class HtmlScanBack implements FileScanner.ScanCallback {
private String webRootPath;
private List<FileEntity> fileEntities;
public HtmlScanBack(String rootPath, List<FileEntity> entity) {
this.webRootPath = rootPath;
if (!this.webRootPath.endsWith(File.separator)) {
this.webRootPath += File.separator;
}
this.fileEntities = entity;
}
public void invoke(File file) {
try {
} catch (Exception e) {
}
}
private String getWebPath(String fileName) {
String webFileName = fileName.substring(this.webRootPath.length());
return "/" + webFileName.replaceAll("\\\\", "\\/");
}
}
}
import com.swift.web.resource.handler.FileEntity;
import com.swift.web.resource.handler.FileScanner;
public class HtmlReplace {
public static void replace(String rootPath, List<FileEntity> entity) {
//FileScanner.scan(rootPath, new String[] { "jsp", "html", "htm" }, new pageScanBack(entity));
FileScanner.scan(rootPath, new String[] { "jsp"}, new pageScanBack(entity));
}
static class pageScanBack implements FileScanner.ScanCallback {
private List<FileEntity> fileEntities;
public pageScanBack(List<FileEntity> entity) {
this.fileEntities = entity;
}
public void invoke(File file) {
try {
InputStreamReader inReader = new InputStreamReader(new FileInputStream(file), "UTF-8");
LineNumberReader inLine = new LineNumberReader(inReader);
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = inLine.readLine()) != null) {
sb.append(line + "\r\n");
}
inReader.close();
inLine.close();
String text =HtmlCompressor.compress(sb.toString());
sb = null;
/*for (FileEntity fe : this.fileEntities) {
text = text.replaceAll(fe.fileName + "[^\"']*", fe.getVersionFileName());
}*/
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file, false), "UTF-8");
writer.write(text);
writer.flush();
writer.close();
inReader = null;
inLine = null;
writer = null;
} catch (Exception e) {
}
}
}
}
import com.swift.web.resource.handler.FileEntity;
import com.swift.web.resource.handler.FileScanner;
import com.yahoo.platform.yui.compressor.YUICompressor;
public class JsCssCompressor {
private static String[] yuiJsArgs;
private static String[] yuiCssArgs;
public static List<FileEntity> compressAll(String rootPath) {
yuiJsArgs = new String[8];
yuiJsArgs[0] = "";
yuiJsArgs[1] = "--type";
yuiJsArgs[2] = "js";
yuiJsArgs[3] = "--charset";
yuiJsArgs[4] = "utf-8";
yuiJsArgs[5] = "--nomunge";
yuiJsArgs[6] = "-o";
yuiJsArgs[7] = "";
yuiCssArgs = new String[7];
yuiCssArgs[0] = "";
yuiCssArgs[1] = "--type";
yuiCssArgs[2] = "css";
yuiCssArgs[3] = "--charset";
yuiCssArgs[4] = "utf-8";
yuiCssArgs[5] = "-o";
yuiCssArgs[6] = "";
List entities = new ArrayList();
FileScanner.scan(rootPath, new String[] { "js", "css" }, new JsCssScanBack(rootPath, entities));
return entities;
}
static class JsCssScanBack implements FileScanner.ScanCallback {
private String webRootPath;
private List<FileEntity> fileEntities;
public JsCssScanBack(String rootPath, List<FileEntity> entity) {
this.webRootPath = rootPath;
if (!this.webRootPath.endsWith(File.separator)) {
this.webRootPath += File.separator;
}
this.fileEntities = entity;
}
public void invoke(File file) {
try {
String fileName = file.getName();
File minFile = getCompressFile(file.getAbsolutePath());
/*if (minFile.exists())
minFile.delete();*/
FileEntity fe = new FileEntity();
fe.fileName = getWebPath(file.getAbsolutePath());
fe.minFileName = getWebPath(minFile.getAbsolutePath());
if (fileName.toLowerCase().endsWith(".js")) {
JsCssCompressor.yuiJsArgs[0] = file.getAbsolutePath();
JsCssCompressor.yuiJsArgs[7] = minFile.getAbsolutePath();
YUICompressor.main(JsCssCompressor.yuiJsArgs);
} else if (fileName.toLowerCase().endsWith(".css")) {
JsCssCompressor.yuiCssArgs[0] = file.getAbsolutePath();
JsCssCompressor.yuiCssArgs[6] = minFile.getAbsolutePath();
YUICompressor.main(JsCssCompressor.yuiCssArgs);
}
fe.version = String.valueOf(minFile.length());
minFile = null;
file = null;
this.fileEntities.add(fe);
} catch (Exception e) {
}
}
private File getCompressFile(String oldFileName) {
int index = oldFileName.lastIndexOf(".");
return new File(oldFileName.substring(0, index) + oldFileName.substring(index));
}
private String getWebPath(String fileName) {
String webFileName = fileName.substring(this.webRootPath.length());
return "/" + webFileName.replaceAll("\\\\", "\\/");
}
}
}