lib: cache not refreshed on changeSTA
[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
3828c808
NR
68 @Override
69 public synchronized MetaData getInfo(String luid) {
70 MetaData info = cacheLib.getInfo(luid);
71 if (info == null) {
72 info = lib.getInfo(luid);
73 }
74
75 return info;
76 }
77
60f72311
NR
78 @Override
79 public synchronized Story getStory(String luid, MetaData meta, Progress pg) {
ff05b828
NR
80 if (pg == null) {
81 pg = new Progress();
82 }
83
84 Progress pgImport = new Progress();
85 Progress pgGet = new Progress();
ff05b828 86
d4449e96 87 pg.setMinMax(0, 4);
ff05b828
NR
88 pg.addProgress(pgImport, 3);
89 pg.addProgress(pgGet, 1);
ff05b828
NR
90
91 if (!isCached(luid)) {
92 try {
93 cacheLib.imprt(lib, luid, pgImport);
efa3c511 94 updateInfo(cacheLib.getInfo(luid));
ff05b828 95 pgImport.done();
ff05b828 96 } catch (IOException e) {
62c63b07 97 Instance.getTraceHandler().error(e);
ff05b828
NR
98 }
99
100 pgImport.done();
101 pgGet.done();
102 }
103
d4449e96
NR
104 String type = cacheLib.getOutputType(meta.isImageDocument());
105 MetaData cachedMeta = meta.clone();
106 cachedMeta.setType(type);
107
108 return cacheLib.getStory(luid, cachedMeta, pg);
109 }
110
111 @Override
112 public synchronized File getFile(final String luid, Progress pg) {
113 if (pg == null) {
114 pg = new Progress();
115 }
116
117 Progress pgGet = new Progress();
118 Progress pgRecall = new Progress();
119
120 pg.setMinMax(0, 5);
121 pg.addProgress(pgGet, 4);
122 pg.addProgress(pgRecall, 1);
123
124 if (!isCached(luid)) {
125 getStory(luid, pgGet);
126 pgGet.done();
127 }
128
ff05b828
NR
129 File file = cacheLib.getFile(luid, pgRecall);
130 pgRecall.done();
131
132 pg.done();
133 return file;
134 }
135
136 @Override
16a81ef7 137 public Image getCover(final String luid) {
ff05b828
NR
138 if (isCached(luid)) {
139 return cacheLib.getCover(luid);
140 }
141
085a2f9a 142 // We could update the cache here, but it's not easy
ff05b828
NR
143 return lib.getCover(luid);
144 }
145
085a2f9a 146 @Override
16a81ef7 147 public Image getSourceCover(String source) {
e1de8087
NR
148 Image custom = getCustomSourceCover(source);
149 if (custom != null) {
150 return custom;
151 }
152
cf45a4c4
NR
153 Image cached = cacheLib.getSourceCover(source);
154 if (cached != null) {
155 return cached;
156 }
157
158 return lib.getSourceCover(source);
e1de8087
NR
159 }
160
3989dfc5
NR
161 @Override
162 public Image getAuthorCover(String author) {
c956ff52 163 Image custom = getCustomAuthorCover(author);
3989dfc5
NR
164 if (custom != null) {
165 return custom;
166 }
167
c956ff52 168 Image cached = cacheLib.getAuthorCover(author);
3989dfc5
NR
169 if (cached != null) {
170 return cached;
171 }
172
c956ff52 173 return lib.getAuthorCover(author);
3989dfc5
NR
174 }
175
e1de8087
NR
176 @Override
177 public Image getCustomSourceCover(String source) {
178 Image custom = cacheLib.getCustomSourceCover(source);
179 if (custom == null) {
180 custom = lib.getCustomSourceCover(source);
181 if (custom != null) {
182 cacheLib.setSourceCover(source, custom);
183 }
184 }
185
186 return custom;
085a2f9a 187 }
c956ff52 188
3989dfc5
NR
189 @Override
190 public Image getCustomAuthorCover(String author) {
191 Image custom = cacheLib.getCustomAuthorCover(author);
192 if (custom == null) {
193 custom = lib.getCustomAuthorCover(author);
194 if (custom != null) {
195 cacheLib.setAuthorCover(author, custom);
196 }
197 }
198
199 return custom;
200 }
085a2f9a
NR
201
202 @Override
203 public void setSourceCover(String source, String luid) {
204 lib.setSourceCover(source, luid);
0dc195de 205 cacheLib.setSourceCover(source, getCover(luid));
085a2f9a
NR
206 }
207
3989dfc5
NR
208 @Override
209 public void setAuthorCover(String author, String luid) {
210 lib.setAuthorCover(author, luid);
211 cacheLib.setAuthorCover(author, getCover(luid));
212 }
213
ff05b828 214 @Override
efa3c511 215 protected void updateInfo(MetaData meta) {
b56c9d60 216 if (meta != null && metas != null) {
efa3c511
NR
217 for (int i = 0; i < metas.size(); i++) {
218 if (metas.get(i).getLuid().equals(meta.getLuid())) {
219 metas.set(i, meta);
220 }
221 }
222 }
223
224 cacheLib.updateInfo(meta);
225 lib.updateInfo(meta);
226 }
227
228 @Override
c8d48938 229 protected void invalidateInfo(String luid) {
e272f05f 230 if (luid == null) {
cbd62024 231 metas = null;
e272f05f 232 } else if (metas != null) {
e272f05f
NR
233 for (int i = 0; i < metas.size(); i++) {
234 if (metas.get(i).getLuid().equals(luid)) {
cbd62024 235 metas.remove(i--);
e272f05f
NR
236 }
237 }
e272f05f
NR
238 }
239
c8d48938
NR
240 cacheLib.invalidateInfo(luid);
241 lib.invalidateInfo(luid);
ff05b828
NR
242 }
243
244 @Override
245 public synchronized Story save(Story story, String luid, Progress pg)
246 throws IOException {
03c1cede
NR
247 Progress pgLib = new Progress();
248 Progress pgCacheLib = new Progress();
249
250 if (pg == null) {
251 pg = new Progress();
252 }
253
254 pg.setMinMax(0, 2);
255 pg.addProgress(pgLib, 1);
256 pg.addProgress(pgCacheLib, 1);
257
258 story = lib.save(story, luid, pgLib);
0fa0fe95 259 story = cacheLib.save(story, story.getMeta().getLuid(), pgCacheLib);
03c1cede 260
efa3c511 261 updateInfo(story.getMeta());
03c1cede 262
ff05b828
NR
263 return story;
264 }
265
266 @Override
267 public synchronized void delete(String luid) throws IOException {
085a2f9a
NR
268 if (isCached(luid)) {
269 cacheLib.delete(luid);
270 }
ff05b828 271 lib.delete(luid);
e272f05f 272
3828c808 273 invalidateInfo(luid);
ff05b828
NR
274 }
275
ff05b828 276 @Override
c8d48938
NR
277 protected synchronized void changeSTA(String luid, String newSource,
278 String newTitle, String newAuthor, Progress pg) throws IOException {
ff05b828
NR
279 if (pg == null) {
280 pg = new Progress();
281 }
282
283 Progress pgCache = new Progress();
284 Progress pgOrig = new Progress();
285 pg.setMinMax(0, 2);
286 pg.addProgress(pgCache, 1);
287 pg.addProgress(pgOrig, 1);
288
e272f05f
NR
289 MetaData meta = getInfo(luid);
290 if (meta == null) {
291 throw new IOException("Story not found: " + luid);
292 }
293
e06632ee 294 if (isCached(luid)) {
c8d48938 295 cacheLib.changeSTA(luid, newSource, newTitle, newAuthor, pgCache);
e06632ee 296 }
ff05b828 297 pgCache.done();
e272f05f 298
c8d48938 299 lib.changeSTA(luid, newSource, newTitle, newAuthor, pgOrig);
ff05b828
NR
300 pgOrig.done();
301
e272f05f 302 meta.setSource(newSource);
c8d48938
NR
303 meta.setTitle(newTitle);
304 meta.setAuthor(newAuthor);
ff05b828 305 pg.done();
3828c808
NR
306
307 invalidateInfo(luid);
ff05b828
NR
308 }
309
310 /**
311 * Check if the {@link Story} denoted by this Library UID is present in the
312 * cache.
313 *
314 * @param luid
315 * the Library UID
316 *
317 * @return TRUE if it is
318 */
319 public boolean isCached(String luid) {
320 return cacheLib.getInfo(luid) != null;
321 }
322
323 /**
324 * Clear the {@link Story} from the cache.
c3b229a1
NR
325 * <p>
326 * The next time we try to retrieve the {@link Story}, it may be required to
327 * cache it again.
ff05b828
NR
328 *
329 * @param luid
330 * the story to clear
331 *
332 * @throws IOException
333 * in case of I/O error
334 */
335 public void clearFromCache(String luid) throws IOException {
e06632ee
NR
336 if (isCached(luid)) {
337 cacheLib.delete(luid);
e06632ee 338 }
ff05b828
NR
339 }
340
edf79e5e
NR
341 @Override
342 public Story imprt(URL url, Progress pg) throws IOException {
343 if (pg == null) {
344 pg = new Progress();
345 }
346
347 Progress pgImprt = new Progress();
348 Progress pgCache = new Progress();
349 pg.setMinMax(0, 10);
350 pg.addProgress(pgImprt, 7);
351 pg.addProgress(pgCache, 3);
352
353 Story story = lib.imprt(url, pgImprt);
354 cacheLib.save(story, story.getMeta().getLuid(), pgCache);
355
efa3c511 356 updateInfo(story.getMeta());
cbd62024 357
edf79e5e
NR
358 pg.done();
359 return story;
360 }
361
ff05b828
NR
362 // All the following methods are only used by Save and Delete in
363 // BasicLibrary:
364
365 @Override
366 protected int getNextId() {
367 throw new java.lang.InternalError("Should not have been called");
368 }
369
370 @Override
371 protected void doDelete(String luid) throws IOException {
372 throw new java.lang.InternalError("Should not have been called");
373 }
374
375 @Override
376 protected Story doSave(Story story, Progress pg) throws IOException {
377 throw new java.lang.InternalError("Should not have been called");
378 }
379}