Fix name of imported cbz, fix library check
[nikiroo-utils.git] / src / be / nikiroo / fanfix / reader / BasicReader.java
1 package be.nikiroo.fanfix.reader;
2
3 import java.awt.Desktop;
4 import java.io.File;
5 import java.io.IOException;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8
9 import be.nikiroo.fanfix.Instance;
10 import be.nikiroo.fanfix.bundles.Config;
11 import be.nikiroo.fanfix.bundles.UiConfig;
12 import be.nikiroo.fanfix.data.MetaData;
13 import be.nikiroo.fanfix.data.Story;
14 import be.nikiroo.fanfix.library.BasicLibrary;
15 import be.nikiroo.fanfix.library.LocalLibrary;
16 import be.nikiroo.fanfix.supported.BasicSupport;
17 import be.nikiroo.utils.Progress;
18 import be.nikiroo.utils.serial.SerialUtils;
19
20 /**
21 * The class that handles the different {@link Story} readers you can use.
22 * <p>
23 * All the readers should be accessed via {@link BasicReader#getReader()}.
24 *
25 * @author niki
26 */
27 public abstract class BasicReader implements Reader {
28 private static BasicLibrary defaultLibrary = Instance.getLibrary();
29 private static ReaderType defaultType = ReaderType.GUI;
30
31 private BasicLibrary lib;
32 private MetaData meta;
33 private Story story;
34 private int chapter;
35
36 /**
37 * Take the default reader type configuration from the config file.
38 */
39 static {
40 String typeString = Instance.getConfig().getString(Config.READER_TYPE);
41 if (typeString != null && !typeString.isEmpty()) {
42 try {
43 ReaderType type = ReaderType.valueOf(typeString.toUpperCase());
44 defaultType = type;
45 } catch (IllegalArgumentException e) {
46 // Do nothing
47 }
48 }
49 }
50
51 @Override
52 public synchronized Story getStory(Progress pg) {
53 if (story == null) {
54 story = getLibrary().getStory(meta.getLuid(), pg);
55 }
56
57 return story;
58 }
59
60 @Override
61 public BasicLibrary getLibrary() {
62 if (lib == null) {
63 lib = defaultLibrary;
64 }
65
66 return lib;
67 }
68
69 @Override
70 public void setLibrary(BasicLibrary lib) {
71 this.lib = lib;
72 }
73
74 @Override
75 public MetaData getMeta() {
76 return meta;
77 }
78
79 @Override
80 public synchronized void setMeta(MetaData meta) throws IOException {
81 setMeta(meta == null ? null : meta.getLuid()); // must check the library
82 }
83
84 @Override
85 public synchronized void setMeta(String luid) throws IOException {
86 story = null;
87 meta = getLibrary().getInfo(luid);
88
89 if (meta == null) {
90 throw new IOException("Cannot retrieve story from library: " + luid);
91 }
92 }
93
94 @Override
95 public synchronized void setMeta(URL source, Progress pg)
96 throws IOException {
97 BasicSupport support = BasicSupport.getSupport(source);
98 if (support == null) {
99 throw new IOException("URL not supported: " + source.toString());
100 }
101
102 story = support.process(source, pg);
103 if (story == null) {
104 throw new IOException(
105 "Cannot retrieve story from external source: "
106 + source.toString());
107 }
108
109 meta = story.getMeta();
110 }
111
112 @Override
113 public int getChapter() {
114 return chapter;
115 }
116
117 @Override
118 public void setChapter(int chapter) {
119 this.chapter = chapter;
120 }
121
122 /**
123 * Return a new {@link BasicReader} ready for use if one is configured.
124 * <p>
125 * Can return NULL if none are configured.
126 *
127 * @return a {@link BasicReader}, or NULL if none configured
128 */
129 public static Reader getReader() {
130 try {
131 if (defaultType != null) {
132 return (Reader) SerialUtils.createObject(defaultType
133 .getTypeName());
134 }
135 } catch (Exception e) {
136 Instance.syserr(new Exception("Cannot create a reader of type: "
137 + defaultType + " (Not compiled in?)", e));
138 }
139
140 return null;
141 }
142
143 /**
144 * The default {@link Reader.ReaderType} used when calling
145 * {@link BasicReader#getReader()}.
146 *
147 * @return the default type
148 */
149 public static ReaderType getDefaultReaderType() {
150 return defaultType;
151 }
152
153 /**
154 * The default {@link Reader.ReaderType} used when calling
155 * {@link BasicReader#getReader()}.
156 *
157 * @param defaultType
158 * the new default type
159 */
160 public static void setDefaultReaderType(ReaderType defaultType) {
161 BasicReader.defaultType = defaultType;
162 }
163
164 /**
165 * Change the default {@link LocalLibrary} to open with the
166 * {@link BasicReader}s.
167 *
168 * @param lib
169 * the new {@link LocalLibrary}
170 */
171 public static void setDefaultLibrary(BasicLibrary lib) {
172 BasicReader.defaultLibrary = lib;
173 }
174
175 /**
176 * Return an {@link URL} from this {@link String}, be it a file path or an
177 * actual {@link URL}.
178 *
179 * @param sourceString
180 * the source
181 *
182 * @return the corresponding {@link URL}
183 *
184 * @throws MalformedURLException
185 * if this is neither a file nor a conventional {@link URL}
186 */
187 public static URL getUrl(String sourceString) throws MalformedURLException {
188 if (sourceString == null || sourceString.isEmpty()) {
189 throw new MalformedURLException("Empty url");
190 }
191
192 URL source = null;
193 try {
194 source = new URL(sourceString);
195 } catch (MalformedURLException e) {
196 File sourceFile = new File(sourceString);
197 source = sourceFile.toURI().toURL();
198 }
199
200 return source;
201 }
202
203 /**
204 * Open the {@link Story} with an external reader (the program will be
205 * passed the main file associated with this {@link Story}).
206 *
207 * @param lib
208 * the {@link BasicLibrary} to select the {@link Story} from
209 * @param luid
210 * the {@link Story} LUID
211 *
212 * @throws IOException
213 * in case of I/O error
214 */
215 public static void openExternal(BasicLibrary lib, String luid)
216 throws IOException {
217 MetaData meta = lib.getInfo(luid);
218 File target = lib.getFile(luid, null);
219
220 openExternal(meta, target);
221 }
222
223 /**
224 * Open the {@link Story} with an external reader (the program will be
225 * passed the given target file).
226 *
227 * @param meta
228 * the {@link Story} to load
229 * @param target
230 * the target {@link File}
231 *
232 * @throws IOException
233 * in case of I/O error
234 */
235 protected static void openExternal(MetaData meta, File target)
236 throws IOException {
237 String program = null;
238 if (meta.isImageDocument()) {
239 program = Instance.getUiConfig().getString(
240 UiConfig.IMAGES_DOCUMENT_READER);
241 } else {
242 program = Instance.getUiConfig().getString(
243 UiConfig.NON_IMAGES_DOCUMENT_READER);
244 }
245
246 if (program != null && program.trim().isEmpty()) {
247 program = null;
248 }
249
250 if (program == null) {
251 try {
252 Desktop.getDesktop().browse(target.toURI());
253 } catch (UnsupportedOperationException e) {
254 Runtime.getRuntime().exec(
255 new String[] { "xdg-open", target.getAbsolutePath() });
256
257 }
258 } else {
259 Runtime.getRuntime().exec(
260 new String[] { program, target.getAbsolutePath() });
261 }
262 }
263 }