313 lines
11 KiB
Java
313 lines
11 KiB
Java
package application;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
|
|
|
|
import de.lcag.common.HashTable;
|
|
import de.lcag.common.Table.TableColumn;
|
|
import routines.LcagFileTools;
|
|
import routines.LcagLogger;
|
|
|
|
public class CommentExtractor {
|
|
private static final String BUGFIX_COMMAND = "BUGFIX_"; // Fix of a Agile Defect in Trackspace
|
|
private static final String STORY_COMMAND = "BUGFIX_"; // User Story in Trackspace to implement
|
|
private static final String HOW_TO_COMMAND = "HOWTO_";
|
|
private static final String DOCUMENT_FLOW_COMMAND = "FLOW_";
|
|
private static final String TODO_COMMAND = "TODO_";
|
|
|
|
private static final String[] COMMAD_LIST = new String[] { HOW_TO_COMMAND, DOCUMENT_FLOW_COMMAND, TODO_COMMAND,
|
|
BUGFIX_COMMAND, STORY_COMMAND };
|
|
|
|
private static final String COL_TYPE = "Type";
|
|
private static final String COL_ID = "Id";
|
|
private static final String COL_KIND = "Kind";
|
|
private static final String COL_STEP = "StepNo";
|
|
private static final String COL_DESC = "Description;style=width: 85%";
|
|
|
|
private static final String COL_FILE = "File";
|
|
private static final String COL_LINE_NO = "LineNo";
|
|
|
|
public static final String JAVA_CODE_BASE_PATH = "/workspace/ebx_lufthansa/ebx_lufthansa-lib/src/main/java/com/lufthansa/ebx";
|
|
public static final String SQL_CODE_BASE_PATH = "/workspace/ebx_lufthansa/ebx_lufthansa-resources/src/main/sql";
|
|
public static final String XSD_CODE_BASE_PATH = "/workspace/MDM-Datamodel";
|
|
public static final String JAVA_CODE_BASE_FULLPATH = "V:/EBX" + JAVA_CODE_BASE_PATH;
|
|
public static final String SQL_CODE_BASE_FULLPATH = "V:/EBX" + SQL_CODE_BASE_PATH;
|
|
public static final String XSD_CODE_BASE_FULLPATH = "V:/EBX" + XSD_CODE_BASE_PATH;
|
|
|
|
public static final String CODE_BASE_GITHUB_DIR = "https://dev.azure.com/LCAGDevOps/MDM/_git/EBX?path=%s&version=GB%s&line=%d&lineEnd=%d&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents";
|
|
public static final String DOC_FILE = "V:/EBX/workspace/ebx_lufthansa/ebx_lufthansa-lib/HowToImplement";
|
|
|
|
private static HashTable resultTable = new HashTable(COL_TYPE, COL_ID, COL_KIND, COL_STEP, COL_DESC, COL_FILE,
|
|
COL_LINE_NO);
|
|
private static String gitBranchName = "main";
|
|
|
|
private static LcagLogger logger = LcagLogger.getLogger(CommentExtractor.class);
|
|
|
|
public static void main(String[] args) {
|
|
String rootDirPath;
|
|
|
|
logger.setJavaLogLevel(LcagLogger.LOG_TRACE);
|
|
if (args.length < 1) {
|
|
rootDirPath = JAVA_CODE_BASE_FULLPATH;
|
|
logger.info("Using default Root directory to scan code: %s", rootDirPath);
|
|
} else {
|
|
rootDirPath = args[0];
|
|
}
|
|
|
|
try {
|
|
gitBranchName = getCurrentGitBranch();
|
|
} catch (Exception e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
}
|
|
|
|
resultTable.setName("MDM EBX Coding HowTo");
|
|
|
|
try {
|
|
extractCodeExamples(rootDirPath);
|
|
|
|
TableColumn sortedResults = resultTable.sort(COL_ID, COL_STEP);
|
|
|
|
String txt = resultTable.asCSV(sortedResults);
|
|
String fileName = DOC_FILE + ".csv";
|
|
LcagFileTools.writeTextFile(fileName, txt);
|
|
|
|
writeHtmlFile(sortedResults);
|
|
|
|
System.out.println(String.format("Saved Code examples to file: %s", DOC_FILE));
|
|
} catch (IOException e) {
|
|
logger.error("Error reading file: %s", e.getMessage());
|
|
}
|
|
}
|
|
|
|
private static void writeHtmlFile(TableColumn sortedResults) throws IOException {
|
|
String fileName = DOC_FILE + ".html";
|
|
|
|
for (int i = 0; i < resultTable.lenght(); i++) {
|
|
int lineNo = (int) resultTable.getCellValue(i, COL_LINE_NO);
|
|
|
|
String colId = (String) resultTable.getCellValue(i, COL_ID);
|
|
String filePath = (String) resultTable.getCellValue(i, COL_FILE);
|
|
String gitURL = String.format(CODE_BASE_GITHUB_DIR, filePath, gitBranchName, lineNo, lineNo + 1);
|
|
String lineNoURL = String.format("<html><a href=\"%s\">%d</a></html>", gitURL, lineNo);
|
|
|
|
if (filePath.endsWith(".java")) {
|
|
filePath = filePath.substring(JAVA_CODE_BASE_PATH.length() + 1);
|
|
} else if (filePath.endsWith(".sql")) {
|
|
filePath = filePath.substring(SQL_CODE_BASE_PATH.length() + 1);
|
|
} else if (filePath.endsWith(".xsd")) {
|
|
filePath = filePath.substring(XSD_CODE_BASE_PATH.length() + 1);
|
|
}
|
|
resultTable.setCellValue(i, COL_FILE, filePath);
|
|
resultTable.setCellValue(i, COL_LINE_NO, lineNoURL);
|
|
|
|
String kind = (String) resultTable.getCellValue(i, COL_KIND);
|
|
|
|
if (kind.equals("Title")) {
|
|
String disc = String.format("<html><b>%s</b></html>", (String) resultTable.getCellValue(i, COL_DESC));
|
|
resultTable.setCellValue(i, COL_DESC, disc);
|
|
|
|
// For BUGFIX or STORY: Add link into trackspace:
|
|
String digits = colId.replaceAll(".*[BS](\\d+).*", "$1"); // Extract digits after 'B'
|
|
|
|
if (!Objects.equals(colId, digits)) {
|
|
String htmlLink = "<html><a href=\"https://trackspace.lhsystems.com/browse/MDMGMT-" + digits
|
|
+ "\" target=\"_blank\">" + colId + "</a></html>";
|
|
|
|
resultTable.setCellValue(i, COL_ID, htmlLink);
|
|
}
|
|
}
|
|
}
|
|
|
|
String txt = resultTable.asHTML(sortedResults);
|
|
|
|
LcagFileTools.writeTextFile(fileName, txt);
|
|
String md = FlexmarkHtmlConverter.builder().build().convert(txt);
|
|
String mdFileName = DOC_FILE + ".md";
|
|
LcagFileTools.writeTextFile(mdFileName, md);
|
|
|
|
}
|
|
|
|
public static String getCurrentGitBranch() throws IOException, InterruptedException {
|
|
Process process = Runtime.getRuntime().exec("git rev-parse --abbrev-ref HEAD");
|
|
process.waitFor();
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
|
return reader.readLine();
|
|
}
|
|
|
|
private static void extractCodeExamples(String pRootDirPath) throws IOException {
|
|
List<File> fileList = LcagFileTools.findFilesWithExtension(pRootDirPath, ".java");
|
|
final List<File> sqlFileList = LcagFileTools.findFilesWithExtension(SQL_CODE_BASE_FULLPATH, ".sql");
|
|
final List<File> xsdFileList = LcagFileTools.findFilesWithExtension(XSD_CODE_BASE_FULLPATH, ".xsd");
|
|
|
|
fileList.addAll(xsdFileList);
|
|
fileList.addAll(sqlFileList);
|
|
|
|
for (File javaFile : fileList) {
|
|
String filename = javaFile.getName();
|
|
BufferedReader reader = new BufferedReader(new FileReader(javaFile));
|
|
StringBuilder currentComment = new StringBuilder();
|
|
boolean inMultilineComment = false;
|
|
boolean inSingleLineComment = false;
|
|
String line;
|
|
int lineNo = 0;
|
|
int commentStartLineNo = 0;
|
|
|
|
logger.trace("Processing file %s...", filename);
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
lineNo += 1;
|
|
line = line.trim();
|
|
|
|
final boolean singleLineComment = line.startsWith("//") /* java */ || line.startsWith("--") /* SQL */;
|
|
|
|
if (!inMultilineComment && singleLineComment) {
|
|
final String comment = line.substring(2).trim();
|
|
|
|
inSingleLineComment = true;
|
|
} else if (line.startsWith("/*") /* java */ || line.startsWith("<!--") /* xml */) {
|
|
final String comment = line.startsWith("/**") ? line.substring(3)
|
|
: (line.startsWith("<!--") ? line.substring(4) : line.substring(2));
|
|
|
|
commentStartLineNo = lineNo;
|
|
inMultilineComment = true;
|
|
currentComment.append(comment.trim());
|
|
}
|
|
|
|
final boolean isFirstLineInComment = lineNo == commentStartLineNo;
|
|
|
|
if (singleLineComment && inSingleLineComment) {
|
|
final String comment = line.substring(2).trim();
|
|
|
|
currentComment.append(" ").append(comment.trim());
|
|
} else if (!singleLineComment && inSingleLineComment) {
|
|
String comment = currentComment.toString().trim();
|
|
inSingleLineComment = false;
|
|
|
|
parseComment(comment, javaFile, lineNo);
|
|
currentComment.setLength(0);
|
|
} else if (inMultilineComment && (line.endsWith("*/") /* java */ || line.endsWith("-->") /* xml */ )) {
|
|
String comment = line.endsWith("*/") ? line.substring(0, line.length() - 2)
|
|
: line.substring(0, line.length() - 3);
|
|
|
|
if (isFirstLineInComment) {
|
|
comment = currentComment.toString().trim();
|
|
comment = comment.endsWith("*/") ? comment.substring(0, comment.length() - 2)
|
|
: comment.substring(0, comment.length() - 3);
|
|
} else {
|
|
currentComment.append(" ").append(comment.trim());
|
|
comment = currentComment.toString().trim();
|
|
}
|
|
|
|
parseComment(comment, javaFile, lineNo);
|
|
|
|
inMultilineComment = false;
|
|
commentStartLineNo = 0;
|
|
currentComment.setLength(0);
|
|
} else if (inMultilineComment && !isFirstLineInComment) {
|
|
if (line.startsWith("*"))
|
|
line = line.substring(1).trim();
|
|
currentComment.append(" ").append(line);
|
|
}
|
|
}
|
|
|
|
reader.close();
|
|
}
|
|
}
|
|
|
|
private static void parseComment(String pComment, File pInFile, int pLineNo) {
|
|
String command = null;
|
|
|
|
String type = null;
|
|
String regEx = String.join("|", COMMAD_LIST);
|
|
Pattern pattern = Pattern.compile(regEx);
|
|
Matcher matcher = pattern.matcher(pComment);
|
|
|
|
List<String> cmdList = new ArrayList<>();
|
|
List<Integer> startPositionList = new ArrayList<>();
|
|
|
|
while (matcher.find()) {
|
|
final int start = matcher.start();
|
|
String cmd = matcher.group();
|
|
|
|
cmdList.add(cmd);
|
|
startPositionList.add(start);
|
|
}
|
|
|
|
if (cmdList.isEmpty())
|
|
return;
|
|
|
|
for (int n = 0; n < cmdList.size(); n++) {
|
|
String cmd = cmdList.get(n);
|
|
int start = startPositionList.get(n);
|
|
int end = 0;
|
|
|
|
if (n == cmdList.size() - 1) {
|
|
end = pComment.length();
|
|
} else {
|
|
String nextCmd = (String) cmdList.get(n + 1);
|
|
end = startPositionList.get(n + 1);
|
|
}
|
|
|
|
start += cmd.length();
|
|
command = pComment.substring(start, end);
|
|
|
|
// FIXME: Problem if comment text also includes "_"
|
|
command = command.replace("_", ";");
|
|
|
|
command = command.replaceFirst(":", ";");
|
|
List<String> split = new ArrayList<>(Arrays.asList(command.split(";")));
|
|
|
|
if (split.size() < 2) {
|
|
logger.warn("Unexpected HowTo format '%s', should be '%s H<ID>: [Title:|<StepNo>.] <Description>",
|
|
pComment, cmd);
|
|
return;
|
|
}
|
|
|
|
type = cmd.substring(0, cmd.length() - 1);
|
|
|
|
String id = split.remove(0);
|
|
String kind = split.remove(0).trim();
|
|
String descr = String.join(" ", split).trim();
|
|
String absoluteSourceCodeFilePath = pInFile.getAbsolutePath();
|
|
|
|
absoluteSourceCodeFilePath = absoluteSourceCodeFilePath.replace("\\", "/");
|
|
absoluteSourceCodeFilePath = absoluteSourceCodeFilePath.replaceFirst("V:/EBX", "");
|
|
|
|
String stepNoStr = "00";
|
|
|
|
if (!"Title".equals(kind)) {
|
|
stepNoStr = kind.replace("Step", "");
|
|
kind = "Step";
|
|
|
|
}
|
|
|
|
int rowNo = resultTable.newRow();
|
|
|
|
resultTable.setCellValue(rowNo, COL_TYPE, type);
|
|
resultTable.setCellValue(rowNo, COL_ID, id);
|
|
resultTable.setCellValue(rowNo, COL_KIND, kind);
|
|
resultTable.setCellValue(rowNo, COL_STEP, stepNoStr);
|
|
resultTable.setCellValue(rowNo, COL_FILE, absoluteSourceCodeFilePath);
|
|
resultTable.setCellValue(rowNo, COL_LINE_NO, pLineNo);
|
|
resultTable.setCellValue(rowNo, COL_DESC, descr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|