added Persistent
[org.ibex.io.git] / src / org / ibex / io / Persistent.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.io;
6 import java.util.*;
7 import java.io.*;
8 import java.nio.*;
9 import java.nio.channels.*;
10 import org.ibex.util.*;
11 import org.ibex.io.*;
12 import com.thoughtworks.xstream.*;
13
14 public class Persistent {
15
16     private static WeakHashMap cache = new WeakHashMap();
17     private static final XStream xstream = new XStream();
18
19     public transient File file;
20     public transient String path;
21     public transient FileLock lock;
22
23     public Persistent(File file) { this.file = file; this.path = file.getAbsolutePath(); }
24     public Persistent(String path) { this(new File(path)); }
25
26     public static Persistent read(File file) throws Exception {
27
28         // check the cache
29         Persistent ret = (Persistent)cache.get(file.getAbsolutePath());
30         if (ret != null) return ret;
31
32         // open a new file
33         ret = (Persistent)xstream.fromXML(new BufferedReader(new InputStreamReader(new FileInputStream(file))));
34         ret.file = file;
35         ret.path = file.getAbsolutePath();
36
37         // lock it
38         ret.lock = new RandomAccessFile(file, "rw").getChannel().tryLock();
39         if (ret.lock == null) throw new RuntimeException("could not acquire lock on " + ret.path);
40
41         // and save it for later
42         cache.put(ret.path, ret);
43         return ret;
44
45     }
46
47     public synchronized void write() throws Exception {
48         FileOutputStream fos = new FileOutputStream(path + "-");
49         FileDescriptor fd = fos.getFD();
50         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
51         xstream.toXML(this, bw);
52         bw.flush();
53         fd.sync();
54         bw.close();
55         new File(path + "-").renameTo(file);
56     }
57
58 }