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