| package org.eclipse.ganymede.webgen; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| public class ParseLogFile { |
| // TODO update the wiki re Ganymede schedule |
| // TODO write instructions for contributing |
| // TODO write instructions for setting this up on your local machine and |
| // build machine |
| // TODO pack200 |
| // TODO web interface to start a new build w/ lockfile to prevent two at |
| // once |
| // TODO article about using including using for RCP |
| public File directory; |
| public BufferedReader input; |
| |
| public List<LogLine> lines; |
| public Status overall_status; |
| public String end_time; |
| GenerateStatusFile statusFile; |
| |
| public static void main(String[] args) throws CloneNotSupportedException { |
| (new ParseLogFile()).do_main(args); |
| } |
| |
| void do_main(String[] args) throws CloneNotSupportedException { |
| try { |
| this.directory = new File(args[0]); |
| this.statusFile = new GenerateStatusFile(this.directory); |
| this.input = new BufferedReader(new FileReader(new File( |
| this.directory, "log.txt"))); |
| read_all_lines_into_memory(); |
| this.input.close(); |
| } catch (IOException x) { |
| try { |
| this.statusFile.write_internal_error_status_file(x); |
| } catch (IOException xx) { |
| // two errors in a row? we'll just give up |
| return; |
| } |
| return; |
| } |
| scan_for_blame(); |
| scan_for_status(); |
| this.statusFile.mark_end_time(); |
| try { |
| write_html_log_files(); |
| } catch (IOException x) { |
| try { |
| this.statusFile.write_internal_error_status_file(x); |
| } catch (IOException xx) { |
| // two errors in a row? we'll just give up |
| return; |
| } |
| return; |
| } |
| try { |
| this.statusFile.write_final_status_file(this.overall_status); |
| } catch (IOException xx) { |
| // an error writing the status file? I guess we can't write the |
| // status file |
| return; |
| } |
| } |
| |
| void scan_for_blame() { |
| Map<String, Blame> blames = new HashMap<String, Blame>(); |
| Set<LogLine> subsetlines = new HashSet<LogLine>(); |
| int state = 0; |
| for (Iterator<LogLine> iterator = lines.iterator(); iterator.hasNext();) { |
| LogLine line = iterator.next(); |
| switch (state) { |
| case 0: |
| subsetlines.add(line); |
| Blame b = line.parseBlame(); |
| if (b != null) { |
| state = 1; |
| blames.put(b.getKey(), b); |
| } |
| break; |
| case 1: |
| b = line.parseBlame(); |
| if (b != null) { |
| blames.put(b.getKey(), b); |
| } else { |
| for (Iterator<LogLine> iterator2 = subsetlines.iterator(); iterator2 |
| .hasNext();) { |
| LogLine logLine = iterator2.next(); |
| logLine.assignBlameIfNeeded(blames); |
| } |
| state = 0; |
| subsetlines = new HashSet<LogLine>(); |
| blames = new HashMap<String, Blame>(); |
| } |
| break; |
| } |
| } |
| } |
| |
| void scan_for_status() throws CloneNotSupportedException { |
| this.overall_status = Status.unknown; |
| for (Iterator<LogLine> iterator = lines.iterator(); iterator.hasNext();) { |
| LogLine line = iterator.next(); |
| this.overall_status = this.overall_status.combine(line |
| .scan_for_status()); |
| } |
| } |
| |
| void write_html_log_files() throws IOException { |
| File outfile = new File(this.directory, "index.html"); |
| PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter( |
| outfile))); |
| write_html_log_header(output); |
| write_error_jumps(output); |
| write_html_log_lines(output); |
| write_html_log_footer(output); |
| output.close(); |
| } |
| |
| private void write_html_log_lines(PrintWriter output) { |
| for (Iterator<LogLine> iterator = lines.iterator(); iterator.hasNext();) { |
| LogLine line = iterator.next(); |
| line.write_log_line(output); |
| output.println("<br>"); |
| } |
| } |
| |
| private void write_error_jumps(PrintWriter output) { |
| List<LogLine> anchoredLines = new ArrayList<LogLine>(); |
| boolean previousLineHadAnchor = false; |
| Blame previousBlame = null; |
| for (Iterator<LogLine> iterator = lines.iterator(); iterator.hasNext();) { |
| LogLine line = iterator.next(); |
| if (line.getAnchor() != null) { |
| if( previousLineHadAnchor |
| && line.getBlame() == previousBlame ) { |
| // skip |
| } else { |
| anchoredLines.add(line); |
| } |
| previousLineHadAnchor = true; |
| previousBlame = line.getBlame(); |
| } else { |
| previousLineHadAnchor = false; |
| } |
| } |
| if (!anchoredLines.isEmpty()) { |
| Map<Object, List<LogLine>> anchoredLinesByBlame = new HashMap<Object, List<LogLine>>(); |
| Set<Object> blameOrder = new TreeSet<Object>( |
| new Comparator<Object>() { |
| public int compare(Object a, Object b) { |
| if (a instanceof Blame) { |
| if (b instanceof Blame) { |
| return ((Blame) a) |
| .stringForStatusMessage() |
| .compareTo( |
| ((Blame) b) |
| .stringForStatusMessage()); |
| } else { |
| return -1; |
| } |
| } else { |
| if (b instanceof Blame) { |
| return 1; |
| } else { |
| return ((String) a).compareTo((String) b); |
| } |
| } |
| } |
| }); |
| for (Iterator<LogLine> iterator = anchoredLines.iterator(); iterator |
| .hasNext();) { |
| LogLine logLine = (LogLine) iterator.next(); |
| Blame b = logLine.getBlame(); |
| List<LogLine> list; |
| if (b == null) |
| list = anchoredLinesByBlame.get("(other)"); |
| else |
| list = anchoredLinesByBlame.get(logLine.getBlame()); |
| if (list == null) { |
| list = new ArrayList<LogLine>(); |
| Object k; |
| if (b == null) |
| k = "(other)"; |
| else |
| k = logLine.getBlame(); |
| blameOrder.add(k); |
| anchoredLinesByBlame.put(k, list); |
| } |
| list.add(logLine); |
| } |
| output.println("<p>Errors: <ul>"); |
| for (Iterator<Object> keysiterator = blameOrder.iterator(); keysiterator |
| .hasNext();) { |
| Object key = keysiterator.next(); |
| output.print("<li>"); |
| if (key instanceof Blame) |
| output.println(((Blame) key).stringForStatusMessage()); |
| else |
| output.println(key); |
| for (Iterator<LogLine> iterator = anchoredLinesByBlame.get(key) |
| .iterator(); iterator.hasNext();) { |
| LogLine line = iterator.next(); |
| output.println("<a href=\"#" + line.getAnchor() |
| + "\"><span style=\"background-color: " |
| + WebPageColors.fail_color() + "\">" |
| + line.linenumber + "</span></a> "); |
| } |
| output.println("</li>"); |
| } |
| output.println("</ul>"); |
| } |
| } |
| |
| private void write_html_log_footer(PrintWriter output) { |
| output.println("<p><em><font size=-1>Build started " |
| + this.statusFile.start_time + "; completed " |
| + this.statusFile.end_time + "</font></em></p>\n"); |
| output.println("</body>\n"); |
| output.println("</html>\n"); |
| } |
| |
| private void write_html_log_header(PrintWriter output) { |
| output.println("<html>\n"); |
| output.println("<head>\n"); |
| output.println("<title>Ganymede Build Log</title>\n"); |
| output |
| .println("<link rel=\"stylesheet\" type=\"text/css\" href=\"http://www.eclipse.org/eclipse.org-common/themes/Phoenix/css/visual.css\" media=\"screen\" />\n"); |
| output.println("</head><body>\n"); |
| output |
| .println("<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"); |
| output |
| .println("<tr style=\"background-image: url(http://dash.eclipse.org/dash/commits/web-app/header_bg.gif);\">\n"); |
| output.println("<td>\n"); |
| output |
| .println("<a href=\"http://www.eclipse.org/\"><img src=\"http://dash.eclipse.org/dash/commits/web-app/header_logo.gif\" width=\"163\" height=\"68\" border=\"0\" alt=\"Eclipse Logo\" class=\"logo\" /></a>\n"); |
| output.println("</td>\n"); |
| output |
| .println("<td align=\"right\" style=\"color: white; font-family: verdana,arial,helvetica; font-size: 1.25em; font-style: italic;\"><b>Ganymede Build Log </b></font> </td>\n"); |
| output.println("</tr>\n"); |
| output.println("</table>\n"); |
| output.println("<p><em><font size=-1>Build started " |
| + this.statusFile.start_time + "; completed " |
| + this.statusFile.end_time + "</font></em></p>\n"); |
| output.println("<h1 style=\"background-color: " |
| + overall_status.color() + "\">Ganymede Build Log</h1>\n"); |
| } |
| |
| void read_all_lines_into_memory() throws IOException { |
| lines = new ArrayList<LogLine>(); |
| String line = input.readLine(); |
| int num = 1; |
| while (line != null) { |
| LogLine logline = new LogLine(line, num++); |
| lines.add(logline); |
| line = input.readLine(); |
| } |
| } |
| |
| } |