a9063308f8faf2ca0741c22b0e2cb21ea198ef96
[fanfix.git] / src / be / nikiroo / fanfix / library / CacheLibrary.java
1 package be.nikiroo.fanfix.library;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.URL;
6 import java.util.List;
7
8 import be.nikiroo.fanfix.Instance;
9 import be.nikiroo.fanfix.bundles.UiConfig;
10 import be.nikiroo.fanfix.data.MetaData;
11 import be.nikiroo.fanfix.data.Story;
12 import be.nikiroo.utils.Image;
13 import be.nikiroo.utils.Progress;
14
15 /**
16 * This library will cache another pre-existing {@link BasicLibrary}.
17 *
18 * @author niki
19 */
20 public 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
49 @Override
50 public Status getStatus() {
51 return lib.getStatus();
52 }
53
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
68 @Override
69 public synchronized File getFile(final String luid, Progress pg) {
70 if (pg == null) {
71 pg = new Progress();
72 }
73
74 Progress pgImport = new Progress();
75 Progress pgGet = new Progress();
76 Progress pgRecall = new Progress();
77
78 pg.setMinMax(0, 5);
79 pg.addProgress(pgImport, 3);
80 pg.addProgress(pgGet, 1);
81 pg.addProgress(pgRecall, 1);
82
83 if (!isCached(luid)) {
84 try {
85 cacheLib.imprt(lib, luid, pgImport);
86 updateInfo(cacheLib.getInfo(luid));
87 pgImport.done();
88 } catch (IOException e) {
89 Instance.getTraceHandler().error(e);
90 }
91
92 pgImport.done();
93 pgGet.done();
94 }
95
96 File file = cacheLib.getFile(luid, pgRecall);
97 pgRecall.done();
98
99 pg.done();
100 return file;
101 }
102
103 @Override
104 public Image getCover(final String luid) {
105 if (isCached(luid)) {
106 return cacheLib.getCover(luid);
107 }
108
109 // We could update the cache here, but it's not easy
110 return lib.getCover(luid);
111 }
112
113 @Override
114 public Image getSourceCover(String source) {
115 // no cache for the source cover
116 return lib.getSourceCover(source);
117 }
118
119 @Override
120 public void setSourceCover(String source, String luid) {
121 lib.setSourceCover(source, luid);
122 cacheLib.setSourceCover(source, getSourceCover(source));
123 }
124
125 @Override
126 protected void updateInfo(MetaData meta) {
127 if (meta != null && metas != null) {
128 for (int i = 0; i < metas.size(); i++) {
129 if (metas.get(i).getLuid().equals(meta.getLuid())) {
130 metas.set(i, meta);
131 }
132 }
133 }
134
135 cacheLib.updateInfo(meta);
136 lib.updateInfo(meta);
137 }
138
139 @Override
140 protected void deleteInfo(String luid) {
141 if (luid == null) {
142 metas = null;
143 } else if (metas != null) {
144 for (int i = 0; i < metas.size(); i++) {
145 if (metas.get(i).getLuid().equals(luid)) {
146 metas.remove(i--);
147 }
148 }
149 }
150
151 cacheLib.deleteInfo(luid);
152 lib.deleteInfo(luid);
153 }
154
155 @Override
156 public synchronized Story save(Story story, String luid, Progress pg)
157 throws IOException {
158 Progress pgLib = new Progress();
159 Progress pgCacheLib = new Progress();
160
161 if (pg == null) {
162 pg = new Progress();
163 }
164
165 pg.setMinMax(0, 2);
166 pg.addProgress(pgLib, 1);
167 pg.addProgress(pgCacheLib, 1);
168
169 story = lib.save(story, luid, pgLib);
170 story = cacheLib.save(story, story.getMeta().getLuid(), pgCacheLib);
171
172 updateInfo(story.getMeta());
173
174 return story;
175 }
176
177 @Override
178 public synchronized void delete(String luid) throws IOException {
179 if (isCached(luid)) {
180 cacheLib.delete(luid);
181 }
182 lib.delete(luid);
183
184 MetaData meta = getInfo(luid);
185 if (meta != null) {
186 metas.remove(meta);
187 }
188 }
189
190 @Override
191 public synchronized void changeSource(String luid, String newSource,
192 Progress pg) throws IOException {
193 if (pg == null) {
194 pg = new Progress();
195 }
196
197 Progress pgCache = new Progress();
198 Progress pgOrig = new Progress();
199 pg.setMinMax(0, 2);
200 pg.addProgress(pgCache, 1);
201 pg.addProgress(pgOrig, 1);
202
203 MetaData meta = getInfo(luid);
204 if (meta == null) {
205 throw new IOException("Story not found: " + luid);
206 }
207
208 if (isCached(luid)) {
209 cacheLib.changeSource(luid, newSource, pgCache);
210 }
211 pgCache.done();
212
213 lib.changeSource(luid, newSource, pgOrig);
214 pgOrig.done();
215
216 meta.setSource(newSource);
217 pg.done();
218 }
219
220 /**
221 * Check if the {@link Story} denoted by this Library UID is present in the
222 * cache.
223 *
224 * @param luid
225 * the Library UID
226 *
227 * @return TRUE if it is
228 */
229 public boolean isCached(String luid) {
230 return cacheLib.getInfo(luid) != null;
231 }
232
233 /**
234 * Clear the {@link Story} from the cache.
235 *
236 * @param luid
237 * the story to clear
238 *
239 * @throws IOException
240 * in case of I/O error
241 */
242 public void clearFromCache(String luid) throws IOException {
243 if (isCached(luid)) {
244 cacheLib.delete(luid);
245 deleteInfo(luid);
246 }
247 }
248
249 @Override
250 public Story imprt(URL url, Progress pg) throws IOException {
251 if (pg == null) {
252 pg = new Progress();
253 }
254
255 Progress pgImprt = new Progress();
256 Progress pgCache = new Progress();
257 pg.setMinMax(0, 10);
258 pg.addProgress(pgImprt, 7);
259 pg.addProgress(pgCache, 3);
260
261 Story story = lib.imprt(url, pgImprt);
262 cacheLib.save(story, story.getMeta().getLuid(), pgCache);
263
264 updateInfo(story.getMeta());
265
266 pg.done();
267 return story;
268 }
269
270 // All the following methods are only used by Save and Delete in
271 // BasicLibrary:
272
273 @Override
274 protected int getNextId() {
275 throw new java.lang.InternalError("Should not have been called");
276 }
277
278 @Override
279 protected void doDelete(String luid) throws IOException {
280 throw new java.lang.InternalError("Should not have been called");
281 }
282
283 @Override
284 protected Story doSave(Story story, Progress pg) throws IOException {
285 throw new java.lang.InternalError("Should not have been called");
286 }
287 }