001: package vqwiki.file;
002:
003: import org.apache.log4j.Logger;
004: import vqwiki.*;
005: import vqwiki.db.DBDate;
006: import vqwiki.utils.DiffUtil;
007: import vqwiki.utils.Utilities;
008: import java.io.*;
009: import java.util.*;
010:
011: /**
012: * Very Quick Wiki - WikiWikiWeb clone
013: * Copyright (C) 2001-2002 Gareth Cronin
014: *
015: * FileVersionManager is the VQWiki native file system implementation of
016: * the version manager for looking after the version trail that is used
017: * in diffs etc.
018: *
019: *This program is free software; you can redistribute it and/or modify
020: *it under the terms of the latest version of the GNU Lesser General
021: *Public License as published by the Free Software Foundation;
022: *
023: *This program is distributed in the hope that it will be useful,
024: *but WITHOUT ANY WARRANTY; without even the implied warranty of
025: *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
026: *GNU Lesser General Public License for more details.
027: *
028: *You should have received a copy of the GNU Lesser General Public License
029: *along with this program (gpl.txt); if not, write to the Free Software
030: *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
031: */
032:
033: public class FileVersionManager implements VersionManager {
034:
035: private static final Logger logger = Logger
036: .getLogger(FileVersionManager.class);
037: private static VersionManager instance;
038:
039: /**
040: *
041: */
042: private FileVersionManager() throws Exception {
043: }
044:
045: /**
046: *
047: */
048: public static VersionManager getInstance() throws Exception {
049: if (instance == null)
050: instance = new FileVersionManager();
051: return instance;
052: }
053:
054: /**
055: *
056: */
057: public synchronized String lookupLastRevision(String virtualWiki,
058: String topicName) throws Exception {
059: return (String) lookupRevision(virtualWiki, topicName, 0);
060: }
061:
062: /**
063: * Revision 0 is the most recent revision
064: */
065: public synchronized Object lookupRevision(String virtualWiki,
066: String topicName, int version) throws Exception {
067: logger.debug("Looking up revision " + version + " for "
068: + virtualWiki + "/" + topicName);
069: File file = FileHandler.getPathFor(virtualWiki,
070: FileHandler.VERSION_DIR);
071: String fileName = Utilities.encodeSafeFileName(topicName
072: + FileHandler.EXT);
073: String[] files = file.list(new FileStartFilter(fileName));
074: if (files == null)
075: return null;
076: if (files.length >= (1 + version)) {
077: Arrays.sort(files);
078: if (logger.isDebugEnabled()) {
079: for (int i = 0; i < files.length; i++) {
080: logger.debug("File " + i + " is " + files[i]);
081: }
082: }
083: logger.debug("Returning looked-up file: " + files[version]);
084: return files[files.length - 1 - version];
085: }
086: logger.debug("No version for revision " + version);
087: return null;
088: }
089:
090: /**
091: *
092: */
093: public String diff(String virtualWiki, String topicName,
094: int revision1, int revision2, boolean useHtml)
095: throws Exception {
096: logger.debug("Diff for version " + revision1
097: + " against version " + revision2 + " of topic "
098: + topicName);
099: String revision1Name = (String) lookupRevision(virtualWiki,
100: topicName, revision1);
101: String revision2Name = (String) lookupRevision(virtualWiki,
102: topicName, revision2);
103: StringBuffer fileName = new StringBuffer();
104: fileName.append(FileHandler.VERSION_DIR);
105: fileName.append(Utilities.sep());
106: fileName.append(revision1Name);
107: logger.debug("Finding path for " + fileName);
108: String fileName1 = FileHandler.getPathFor(virtualWiki,
109: Utilities.decodeSafeFileName(fileName.toString()))
110: .getPath();
111: fileName = new StringBuffer();
112: fileName.append(FileHandler.VERSION_DIR);
113: fileName.append(Utilities.sep());
114: fileName.append(revision2Name);
115: logger.debug("Finding path for " + fileName);
116: String fileName2 = FileHandler.getPathFor(virtualWiki,
117: Utilities.decodeSafeFileName(fileName.toString()))
118: .getPath();
119: logger.debug("Diffing: " + fileName1 + " against " + fileName2);
120: FileHandler handler = new FileHandler();
121: String contents1 = (handler.read(new File(fileName1)))
122: .toString();
123: String contents2 = (handler.read(new File(fileName2)))
124: .toString();
125: return DiffUtil.diff(contents1, contents2, useHtml);
126: }
127:
128: /**
129: *
130: */
131: public Date lastRevisionDate(String virtualWiki, String topicName)
132: throws Exception {
133: String revision = this .lookupLastRevision(virtualWiki,
134: topicName);
135: if (revision == null)
136: return null;
137: return Utilities.convertFileFriendlyDate(revision);
138: }
139:
140: /**
141: * Returns all versions of the given topic in reverse chronological order
142: * @param virtualWiki
143: * @param topicName
144: * @return
145: * @throws Exception
146: */
147: public List getAllVersions(String virtualWiki, String topicName)
148: throws Exception {
149: List all = new LinkedList();
150: File file = FileHandler.getPathFor(virtualWiki,
151: FileHandler.VERSION_DIR);
152: String fileName = Utilities.encodeSafeFileName(topicName
153: + FileHandler.EXT);
154: String[] files = file.list(new FileStartFilter(fileName));
155: if (files == null)
156: return all;
157: Arrays.sort(files, new Comparator() {
158: public int compare(Object o1, Object o2) {
159: String one = (String) o1;
160: String two = (String) o2;
161: return two.compareTo(one);
162: }
163: });
164: for (int i = 0; i < files.length; i++) {
165: String currentFile = files[i];
166: TopicVersion version = new TopicVersion(virtualWiki,
167: topicName, new DBDate(Utilities
168: .convertFileFriendlyDate(currentFile)), i);
169: all.add(version);
170: }
171: return all;
172: }
173:
174: /**
175: *
176: */
177: public TopicVersion getTopicVersion(String virtualWiki,
178: String topicName, int versionNumber) throws Exception {
179: List allVersions = getAllVersions(virtualWiki, topicName);
180: return (TopicVersion) allVersions.get(versionNumber);
181: }
182:
183: /**
184: *
185: */
186: public String getVersionContents(String virtualWiki,
187: String topicName, int versionNumber) throws Exception {
188: String fileName = (String) lookupRevision(virtualWiki,
189: topicName, versionNumber);
190: logger.debug("Getting file " + fileName);
191: FileHandler fileHandler = (FileHandler) WikiBase.getInstance()
192: .getHandler();
193: File file = new File(FileHandler.getPathFor(virtualWiki,
194: FileHandler.VERSION_DIR), fileName);
195: return fileHandler.read(file).toString();
196: }
197:
198: /**
199: *
200: */
201: public int getNumberOfVersions(String virtualWiki, String topicName)
202: throws Exception {
203: File file = FileHandler.getPathFor(virtualWiki,
204: FileHandler.VERSION_DIR);
205: String fileName = Utilities.encodeSafeFileName(topicName
206: + FileHandler.EXT);
207: String[] files = file.list(new FileStartFilter(fileName));
208: if (files != null)
209: return files.length;
210: return -1;
211: }
212:
213: /**
214: *
215: */
216: public void addVersion(String virtualWiki, String topicName,
217: String contents, Date at) throws Exception {
218: File versionDir = FileHandler.getPathFor(virtualWiki,
219: FileHandler.VERSION_DIR);
220: StringBuffer buffer = new StringBuffer();
221: buffer.append(topicName);
222: buffer.append(FileHandler.EXT);
223: buffer.append(Utilities.fileFriendlyDate(at));
224: File versionFile = new File(versionDir, buffer.toString());
225: Writer writer = new OutputStreamWriter(new FileOutputStream(
226: versionFile), Environment.getInstance()
227: .getFileEncoding());
228: writer.write(contents);
229: writer.close();
230: }
231: }
|