public class CacheLibrary extends BasicLibrary {
private List<MetaData> metasReal;
private List<MetaData> metasMixed;
+ private Object metasLock = new Object();
+
private BasicLibrary lib;
private LocalLibrary cacheLib;
/**
* Create a cache library around the given one.
* <p>
- * It will return the same result, but those will be saved to disk at the same
- * time to be fetched quicker the next time.
+ * It will return the same result, but those will be saved to disk at the
+ * same time to be fetched quicker the next time.
*
- * @param cacheDir the cache directory where to save the files to disk
- * @param lib the original library to wrap
- * @param config the configuration used to know which kind of default
- * {@link OutputType} to use for images and non-images stories
+ * @param cacheDir
+ * the cache directory where to save the files to disk
+ * @param lib
+ * the original library to wrap
+ * @param config
+ * the configuration used to know which kind of default
+ * {@link OutputType} to use for images and non-images stories
*/
- public CacheLibrary(File cacheDir, BasicLibrary lib, UiConfigBundle config) {
+ public CacheLibrary(File cacheDir, BasicLibrary lib,
+ UiConfigBundle config) {
this.cacheLib = new LocalLibrary(cacheDir, //
config.getString(UiConfig.GUI_NON_IMAGES_DOCUMENT_TYPE),
config.getString(UiConfig.GUI_IMAGES_DOCUMENT_TYPE), true);
}
@Override
- protected synchronized List<MetaData> getMetas(Progress pg) throws IOException {
- // We make sure that cached metas have precedence
-
+ protected List<MetaData> getMetas(Progress pg) throws IOException {
if (pg == null) {
pg = new Progress();
}
- if (metasMixed == null) {
- if (metasReal == null) {
- metasReal = lib.getMetas(pg);
- }
-
- metasMixed = new ArrayList<MetaData>();
- TreeSet<String> cachedLuids = new TreeSet<String>();
- for (MetaData cachedMeta : cacheLib.getMetas(null)) {
- metasMixed.add(cachedMeta);
- cachedLuids.add(cachedMeta.getLuid());
- }
- for (MetaData realMeta : metasReal) {
- if (!cachedLuids.contains(realMeta.getLuid())) {
- metasMixed.add(realMeta);
+ List<MetaData> copy;
+ synchronized (metasLock) {
+ // We make sure that cached metas have precedence
+ if (metasMixed == null) {
+ if (metasReal == null) {
+ metasReal = lib.getMetas(pg);
+ }
+
+ metasMixed = new ArrayList<MetaData>();
+ TreeSet<String> cachedLuids = new TreeSet<String>();
+ for (MetaData cachedMeta : cacheLib.getMetas(null)) {
+ metasMixed.add(cachedMeta);
+ cachedLuids.add(cachedMeta.getLuid());
+ }
+ for (MetaData realMeta : metasReal) {
+ if (!cachedLuids.contains(realMeta.getLuid())) {
+ metasMixed.add(realMeta);
+ }
}
}
+
+ copy = new ArrayList<MetaData>(metasMixed);
}
pg.done();
- return new ArrayList<MetaData>(metasMixed);
+ return copy;
}
@Override
- public synchronized Story getStory(String luid, MetaData meta, Progress pg) throws IOException {
+ public synchronized Story getStory(String luid, MetaData meta, Progress pg)
+ throws IOException {
if (pg == null) {
pg = new Progress();
}
}
@Override
- public synchronized File getFile(final String luid, Progress pg) throws IOException {
+ public synchronized File getFile(final String luid, Progress pg)
+ throws IOException {
if (pg == null) {
pg = new Progress();
}
* Invalidate the {@link Story} cache (when the content has changed, but we
* already have it) with the new given meta.
* <p>
- * <b>Make sure to always use {@link MetaData} from the cached library
- * in priority, here.</b>
+ * <b>Make sure to always use {@link MetaData} from the cached library in
+ * priority, here.</b>
*
* @param meta
* the {@link Story} to clear from the cache
throw new IOException(
"This method is not supported in a CacheLibrary, please use updateMetaCache");
}
-
+
// relplace the meta in Metas by Meta, add it if needed
// return TRUE = added
private boolean updateMetaCache(List<MetaData> metas, MetaData meta) {
if (meta != null && metas != null) {
- boolean changed = false;
- for (int i = 0; i < metas.size(); i++) {
- if (metas.get(i).getLuid().equals(meta.getLuid())) {
- metas.set(i, meta);
- changed = true;
+ synchronized (metasLock) {
+ boolean changed = false;
+ for (int i = 0; i < metas.size(); i++) {
+ if (metas.get(i).getLuid().equals(meta.getLuid())) {
+ metas.set(i, meta);
+ changed = true;
+ }
}
- }
- if (!changed) {
- metas.add(meta);
- return true;
+ if (!changed) {
+ metas.add(meta);
+ return true;
+ }
}
}
-
+
return false;
}
@Override
protected void invalidateInfo(String luid) {
if (luid == null) {
- metasReal = null;
- metasMixed = null;
+ synchronized (metasLock) {
+ metasReal = null;
+ metasMixed = null;
+ }
} else {
invalidateInfo(metasReal, luid);
invalidateInfo(metasMixed, luid);
// luid cannot be null
private void invalidateInfo(List<MetaData> metas, String luid) {
if (metas != null) {
- for (int i = 0; i < metas.size(); i++) {
- if (metas.get(i).getLuid().equals(luid)) {
- metas.remove(i--);
+ synchronized (metasLock) {
+ for (int i = 0; i < metas.size(); i++) {
+ if (metas.get(i).getLuid().equals(luid)) {
+ metas.remove(i--);
+ }
}
}
}
}
@Override
- public synchronized Story save(Story story, String luid, Progress pg) throws IOException {
+ public synchronized Story save(Story story, String luid, Progress pg)
+ throws IOException {
Progress pgLib = new Progress();
Progress pgCacheLib = new Progress();
story = lib.save(story, luid, pgLib);
updateMetaCache(metasReal, story.getMeta());
-
+
story = cacheLib.save(story, story.getMeta().getLuid(), pgCacheLib);
updateMetaCache(metasMixed, story.getMeta());
}
@Override
- protected synchronized void changeSTA(String luid, String newSource, String newTitle, String newAuthor, Progress pg)
- throws IOException {
+ protected synchronized void changeSTA(String luid, String newSource,
+ String newTitle, String newAuthor, Progress pg) throws IOException {
if (pg == null) {
pg = new Progress();
}
}
@Override
- public synchronized MetaData imprt(URL url, Progress pg) throws IOException {
+ public MetaData imprt(URL url, Progress pg) throws IOException {
if (pg == null) {
pg = new Progress();
}
MetaData meta = lib.imprt(url, pgImprt);
updateMetaCache(metasReal, meta);
metasMixed = null;
+
clearFromCache(meta.getLuid());
pg.done();