cbd4e0308a4584895b805d7ed3ac8bbdaf2c3732
[fanfix.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 Story story;
33
34 /**
35 * Take the default reader type configuration from the config file.
36 */
37 static {
38 String typeString = Instance.getConfig().getString(Config.READER_TYPE);
39 if (typeString != null && !typeString.isEmpty()) {
40 try {
41 ReaderType type = ReaderType.valueOf(typeString.toUpperCase());
42 defaultType = type;
43 } catch (IllegalArgumentException e) {
44 // Do nothing
45 }
46 }
47 }
48
49 public Story getStory() {
50 return story;
51 }
52
53 public BasicLibrary getLibrary() {
54 if (lib == null) {
55 lib = defaultLibrary;
56 }
57
58 return lib;
59 }
60
61 public void setLibrary(LocalLibrary lib) {
62 this.lib = lib;
63 }
64
65 public void setStory(String luid, Progress pg) throws IOException {
66 story = lib.getStory(luid, pg);
67 if (story == null) {
68 throw new IOException("Cannot retrieve story from library: " + luid);
69 }
70 }
71
72 public void setStory(URL source, Progress pg) throws IOException {
73 BasicSupport support = BasicSupport.getSupport(source);
74 if (support == null) {
75 throw new IOException("URL not supported: " + source.toString());
76 }
77
78 story = support.process(source, pg);
79 if (story == null) {
80 throw new IOException(
81 "Cannot retrieve story from external source: "
82 + source.toString());
83
84 }
85 }
86
87 /**
88 * Return a new {@link BasicReader} ready for use if one is configured.
89 * <p>
90 * Can return NULL if none are configured.
91 *
92 * @return a {@link BasicReader}, or NULL if none configured
93 */
94 public static Reader getReader() {
95 try {
96 if (defaultType != null) {
97 return (Reader) SerialUtils.createObject(defaultType
98 .getTypeName());
99 }
100 } catch (Exception e) {
101 Instance.syserr(new Exception("Cannot create a reader of type: "
102 + defaultType + " (Not compiled in?)", e));
103 }
104
105 return null;
106 }
107
108 /**
109 * The default {@link ReaderType} used when calling
110 * {@link BasicReader#getReader()}.
111 *
112 * @return the default type
113 */
114 public static ReaderType getDefaultReaderType() {
115 return defaultType;
116 }
117
118 /**
119 * The default {@link ReaderType} used when calling
120 * {@link BasicReader#getReader()}.
121 *
122 * @param defaultType
123 * the new default type
124 */
125 public static void setDefaultReaderType(ReaderType defaultType) {
126 BasicReader.defaultType = defaultType;
127 }
128
129 /**
130 * Change the default {@link LocalLibrary} to open with the
131 * {@link BasicReader}s.
132 *
133 * @param lib
134 * the new {@link LocalLibrary}
135 */
136 public static void setDefaultLibrary(BasicLibrary lib) {
137 BasicReader.defaultLibrary = lib;
138 }
139
140 /**
141 * Return an {@link URL} from this {@link String}, be it a file path or an
142 * actual {@link URL}.
143 *
144 * @param sourceString
145 * the source
146 *
147 * @return the corresponding {@link URL}
148 *
149 * @throws MalformedURLException
150 * if this is neither a file nor a conventional {@link URL}
151 */
152 public static URL getUrl(String sourceString) throws MalformedURLException {
153 if (sourceString == null || sourceString.isEmpty()) {
154 throw new MalformedURLException("Empty url");
155 }
156
157 URL source = null;
158 try {
159 source = new URL(sourceString);
160 } catch (MalformedURLException e) {
161 File sourceFile = new File(sourceString);
162 source = sourceFile.toURI().toURL();
163 }
164
165 return source;
166 }
167
168 /**
169 * Open the {@link Story} with an external reader (the program will be
170 * passed the main file associated with this {@link Story}).
171 *
172 * @param lib
173 * the {@link BasicLibrary} to select the {@link Story} from
174 * @param luid
175 * the {@link Story} LUID
176 *
177 * @throws IOException
178 * in case of I/O error
179 */
180 public static void open(BasicLibrary lib, String luid) throws IOException {
181 MetaData meta = lib.getInfo(luid);
182 File target = lib.getFile(luid);
183
184 open(meta, target);
185 }
186
187 /**
188 * Open the {@link Story} with an external reader (the program will be
189 * passed the given target file).
190 *
191 * @param meta
192 * the {@link Story} to load
193 * @param target
194 * the target {@link File}
195 *
196 * @throws IOException
197 * in case of I/O error
198 */
199 protected static void open(MetaData meta, File target) throws IOException {
200 String program = null;
201 if (meta.isImageDocument()) {
202 program = Instance.getUiConfig().getString(
203 UiConfig.IMAGES_DOCUMENT_READER);
204 } else {
205 program = Instance.getUiConfig().getString(
206 UiConfig.NON_IMAGES_DOCUMENT_READER);
207 }
208
209 if (program != null && program.trim().isEmpty()) {
210 program = null;
211 }
212
213 if (program == null) {
214 try {
215 Desktop.getDesktop().browse(target.toURI());
216 } catch (UnsupportedOperationException e) {
217 Runtime.getRuntime().exec(
218 new String[] { "xdg-open", target.getAbsolutePath() });
219
220 }
221 } else {
222 Runtime.getRuntime().exec(
223 new String[] { program, target.getAbsolutePath() });
224 }
225 }
226 }