cached lib can now getStory()
[fanfix.git] / src / be / nikiroo / fanfix / library / CacheLibrary.java
CommitLineData
ff05b828
NR
1package be.nikiroo.fanfix.library;
2
ff05b828
NR
3import java.io.File;
4import java.io.IOException;
edf79e5e 5import java.net.URL;
ff05b828
NR
6import java.util.List;
7
8import be.nikiroo.fanfix.Instance;
9import be.nikiroo.fanfix.bundles.UiConfig;
10import be.nikiroo.fanfix.data.MetaData;
11import be.nikiroo.fanfix.data.Story;
16a81ef7 12import be.nikiroo.utils.Image;
ff05b828
NR
13import be.nikiroo.utils.Progress;
14
15/**
16 * This library will cache another pre-existing {@link BasicLibrary}.
17 *
18 * @author niki
19 */
20public class CacheLibrary extends BasicLibrary {
21 private List<MetaData> metas;
22 private BasicLibrary lib;
23 private LocalLibrary cacheLib;
24
25 /**
26 * Create a cache library around the given one.
27 * <p>
28 * It will return the same result, but those will be saved to disk at the
29 * same time to be fetched quicker the next time.
30 *
31 * @param cacheDir
32 * the cache directory where to save the files to disk
33 * @param lib
34 * the original library to wrap
35 */
36 public CacheLibrary(File cacheDir, BasicLibrary lib) {
37 this.cacheLib = new LocalLibrary(cacheDir, Instance.getUiConfig()
38 .getString(UiConfig.GUI_NON_IMAGES_DOCUMENT_TYPE), Instance
39 .getUiConfig().getString(UiConfig.GUI_IMAGES_DOCUMENT_TYPE),
40 true);
41 this.lib = lib;
42 }
43
44 @Override
45 public String getLibraryName() {
46 return lib.getLibraryName();
47 }
48
e6249b0f
NR
49 @Override
50 public Status getStatus() {
51 return lib.getStatus();
52 }
53
ff05b828
NR
54 @Override
55 protected List<MetaData> getMetas(Progress pg) {
56 if (pg == null) {
57 pg = new Progress();
58 }
59
60 if (metas == null) {
61 metas = lib.getMetas(pg);
62 }
63
64 pg.done();
65 return metas;
66 }
67
60f72311
NR
68 @Override
69 public synchronized Story getStory(String luid, MetaData meta, Progress pg) {
70 String normal = Instance.getUiConfig().getString(
71 UiConfig.GUI_NON_IMAGES_DOCUMENT_TYPE);
72 String images = Instance.getUiConfig().getString(
73 UiConfig.GUI_IMAGES_DOCUMENT_TYPE);
74 String type = meta.isImageDocument() ? images : normal;
75
76 MetaData cachedMeta = meta.clone();
77 cachedMeta.setType(type);
78
79 return super.getStory(luid, cachedMeta, pg);
80 }
81
ff05b828
NR
82 @Override
83 public synchronized File getFile(final String luid, Progress pg) {
84 if (pg == null) {
85 pg = new Progress();
86 }
87
88 Progress pgImport = new Progress();
89 Progress pgGet = new Progress();
90 Progress pgRecall = new Progress();
91
92 pg.setMinMax(0, 5);
93 pg.addProgress(pgImport, 3);
94 pg.addProgress(pgGet, 1);
95 pg.addProgress(pgRecall, 1);
96
97 if (!isCached(luid)) {
98 try {
99 cacheLib.imprt(lib, luid, pgImport);
efa3c511 100 updateInfo(cacheLib.getInfo(luid));
ff05b828 101 pgImport.done();
ff05b828 102 } catch (IOException e) {
62c63b07 103 Instance.getTraceHandler().error(e);
ff05b828
NR
104 }
105
106 pgImport.done();
107 pgGet.done();
108 }
109
110 File file = cacheLib.getFile(luid, pgRecall);
111 pgRecall.done();
112
113 pg.done();
114 return file;
115 }
116
117 @Override
16a81ef7 118 public Image getCover(final String luid) {
ff05b828
NR
119 if (isCached(luid)) {
120 return cacheLib.getCover(luid);
121 }
122
085a2f9a 123 // We could update the cache here, but it's not easy
ff05b828
NR
124 return lib.getCover(luid);
125 }
126
085a2f9a 127 @Override
16a81ef7 128 public Image getSourceCover(String source) {
e1de8087
NR
129 Image custom = getCustomSourceCover(source);
130 if (custom != null) {
131 return custom;
132 }
133
cf45a4c4
NR
134 Image cached = cacheLib.getSourceCover(source);
135 if (cached != null) {
136 return cached;
137 }
138
139 return lib.getSourceCover(source);
e1de8087
NR
140 }
141
3989dfc5
NR
142 @Override
143 public Image getAuthorCover(String author) {
c956ff52 144 Image custom = getCustomAuthorCover(author);
3989dfc5
NR
145 if (custom != null) {
146 return custom;
147 }
148
c956ff52 149 Image cached = cacheLib.getAuthorCover(author);
3989dfc5
NR
150 if (cached != null) {
151 return cached;
152 }
153
c956ff52 154 return lib.getAuthorCover(author);
3989dfc5
NR
155 }
156
e1de8087
NR
157 @Override
158 public Image getCustomSourceCover(String source) {
159 Image custom = cacheLib.getCustomSourceCover(source);
160 if (custom == null) {
161 custom = lib.getCustomSourceCover(source);
162 if (custom != null) {
163 cacheLib.setSourceCover(source, custom);
164 }
165 }
166
167 return custom;
085a2f9a 168 }
c956ff52 169
3989dfc5
NR
170 @Override
171 public Image getCustomAuthorCover(String author) {
172 Image custom = cacheLib.getCustomAuthorCover(author);
173 if (custom == null) {
174 custom = lib.getCustomAuthorCover(author);
175 if (custom != null) {
176 cacheLib.setAuthorCover(author, custom);
177 }
178 }
179
180 return custom;
181 }
085a2f9a
NR
182
183 @Override
184 public void setSourceCover(String source, String luid) {
185 lib.setSourceCover(source, luid);
0dc195de 186 cacheLib.setSourceCover(source, getCover(luid));
085a2f9a
NR
187 }
188
3989dfc5
NR
189 @Override
190 public void setAuthorCover(String author, String luid) {
191 lib.setAuthorCover(author, luid);
192 cacheLib.setAuthorCover(author, getCover(luid));
193 }
194
ff05b828 195 @Override
efa3c511 196 protected void updateInfo(MetaData meta) {
b56c9d60 197 if (meta != null && metas != null) {
efa3c511
NR
198 for (int i = 0; i < metas.size(); i++) {
199 if (metas.get(i).getLuid().equals(meta.getLuid())) {
200 metas.set(i, meta);
201 }
202 }
203 }
204
205 cacheLib.updateInfo(meta);
206 lib.updateInfo(meta);
207 }
208
209 @Override
c8d48938 210 protected void invalidateInfo(String luid) {
e272f05f 211 if (luid == null) {
cbd62024 212 metas = null;
e272f05f 213 } else if (metas != null) {
e272f05f
NR
214 for (int i = 0; i < metas.size(); i++) {
215 if (metas.get(i).getLuid().equals(luid)) {
cbd62024 216 metas.remove(i--);
e272f05f
NR
217 }
218 }
e272f05f
NR
219 }
220
c8d48938
NR
221 cacheLib.invalidateInfo(luid);
222 lib.invalidateInfo(luid);
ff05b828
NR
223 }
224
225 @Override
226 public synchronized Story save(Story story, String luid, Progress pg)
227 throws IOException {
03c1cede
NR
228 Progress pgLib = new Progress();
229 Progress pgCacheLib = new Progress();
230
231 if (pg == null) {
232 pg = new Progress();
233 }
234
235 pg.setMinMax(0, 2);
236 pg.addProgress(pgLib, 1);
237 pg.addProgress(pgCacheLib, 1);
238
239 story = lib.save(story, luid, pgLib);
0fa0fe95 240 story = cacheLib.save(story, story.getMeta().getLuid(), pgCacheLib);
03c1cede 241
efa3c511 242 updateInfo(story.getMeta());
03c1cede 243
ff05b828
NR
244 return story;
245 }
246
247 @Override
248 public synchronized void delete(String luid) throws IOException {
085a2f9a
NR
249 if (isCached(luid)) {
250 cacheLib.delete(luid);
251 }
ff05b828 252 lib.delete(luid);
e272f05f 253
cbd62024
NR
254 MetaData meta = getInfo(luid);
255 if (meta != null) {
256 metas.remove(meta);
e272f05f 257 }
ff05b828
NR
258 }
259
ff05b828 260 @Override
c8d48938
NR
261 protected synchronized void changeSTA(String luid, String newSource,
262 String newTitle, String newAuthor, Progress pg) throws IOException {
ff05b828
NR
263 if (pg == null) {
264 pg = new Progress();
265 }
266
267 Progress pgCache = new Progress();
268 Progress pgOrig = new Progress();
269 pg.setMinMax(0, 2);
270 pg.addProgress(pgCache, 1);
271 pg.addProgress(pgOrig, 1);
272
e272f05f
NR
273 MetaData meta = getInfo(luid);
274 if (meta == null) {
275 throw new IOException("Story not found: " + luid);
276 }
277
e06632ee 278 if (isCached(luid)) {
c8d48938 279 cacheLib.changeSTA(luid, newSource, newTitle, newAuthor, pgCache);
e06632ee 280 }
ff05b828 281 pgCache.done();
e272f05f 282
c8d48938 283 lib.changeSTA(luid, newSource, newTitle, newAuthor, pgOrig);
ff05b828
NR
284 pgOrig.done();
285
e272f05f 286 meta.setSource(newSource);
c8d48938
NR
287 meta.setTitle(newTitle);
288 meta.setAuthor(newAuthor);
ff05b828
NR
289 pg.done();
290 }
291
292 /**
293 * Check if the {@link Story} denoted by this Library UID is present in the
294 * cache.
295 *
296 * @param luid
297 * the Library UID
298 *
299 * @return TRUE if it is
300 */
301 public boolean isCached(String luid) {
302 return cacheLib.getInfo(luid) != null;
303 }
304
305 /**
306 * Clear the {@link Story} from the cache.
c3b229a1
NR
307 * <p>
308 * The next time we try to retrieve the {@link Story}, it may be required to
309 * cache it again.
ff05b828
NR
310 *
311 * @param luid
312 * the story to clear
313 *
314 * @throws IOException
315 * in case of I/O error
316 */
317 public void clearFromCache(String luid) throws IOException {
e06632ee
NR
318 if (isCached(luid)) {
319 cacheLib.delete(luid);
e06632ee 320 }
ff05b828
NR
321 }
322
edf79e5e
NR
323 @Override
324 public Story imprt(URL url, Progress pg) throws IOException {
325 if (pg == null) {
326 pg = new Progress();
327 }
328
329 Progress pgImprt = new Progress();
330 Progress pgCache = new Progress();
331 pg.setMinMax(0, 10);
332 pg.addProgress(pgImprt, 7);
333 pg.addProgress(pgCache, 3);
334
335 Story story = lib.imprt(url, pgImprt);
336 cacheLib.save(story, story.getMeta().getLuid(), pgCache);
337
efa3c511 338 updateInfo(story.getMeta());
cbd62024 339
edf79e5e
NR
340 pg.done();
341 return story;
342 }
343
ff05b828
NR
344 // All the following methods are only used by Save and Delete in
345 // BasicLibrary:
346
347 @Override
348 protected int getNextId() {
349 throw new java.lang.InternalError("Should not have been called");
350 }
351
352 @Override
353 protected void doDelete(String luid) throws IOException {
354 throw new java.lang.InternalError("Should not have been called");
355 }
356
357 @Override
358 protected Story doSave(Story story, Progress pg) throws IOException {
359 throw new java.lang.InternalError("Should not have been called");
360 }
361}