KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > fjank > jcache > persistence > CacheFileAdapter


1 /* Open Source Java Caching Service
2 * Copyright (C) 2002 Frank Karlstrøm
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * The author can be contacted by email: fjankk@users.sourceforge.net
18 */

19 package org.fjank.jcache.persistence;
20
21 import java.io.BufferedInputStream JavaDoc;
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.NotSerializableException JavaDoc;
28 import java.io.ObjectInputStream JavaDoc;
29 import java.io.ObjectOutputStream JavaDoc;
30 import java.io.RandomAccessFile JavaDoc;
31 import java.io.Serializable JavaDoc;
32 import javax.util.jcache.DiskCacheException;
33 import org.fjank.jcache.CacheObject;
34 import org.fjank.jcache.DiskCacheObject;
35
36
37 /**
38  * Provides thread safe access to the underlying random access file.
39  */

40 public class CacheFileAdapter {
41     /** the path to the files */
42     private final String JavaDoc filepath;
43
44     /** an accessor to the file */
45     private RandomAccessFile JavaDoc raf;
46    
47     /**
48      * Creates a new CacheFileAdapter object.
49      *
50      * @param file the file to adapt to
51      *
52      * @throws DiskCacheException if any exceptioins occur.
53      */

54     public CacheFileAdapter(final File JavaDoc file) {
55         this.filepath = file.getAbsolutePath();
56         try {
57             raf = new RandomAccessFile JavaDoc(filepath, "rw");
58         } catch (FileNotFoundException JavaDoc e) {
59             throw new IllegalStateException JavaDoc(
60                 "The disk cache could not be initialized.");
61         }
62     }
63
64     /**
65      * returns a String representation of this object.
66      *
67      * @return a String representation of this object.
68      */

69     public String JavaDoc toString() {
70         return getClass().getName() + ", file:" + filepath;
71     }
72     /**
73      * reads from the diskfile, and return the raw bytes
74      * contained at that pos. Its up to the client to deSerialize.
75      * @param pos the position to start at.
76      * @return a byte[] containing the raw bytes for the object.
77      */

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 JavaDoc("The Cache file is corrupted.");
93             }
94             return data;
95         } catch (IOException JavaDoc e) {
96             throw new IllegalStateException JavaDoc(e.getMessage());
97         }
98     }
99     
100     /**
101      * reads an object starting at the position,.
102      *
103      * @param pos the position to start at
104      *
105      * @return a Serializable object read from the diskcache.
106      * @throws DiskCacheException
107      *
108      * @throws DiskCacheException if any exceptions occur.
109      */

110     public Serializable JavaDoc 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 JavaDoc 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 JavaDoc e) {
132             throw new IllegalStateException JavaDoc(e.getMessage());
133         }
134     }
135
136     /**
137      * writes an object down to the cachefile
138      *
139      * @param obj the object to write
140      * @param pos the position to start at.
141      *
142      * @throws DiskCacheException if any exception occur.
143      */

144     public void writeObject(final Serializable JavaDoc obj, final long pos) {
145         write(serialize(obj), pos);
146     }
147
148     /**
149      * adds an object to the diskcache.
150      *
151      * @param obj the object to add.
152      *
153      * @return a disk element descriptor used to locate the object
154      *
155      * @throws DiskCacheException if any exceptions occur.
156      */

157     public DiskElementDescriptor appendObject(CacheObject obj) {
158         long pos = -1;
159         DiskElementDescriptor ded = new DiskElementDescriptor();
160         byte[] data = serialize((Serializable JavaDoc) 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 JavaDoc e) {
173             throw new IllegalStateException JavaDoc(e.getMessage());
174         }
175     }
176
177     public synchronized void close() {
178         try {
179             raf.close();
180         } catch (IOException JavaDoc e) {
181             throw new IllegalStateException JavaDoc(e.getMessage());
182         }
183     }
184
185     public synchronized void reset() {
186         close();
187         File JavaDoc f = new File JavaDoc(filepath);
188         //boolean deleted = f.delete();
189
int retries=10;
190
191         while (!f.delete()) {
192             retries--;
193             if(retries<=0) {
194                 throw new IllegalStateException JavaDoc("Failed to delete " + f.getName());
195             }
196             // todo busy wait.
197
try {
198                 Thread.sleep(100);
199             } catch (InterruptedException JavaDoc e1) {
200                 //interrupted.
201
}
202         }
203         try {
204             raf = new RandomAccessFile JavaDoc(filepath, "rw");
205         } catch (FileNotFoundException JavaDoc e) {
206             throw new IllegalStateException JavaDoc(e.getMessage());
207         }
208     }
209
210     public static byte[] serialize(Serializable JavaDoc obj) {
211         ObjectOutputStream JavaDoc oos = null;
212         try {
213             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
214             oos = new ObjectOutputStream JavaDoc(baos);
215             oos.writeObject(obj);
216             return baos.toByteArray();
217         } catch (NotSerializableException JavaDoc e) {
218             throw new IllegalStateException JavaDoc(e.getMessage());
219         } catch (IOException JavaDoc e) {
220             throw new IllegalStateException JavaDoc(e.getMessage());
221         } finally {
222             if (oos != null) {
223                 try {
224                     oos.close();
225                 } catch (IOException JavaDoc e) {
226                     throw new IllegalStateException JavaDoc(
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 JavaDoc ois = null;
235         try {
236             ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(data);
237             BufferedInputStream JavaDoc bis = new BufferedInputStream JavaDoc(bais);
238             ois=new ObjectInputStream JavaDoc(bis);
239             DiskCacheObject obj = (DiskCacheObject) ois.readObject();
240             obj.getCacheObject().resetRefCount();
241             return obj;
242         } catch (IOException JavaDoc e) {
243             throw new IllegalStateException JavaDoc("An exception occured when reading from the disk cache." +
244                     " Reason: " + e.getMessage());
245         } catch (ClassNotFoundException JavaDoc e) {
246             throw new IllegalStateException JavaDoc("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 JavaDoc e) {
253                     throw new IllegalStateException JavaDoc(
254                         "Failed to close stream to DiskCache, "
255                         + "cache may be corrupted. Reason: " + e.getMessage());
256                 }
257             }
258         }
259     }
260 }
261
Popular Tags