(no commit message)
[utils] / crawler / kiss / src / org / wamblee / crawler / kiss / Program.java
index 765ddfe1b2b8b590dacd1e168194d0adb20cab4f..c80fea246badc9c8cfe19c2e9b0addb78e1ea392 100644 (file)
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */ 
+ */
 
 package org.wamblee.crawler.kiss;
 
+import java.util.Comparator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.DocumentFactory;
+import org.dom4j.Element;
 import org.wamblee.crawler.Action;
+import org.wamblee.crawler.Page;
+import org.wamblee.crawler.PageException;
 
 /**
- * 
+ * Represents a television program.
  */
 public class Program {
     
+    /**
+     * Lexicographical comparison of programs based on (time, title, channel). 
+     *
+     */
+    public static class TimeSorter implements Comparator<Program> { 
+     
+        /* (non-Javadoc)
+         * @see java.util.Comparator#compare(T, T)
+         */
+        public int compare(Program o1, Program o2) { 
+            int value = o1.getInterval().getBegin().compareTo(o2.getInterval().getBegin());
+            if ( value != 0 ) { 
+                return value; 
+            }
+            value = o1.getName().compareTo(o2.getName()); 
+            if (value != 0 ) { 
+                return value; 
+            }
+            return o1.getChannel().compareTo(o2.getChannel());
+        }
+    }
+    
+    private static final Log LOG = LogFactory.getLog(Program.class);
+
+    /**
+     * Name of the record action on the program details page.
+     */
     private static final String RECORD_ACTION = "record";
+
+    private static final String RESULT_ELEM = "result";
+
+    public enum RecordingResult {
+        OK("Successfully recorded programs"), DUPLICATE(
+                "Already recorded programs"), CONFLICT(
+                "Programs in conflict with another recorded program"), OLDSHOW(
+                "Programs that occurred in the past"), ERROR(
+                "Programs that could not be recorded for technical reasons");
+
+        private String _description;
+
+        private RecordingResult(String aDescription) {
+            _description = aDescription;
+        }
+
+        public String getDescription() {
+            return _description;
+        }
+    };
+
+    /**
+     * Indent string to use for pretty printing.
+     */
     private static final String INDENT = "       ";
-    
-    private String _channel; 
+
+    /**
+     * Channel the program is on.
+     */
+    private String _channel;
+
+    /**
+     * Program name.
+     */
     private String _name;
-    private String _description; 
+
+    /**
+     * Program description.
+     */
+    private String _description;
+
+    /**
+     * Keywords or classification of the program.
+     */
     private String _keywords;
+
+    /**
+     * Time interval for the program (from/to).
+     */
     private TimeInterval _interval;
-    private Action _programInfo; 
-    
-    public Program(String aChannel, String aName, String aDescription, String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
-        _channel = aChannel; 
-        _name = aName;  
+
+    /**
+     * Action to execute to obtain program information and/or record the
+     * program.
+     */
+    private Action _programInfo;
+
+    /**
+     * Constructs the program.
+     * 
+     * @param aChannel
+     *            Channel name.
+     * @param aName
+     *            Program name.
+     * @param aDescription
+     *            Description.
+     * @param aKeywords
+     *            Keywords/classification.
+     * @param aInterval
+     *            Time interval.
+     * @param aProgramInfo
+     *            Action to execute for detailed program information or for
+     *            recording the page.
+     */
+    public Program(String aChannel, String aName, String aDescription,
+            String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
+        _channel = aChannel;
+        _name = aName;
         _description = aDescription;
-        _keywords = aKeywords; 
+        _keywords = aKeywords;
         _interval = aInterval;
-        _programInfo = aProgramInfo; 
+        _programInfo = aProgramInfo;
     }
-    
-    public String getChannel() { 
-        return _channel; 
+
+    /**
+     * Gets the channel.
+     * 
+     * @return Channel.
+     */
+    public String getChannel() {
+        return _channel;
     }
-    
-    public String getName() { 
-        return _name; 
+
+    /**
+     * Gets the program name.
+     * 
+     * @return Name.
+     */
+    public String getName() {
+        return _name;
     }
-    
-    public String getDescription() { 
+
+    /**
+     * Gets the description.
+     * 
+     * @return Description.
+     */
+    public String getDescription() {
         return _description;
     }
-    
-    public String getKeywords() { 
-        return _keywords; 
+
+    /**
+     * Gets the keywords/classification.
+     * 
+     * @return Keywords/classification
+     */
+    public String getKeywords() {
+        return _keywords;
     }
-    
-    public TimeInterval getInterval() { 
-        return _interval; 
+
+    /**
+     * Gets the time interval.
+     * 
+     * @return Time interval.
+     */
+    public TimeInterval getInterval() {
+        return _interval;
     }
     
-    public boolean record() { 
-        Action record = _programInfo.execute().getAction(RECORD_ACTION); 
-        if ( record == null) { 
-            return false;
+    /**
+     * Checks if recording is possible. 
+     * @return True iff recording is possible. 
+     */
+    public boolean isRecordingPossible() { 
+        try {
+            Action record = _programInfo.execute().getAction(RECORD_ACTION);
+            if (record == null) {
+                return false; 
+            }
+            return true; 
+        } catch (PageException e) {
+            return false; 
         }
-        record.execute(); 
-        return true; 
     }
-    
-    public void accept(Visitor aVisitor) { 
+
+    /**
+     * Records the show.
+     * 
+     * @return Status describing the result of recording.
+     */
+    public RecordingResult record() {
+        LOG.info("Recording " + this);
+        if ( SystemProperties.isRecordDisabled() ) { 
+            return RecordingResult.OK;
+        }
+        try {
+            Action record = _programInfo.execute().getAction(RECORD_ACTION);
+            if (record == null) {
+                LOG.info("  result: " + RecordingResult.OLDSHOW);
+                return RecordingResult.OLDSHOW;
+            }
+            Page result = record.execute();
+            RecordingResult recordingResult = RecordingResult.valueOf(result.getContent().getText());
+            LOG.info("  result: " + recordingResult);
+            return recordingResult;
+        } catch (PageException e) {
+            LOG.warn("Technical problem recording program: '" + this + "'", e);
+            LOG.info("  result: " + RecordingResult.ERROR);
+            return RecordingResult.ERROR;
+        }
+    }
+
+    /**
+     * Accepts the visitor.
+     * 
+     * @param aVisitor
+     *            Visitor.
+     */
+    public void accept(Visitor aVisitor) {
         aVisitor.visitProgram(this);
     }
-    
-    /* (non-Javadoc)
+
+    /*
+     * (non-Javadoc)
+     * 
      * @see java.lang.Object#toString()
      */
     @Override
     public String toString() {
-        return _interval + " - " + _name + " (" + _channel + "/" + _keywords + ")" + "\n" + 
-          (INDENT + _description).replaceAll("\n", "\n" + INDENT);  
+        return _interval + " - " + _name + " (" + _channel + "/" + _keywords
+                + ")" + "\n"
+                + (INDENT + _description).replaceAll("\n", "\n" + INDENT);
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if ( !(obj instanceof Program)) { 
+            return false; 
+        }
+        Program program = (Program)obj; 
+        return getName().equals(program.getName()) && 
+               _programInfo.equals(program._programInfo);
+    }
+    
+    /**
+     * Converts program information to XML. 
+     * @return XML representation of program information.  
+     */
+    public Element asXml() { 
+        DocumentFactory factory = DocumentFactory.getInstance();
+        Element program = factory.createElement("program"); 
+        program.addElement("name").setText(getName());
+        program.addElement("description").setText(getDescription());
+        program.addElement("keywords").setText(getKeywords());
+        program.addElement("channel").setText(getChannel());
+        Element interval = program.addElement("interval");
+        interval.addElement("begin").setText(getInterval().getBegin().toString());
+        interval.addElement("end").setText(getInterval().getEnd().toString());
+        return program; 
     }
 }