Java tutorial
/** * Copyright (C) 2009 JunHo Yoon * * bullshtml is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * bullshtml is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * */ package com.junoyoon; import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import org.stringtemplate.v4.ST; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.DefaultParser; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; /** * Main class * * @author JunHo Yoon (junoyoon@gmail.com) */ public class BullsHtml { private static final Options OPTS = new Options(); static { BullsHtml.OPTS.addOption("e", "encoding", true, "source code encoding."); BullsHtml.OPTS.addOption("h", "help", false, "print help"); BullsHtml.OPTS.addOption("f", "help", true, "assign test.cov file"); BullsHtml.OPTS.addOption("v", "verbose", false, "vebose output mode"); } /** System default encoding */ public static String enc = Constant.DEFAULT_ENCODING; /** Map b/w path and src */ public static Map<File, SrcDir> srcMap = new HashMap<File, SrcDir>(); /** top most dir list */ public static ArrayList<SrcDir> baseList = new ArrayList<SrcDir>(); /** src file list */ public static ArrayList<SrcFile> srcFileList = new ArrayList<SrcFile>(); public static Encoding sourceEncoding = Encoding.UTF_8; private static boolean verbose; /** * Construct Src and Dir List. After calling the method, the static variable * {@link BullsHtml.srcMap}, {@link BullsHtml.baseList}, * {@link BullsHtml.srcFileList} are constructed. * * @param covfile */ @SuppressWarnings("serial") public void process(final String covfile) { try { String output = BullsUtil.getCmdOutput(new ArrayList<String>() { { add("covxml"); add("--no-banner"); if (covfile != null) { add("-f"); add(covfile); } } }); if (output == null) { BullsHtml.printErrorAndExit( "While running covxml, A error occurs.\nPlease check bullseyecoverage path is and COVFILE environment variable"); } StringReader reader = new StringReader(output); processInternal(reader); } catch (Exception e) { BullsHtml.printErrorAndExit( "While running covxml, A error occurs.\nPlease check bullseyecoverage path is and COVFILE environment variable", e); } } public void processInternal(Reader reader) throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); Document build = builder.build(reader); Element root = build.getRootElement(); File rootDir = new File(root.getAttributeValue("dir")); buildSrcFileList(BullsHtml.srcFileList, root, rootDir); if (BullsHtml.baseList.size() > 1) { SrcDir dir = new SrcDir() { @Override public String getNormalizedPath() { return "_"; } @Override public File generateHtml(File targetPath) { File nPath = new File(targetPath, "_.html"); BullsUtil.writeToFile(nPath, getHtml()); return nPath; } }; dir.init(new File("/")); dir.addChildren(BullsHtml.baseList); BullsHtml.baseList.clear(); BullsHtml.baseList.add(dir); } else if (BullsHtml.baseList.size() == 1) { SrcDir dir = BullsHtml.baseList.get(0); while (!dir.isWorthToPrint()) { dir = (SrcDir) dir.child.get(0); } BullsHtml.baseList.set(0, dir); } } Pattern rootPathPattern = Pattern.compile("^([a-zA-Z]:|/)"); private void buildSrcFileList(ArrayList<SrcFile> srcFileList, Element eachFolder, File baseDir) { try { baseDir = baseDir.getCanonicalFile(); } catch (IOException e) { BullsHtml.printErrorAndExit(e); } for (Object elementObject : eachFolder.getChildren()) { Element element = (Element) elementObject; String name = element.getName(); if ("folder".equals(name)) { String newFolderName = element.getAttributeValue("name"); File newFile = this.rootPathPattern.matcher(newFolderName).find() ? new File(newFolderName) : new File(baseDir, newFolderName); buildSrcFileList(srcFileList, element, newFile); } else if ("src".equals(name)) { srcFileList.add(new SrcFile().init(baseDir, element)); } } } public void generateCloverXml(File o) { Set<SrcDir> parentDirList = new HashSet<SrcDir>(); for (SrcFile srcFile : BullsHtml.srcFileList) { parentDirList.add(srcFile.parentDir); } ST template = BullsUtil.getTemplate("clover"); template.add("mtime", System.currentTimeMillis() / 1000); if (BullsHtml.baseList.isEmpty()) { template.add("summary", new SrcDir()); } else { template.add("summary", BullsHtml.baseList.get(0)); } template.add("parentDirList", parentDirList); BullsUtil.writeToFile(new File(o, "clover.xml"), template.render()); } /** * Copy static resources * * @param outputFolder * the target folder * @throws IOException */ public void copyResources(String outputFolder) throws IOException { BullsUtil.copyResource(outputFolder + "/js/popup.js", "js_resources/popup.js"); BullsUtil.copyResource(outputFolder + "/js/sortabletable.js", "js_resources/sortabletable.js"); BullsUtil.copyResource(outputFolder + "/js/customsorttypes.js", "js_resources/customsorttypes.js"); BullsUtil.copyResource(outputFolder + "/js/stringbuilder.js", "js_resources/stringbuilder.js"); BullsUtil.copyResource(outputFolder + "/css/help.css", "css_resources/help.css"); BullsUtil.copyResource(outputFolder + "/css/main.css", "css_resources/main.css"); BullsUtil.copyResource(outputFolder + "/css/highlight.css", "css_resources/highlight.css"); BullsUtil.copyResource(outputFolder + "/css/sortabletable.css", "css_resources/sortabletable.css"); BullsUtil.copyResource(outputFolder + "/css/source-viewer.css", "css_resources/source-viewer.css"); BullsUtil.copyResource(outputFolder + "/css/tooltip.css", "css_resources/tooltip.css"); BullsUtil.copyResource(outputFolder + "/images/upper.png", "images_resources/upper.png"); BullsUtil.copyResource(outputFolder + "/images/check_icon.png", "images_resources/check_icon.png"); BullsUtil.copyResource(outputFolder + "/images/uncheck_icon.png", "images_resources/uncheck_icon.png"); BullsUtil.copyResource(outputFolder + "/images/blank.png", "images_resources/blank.png"); BullsUtil.copyResource(outputFolder + "/images/downsimple.png", "images_resources/downsimple.png"); BullsUtil.copyResource(outputFolder + "/images/upsimple.png", "images_resources/upsimple.png"); BullsUtil.copyResource(outputFolder + "/index.html", "html_resources/index.html"); BullsUtil.copyResource(outputFolder + "/help.html", "html_resources/help.html"); } /** * Show usage */ private static void usage() { String file = "com/junoyoon/usage.txt"; String output = BullsUtil.loadResourceContent(file); printMessage(output); System.exit(0); } /** * Print Message * * @param message * message to print */ public static void printMessage(String message) { System.out.println(message); } /** * Print Error Message and Exit * * @param message * message to print */ public static void printErrorAndExit(String message, Exception e) { System.err.println(message); if (BullsHtml.verbose) { e.printStackTrace(System.err); } System.exit(-1); } /** * Print Error Message and Exit * * @param message * message to print */ public static void printErrorAndExit(String message) { System.err.println("ERROR :" + message); System.exit(-1); } /** * Print Error Message and Exit * * @param message * message to print */ public static void printErrorAndExit(Exception e) { System.err.println("ERROR :" + e.getMessage()); e.printStackTrace(System.err); System.exit(-1); } /** * generate html * * @param targetPath * output dir */ public void generateHtml(File targetPath) { for (SrcDir srcDir : BullsHtml.baseList) { srcDir.generateHtml(targetPath); generateChildHtml(targetPath, srcDir); } generateDirListHtml(targetPath); generateFileListHtml(targetPath); generateMainHtml(targetPath); } public static boolean isSingleElement(SrcDir dir) { return dir.child.size() == 1 && dir.child.get(0) instanceof SrcDir; } /** * generate main html page * * @param path * output dir */ public void generateMainHtml(File path) { ST template = BullsUtil.getTemplate("frame_summary"); File nPath = new File(path, "frame_summary.html"); template.add("baseDir", BullsHtml.baseList); List<SrcFile> localSrcFileList = new ArrayList<SrcFile>(BullsHtml.srcFileList); // Sort By Risk Collections.sort(localSrcFileList, new Comparator<SrcFile>() { public int compare(SrcFile o1, SrcFile o2) { // System.out.println(o2.name + o2.risk + o1.name + o1.risk + // (o1.risk -o2.risk )); return o2.risk - o1.risk; } }); template.add("srcFileList", localSrcFileList.subList(0, Math.min(10, BullsHtml.srcFileList.size()))); List<SrcDir> dirFileList = getSrcDirList(); template.add("dirList", dirFileList.subList(0, Math.min(10, dirFileList.size()))); BullsUtil.writeToFile(nPath, template.render()); } public List<SrcDir> getSrcDirList() { ArrayList<SrcDir> list = new ArrayList<SrcDir>(); for (SrcDir srcDir : BullsHtml.srcMap.values()) { if (srcDir.isWorthToPrint()) { list.add(srcDir); } } Collections.sort(list, new Comparator<SrcDir>() { public int compare(SrcDir o1, SrcDir o2) { // System.out.println(o2.name + o2.risk + o1.name + o1.risk + // (o1.risk -o2.risk )); return o1.path.compareTo(o2.path); } }); return list; } /** * generate upper left dir html page * * @param path * output dir */ public void generateDirListHtml(File path) { ST template = BullsUtil.getTemplate("frame_dirs"); template.add("srcDirList", getSrcDirList()); File nPath = new File(path, "frame_dirs.html"); BullsUtil.writeToFile(nPath, template.render()); } /** * generate down left src html page * * @param path * output dir */ public void generateFileListHtml(File path) { ST template = BullsUtil.getTemplate("frame_files"); Collections.sort(BullsHtml.srcFileList); template.add("srcFileList", BullsHtml.srcFileList); BullsUtil.writeToFile(new File(path, "frame_files.html"), template.render()); } /** * generate each dir/file html page * * @param outputPath * @param dir * @param baseNormalizedName */ public void generateChildHtml(File outputPath, SrcDir dir) { for (Src src : dir.child) { src.generateHtml(outputPath); if (src instanceof SrcDir) { generateChildHtml(outputPath, (SrcDir) src); } } } /** * @param args */ public static void main(String[] args) { final CommandLineParser clp = new DefaultParser(); CommandLine line = null; // parse CLI options try { line = clp.parse(BullsHtml.OPTS, args); } catch (ParseException e) { printMessage("Invalid options"); usage(); return; } String sourceEncoding = BullsHtml.enc; // get encoding option if (line.hasOption("e")) { sourceEncoding = line.getOptionValue("e"); } // print usage if -h if (line.hasOption("h")) { usage(); } if (line.hasOption("v")) { BullsHtml.verbose = true; } String covfile = null; if (line.hasOption("f")) { covfile = line.getOptionValue("f"); if (!new File(covfile).exists()) { printErrorAndExit(covfile + " does not exists"); } } String outputPath = "."; if (line.getArgs().length != 1) { printErrorAndExit("please provide the html output directory"); } outputPath = line.getArgs()[0]; File o = new File(outputPath); if (!o.exists()) { if (!o.mkdirs()) { printErrorAndExit(outputPath + " directory can be not created."); } } else if (!o.isDirectory()) { printErrorAndExit(outputPath + " is not directory."); } else if (!o.canWrite()) { printErrorAndExit(outputPath + " is not writable."); } BullsHtml bullshtml = new BullsHtml(); bullshtml.process(covfile); if (BullsHtml.baseList.isEmpty()) { printErrorAndExit( "No coverage was recorded in cov file. please check if src is compiled with coverage on."); } try { bullshtml.copyResources(outputPath); } catch (Exception e) { printErrorAndExit("The output " + outputPath + " is not writable.", e); } BullsHtml.sourceEncoding = Encoding.getEncoding(sourceEncoding); bullshtml.generateHtml(o); bullshtml.generateCloverXml(o); } }