Network server and Library + nikiroo-utils update
[nikiroo-utils.git] / src / be / nikiroo / fanfix / reader / BasicReader.java
CommitLineData
89cb07a6
NR
1package be.nikiroo.fanfix.reader;
2
c1873e56 3import java.awt.Desktop;
3b2b638f 4import java.io.File;
89cb07a6 5import java.io.IOException;
3b2b638f 6import java.net.MalformedURLException;
89cb07a6
NR
7import java.net.URL;
8
9import be.nikiroo.fanfix.Instance;
10import be.nikiroo.fanfix.Library;
d0114000 11import be.nikiroo.fanfix.bundles.Config;
c1873e56
NR
12import be.nikiroo.fanfix.bundles.UiConfig;
13import be.nikiroo.fanfix.data.MetaData;
89cb07a6
NR
14import be.nikiroo.fanfix.data.Story;
15import be.nikiroo.fanfix.supported.BasicSupport;
3b2b638f 16import be.nikiroo.utils.Progress;
9119671d 17import be.nikiroo.utils.serial.SerialUtils;
89cb07a6
NR
18
19/**
dd56a893 20 * The class that handles the different {@link Story} readers you can use.
89cb07a6 21 * <p>
dd56a893 22 * All the readers should be accessed via {@link BasicReader#getReader()}.
89cb07a6
NR
23 *
24 * @author niki
25 */
3727aae2
NR
26public abstract class BasicReader {
27 public enum ReaderType {
28 /** Simple reader that outputs everything on the console */
29 CLI,
30 /** Reader that starts local programs to handle the stories */
c1873e56
NR
31 GUI,
32 /** A text (UTF-8) reader with menu and text windows */
33 TUI,
b0e88ebd 34
9119671d 35 ;
b0e88ebd 36
9119671d
NR
37 public String getTypeName() {
38 String pkg = "be.nikiroo.fanfix.reader.";
39 switch (this) {
b0e88ebd
NR
40 case CLI:
41 return pkg + "CliReader";
42 case TUI:
43 return pkg + "TuiReader";
44 case GUI:
45 return pkg + "LocalReader";
9119671d 46 }
b0e88ebd 47
9119671d
NR
48 return null;
49 }
3727aae2
NR
50 }
51
b0e88ebd 52 private static Library defaultLibrary = Instance.getLibrary();
c1873e56 53 private static ReaderType defaultType = ReaderType.GUI;
b0e88ebd
NR
54
55 private Library lib;
89cb07a6 56 private Story story;
3727aae2
NR
57 private ReaderType type;
58
d0114000
NR
59 /**
60 * Take the default reader type configuration from the config file.
61 */
3727aae2 62 static {
d0114000
NR
63 String typeString = Instance.getConfig().getString(Config.READER_TYPE);
64 if (typeString != null && !typeString.isEmpty()) {
65 try {
66 ReaderType type = ReaderType.valueOf(typeString.toUpperCase());
67 defaultType = type;
68 } catch (IllegalArgumentException e) {
69 // Do nothing
70 }
71 }
3727aae2
NR
72 }
73
74 /**
75 * The type of this reader.
76 *
77 * @return the type
78 */
79 public ReaderType getType() {
80 return type;
81 }
82
83 /**
84 * The type of this reader.
85 *
86 * @param type
87 * the new type
88 */
89 protected BasicReader setType(ReaderType type) {
90 this.type = type;
91 return this;
92 }
89cb07a6
NR
93
94 /**
95 * Return the current {@link Story}.
96 *
97 * @return the {@link Story}
98 */
99 public Story getStory() {
100 return story;
101 }
102
b0e88ebd
NR
103 /**
104 * The {@link Library} to load the stories from (by default, takes the
105 * default {@link Library}).
106 *
107 * @return the {@link Library}
108 */
109 public Library getLibrary() {
110 if (lib == null) {
111 lib = defaultLibrary;
112 }
113
114 return lib;
115 }
116
117 /**
118 * Change the {@link Library} that will be managed by this
119 * {@link BasicReader}.
120 *
121 * @param lib
122 * the new {@link Library}
123 */
124 public void setLibrary(Library lib) {
125 this.lib = lib;
126 }
127
89cb07a6 128 /**
3727aae2 129 * Create a new {@link BasicReader} for a {@link Story} in the
b0e88ebd 130 * {@link Library}.
89cb07a6
NR
131 *
132 * @param luid
133 * the {@link Story} ID
92fb0719
NR
134 * @param pg
135 * the optional progress reporter
136 *
89cb07a6
NR
137 * @throws IOException
138 * in case of I/O error
139 */
92fb0719 140 public void setStory(String luid, Progress pg) throws IOException {
b0e88ebd 141 story = lib.getStory(luid, pg);
89cb07a6 142 if (story == null) {
92fb0719 143 throw new IOException("Cannot retrieve story from library: " + luid);
89cb07a6
NR
144 }
145 }
146
147 /**
3727aae2 148 * Create a new {@link BasicReader} for an external {@link Story}.
89cb07a6
NR
149 *
150 * @param source
151 * the {@link Story} {@link URL}
92fb0719
NR
152 * @param pg
153 * the optional progress reporter
154 *
89cb07a6
NR
155 * @throws IOException
156 * in case of I/O error
157 */
92fb0719 158 public void setStory(URL source, Progress pg) throws IOException {
89cb07a6
NR
159 BasicSupport support = BasicSupport.getSupport(source);
160 if (support == null) {
161 throw new IOException("URL not supported: " + source.toString());
162 }
163
92fb0719 164 story = support.process(source, pg);
89cb07a6
NR
165 if (story == null) {
166 throw new IOException(
167 "Cannot retrieve story from external source: "
168 + source.toString());
169
170 }
171 }
172
173 /**
174 * Start the {@link Story} Reading.
175 *
176 * @throws IOException
177 * in case of I/O error or if the {@link Story} was not
178 * previously set
179 */
180 public abstract void read() throws IOException;
181
182 /**
183 * Read the selected chapter (starting at 1).
184 *
185 * @param chapter
186 * the chapter
edd46289
NR
187 *
188 * @throws IOException
189 * in case of I/O error or if the {@link Story} was not
190 * previously set
89cb07a6 191 */
edd46289 192 public abstract void read(int chapter) throws IOException;
89cb07a6
NR
193
194 /**
b0e88ebd
NR
195 * Start the reader in browse mode for the given source (or pass NULL for
196 * all sources).
89cb07a6 197 *
b0e88ebd
NR
198 * @param library
199 * the library to browse
200 *
201 * @param source
89cb07a6
NR
202 * the type of {@link Story} to take into account, or NULL for
203 * all
204 */
b0e88ebd 205 public abstract void browse(String source);
3727aae2
NR
206
207 /**
d0114000
NR
208 * Return a new {@link BasicReader} ready for use if one is configured.
209 * <p>
210 * Can return NULL if none are configured.
3727aae2 211 *
d0114000 212 * @return a {@link BasicReader}, or NULL if none configured
3727aae2
NR
213 */
214 public static BasicReader getReader() {
333f0e7b
NR
215 try {
216 if (defaultType != null) {
b0e88ebd
NR
217 return ((BasicReader) SerialUtils.createObject(defaultType
218 .getTypeName())).setType(defaultType);
d0114000 219 }
9119671d 220 } catch (Exception e) {
333f0e7b 221 Instance.syserr(new Exception("Cannot create a reader of type: "
9119671d 222 + defaultType + " (Not compiled in?)", e));
3727aae2
NR
223 }
224
225 return null;
226 }
227
228 /**
229 * The default {@link ReaderType} used when calling
230 * {@link BasicReader#getReader()}.
231 *
232 * @return the default type
233 */
234 public static ReaderType getDefaultReaderType() {
235 return defaultType;
236 }
237
238 /**
239 * The default {@link ReaderType} used when calling
240 * {@link BasicReader#getReader()}.
241 *
242 * @param defaultType
243 * the new default type
244 */
245 public static void setDefaultReaderType(ReaderType defaultType) {
246 BasicReader.defaultType = defaultType;
247 }
3b2b638f 248
b0e88ebd
NR
249 /**
250 * Change the default {@link Library} to open with the {@link BasicReader}s.
251 *
252 * @param lib
253 * the new {@link Library}
254 */
255 public static void setDefaultLibrary(Library lib) {
256 BasicReader.defaultLibrary = lib;
257 }
258
3b2b638f
NR
259 /**
260 * Return an {@link URL} from this {@link String}, be it a file path or an
261 * actual {@link URL}.
262 *
263 * @param sourceString
264 * the source
265 *
266 * @return the corresponding {@link URL}
267 *
268 * @throws MalformedURLException
269 * if this is neither a file nor a conventional {@link URL}
270 */
271 public static URL getUrl(String sourceString) throws MalformedURLException {
272 if (sourceString == null || sourceString.isEmpty()) {
273 throw new MalformedURLException("Empty url");
274 }
275
276 URL source = null;
277 try {
278 source = new URL(sourceString);
279 } catch (MalformedURLException e) {
280 File sourceFile = new File(sourceString);
281 source = sourceFile.toURI().toURL();
282 }
283
284 return source;
285 }
c1873e56
NR
286
287 // open with external player the related file
b0e88ebd
NR
288 public static void open(Library lib, String luid) throws IOException {
289 MetaData meta = lib.getInfo(luid);
290 File target = lib.getFile(luid);
c1873e56
NR
291
292 open(meta, target);
293 }
294
295 // open with external player the related file
296 protected static void open(MetaData meta, File target) throws IOException {
297 String program = null;
298 if (meta.isImageDocument()) {
299 program = Instance.getUiConfig().getString(
300 UiConfig.IMAGES_DOCUMENT_READER);
301 } else {
302 program = Instance.getUiConfig().getString(
303 UiConfig.NON_IMAGES_DOCUMENT_READER);
304 }
305
306 if (program != null && program.trim().isEmpty()) {
307 program = null;
308 }
309
310 if (program == null) {
311 try {
312 Desktop.getDesktop().browse(target.toURI());
313 } catch (UnsupportedOperationException e) {
314 Runtime.getRuntime().exec(
315 new String[] { "xdg-open", target.getAbsolutePath() });
316
317 }
318 } else {
319 Runtime.getRuntime().exec(
320 new String[] { program, target.getAbsolutePath() });
321 }
322 }
89cb07a6 323}