001: package net.suberic.util.cache;
002:
003: import java.io.*;
004:
005: /**
006: * This represents a cached object. It stores the object itself, plus
007: * the size and last accessed time.
008: *
009: * This implementation uses files to store the information in the cache.
010: */
011: public class FileSizedCacheEntry extends SizedCacheEntry {
012:
013: // the stored object itself. note that this could be a reference to
014: // another object, or a source from which the object may be accessed.
015: protected Object cachedValue;
016:
017: // the last accessed time
018: protected long lastAccessedTime;
019:
020: // the size that the cachedValue occupies in the cache.
021: protected long size = 0;
022:
023: /**
024: * Creates a new FileSizedCacheEntry containing value which has been most
025: * recently accessed now.
026: */
027: public FileSizedCacheEntry(Object value, boolean create,
028: String filename) {
029: File f = new File(filename);
030: try {
031: saveValue(f, value);
032: } catch (Exception e) {
033: }
034: cachedValue = f;
035:
036: touchEntry();
037: }
038:
039: /**
040: * This gets the cached value. Implementations may vary for this.
041: */
042: public Object getCachedValue() {
043: Object o = null;
044: try {
045: o = loadValue();
046: } catch (IOException ioe) {
047: }
048:
049: return o;
050: }
051:
052: /**
053: * Loads the given value from the source file.
054: *
055: * Note that this should also set the size.
056: */
057: public Object loadValue() throws IOException {
058: File f = getCacheFile();
059: ObjectInputStream ois = new ObjectInputStream(
060: new FileInputStream(f));
061: size = ois.available();
062: Object returnValue = null;
063: try {
064: returnValue = ois.readObject();
065: } catch (ClassNotFoundException cnfe) {
066: throw new IOException("Class not found: " + cnfe);
067: }
068: ois.close();
069: return returnValue;
070: }
071:
072: /**
073: * Saves the given value to the source file.
074: *
075: * Note that this should also set the size.
076: */
077: public void saveValue(File f, Object value) throws IOException {
078: ObjectOutputStream oos = new ObjectOutputStream(
079: new FileOutputStream(f));
080: oos.writeObject(value);
081: oos.close();
082: }
083:
084: /**
085: * Deletes this entry. Should be called in order to clean up entries
086: * for which simple removal from memory is insufficient.
087: *
088: * The default implementation does nothing; subclasses should override
089: * this method if cleanup is required.
090: */
091: public boolean removeFromCache() {
092: if (cachedValue instanceof File) {
093: ((File) cachedValue).delete();
094: return true;
095: } else
096: return false;
097: }
098:
099: /**
100: * Touches the SizedCacheEntry, making its last accessed time now.
101: */
102: public void touchEntry() {
103: lastAccessedTime = System.currentTimeMillis();
104: getCacheFile().setLastModified(lastAccessedTime);
105: }
106:
107: /**
108: * Gets the size of this SizedCacheEntry.
109: */
110: public long getSize() {
111: return size;
112: }
113:
114: /**
115: * Gets the last accessed time for this entry.
116: */
117: public long getLastAccessedTime() {
118: return lastAccessedTime;
119: }
120:
121: /**
122: * Gets the File object for the cache.
123: */
124: public File getCacheFile() {
125: return (File) cachedValue;
126: }
127:
128: /**
129: * Compares the underlying value for equality.
130: */
131: public boolean equals(Object o) {
132: if (o != null) {
133: Object testValue = null;
134: if (o instanceof SizedCacheEntry) {
135: testValue = ((SizedCacheEntry) o).getCachedValue();
136: } else {
137: testValue = o;
138: }
139: return o.equals(cachedValue);
140: }
141:
142: return (cachedValue == null);
143: }
144: }
|