2 * Copyright 2005 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.wamblee.crawler.kiss.guide;
19 import java.util.Comparator;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.dom4j.DocumentFactory;
24 import org.dom4j.Element;
25 import org.wamblee.crawler.Action;
26 import org.wamblee.crawler.Page;
27 import org.wamblee.crawler.PageException;
28 import org.wamblee.crawler.kiss.main.SystemProperties;
31 * Represents a television program.
33 public class Program {
36 * Lexicographical comparison of programs based on (time, title, channel).
39 public static class TimeSorter implements Comparator<Program> {
42 * Lexicographical comparison based on start time, program name, and
49 * @return See {@link Comparator#compare(T, T)}
51 public int compare(Program aProgram1, Program aProgram2) {
52 int value = aProgram1.getInterval().getBegin().compareTo(
53 aProgram2.getInterval().getBegin());
57 value = aProgram1.getName().compareTo(aProgram2.getName());
61 return aProgram1.getChannel().compareTo(aProgram2.getChannel());
65 private static final Log LOG = LogFactory.getLog(Program.class);
68 * Name of the record action on the program details page.
70 private static final String RECORD_ACTION = "record";
73 * Result of recording a program.
76 public enum RecordingResult {
78 * Successfully recorded.
80 OK("Successfully recorded programs"),
83 * Already recorded program.
85 DUPLICATE("Already recorded programs"),
88 * Recording conflict with another program.
90 CONFLICT("Programs in conflict with another recorded program"),
93 * Program occurred in the past.
95 OLDSHOW("Programs that occurred in the past"),
98 * Program could not be recorded for technical reasons.
100 ERROR("Programs that could not be recorded for technical reasons");
102 private String _description;
104 private RecordingResult(String aDescription) {
105 _description = aDescription;
109 * Gets the description.
110 * @return Description.
112 public String getDescription() {
118 * Indent string to use for pretty printing.
120 private static final String INDENT = " ";
123 * Channel the program is on.
125 private String _channel;
130 private String _name;
133 * Program description.
135 private String _description;
138 * Keywords or classification of the program.
140 private String _keywords;
143 * Time interval for the program (from/to).
145 private TimeInterval _interval;
148 * Action to execute to obtain program information and/or record the
151 private Action _programInfo;
154 * Constructs the program.
160 * @param aDescription
163 * Keywords/classification.
166 * @param aProgramInfo
167 * Action to execute for detailed program information or for
168 * recording the page.
170 public Program(String aChannel, String aName, String aDescription,
171 String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
174 _description = aDescription;
175 _keywords = aKeywords;
176 _interval = aInterval;
177 _programInfo = aProgramInfo;
185 public String getChannel() {
190 * Gets the program name.
194 public String getName() {
199 * Gets the description.
201 * @return Description.
203 public String getDescription() {
208 * Gets the keywords/classification.
210 * @return Keywords/classification
212 public String getKeywords() {
217 * Gets the time interval.
219 * @return Time interval.
221 public TimeInterval getInterval() {
226 * Checks if recording is possible.
228 * @return True iff recording is possible.
230 public boolean isRecordingPossible() {
232 Action record = _programInfo.execute().getAction(RECORD_ACTION);
233 if (record == null) {
237 } catch (PageException e) {
245 * @return Status describing the result of recording.
247 public RecordingResult record() {
248 LOG.info("Recording " + this);
249 if (SystemProperties.isRecordDisabled()) {
250 return RecordingResult.OK;
253 Action record = _programInfo.execute().getAction(RECORD_ACTION);
254 if (record == null) {
255 LOG.info(" result: " + RecordingResult.OLDSHOW);
256 return RecordingResult.OLDSHOW;
258 Page result = record.execute();
259 RecordingResult recordingResult = RecordingResult.valueOf(result
260 .getContent().getText());
261 LOG.info(" result: " + recordingResult);
262 return recordingResult;
263 } catch (PageException e) {
264 LOG.warn("Technical problem recording program: '" + this + "'", e);
265 LOG.info(" result: " + RecordingResult.ERROR);
266 return RecordingResult.ERROR;
271 * Accepts the visitor.
276 public void accept(Visitor aVisitor) {
277 aVisitor.visitProgram(this);
283 * @see java.lang.Object#toString()
286 public String toString() {
287 return _interval + " - " + _name + " (" + _channel + "/" + _keywords
289 + (INDENT + _description).replaceAll("\n", "\n" + INDENT);
295 * @see java.lang.Object#equals(java.lang.Object)
298 public boolean equals(Object aObject) {
299 if (!(aObject instanceof Program)) {
302 Program program = (Program) aObject;
303 return getName().equals(program.getName())
304 && _programInfo.equals(program._programInfo);
310 * @see java.lang.Object#hashCode()
313 public int hashCode() {
314 return getName().hashCode();
318 * Converts program information to XML.
320 * @return XML representation of program information.
322 public Element asXml() {
323 DocumentFactory factory = DocumentFactory.getInstance();
324 Element program = factory.createElement("program");
325 program.addElement("name").setText(getName());
326 program.addElement("description").setText(getDescription());
327 program.addElement("keywords").setText(getKeywords());
328 program.addElement("channel").setText(getChannel());
329 Element interval = program.addElement("interval");
330 interval.addElement("begin").setText(
331 getInterval().getBegin().toString());
332 interval.addElement("end").setText(getInterval().getEnd().toString());