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
.BasicLibrary
;
10 import be
.nikiroo
.fanfix
.Instance
;
11 import be
.nikiroo
.fanfix
.LocalLibrary
;
12 import be
.nikiroo
.fanfix
.bundles
.Config
;
13 import be
.nikiroo
.fanfix
.bundles
.UiConfig
;
14 import be
.nikiroo
.fanfix
.data
.MetaData
;
15 import be
.nikiroo
.fanfix
.data
.Story
;
16 import be
.nikiroo
.fanfix
.supported
.BasicSupport
;
17 import be
.nikiroo
.utils
.Progress
;
18 import be
.nikiroo
.utils
.serial
.SerialUtils
;
21 * The class that handles the different {@link Story} readers you can use.
23 * All the readers should be accessed via {@link BasicReader#getReader()}.
27 public abstract class BasicReader
{
29 * A type of {@link BasicReader}.
33 public enum ReaderType
{
34 /** Simple reader that outputs everything on the console */
36 /** Reader that starts local programs to handle the stories */
38 /** A text (UTF-8) reader with menu and text windows */
44 * Return the full class name of a type that implements said
47 * @return the class name
49 public String
getTypeName() {
50 String pkg
= "be.nikiroo.fanfix.reader.";
53 return pkg
+ "CliReader";
55 return pkg
+ "TuiReader";
57 return pkg
+ "GuiReader";
64 private static BasicLibrary defaultLibrary
= Instance
.getLibrary();
65 private static ReaderType defaultType
= ReaderType
.GUI
;
67 private BasicLibrary lib
;
69 private ReaderType type
;
72 * Take the default reader type configuration from the config file.
75 String typeString
= Instance
.getConfig().getString(Config
.READER_TYPE
);
76 if (typeString
!= null && !typeString
.isEmpty()) {
78 ReaderType type
= ReaderType
.valueOf(typeString
.toUpperCase());
80 } catch (IllegalArgumentException e
) {
87 * The type of this reader.
91 public ReaderType
getType() {
96 * The type of this reader.
103 protected BasicReader
setType(ReaderType type
) {
109 * Return the current {@link Story}.
111 * @return the {@link Story}
113 public Story
getStory() {
118 * The {@link LocalLibrary} to load the stories from (by default, takes the
119 * default {@link LocalLibrary}).
121 * @return the {@link LocalLibrary}
123 public BasicLibrary
getLibrary() {
125 lib
= defaultLibrary
;
132 * Change the {@link LocalLibrary} that will be managed by this
133 * {@link BasicReader}.
136 * the new {@link LocalLibrary}
138 public void setLibrary(LocalLibrary lib
) {
143 * Create a new {@link BasicReader} for a {@link Story} in the
144 * {@link LocalLibrary}.
147 * the {@link Story} ID
149 * the optional progress reporter
151 * @throws IOException
152 * in case of I/O error
154 public void setStory(String luid
, Progress pg
) throws IOException
{
155 story
= lib
.getStory(luid
, pg
);
157 throw new IOException("Cannot retrieve story from library: " + luid
);
162 * Create a new {@link BasicReader} for an external {@link Story}.
165 * the {@link Story} {@link URL}
167 * the optional progress reporter
169 * @throws IOException
170 * in case of I/O error
172 public void setStory(URL source
, Progress pg
) throws IOException
{
173 BasicSupport support
= BasicSupport
.getSupport(source
);
174 if (support
== null) {
175 throw new IOException("URL not supported: " + source
.toString());
178 story
= support
.process(source
, pg
);
180 throw new IOException(
181 "Cannot retrieve story from external source: "
182 + source
.toString());
188 * Start the {@link Story} Reading.
190 * @throws IOException
191 * in case of I/O error or if the {@link Story} was not
194 public abstract void read() throws IOException
;
197 * Read the selected chapter (starting at 1).
202 * @throws IOException
203 * in case of I/O error or if the {@link Story} was not
206 public abstract void read(int chapter
) throws IOException
;
209 * Start the reader in browse mode for the given source (or pass NULL for
213 * the type of {@link Story} to take into account, or NULL for
216 public abstract void browse(String source
);
219 * Return a new {@link BasicReader} ready for use if one is configured.
221 * Can return NULL if none are configured.
223 * @return a {@link BasicReader}, or NULL if none configured
225 public static BasicReader
getReader() {
227 if (defaultType
!= null) {
228 return ((BasicReader
) SerialUtils
.createObject(defaultType
229 .getTypeName())).setType(defaultType
);
231 } catch (Exception e
) {
232 Instance
.syserr(new Exception("Cannot create a reader of type: "
233 + defaultType
+ " (Not compiled in?)", e
));
240 * The default {@link ReaderType} used when calling
241 * {@link BasicReader#getReader()}.
243 * @return the default type
245 public static ReaderType
getDefaultReaderType() {
250 * The default {@link ReaderType} used when calling
251 * {@link BasicReader#getReader()}.
254 * the new default type
256 public static void setDefaultReaderType(ReaderType defaultType
) {
257 BasicReader
.defaultType
= defaultType
;
261 * Change the default {@link LocalLibrary} to open with the
262 * {@link BasicReader}s.
265 * the new {@link LocalLibrary}
267 public static void setDefaultLibrary(BasicLibrary lib
) {
268 BasicReader
.defaultLibrary
= lib
;
272 * Return an {@link URL} from this {@link String}, be it a file path or an
273 * actual {@link URL}.
275 * @param sourceString
278 * @return the corresponding {@link URL}
280 * @throws MalformedURLException
281 * if this is neither a file nor a conventional {@link URL}
283 public static URL
getUrl(String sourceString
) throws MalformedURLException
{
284 if (sourceString
== null || sourceString
.isEmpty()) {
285 throw new MalformedURLException("Empty url");
290 source
= new URL(sourceString
);
291 } catch (MalformedURLException e
) {
292 File sourceFile
= new File(sourceString
);
293 source
= sourceFile
.toURI().toURL();
300 * Open the {@link Story} with an external reader (the program will be
301 * passed the main file associated with this {@link Story}).
304 * the {@link BasicLibrary} to select the {@link Story} from
306 * the {@link Story} LUID
308 * @throws IOException
309 * in case of I/O error
311 public static void open(BasicLibrary lib
, String luid
) throws IOException
{
312 MetaData meta
= lib
.getInfo(luid
);
313 File target
= lib
.getFile(luid
);
319 * Open the {@link Story} with an external reader (the program will be
320 * passed the given target file).
323 * the {@link Story} to load
325 * the target {@link File}
327 * @throws IOException
328 * in case of I/O error
330 protected static void open(MetaData meta
, File target
) throws IOException
{
331 String program
= null;
332 if (meta
.isImageDocument()) {
333 program
= Instance
.getUiConfig().getString(
334 UiConfig
.IMAGES_DOCUMENT_READER
);
336 program
= Instance
.getUiConfig().getString(
337 UiConfig
.NON_IMAGES_DOCUMENT_READER
);
340 if (program
!= null && program
.trim().isEmpty()) {
344 if (program
== null) {
346 Desktop
.getDesktop().browse(target
.toURI());
347 } catch (UnsupportedOperationException e
) {
348 Runtime
.getRuntime().exec(
349 new String
[] { "xdg-open", target
.getAbsolutePath() });
353 Runtime
.getRuntime().exec(
354 new String
[] { program
, target
.getAbsolutePath() });