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 TimeComparator 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.
99 * Already recorded program.
104 * Recording conflict with another program.
109 * Program occurred in the past.
114 * Program could not be recorded for technical reasons.
120 * Indent string to use for pretty printing.
122 private static final String INDENT = " ";
125 * Channel the program is on.
127 private String _channel;
132 private String _name;
135 * Program description.
137 private String _description;
140 * Keywords or classification of the program.
142 private String _keywords;
145 * Time interval for the program (from/to).
147 private TimeInterval _interval;
150 * Action to execute to obtain program information and/or record the
153 private Action _programInfo;
156 * Constructs the program.
162 * @param aDescription
165 * Keywords/classification.
168 * @param aProgramInfo
169 * Action to execute for detailed program information or for
170 * recording the page.
172 public Program(String aChannel, String aName, String aDescription,
173 String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
176 _description = aDescription;
177 _keywords = aKeywords;
178 _interval = aInterval;
179 _programInfo = aProgramInfo;
187 public String getChannel() {
192 * Gets the program name.
196 public String getName() {
201 * Gets the description.
203 * @return Description.
205 public String getDescription() {
210 * Gets the keywords/classification.
212 * @return Keywords/classification
214 public String getKeywords() {
219 * Gets the time interval.
221 * @return Time interval.
223 public TimeInterval getInterval() {
228 * Checks if recording is possible.
230 * @return True iff recording is possible.
232 public boolean isRecordingPossible() {
234 return _programInfo.execute().getAction(RECORD_ACTION) != null;
235 } catch (PageException e) {
243 * @return Status describing the result of recording.
245 public RecordingResult record() {
246 LOG.info("Recording " + this);
247 if (SystemProperties.isRecordDisabled()) {
248 return RecordingResult.OK;
251 Action record = _programInfo.execute().getAction(RECORD_ACTION);
252 if (record == null) {
253 LOG.info(" result: " + RecordingResult.OLDSHOW);
254 return RecordingResult.OLDSHOW;
256 Page result = record.execute();
257 RecordingResult recordingResult = RecordingResult.valueOf(result
258 .getContent().getText());
259 LOG.info(" result: " + recordingResult);
260 return recordingResult;
261 } catch (PageException e) {
262 LOG.warn("Technical problem recording program: '" + this + "'", e);
263 LOG.info(" result: " + RecordingResult.ERROR);
264 return RecordingResult.ERROR;
269 * Accepts the visitor.
274 public void accept(Visitor aVisitor) {
275 aVisitor.visitProgram(this);
281 * @see java.lang.Object#toString()
284 public String toString() {
285 return _interval + " - " + _name + " (" + _channel + "/" + _keywords
287 + (INDENT + _description).replaceAll("\n", "\n" + INDENT);
293 * @see java.lang.Object#equals(java.lang.Object)
296 public boolean equals(Object aObject) {
297 if (!(aObject instanceof Program)) {
300 Program program = (Program) aObject;
301 return getName().equals(program.getName())
302 && _programInfo.equals(program._programInfo);
308 * @see java.lang.Object#hashCode()
311 public int hashCode() {
312 return getName().hashCode();
316 * Converts program information to XML.
318 * @return XML representation of program information.
320 public Element asXml() {
321 DocumentFactory factory = DocumentFactory.getInstance();
322 Element program = factory.createElement(ELEM_PROGRAM);
323 program.addElement(ELEM_NAME).setText(getName());
324 program.addElement(ELEM_DESCRIPTION).setText(getDescription());
325 program.addElement(ELEM_KEYWORDS).setText(getKeywords());
326 program.addElement(ELEM_CHANNEL).setText(getChannel());
327 Element interval = program.addElement(ELEM_INTERVAL);
328 interval.addElement(ELEM_BEGIN_TIME).setText(
329 getInterval().getBegin().toString());
330 interval.addElement(ELEM_END_TIME).setText(
331 getInterval().getEnd().toString());