package org.wamblee.crawler.kiss.main;
import java.util.EnumMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.wamblee.crawler.kiss.guide.Program;
+import org.wamblee.crawler.kiss.guide.TimeInterval;
import org.wamblee.crawler.kiss.guide.Program.RecordingResult;
/**
* in what order and makes decisions in case of conflicts.
*/
public class ProgramActionExecutor {
-
- private static final Log LOG = LogFactory.getLog(ProgramActionExecutor.class);
+
+ private static final Log LOG = LogFactory
+ .getLog(ProgramActionExecutor.class);
/**
* A map of category name to a set of program. Useful for displaying the
private Map<String, Set<Program>> _interestingShows;
/**
- * Set of programs to record.
+ * Map of priority to set of programs.
*/
- private Set<Program> _showsToRecord;
+ private Map<Integer, Set<Program>> _showsToRecord;
/**
* Map or recording result to a set of programs.
*/
public ProgramActionExecutor() {
_interestingShows = new TreeMap<String, Set<Program>>();
- _showsToRecord = new TreeSet<Program>(new Program.TimeSorter());
+ _showsToRecord = new TreeMap<Integer, Set<Program>>();
_recordings = new EnumMap<RecordingResult, Set<Program>>(
RecordingResult.class);
for (RecordingResult result : RecordingResult.values()) {
*/
public void recordProgram(int aPriority, Program aProgram) {
LOG.info("priority = " + aPriority + ", program: " + aProgram);
- _showsToRecord.add(aProgram);
+ // Putting -priority into the set makes sure that iteration order
+ // over the priorities will go from higher priority to lower priority.
+ Set<Program> programs = _showsToRecord.get(-aPriority);
+ if (programs == null) {
+ programs = new TreeSet<Program>(new Program.TimeSorter());
+ _showsToRecord.put(-aPriority, programs);
+ }
+ programs.add(aProgram);
}
/**
*
*/
public void commit() {
- for (Program program : _showsToRecord) {
- RecordingResult result = program.record();
- _recordings.get(result).add(program);
+ Set<TimeInterval> previouslyRecorded = new HashSet<TimeInterval>();
+ for (Integer priority : _showsToRecord.keySet()) {
+ for (Program program : _showsToRecord.get(priority)) {
+ TimeInterval interval = program.getInterval();
+ if ( recordingConflictExists(previouslyRecorded, interval)) {
+ _recordings.get(RecordingResult.CONFLICT).add(program);
+ } else {
+ RecordingResult result = program.record();
+ _recordings.get(result).add(program);
+ previouslyRecorded.add(interval);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks an interval for overlap with a previously recorded program.
+ * @param aPreviouslyRecorded Previously recorded programs.
+ * @param interval Interval.
+ * @return True iff there is a recording conflict.
+ */
+ private boolean recordingConflictExists(Set<TimeInterval> aPreviouslyRecorded, TimeInterval interval) {
+ for (TimeInterval recordedInterval: aPreviouslyRecorded ) {
+ if ( interval.overlap(recordedInterval)) {
+ return true;
+ }
}
+ return false;
}
/**
* Parse the configuration of desired programs.
*/
class ProgramConfigurationParser {
-
- /**
- *
- */
private static final int DEFAULT_SMTP_PORT = 25;
+
+ private static final int DEFAULT_PRIORITY = 1;
private static final String ELEM_PASSWORD = "password";
// Configuration of interesting programs.
private static final String ELEM_PROGRAM = "program";
+
+ private static final String ELEM_PRIORITY = "priority";
private static final String ELEM_PATTERN = "match";
}
Element actionElem = program.element(ELEM_ACTION);
- ProgramAction action = new RecordProgramAction(1);
+ int priority = DEFAULT_PRIORITY;
+ String priorityString = program.elementTextTrim(ELEM_PRIORITY);
+ if ( priorityString != null ) {
+ priority = Integer.valueOf(priorityString);
+ }
+ ProgramAction action = new RecordProgramAction(priority);
if (actionElem != null) {
if (actionElem.getText().equals(ACTION_NOTIFY)) {
action = new InterestingProgramAction(category);