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 {
35 private static final String ELEM_PROGRAM = "program";
37 private static final String ELEM_NAME = "name";
39 private static final String ELEM_KEYWORDS = "keywords";
41 private static final String ELEM_DESCRIPTION = "description";
43 private static final String ELEM_CHANNEL = "channel";
45 private static final String ELEM_INTERVAL = "interval";
47 private static final String ELEM_END_TIME = "end";
49 private static final String ELEM_BEGIN_TIME = "begin";
52 * Lexicographical comparison of programs based on (time, title, channel).
55 public static class TimeSorter implements Comparator<Program> {
58 * Lexicographical comparison based on start time, program name, and
65 * @return See {@link Comparator#compare(T, T)}
67 public int compare(Program aProgram1, Program aProgram2) {
68 int value = aProgram1.getInterval().getBegin().compareTo(
69 aProgram2.getInterval().getBegin());
73 value = aProgram1.getName().compareTo(aProgram2.getName());
77 return aProgram1.getChannel().compareTo(aProgram2.getChannel());
81 private static final Log LOG = LogFactory.getLog(Program.class);
84 * Name of the record action on the program details page.
86 private static final String RECORD_ACTION = "record";
89 * Result of recording a program.
92 public enum RecordingResult {
94 * Successfully recorded.
96 OK("Successfully recorded programs"),
99 * Already recorded program.
101 DUPLICATE("Already recorded programs"),
104 * Recording conflict with another program.
106 CONFLICT("Programs in conflict with another recorded program"),
109 * Program occurred in the past.
111 OLDSHOW("Programs that occurred in the past"),
114 * Program could not be recorded for technical reasons.
116 ERROR("Programs that could not be recorded for technical reasons");
118 private String _description;
120 private RecordingResult(String aDescription) {
121 _description = aDescription;
125 * Gets the description.
127 * @return Description.
129 public String getDescription() {
135 * Indent string to use for pretty printing.
137 private static final String INDENT = " ";
140 * Channel the program is on.
142 private String _channel;
147 private String _name;
150 * Program description.
152 private String _description;
155 * Keywords or classification of the program.
157 private String _keywords;
160 * Time interval for the program (from/to).
162 private TimeInterval _interval;
165 * Action to execute to obtain program information and/or record the
168 private Action _programInfo;
171 * Constructs the program.
177 * @param aDescription
180 * Keywords/classification.
183 * @param aProgramInfo
184 * Action to execute for detailed program information or for
185 * recording the page.
187 public Program(String aChannel, String aName, String aDescription,
188 String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
191 _description = aDescription;
192 _keywords = aKeywords;
193 _interval = aInterval;
194 _programInfo = aProgramInfo;
202 public String getChannel() {
207 * Gets the program name.
211 public String getName() {
216 * Gets the description.
218 * @return Description.
220 public String getDescription() {
225 * Gets the keywords/classification.
227 * @return Keywords/classification
229 public String getKeywords() {
234 * Gets the time interval.
236 * @return Time interval.
238 public TimeInterval getInterval() {
243 * Checks if recording is possible.
245 * @return True iff recording is possible.
247 public boolean isRecordingPossible() {
249 Action record = _programInfo.execute().getAction(RECORD_ACTION);
250 if (record == null) {
254 } catch (PageException e) {
262 * @return Status describing the result of recording.
264 public RecordingResult record() {
265 LOG.info("Recording " + this);
266 if (SystemProperties.isRecordDisabled()) {
267 return RecordingResult.OK;
270 Action record = _programInfo.execute().getAction(RECORD_ACTION);
271 if (record == null) {
272 LOG.info(" result: " + RecordingResult.OLDSHOW);
273 return RecordingResult.OLDSHOW;
275 Page result = record.execute();
276 RecordingResult recordingResult = RecordingResult.valueOf(result
277 .getContent().getText());
278 LOG.info(" result: " + recordingResult);
279 return recordingResult;
280 } catch (PageException e) {
281 LOG.warn("Technical problem recording program: '" + this + "'", e);
282 LOG.info(" result: " + RecordingResult.ERROR);
283 return RecordingResult.ERROR;
288 * Accepts the visitor.
293 public void accept(Visitor aVisitor) {
294 aVisitor.visitProgram(this);
300 * @see java.lang.Object#toString()
303 public String toString() {
304 return _interval + " - " + _name + " (" + _channel + "/" + _keywords
306 + (INDENT + _description).replaceAll("\n", "\n" + INDENT);
312 * @see java.lang.Object#equals(java.lang.Object)
315 public boolean equals(Object aObject) {
316 if (!(aObject instanceof Program)) {
319 Program program = (Program) aObject;
320 return getName().equals(program.getName())
321 && _programInfo.equals(program._programInfo);
327 * @see java.lang.Object#hashCode()
330 public int hashCode() {
331 return getName().hashCode();
335 * Converts program information to XML.
337 * @return XML representation of program information.
339 public Element asXml() {
340 DocumentFactory factory = DocumentFactory.getInstance();
341 Element program = factory.createElement(ELEM_PROGRAM);
342 program.addElement(ELEM_NAME).setText(getName());
343 program.addElement(ELEM_DESCRIPTION).setText(getDescription());
344 program.addElement(ELEM_KEYWORDS).setText(getKeywords());
345 program.addElement(ELEM_CHANNEL).setText(getChannel());
346 Element interval = program.addElement(ELEM_INTERVAL);
347 interval.addElement(ELEM_BEGIN_TIME).setText(
348 getInterval().getBegin().toString());
349 interval.addElement(ELEM_END_TIME).setText(
350 getInterval().getEnd().toString());