1 19 package org.fjank.jcache.persistence; 20 21 import java.io.BufferedInputStream ; 22 import java.io.ByteArrayInputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.File ; 25 import java.io.FileNotFoundException ; 26 import java.io.IOException ; 27 import java.io.NotSerializableException ; 28 import java.io.ObjectInputStream ; 29 import java.io.ObjectOutputStream ; 30 import java.io.RandomAccessFile ; 31 import java.io.Serializable ; 32 import javax.util.jcache.DiskCacheException; 33 import org.fjank.jcache.CacheObject; 34 import org.fjank.jcache.DiskCacheObject; 35 36 37 40 public class CacheFileAdapter { 41 42 private final String filepath; 43 44 45 private RandomAccessFile raf; 46 47 54 public CacheFileAdapter(final File file) { 55 this.filepath = file.getAbsolutePath(); 56 try { 57 raf = new RandomAccessFile (filepath, "rw"); 58 } catch (FileNotFoundException e) { 59 throw new IllegalStateException ( 60 "The disk cache could not be initialized."); 61 } 62 } 63 64 69 public String toString() { 70 return getClass().getName() + ", file:" + filepath; 71 } 72 78 public byte[] read(long pos) { 79 byte[] data = null; 80 boolean corrupted = false; 81 try { 82 synchronized (this) { 83 raf.seek(pos); 84 int datalen = raf.readInt(); 85 if (datalen > raf.length()) { 86 corrupted = true; 87 } else { 88 raf.readFully(data = new byte[datalen]); 89 } 90 } 91 if (corrupted) { 92 throw new IllegalStateException ("The Cache file is corrupted."); 93 } 94 return data; 95 } catch (IOException e) { 96 throw new IllegalStateException (e.getMessage()); 97 } 98 } 99 100 110 public Serializable readObject(long pos) throws DiskCacheException { 111 byte[] data = read(pos); 112 return deSerialize(data); 113 114 } 115 116 117 118 public synchronized void append(byte[] data) throws DiskCacheException { 119 try { 120 write(data, raf.length()); 121 } catch (IOException e) { 122 throw new DiskCacheException(e); 123 } 124 } 125 126 public synchronized void write(byte[] data, long pos) { 127 try { 128 raf.seek(pos); 129 raf.writeInt(data.length); 130 raf.write(data); 131 } catch (IOException e) { 132 throw new IllegalStateException (e.getMessage()); 133 } 134 } 135 136 144 public void writeObject(final Serializable obj, final long pos) { 145 write(serialize(obj), pos); 146 } 147 148 157 public DiskElementDescriptor appendObject(CacheObject obj) { 158 long pos = -1; 159 DiskElementDescriptor ded = new DiskElementDescriptor(); 160 byte[] data = serialize((Serializable ) obj); 161 synchronized (this) { 162 pos = length(); 163 ded.init(pos, data); 164 write(data, pos); 165 } 166 return ded; 167 } 168 169 public synchronized long length() { 170 try { 171 return raf.length(); 172 } catch (IOException e) { 173 throw new IllegalStateException (e.getMessage()); 174 } 175 } 176 177 public synchronized void close() { 178 try { 179 raf.close(); 180 } catch (IOException e) { 181 throw new IllegalStateException (e.getMessage()); 182 } 183 } 184 185 public synchronized void reset() { 186 close(); 187 File f = new File (filepath); 188 int retries=10; 190 191 while (!f.delete()) { 192 retries--; 193 if(retries<=0) { 194 throw new IllegalStateException ("Failed to delete " + f.getName()); 195 } 196 try { 198 Thread.sleep(100); 199 } catch (InterruptedException e1) { 200 } 202 } 203 try { 204 raf = new RandomAccessFile (filepath, "rw"); 205 } catch (FileNotFoundException e) { 206 throw new IllegalStateException (e.getMessage()); 207 } 208 } 209 210 public static byte[] serialize(Serializable obj) { 211 ObjectOutputStream oos = null; 212 try { 213 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 214 oos = new ObjectOutputStream (baos); 215 oos.writeObject(obj); 216 return baos.toByteArray(); 217 } catch (NotSerializableException e) { 218 throw new IllegalStateException (e.getMessage()); 219 } catch (IOException e) { 220 throw new IllegalStateException (e.getMessage()); 221 } finally { 222 if (oos != null) { 223 try { 224 oos.close(); 225 } catch (IOException e) { 226 throw new IllegalStateException ( 227 "Failed to close stream to DiskCache, " 228 + "cache may be corrupted. Reason: " + e.getMessage()); 229 } 230 } 231 } 232 } 233 public static DiskCacheObject deSerialize(byte[] data) throws DiskCacheException { 234 ObjectInputStream ois = null; 235 try { 236 ByteArrayInputStream bais = new ByteArrayInputStream (data); 237 BufferedInputStream bis = new BufferedInputStream (bais); 238 ois=new ObjectInputStream (bis); 239 DiskCacheObject obj = (DiskCacheObject) ois.readObject(); 240 obj.getCacheObject().resetRefCount(); 241 return obj; 242 } catch (IOException e) { 243 throw new IllegalStateException ("An exception occured when reading from the disk cache." + 244 " Reason: " + e.getMessage()); 245 } catch (ClassNotFoundException e) { 246 throw new IllegalStateException ("A class could not be found when deSerializing." + 247 " Reason: " + e.getMessage()); 248 } finally { 249 if (ois != null) { 250 try { 251 ois.close(); 252 } catch (IOException e) { 253 throw new IllegalStateException ( 254 "Failed to close stream to DiskCache, " 255 + "cache may be corrupted. Reason: " + e.getMessage()); 256 } 257 } 258 } 259 } 260 } 261 | Popular Tags |