1 package be
.nikiroo
.fanfix
.reader
;
3 import java
.awt
.Desktop
;
5 import java
.io
.IOException
;
6 import java
.net
.MalformedURLException
;
9 import be
.nikiroo
.fanfix
.Instance
;
10 import be
.nikiroo
.fanfix
.Library
;
11 import be
.nikiroo
.fanfix
.bundles
.Config
;
12 import be
.nikiroo
.fanfix
.bundles
.UiConfig
;
13 import be
.nikiroo
.fanfix
.data
.MetaData
;
14 import be
.nikiroo
.fanfix
.data
.Story
;
15 import be
.nikiroo
.fanfix
.supported
.BasicSupport
;
16 import be
.nikiroo
.utils
.Progress
;
17 import be
.nikiroo
.utils
.serial
.SerialUtils
;
20 * The class that handles the different {@link Story} readers you can use.
22 * All the readers should be accessed via {@link BasicReader#getReader()}.
26 public abstract class BasicReader
{
27 public enum ReaderType
{
28 /** Simple reader that outputs everything on the console */
30 /** Reader that starts local programs to handle the stories */
32 /** A text (UTF-8) reader with menu and text windows */
37 public String
getTypeName() {
38 String pkg
= "be.nikiroo.fanfix.reader.";
41 return pkg
+ "CliReader";
43 return pkg
+ "TuiReader";
45 return pkg
+ "LocalReader";
52 private static Library defaultLibrary
= Instance
.getLibrary();
53 private static ReaderType defaultType
= ReaderType
.GUI
;
57 private ReaderType type
;
60 * Take the default reader type configuration from the config file.
63 String typeString
= Instance
.getConfig().getString(Config
.READER_TYPE
);
64 if (typeString
!= null && !typeString
.isEmpty()) {
66 ReaderType type
= ReaderType
.valueOf(typeString
.toUpperCase());
68 } catch (IllegalArgumentException e
) {
75 * The type of this reader.
79 public ReaderType
getType() {
84 * The type of this reader.
89 protected BasicReader
setType(ReaderType type
) {
95 * Return the current {@link Story}.
97 * @return the {@link Story}
99 public Story
getStory() {
104 * The {@link Library} to load the stories from (by default, takes the
105 * default {@link Library}).
107 * @return the {@link Library}
109 public Library
getLibrary() {
111 lib
= defaultLibrary
;
118 * Change the {@link Library} that will be managed by this
119 * {@link BasicReader}.
122 * the new {@link Library}
124 public void setLibrary(Library lib
) {
129 * Create a new {@link BasicReader} for a {@link Story} in the
133 * the {@link Story} ID
135 * the optional progress reporter
137 * @throws IOException
138 * in case of I/O error
140 public void setStory(String luid
, Progress pg
) throws IOException
{
141 story
= lib
.getStory(luid
, pg
);
143 throw new IOException("Cannot retrieve story from library: " + luid
);
148 * Create a new {@link BasicReader} for an external {@link Story}.
151 * the {@link Story} {@link URL}
153 * the optional progress reporter
155 * @throws IOException
156 * in case of I/O error
158 public void setStory(URL source
, Progress pg
) throws IOException
{
159 BasicSupport support
= BasicSupport
.getSupport(source
);
160 if (support
== null) {
161 throw new IOException("URL not supported: " + source
.toString());
164 story
= support
.process(source
, pg
);
166 throw new IOException(
167 "Cannot retrieve story from external source: "
168 + source
.toString());
174 * Start the {@link Story} Reading.
176 * @throws IOException
177 * in case of I/O error or if the {@link Story} was not
180 public abstract void read() throws IOException
;
183 * Read the selected chapter (starting at 1).
188 * @throws IOException
189 * in case of I/O error or if the {@link Story} was not
192 public abstract void read(int chapter
) throws IOException
;
195 * Start the reader in browse mode for the given source (or pass NULL for
199 * the library to browse
202 * the type of {@link Story} to take into account, or NULL for
205 public abstract void browse(String source
);
208 * Return a new {@link BasicReader} ready for use if one is configured.
210 * Can return NULL if none are configured.
212 * @return a {@link BasicReader}, or NULL if none configured
214 public static BasicReader
getReader() {
216 if (defaultType
!= null) {
217 return ((BasicReader
) SerialUtils
.createObject(defaultType
218 .getTypeName())).setType(defaultType
);
220 } catch (Exception e
) {
221 Instance
.syserr(new Exception("Cannot create a reader of type: "
222 + defaultType
+ " (Not compiled in?)", e
));
229 * The default {@link ReaderType} used when calling
230 * {@link BasicReader#getReader()}.
232 * @return the default type
234 public static ReaderType
getDefaultReaderType() {
239 * The default {@link ReaderType} used when calling
240 * {@link BasicReader#getReader()}.
243 * the new default type
245 public static void setDefaultReaderType(ReaderType defaultType
) {
246 BasicReader
.defaultType
= defaultType
;
250 * Change the default {@link Library} to open with the {@link BasicReader}s.
253 * the new {@link Library}
255 public static void setDefaultLibrary(Library lib
) {
256 BasicReader
.defaultLibrary
= lib
;
260 * Return an {@link URL} from this {@link String}, be it a file path or an
261 * actual {@link URL}.
263 * @param sourceString
266 * @return the corresponding {@link URL}
268 * @throws MalformedURLException
269 * if this is neither a file nor a conventional {@link URL}
271 public static URL
getUrl(String sourceString
) throws MalformedURLException
{
272 if (sourceString
== null || sourceString
.isEmpty()) {
273 throw new MalformedURLException("Empty url");
278 source
= new URL(sourceString
);
279 } catch (MalformedURLException e
) {
280 File sourceFile
= new File(sourceString
);
281 source
= sourceFile
.toURI().toURL();
287 // open with external player the related file
288 public static void open(Library lib
, String luid
) throws IOException
{
289 MetaData meta
= lib
.getInfo(luid
);
290 File target
= lib
.getFile(luid
);
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
);
302 program
= Instance
.getUiConfig().getString(
303 UiConfig
.NON_IMAGES_DOCUMENT_READER
);
306 if (program
!= null && program
.trim().isEmpty()) {
310 if (program
== null) {
312 Desktop
.getDesktop().browse(target
.toURI());
313 } catch (UnsupportedOperationException e
) {
314 Runtime
.getRuntime().exec(
315 new String
[] { "xdg-open", target
.getAbsolutePath() });
319 Runtime
.getRuntime().exec(
320 new String
[] { program
, target
.getAbsolutePath() });