// // @(#)TurnParser.java 1.00 6/2002 // // Copyright 2002 Zachary DelProposto. All rights reserved. // Use is subject to license terms. // // // This program 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. // // This program 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. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Or from http://www.gnu.org/ // package dip.judge.parser; import dip.world.Phase; import dip.misc.Utils; import java.io.*; import java.util.regex.*; import java.util.*; /** * Parses the Turns of a History file. * <p> * * * * * */ public class TurnParser { // il8n constants private static final String TP_NO_SUBJECT = "JP.turn.nosubject"; private static final String TP_BAD_PHASE = "JP.turn.badphase"; private static final String TP_BAD_SUBJECT = "JP.turn.badsubject"; /** * Pattern for matching the phase in the Subject: line<br> * xDDDDx pattern. Entire group is used. */ public static final String SUBJ_PHASE_REGEX = "\\s+\\p{Alpha}\\d{4}\\p{Alpha}\\s+"; /** * Pattern for matching the phase in the Subject: line<br> * xDDDDx pattern. Entire group is used. * For older versions of nJudge */ public static final String SUBJ_PHASE_REGEX_OLD = "\\s+\\p{Alpha}\\d{4}\\p{Alpha}\\s*$"; /** * This text (or pattern) must be present in the Subject: line. If it is not present, * the turn is ignored. */ public static final String RESULT_SUBJ_REGEX = "(?i)results"; // instance variables private Turn[] turns = null; /** Create the TurnParser and perform parsing. */ public TurnParser(String input) throws IOException, PatternSyntaxException { parseTurns(input); }// TurnParser() /** Returns the turns. If not parsed, or an error occured, it may return null. */ public Turn[] getTurns() { return turns; }// getTurns() /** * Creates Turn objects. * * * * * */ private void parseTurns(String input) throws IOException, PatternSyntaxException { // patterns Pattern subjPhasePattern = Pattern.compile(SUBJ_PHASE_REGEX); Pattern subjPhasePatternOld = Pattern.compile(SUBJ_PHASE_REGEX_OLD); Pattern isResultsPattern = Pattern.compile(RESULT_SUBJ_REGEX); LinkedList turnList = new LinkedList(); BufferedReader reader = new BufferedReader(new StringReader(input)); String line = reader.readLine(); StringBuffer sb = null; Turn turn = new Turn(); // current turn Turn lastTurn = null; // previous turn while(line != null) { int pos = line.toLowerCase().indexOf("date:"); if(pos >= 0 && pos < 10) { turn.setDateLine(line); // set the subject line; if not present, throw an error (shouldn't occur) String nextLine = reader.readLine(); if( nextLine.toLowerCase().indexOf("subject:") == -1 ) { throw new IOException(Utils.getLocalString(TP_NO_SUBJECT)); } else if(isResultsPattern.matcher(nextLine).find()) { turn.setSubjectLine(nextLine); // regex parse the subject line Matcher m = subjPhasePattern.matcher(nextLine); Matcher m_o = subjPhasePatternOld.matcher(nextLine); if(m.find()) { Phase phase = Phase.parse(m.group(0).trim()); if(phase == null) { throw new IOException(Utils.getLocalString(TP_BAD_PHASE, m.group(0).trim())); } turn.setPhase(phase); } else if(m_o.find()) { Phase phase = Phase.parse(m_o.group(0).trim()); if(phase == null) { throw new IOException(Utils.getLocalString(TP_BAD_PHASE, m_o.group(0).trim())); } turn.setPhase(phase); } else { throw new IOException(Utils.getLocalString(TP_BAD_SUBJECT, nextLine)); } if(lastTurn != null) { lastTurn.setText(sb.toString()); turnList.add(lastTurn); lastTurn = null; } lastTurn = turn; turn = new Turn(); sb = new StringBuffer(512); } } else if(sb != null) { // accumulate text sb.append(line); sb.append('\n'); } line = reader.readLine(); } // add last turn if(lastTurn != null) { lastTurn.setText(sb.toString()); turnList.add(lastTurn); } // convert to array turns = (Turn[]) turnList.toArray(new Turn[turnList.size()]); }// parseTurns() /** A Turn object is created for each Turn detected in the History file. */ public static class Turn { private String dateLine; private String subjectLine; private String text; private Phase phase; public Turn() {} /** Sets the unparsed Date: line */ public void setDateLine(String value) { dateLine = value; } /** Sets the unparsed Subject: line */ public void setSubjectLine(String value) { subjectLine = value; } /** Sets the PhaseType */ public void setPhase(Phase value) { phase = value; } /** Sets the text between Subject: and upto (but not including) the next Date: line */ public void setText(String value) { text = value; } /** Returns the unparsed Date: line */ public String getDateLine() { return dateLine; } /** Returns the unparsed Subject: line */ public String getSubjectLine() { return subjectLine; } /** Returns the PhaseType, or null if it cannot be detected. */ public Phase getPhase() { return phase; } /** Returns the text between Subject: upto (but not including) the next Date: line */ public String getText() { return text; } }// nested class Turn }// class TurnParser