Version 1.2.2: fixes, export in UI
[fanfix.git] / src / be / nikiroo / fanfix / reader / BasicReader.java
1 package be.nikiroo.fanfix.reader;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7
8 import be.nikiroo.fanfix.Instance;
9 import be.nikiroo.fanfix.Library;
10 import be.nikiroo.fanfix.bundles.Config;
11 import be.nikiroo.fanfix.data.Story;
12 import be.nikiroo.fanfix.supported.BasicSupport;
13 import be.nikiroo.utils.Progress;
14
15 /**
16 * The class that handles the different {@link Story} readers you can use.
17 * <p>
18 * All the readers should be accessed via {@link BasicReader#getReader()}.
19 *
20 * @author niki
21 */
22 public abstract class BasicReader {
23 public enum ReaderType {
24 /** Simple reader that outputs everything on the console */
25 CLI,
26 /** Reader that starts local programs to handle the stories */
27 LOCAL
28 }
29
30 private static ReaderType defaultType = ReaderType.CLI;
31 private Story story;
32 private ReaderType type;
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 /**
50 * The type of this reader.
51 *
52 * @return the type
53 */
54 public ReaderType getType() {
55 return type;
56 }
57
58 /**
59 * The type of this reader.
60 *
61 * @param type
62 * the new type
63 */
64 protected BasicReader setType(ReaderType type) {
65 this.type = type;
66 return this;
67 }
68
69 /**
70 * Return the current {@link Story}.
71 *
72 * @return the {@link Story}
73 */
74 public Story getStory() {
75 return story;
76 }
77
78 /**
79 * Create a new {@link BasicReader} for a {@link Story} in the
80 * {@link Library} .
81 *
82 * @param luid
83 * the {@link Story} ID
84 * @param pg
85 * the optional progress reporter
86 *
87 * @throws IOException
88 * in case of I/O error
89 */
90 public void setStory(String luid, Progress pg) throws IOException {
91 story = Instance.getLibrary().getStory(luid, pg);
92 if (story == null) {
93 throw new IOException("Cannot retrieve story from library: " + luid);
94 }
95 }
96
97 /**
98 * Create a new {@link BasicReader} for an external {@link Story}.
99 *
100 * @param source
101 * the {@link Story} {@link URL}
102 * @param pg
103 * the optional progress reporter
104 *
105 * @throws IOException
106 * in case of I/O error
107 */
108 public void setStory(URL source, Progress pg) throws IOException {
109 BasicSupport support = BasicSupport.getSupport(source);
110 if (support == null) {
111 throw new IOException("URL not supported: " + source.toString());
112 }
113
114 story = support.process(source, pg);
115 if (story == null) {
116 throw new IOException(
117 "Cannot retrieve story from external source: "
118 + source.toString());
119
120 }
121 }
122
123 /**
124 * Start the {@link Story} Reading.
125 *
126 * @throws IOException
127 * in case of I/O error or if the {@link Story} was not
128 * previously set
129 */
130 public abstract void read() throws IOException;
131
132 /**
133 * Read the selected chapter (starting at 1).
134 *
135 * @param chapter
136 * the chapter
137 *
138 * @throws IOException
139 * in case of I/O error or if the {@link Story} was not
140 * previously set
141 */
142 public abstract void read(int chapter) throws IOException;
143
144 /**
145 * Start the reader in browse mode for the given type (or pass NULL for all
146 * types).
147 *
148 * @param type
149 * the type of {@link Story} to take into account, or NULL for
150 * all
151 */
152 public abstract void start(String type);
153
154 /**
155 * Return a new {@link BasicReader} ready for use if one is configured.
156 * <p>
157 * Can return NULL if none are configured.
158 *
159 * @return a {@link BasicReader}, or NULL if none configured
160 */
161 public static BasicReader getReader() {
162 try {
163 if (defaultType != null) {
164 switch (defaultType) {
165 case LOCAL:
166 return new LocalReader().setType(ReaderType.LOCAL);
167 case CLI:
168 return new CliReader().setType(ReaderType.CLI);
169 }
170 }
171 } catch (IOException e) {
172 Instance.syserr(new Exception("Cannot create a reader of type: "
173 + defaultType, e));
174 }
175
176 return null;
177 }
178
179 /**
180 * The default {@link ReaderType} used when calling
181 * {@link BasicReader#getReader()}.
182 *
183 * @return the default type
184 */
185 public static ReaderType getDefaultReaderType() {
186 return defaultType;
187 }
188
189 /**
190 * The default {@link ReaderType} used when calling
191 * {@link BasicReader#getReader()}.
192 *
193 * @param defaultType
194 * the new default type
195 */
196 public static void setDefaultReaderType(ReaderType defaultType) {
197 BasicReader.defaultType = defaultType;
198 }
199
200 /**
201 * Return an {@link URL} from this {@link String}, be it a file path or an
202 * actual {@link URL}.
203 *
204 * @param sourceString
205 * the source
206 *
207 * @return the corresponding {@link URL}
208 *
209 * @throws MalformedURLException
210 * if this is neither a file nor a conventional {@link URL}
211 */
212 public static URL getUrl(String sourceString) throws MalformedURLException {
213 if (sourceString == null || sourceString.isEmpty()) {
214 throw new MalformedURLException("Empty url");
215 }
216
217 URL source = null;
218 try {
219 source = new URL(sourceString);
220 } catch (MalformedURLException e) {
221 File sourceFile = new File(sourceString);
222 source = sourceFile.toURI().toURL();
223 }
224
225 return source;
226 }
227 }