package org.csstudio.sds.ui.dialogs;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.DiskStoreConfiguration;
import org.csstudio.sds.ui.SdsUiPlugin;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
public class ThumbnailImageCache {
private static final String CACHE_FOLDER_NAME = "libraryCache";
private Cache cache;
private CacheManager cacheManager;
public ThumbnailImageCache() {
File cacheDirectory = getImageCacheDirectory();
Configuration configuration = new Configuration();
configuration.addDiskStore(new DiskStoreConfiguration().path(cacheDirectory.getAbsolutePath()));
cacheManager = CacheManager.create(configuration);
CacheConfiguration config = new CacheConfiguration("DisplayThumbnailCache", 1000);
config.overflowToOffHeap(false);
config.overflowToDisk(true);
config.setDiskPersistent(true);
config.setTimeToIdleSeconds(60 * 60 * 24 * 7);
config.setTimeToLiveSeconds(60 * 60 * 24 * 30);
config.setMaxEntriesLocalHeap(100);
config.setMaxBytesLocalDisk("25M");
config.setMaxEntriesLocalDisk(10000);
cache = new Cache(config);
cacheManager.addCache(cache);
}
public ImageData getCachedImage(File file) {
assert file != null : "Precondition failed: file != null";
Element element = cache.get(file);
if (element != null) {
byte[][] value = (byte[][]) element.getValue();
if (Arrays.equals(value[0], hashFile(file))) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(value[1]);
try {
ImageLoader imageLoader = new ImageLoader();
return imageLoader.load(inputStream)[0];
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
}
public void cacheImage(File file, ImageData imageData) {
assert imageData != null;
byte[] hash = hashFile(file);
if (hash != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { imageData };
imageLoader.save(byteArrayOutputStream, SWT.IMAGE_PNG);
byte[] thumbnailData = byteArrayOutputStream.toByteArray();
cache.put(new Element(file, new byte[][] { hash, thumbnailData }));
cache.flush();
}
}
private File getImageCacheDirectory() {
File workspaceFile = ResourcesPlugin.getWorkspace().getRoot()
.getLocation().toFile();
File result = new File(workspaceFile, ".metadata/.plugins/" + SdsUiPlugin.PLUGIN_ID + "/" + CACHE_FOLDER_NAME);
if (!result.exists()) {
result.mkdirs();
}
return result;
}
private byte[] hashFile(File file) {
assert file != null : "Precondition failed: file != null";
assert file.exists() : "Precondition failed: file.exists()";
FileInputStream fis = null;
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
messageDigest.update(dataBytes, 0, nread);
}
return messageDigest.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public void shutdown() {
cacheManager.shutdown();
}
}