package org.csstudio.sds.ui.thumbnail;
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.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import org.csstudio.platform.model.pvs.ControlSystemEnum;
import org.csstudio.platform.model.pvs.IProcessVariableAddress;
import org.csstudio.platform.model.pvs.ProcessVariableAdressFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
public class DisplayCacheValue implements Serializable {
private static final long serialVersionUID = 5067117487677452786L;
private byte[] hash;
private byte[] imageBytes;
private Set<SerializableTuple<ControlSystemEnum, String>> pvTuples;
public DisplayCacheValue() {
}
public DisplayCacheValue(File file, ImageData imageData,
Set<IProcessVariableAddress> pvAddresses) {
hash = hashFile(file);
// serialize ImageData
if(imageData == null) {
imageBytes = null;
}
else {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { imageData };
imageLoader.save(byteArrayOutputStream, SWT.IMAGE_PNG);
imageBytes = byteArrayOutputStream.toByteArray();
}
this.pvTuples = new HashSet<DisplayCacheValue.SerializableTuple<ControlSystemEnum, String>>(
pvAddresses.size());
for (IProcessVariableAddress processVariableAddress : pvAddresses) {
SerializableTuple<ControlSystemEnum, String> pvTuple = new SerializableTuple<ControlSystemEnum, String>(
processVariableAddress.getControlSystem(),
processVariableAddress.getRawName());
this.pvTuples.add(pvTuple);
}
}
public ImageData getImage() {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
return new ImageLoader().load(inputStream)[0];
}
public byte[] getHash() {
return hash;
}
public Set<IProcessVariableAddress> getProcessVariableAddresses() {
Set<IProcessVariableAddress> result = new HashSet<IProcessVariableAddress>(
pvTuples.size());
for (SerializableTuple<ControlSystemEnum, String> pvTuple : pvTuples) {
IProcessVariableAddress processVariableAddress = ProcessVariableAdressFactory
.getInstance().createProcessVariableAdress(pvTuple.getS2(),
pvTuple.getS1());
result.add(processVariableAddress);
}
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 static class Tuple<T1, T2> {
private T1 p1;
private T2 p2;
public Tuple(T1 p1, T2 p2) {
this.p1 = p1;
this.p2 = p2;
}
public T1 getP1() {
return p1;
}
public T2 getP2() {
return p2;
}
}
public static class SerializableTuple<T1 extends Serializable, T2 extends Serializable>
implements Serializable {
private static final long serialVersionUID = -3037433875843076362L;
private T1 s1;
private T2 s2;
public SerializableTuple(T1 s1, T2 s2) {
this.s1 = s1;
this.s2 = s2;
}
public T1 getS1() {
return s1;
}
public T2 getS2() {
return s2;
}
}
}