blob: e7c9bbb7d4503ae1dce7731301554c476174ead4 [file] [log] [blame]
package org.eclipse.europa.tools.webgen;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LogFileParser {
public BufferedReader input;
public List<ProjectLog> projects;
public List<LogLine> lines;
public Status status;
public LogFileParser(File f) throws IOException {
input = new BufferedReader(new FileReader(f));
}
public void parse() throws IOException {
read_all_lines_into_memory();
divide_into_projects();
for (Iterator<ProjectLog> iterator = projects.iterator(); iterator
.hasNext();) {
ProjectLog project = iterator.next();
project.divide_into_features();
}
}
void scan_for_status() throws IOException {
this.status = Status.unknown;
for (Iterator<ProjectLog> iterator = projects.iterator(); iterator
.hasNext();) {
ProjectLog project = iterator.next();
project.scan_for_status();
this.status = this.status.combine(project.status);
}
if (this.status.isFail())
this.status = Status.fail;
}
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();
}
}
void divide_into_projects() {
/*
* This algorithm works by looking through the lines of the log
* file for special marker lines. In general, it keeps three pointers:
*
* ...
* ...
* ... <-- start (of the project I'm currently scanning)
* ... \
* ... |<-- (body of the project I'm currently scanning)
* ... /
* ... <-- potential_end (of the project I'm currently scanning)
* ... \
* ... |<-- (body of the next project)
* ... /
* ... <-- line_number (the current line)
*
* This is because we don't know we're in a new project until we encounter
* the "Project:" header, but at the same time the beginning of the new
* project is the previous "update:" line before the Project: line.
*/
projects = new ArrayList<ProjectLog>();
ProjectLog current = new ProjectLog("prefix", "");
projects.add(current);
Pattern p1 = Pattern
.compile("\\[echo\\]\\s+\\-*\\s+Project:\\s+([\\w\\s_\\-\\.,]+)\\s+Responsible:\\s+(\\w+)");
Pattern p2 = Pattern.compile("update:");
Pattern p3 = Pattern.compile("^Total time:");
int start_of_current_project = 0;
int potential_end = 0;
Iterator<LogLine> iter = lines.iterator();
int line_number = 0;
while (iter.hasNext()) {
LogLine line = iter.next();
Matcher m1 = p1.matcher(line.line);
Matcher m2 = p2.matcher(line.line);
Matcher m3 = p3.matcher(line.line);
/*
* If we've found a "Project:" line then we need
* to start a new project section.
*/
if (m1.find()) {
/* special case for the first project in the file:
* we haven't seen the end of the previous project yet (because
* there isn't one), so the Project: line be the "end" of the
* non-existent previous project */
if (start_of_current_project == potential_end)
potential_end = line_number;
/* save away the lines for the current project, i.e.,
* the one we were collecting for, not the one for which
* we've just seen the start line */
current.lines = lines.subList(start_of_current_project, potential_end);
/* the start of the next project section is the end
* of the current one */
start_of_current_project = potential_end;
/* the end of the next project cannot be earlier than
* it's beginning, so set it as well */
potential_end = start_of_current_project;
/* start a new project with the new name, etc.
* We are now scanning lines for this project. */
current = new ProjectLog(m1.group(1), m1.group(2));
projects.add(current);
}
/*
* If we've found "update:" then it marks the potential
* end to the current project. We won't know that until
* we find a "Project:" line, but we record it as a
* potential end here.
*/
if (m2.matches() )
potential_end = line_number;
/*
* If we've found "Total time:" then the NEXT line is
* the potential end to the current project. Again, we
* won't know that until...
*/
if (m3.find() )
potential_end = line_number + 1;
line_number++;
}
potential_end = line_number;
current.lines = lines.subList(start_of_current_project, potential_end);
}
}