more robustness, now a detailed report is always sent, also if crawling
[utils] / crawler / kiss / src / org / wamblee / crawler / kiss / main / Report.java
1 /*
2  * Copyright 2005 the original author or authors.
3  * 
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */
16
17 package org.wamblee.crawler.kiss.main;
18
19 import java.util.ArrayList;
20 import java.util.EnumMap;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.TreeMap;
26 import java.util.TreeSet;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.dom4j.DocumentFactory;
31 import org.dom4j.Element;
32 import org.wamblee.crawler.kiss.guide.Program;
33 import org.wamblee.crawler.kiss.guide.Program.RecordingResult;
34
35 /**
36  * Represents a report on the actions of the crawler.
37  */
38 public class Report {
39
40     private static final Log LOG = LogFactory
41             .getLog(Report.class);
42
43     /**
44      * A map of category name to a set of program. Useful for displaying the
45      * output of possibly interesting programs on a per category basis.
46      */
47     private Map<String, Set<Program>> _interestingShows;
48
49     /**
50      * Map or recording result to a set of programs.
51      */
52     private EnumMap<RecordingResult, Set<Program>> _recordings;
53
54     /**
55      * Messages generated while doing all the work.
56      */
57     private List<String> _messages;
58
59     /**
60      * Constructs the program action executor.
61      * 
62      */
63     public Report() {
64         _interestingShows = new TreeMap<String, Set<Program>>();
65         _recordings = new EnumMap<RecordingResult, Set<Program>>(
66                 RecordingResult.class);
67         for (RecordingResult result : RecordingResult.values()) {
68             _recordings.put(result, new TreeSet<Program>(
69                     new Program.TimeSorter()));
70         }
71         _messages = new ArrayList<String>();
72     }
73
74     /**
75      * Adds a message.
76      * 
77      * @param aMessage
78      *            Message to add.
79      */
80     public void addMessage(String aMessage) {
81         _messages.add(aMessage);
82     }
83     
84     /**
85      * Adds a message.
86      * 
87      * @param aMessage
88      *            Message to add.
89      * @param aException Exception that caused the problem.
90      */
91     public void addMessage(String aMessage, Exception aException) {
92         _messages.add(aMessage + ": " + aException.getMessage());
93     }
94
95     /**
96      * Called to indicate that a program is interesting. 
97      * 
98      * @param aCategory
99      *            Category of the program.
100      * @param aProgram
101      *            Program.
102      */
103     public void interestingProgram(String aCategory, Program aProgram) {
104         LOG.info("category = '" + aCategory + "', program: " + aProgram);
105         Set<Program> programs = _interestingShows.get(aCategory);
106         if (programs == null) {
107             programs = new TreeSet<Program>(new Program.TimeSorter());
108             _interestingShows.put(aCategory, programs);
109         }
110         programs.add(aProgram);
111     }
112     
113     /**
114      * Called to specify the result of recording a program. 
115      * @param aResult Result. 
116      * @param aProgram Program. 
117      */
118     public void setRecordingResult(RecordingResult aResult, Program aProgram) { 
119         _recordings.get(aResult).add(aProgram);   
120     }
121
122   
123     /**
124      * Get report as XML.
125      * 
126      * @return XML report
127      */
128     public Element asXml() {
129         DocumentFactory factory = DocumentFactory.getInstance();
130         Element report = factory.createElement("report");
131
132         if (_messages.size() > 0) {
133             Element messages = report.addElement("messages");
134             for (String message : _messages) {
135                 messages.addElement("message").setText(message);
136             }
137         }
138
139         Set<Program> reportedPrograms = new HashSet<Program>();
140
141         for (RecordingResult result : RecordingResult.values()) {
142             if (_recordings.get(result).size() > 0) {
143                 Element recordingResult = report.addElement("recorded")
144                         .addAttribute("result", result.toString());
145
146                 for (Program program : _recordings.get(result)) {
147                     recordingResult.add(program.asXml());
148                     reportedPrograms.add(program);
149                 }
150             }
151         }
152
153         if (_interestingShows.size() > 0) {
154             Element interesting = report.addElement("interesting");
155             for (String category : _interestingShows.keySet()) {
156                 Element categoryElem = interesting;
157                 if (category.length() > 0) {
158                     categoryElem = interesting.addElement("category");
159                     categoryElem.addAttribute("name", category);
160                 }
161                 for (Program program : _interestingShows.get(category)) {
162                     if (!reportedPrograms.contains(program)) {
163                         categoryElem.add(program.asXml());
164                     } else {
165                         LOG.info("Category '" + category + "', program "
166                                 + program + " already reported");
167                     }
168                 }
169                 if (categoryElem.elements().size() == 0) {
170                     // Remove empty category element.
171                     LOG
172                             .info("Removing element for category '" + category
173                                     + "'");
174                     interesting.remove(categoryElem);
175                 }
176             }
177
178         }
179
180         return report;
181     }
182 }