1 package org.daisy.pipeline.tts;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import net.sf.saxon.s9api.XdmNode;
11
12 import org.daisy.pipeline.audio.AudioClip;
13 import org.slf4j.Logger;
14
15
16
17
18
19
20 public class TTSLog {
21
22 private final Logger slf4jLogger;
23
24 public TTSLog() {
25 this(null);
26 }
27
28 public TTSLog(Logger slf4jLogger) {
29 this.slf4jLogger = slf4jLogger;
30 }
31
32 public enum ErrorCode {
33 UNEXPECTED_VOICE,
34 AUDIO_MISSING,
35 CRITICAL_ERROR,
36 ERROR,
37 WARNING
38 }
39
40 public static class Error {
41
42 private final ErrorCode key;
43 private String message;
44 private Throwable cause;
45
46 public Error(ErrorCode key, String message) {
47 this(key, message, null);
48 }
49
50 public Error(ErrorCode key, String message, Throwable cause) {
51 this.key = key;
52 this.message = message;
53 this.cause = cause;
54 }
55
56 public ErrorCode getErrorCode() {
57 return key;
58 }
59
60 public String getMessage() {
61 return message;
62 }
63
64 public Throwable getCause() {
65 return cause;
66 }
67 }
68
69 public class Entry {
70
71 private final String sentenceId;
72
73 private Entry(String sentenceId) {
74 this.sentenceId = sentenceId;
75 }
76
77 public void addError(Error err) {
78 errors.add(err);
79 String msg = err.getMessage();
80 if (err.getCause() != null && slf4jLogger != null)
81 msg += " (Please see detailed log and TTS log for more info.)";
82 else
83 msg += " (Please see TTS log for more info.)";
84 switch (err.getErrorCode()) {
85 case WARNING:
86 case ERROR:
87 break;
88 default:
89 msg = err.getErrorCode() + ": " + msg;
90 }
91 msg = "While processing sentence with ID " + sentenceId + ": " + msg;
92 switch (err.getErrorCode()) {
93 case WARNING:
94 case AUDIO_MISSING:
95 if (slf4jLogger != null)
96 slf4jLogger.warn(msg);
97 break;
98 default:
99 if (slf4jLogger != null)
100 slf4jLogger.error(msg);
101 }
102 if (err.getCause() != null)
103 if (slf4jLogger != null)
104 slf4jLogger.debug("Error stack trace:", err.getCause());
105 }
106
107 public Collection<Error> getReadOnlyErrors() {
108 return errors;
109 }
110
111
112
113
114 public void setSSML(XdmNode ssml) {
115 this.ssml = ssml;
116 }
117
118 public XdmNode getSSML() {
119 return ssml;
120 }
121
122
123
124
125 public void setSelectedVoice(Voice v) {
126 this.selectedVoice = v;
127 }
128
129 public Voice getSelectedVoice() {
130 return selectedVoice;
131 }
132
133
134
135
136
137
138 public void setActualVoice(Voice v) {
139 this.actualVoice = v;
140 }
141
142 public Voice getActualVoice() {
143 return actualVoice;
144 }
145
146
147
148
149 public void setClip(AudioClip clip) {
150 this.clip = clip;
151 }
152
153 public AudioClip getClip() {
154 return clip;
155 }
156
157
158
159
160 public void setTimeout(float secs) {
161 this.timeout = secs;
162 }
163
164 public float getTimeout() {
165 return timeout;
166 }
167
168
169
170
171 public void setTimeElapsed(float secs) {
172 this.timeElapsed = secs;
173 }
174
175 public float getTimeElapsed() {
176 return this.timeElapsed;
177 }
178
179 private List<Error> errors = new ArrayList<Error>();
180 private XdmNode ssml;
181 private Voice selectedVoice;
182 private Voice actualVoice;
183 private AudioClip clip;
184 private float timeout;
185 private float timeElapsed;
186 }
187
188
189
190
191 public Entry getOrCreateEntry(String sentenceId) {
192 Entry res = mLog.get(sentenceId);
193 if (res != null)
194 return res;
195 res = new Entry(sentenceId);
196 mLog.put(sentenceId, res);
197 return res;
198 }
199
200
201
202
203
204 public Entry getWritableEntry(String sentenceId) {
205 return mLog.get(sentenceId);
206 }
207
208 public Set<Map.Entry<String, Entry>> getEntries() {
209 return mLog.entrySet();
210 }
211
212 public void addGeneralError(ErrorCode errcode, String message) {
213 addGeneralError(errcode, message, null);
214 }
215
216 public void addGeneralError(ErrorCode errcode, String message, Throwable cause) {
217 synchronized (generalErrors) {
218 generalErrors.add(new Error(errcode, message, cause));
219 }
220 if (cause != null)
221 message += " (Please see detailed log for more info.)";
222 switch (errcode) {
223 case WARNING:
224 case ERROR:
225 break;
226 default:
227 message = "" + errcode + ": " + message;
228 }
229 switch (errcode) {
230 case WARNING:
231 case AUDIO_MISSING:
232 if (slf4jLogger != null)
233 slf4jLogger.warn(message);
234 break;
235 default:
236 if (slf4jLogger != null)
237 slf4jLogger.error(message);
238 }
239 if (cause != null)
240 if (slf4jLogger != null)
241 slf4jLogger.debug("Error stack trace:", cause);
242 }
243
244 public Collection<Error> readonlyGeneralErrors() {
245 return generalErrors;
246 }
247
248 private List<Error> generalErrors = new ArrayList<Error>();
249 private Map<String, Entry> mLog = new HashMap<String, Entry>();
250 }
251