DiffPrint.java
Join the DZone community and get the full member experience.
Join For Freeソースレビュー用ã«è‰²ã‚’付ã‘ã¦ã‚½ãƒ¼ã‚¹ã‚’表示ã•ã›ãŸHTMLファイルを出力ã—ã¦å·®åˆ†ã‚’分ã‹ã‚Šã‚„ã™ãå°åˆ·ã™ã‚‹ã“ã¨ã‚’支æ´ã™ã‚‹ãƒ„ールã§ã™ã€‚
see:
ソースレビュー用ã®å·®åˆ†å°åˆ·æ©Ÿèƒ½
ソースレビュー用ã®å·®åˆ†å°åˆ·æ©Ÿèƒ½ãã®ï¼’
ソースレビュー用ã®å·®åˆ†å°åˆ·æ©Ÿèƒ½ãã®ï¼“
DiffPrint.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.StringTokenizer;
/**
* @author fumokmm
*
*/
public class DiffPrint {
private static final String LS = System.getProperty("line.separator"); // 改行文å—
private static final String FS = System.getProperty("file.separator"); // ファイル区切り文å—
private static final String HTML_AMP = "&";
private static final String HTML_GT = ">";
private static final String HTML_LT = "<";
private static final String HTML_DOUBLE_QUOT = """;
private static final String HTML_SPACE = " ";
private static final String HTML_TAB = HTML_SPACE + HTML_SPACE + HTML_SPACE + HTML_SPACE;
/** ãƒã‚¤ãƒ©ã‚¤ãƒˆ:行 */
private static final String HILIGHT = "*";
/** ãƒã‚¤ãƒ©ã‚¤ãƒˆ:è¿½åŠ è¡Œ */
private static final String HILIGHT_PLUS = "+";
/** ãƒã‚¤ãƒ©ã‚¤ãƒˆ:削除行 */
private static final String HILIGHT_MINUS = "-";
/** ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚»ãƒ‘レータ */
private static final String HILIGHT_SEP = "|";
private String src = null;
private String fileName = null;
/**
* 差分å°åˆ·ç”¨HTMLを出力ã—ã¾ã™ã€‚
*
* @param args 0:inDir 1:outDir
*/
public static void main(String[] args) throws IOException {
System.out.println("処ç†é–‹å§‹");
/* 入力ファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª */
File inDir = new File(".");
if (args.length > 0 && args[0] != null && args[0].trim().length() > 0) {
inDir = new File(args[0]);
}
if (!inDir.exists()) {
inDir.mkdir();
}
/* 出力ファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª */
File outDir = new File(".");
if (args.length > 1 && args[1] != null && args[1].trim().length() > 0) {
outDir = new File(args[1]);
}
if (!outDir.exists()) {
outDir.mkdir();
}
/* スタイルシートファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª */
File cssDir = new File(outDir.getPath() + FS + "css");
if (!cssDir.exists()) {
cssDir.mkdir();
}
DiffPrint dp = new DiffPrint();
File outFile = null;
File cssFile = new File(cssDir.getPath() + FS + "diffprint.css");
File[] inFiles = inDir.listFiles();
for (File file : inFiles) {
if (file.isFile()) {
outFile = new File(outDir.getPath() + FS + file.getName() + "_dp.html");
dp.readSource(file);
dp.writeSource(outFile);
System.out.println("IN -> " + file);
System.out.println("OUT -> " + outFile);
}
}
dp.writeCss(cssFile);
System.out.println("CSS -> " + cssFile);
System.out.println("処ç†çµ‚了");
}
/**
* ãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µåã‚’è¿”ã™
*
* @param file ファイル
* @return ext æ‹¡å¼µå
*/
private static String getExtension(File file) {
StringTokenizer st = new StringTokenizer(file.getName(), ".");
String ext = null;
while (st.hasMoreTokens()) {
ext = st.nextToken();
}
return ext;
}
/**
* ソースファイルã®èªã¿è¾¼ã¿ã¾ã™
*
* @param inFile ソースファイル
*/
public void readSource(File inFile) throws IOException {
StringBuilder sb = new StringBuilder();
InputStreamReader inReader = new InputStreamReader(new FileInputStream(inFile));
int ch;
while ((ch = inReader.read()) != -1) {
sb.append((char) ch);
}
this.src = sb.toString();
this.fileName = inFile.getName();
}
/**
* çµæžœã‚’HTMLå½¢å¼ã§æ›¸ã出ã—ã¾ã™
*
* @param outFile çµæžœã‚’出力ã™ã‚‹ãƒ•ァイル
*/
public void writeSource(File outFile) throws IOException {
BufferedReader reader = new BufferedReader(new StringReader(this.src));
FileWriter fw = new FileWriter(outFile);
/* å‰åŠéƒ¨åˆ† */
fw.write(makePreSourceArea());
int rowNum = 0;
String line;
while ((line = reader.readLine()) != null) {
/* ソース部分 */
fw.write(makeSourceArea(++rowNum, line));
}
/* 後åŠéƒ¨åˆ† */
fw.write(makePostSourceArea(++rowNum));
fw.close();
}
/**
* スタイルシートファイルを作æˆã—ã¾ã™ã€‚
*
* @param cssFile 出力ã™ã‚‹ã‚¹ã‚¿ã‚¤ãƒ«ã‚·ãƒ¼ãƒˆãƒ•ァイル
*/
public void writeCss(File cssFile) throws IOException {
FileWriter fw = new FileWriter(cssFile);
fw.write(makeCssArea());
fw.close();
}
/**
* 出力ソースã®å‰åŠéƒ¨åˆ†ã‚’作æˆã—ã¾ã™ã€‚
*
* @return 出力ソースã®å‰åŠéƒ¨åˆ†
*/
private String makePreSourceArea() {
StringBuilder sb = new StringBuilder();
sb.append("").append(LS);
sb.append("").append(LS);
sb.append("").append(LS);
sb.append("").append(this.fileName).append(" ").append(LS);
sb.append("").append(LS);
sb.append("").append(LS);
sb.append("").append(LS);
sb.append("").append(this.fileName).append(" ").append(LS);
return sb.toString();
}
/**
* 出力ソースã®å¾ŒåŠéƒ¨åˆ†ã‚’作æˆã—ã¾ã™ã€‚
*
* @param rowNum 行番å·
* @return 出力ソースã®å¾ŒåŠéƒ¨åˆ†
*/
private String makePostSourceArea(int rowNum) {
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append("").append(rowNum).append(" ");
sb.append("[EOF] ");
sb.append(" ").append(LS);
sb.append("
").append(LS);
sb.append("").append(LS);
sb.append("").append(LS);
return sb.toString();
}
/**
* ソース部分を作æˆã—ã¾ã™ã€‚
*
* @param rowNum 行番å·
* @param line ソース一行分
* @return 出力ソース一行分
*/
private String makeSourceArea(int rowNum, String line) {
/* ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡Œã‹ã©ã†ã‹ã®åˆ¤å®š */
String hilightMark = isHilight(line);
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append("");
if (hilightMark != null) {
sb.append(hilightMark);
}
sb.append(rowNum);
sb.append(" ");
sb.append("").append(htmlEscape(line)).append(" ");
sb.append(" ").append(LS);
return sb.toString();
}
/**
* ã‚¹ã‚¿ã‚¤ãƒ«ã‚·ãƒ¼ãƒˆã®æ–‡å—列を作æˆã—ã¾ã™ã€‚
*
* @return CSS
*/
private String makeCssArea() {
StringBuilder sb = new StringBuilder();
sb.append("body {").append(LS);
sb.append("\tfont-family: \"ï¼ï¼³ ゴシック\";").append(LS);
sb.append("}").append(LS);
sb.append(".source-table {").append(LS);
sb.append("\twidth: 650px;").append(LS); // 650ã ã¨ã´ã£ãŸã‚Šãらã„
sb.append("\twidth: 645px;").append(LS); // 650ã ã¨ã´ã£ãŸã‚Šãらã„
sb.append("\tfont-size: 12px;").append(LS);
sb.append("}").append(LS);
sb.append(".row-num {").append(LS);
sb.append("\ttext-align: right;").append(LS);
sb.append("\tvertical-align: top;").append(LS);
sb.append("\tword-break: keep-all;").append(LS);
sb.append("\tword-wrap: normal;").append(LS);
sb.append("\tborder-right: 1px solid gray;").append(LS);
sb.append("}").append(LS);
sb.append(".source {").append(LS);
sb.append("\tpadding-left: 0.3em;").append(LS);
sb.append("\tword-break: break-all;").append(LS);
sb.append("\tword-wrap: break-word;").append(LS);
sb.append("}").append(LS);
sb.append(".end-of-file {").append(LS);
sb.append("\tcolor: gray;").append(LS);
sb.append("\tpadding-left: 0.3em;").append(LS);
sb.append("\tword-break: break-all;").append(LS);
sb.append("\tword-wrap: break-word;").append(LS);
sb.append("}").append(LS);
sb.append("caption {").append(LS);
sb.append("\ttext-align: left;").append(LS);
sb.append("\tfont-weight: bold;").append(LS);
sb.append("}").append(LS);
sb.append(".hilight {").append(LS);
sb.append("\tbackground-color: yellow;").append(LS);
sb.append("}").append(LS);
sb.append(".hilight-plus {").append(LS);
sb.append("\tbackground-color: gold;").append(LS);
sb.append("}").append(LS);
sb.append(".hilight-minus {").append(LS);
sb.append("\tbackground-color: silver;").append(LS);
return sb.toString();
}
/**
* ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡Œã‹ã©ã†ã‹åˆ¤å®šã—ã¾ã™
*
* @param line ソース一行分
* @return ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡Œã®å ´åˆã€cssã®ãƒã‚¤ãƒ©ã‚¤ãƒˆç”¨ã‚¯ãƒ©ã‚¹åã‚’è¿”å´ã€‚
* ãƒã‚¤ãƒ©ã‚¤ãƒˆè¡Œã§ãªã‘れã°nullã‚’è¿”å´ã€‚
*/
private String isHilight(String line) {
if (line.startsWith(HILIGHT + HILIGHT_SEP)) {
return HILIGHT;
} else if (line.startsWith(HILIGHT_PLUS + HILIGHT_SEP)) {
return HILIGHT_PLUS;
} else if (line.startsWith(HILIGHT_MINUS + HILIGHT_SEP)) {
return HILIGHT_MINUS;
}
return null;
}
private String makeHilight(String mark) {
if (HILIGHT.equals(mark)) {
return " class=\"hilight\"";
} else if (HILIGHT_PLUS.equals(mark)) {
return " class=\"hilight-plus\"";
} else if (HILIGHT_MINUS.equals(mark)) {
return " class=\"hilight-minus\"";
}
return "";
}
/**
* ãƒã‚¤ãƒ©ã‚¤ãƒˆéƒ¨ã‚’除去ã—ã¾ã™ã€‚
*
* @param line ソース一行分
* @return ãƒã‚¤ãƒ©ã‚¤ãƒˆéƒ¨ã‚’除去ã—ãŸã‚½ãƒ¼ã‚¹ä¸€è¡Œåˆ†
*/
private String deleteHilightMark(String line) {
return line.replace(HILIGHT + HILIGHT_SEP, "")
.replace(HILIGHT_MINUS + HILIGHT_SEP, "")
.replace(HILIGHT_PLUS + HILIGHT_SEP, "");
}
/**
* HTMLエスケープを施ã—ã¦è¿”å´ã—ã¾ã™ã€‚
*
* @param line ソース一行分
* @return HTMLエスケープã•れãŸã‚½ãƒ¼ã‚¹ä¸€è¡Œåˆ†
*/
private String htmlEscape(String line) {
return line.replaceAll("&", HTML_AMP)
.replaceAll("<", HTML_LT)
.replaceAll(">", HTML_GT)
.replaceAll("\"", HTML_DOUBLE_QUOT)
.replaceAll(" ", HTML_SPACE)
.replaceAll("\t", HTML_TAB);
}
}
Opinions expressed by DZone contributors are their own.
Comments