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