001 package crisp.wbwiki.server;
002
003 import java.beans.XMLDecoder;
004 import java.beans.XMLEncoder;
005 import java.io.File;
006 import java.io.FileInputStream;
007 import java.io.FileOutputStream;
008 import java.io.IOException;
009 import java.io.InputStream;
010 import java.io.OutputStream;
011
012 import org.apache.log4j.Logger;
013
014 import crisp.wbwiki.client.Page;
015
016 /**
017 * Implementation of WikiDb that stores to a text file.
018 *
019 * @author Henrik Kniberg
020 */
021 public class WikiDbTextFile implements WikiDb {
022 private Logger log = Logger.getLogger(getClass());
023 private File path;
024
025 /**
026 * @param path Path to the file used to store wiki data (required).
027 */
028 public WikiDbTextFile(File path) {
029 if (path == null) {
030 throw new IllegalArgumentException("No path provided");
031 }
032 this.path = path;
033 }
034
035 /**
036 * Path to the file used to store wiki data. Never null.
037 */
038 public File getPath() {
039 return path;
040 }
041
042 public synchronized Page loadPage() {
043 if (path.exists() && path.length() > 0) {
044 log.debug("Loading from " + path.getAbsolutePath());
045 InputStream stream = null;
046 try {
047 stream = new FileInputStream(path);
048 XMLDecoder decoder = new XMLDecoder(stream);
049 Page page = (Page) decoder.readObject();
050 decoder.close();
051 return page;
052
053 } catch (IOException e) {
054 throw new RuntimeException("Problem while trying to read " + path.getAbsolutePath(), e);
055 } finally {
056 try {
057 stream.close();
058 } catch (IOException err) {
059 log.error("Error while closing stream. Ignoring it and moving on.", err);
060 }
061 }
062 } else {
063 log.debug("File doesn't exist or is empty: " + path.getAbsolutePath());
064
065 return new Page(1, "");
066 }
067 }
068
069 /**
070 * Saves the page and increments the version.
071 * @param pageContent
072 */
073 public synchronized int savePage(String pageContent) {
074 if (pageContent == null) {
075 pageContent = "";
076 }
077 int version = getCurrentVersion() + 1;
078 Page newPage = new Page(version, pageContent);
079
080 OutputStream stream = null;
081 try {
082 stream = new FileOutputStream(path, false);
083 XMLEncoder encoder = new XMLEncoder(stream);
084 encoder.writeObject(newPage);
085 encoder.flush();
086 encoder.close();
087 return version;
088 } catch (IOException e) {
089 throw new RuntimeException("Problem while trying to write to " + path.getAbsolutePath(), e);
090 } finally {
091 try {
092 stream.close();
093 } catch (IOException err) {
094 log.error("Error while closing stream. Ignoring it and moving on.", err);
095 }
096 }
097 }
098
099 public synchronized int getCurrentVersion() {
100 //@optimize this should probably be cached
101 return loadPage().getVersion();
102 }
103
104 }