001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package fitnesse.wiki;
004:
005: import java.io.*;
006: import java.util.*;
007: import java.util.regex.Pattern;
008: import java.util.zip.*;
009: import java.text.SimpleDateFormat;
010: import fitnesse.util.*;
011: import fitnesse.util.StreamReader;
012: import fitnesse.wikitext.widgets.WikiWordWidget;
013:
014: public class FileSystemPage extends CachingPage {
015:
016: private static final long serialVersionUID = 1L;
017:
018: public static final String contentFilename = "/content.txt";
019:
020: public static final String propertiesFilename = "/properties.xml";
021:
022: private String path;
023:
024: protected FileSystemPage(String path, String name, WikiPage parent)
025: throws Exception {
026: super (name, parent);
027: this .path = path;
028: }
029:
030: public static WikiPage makeRoot(String path, String name)
031: throws Exception {
032: FileSystemPage root = new FileSystemPage(path, name, null);
033: return root;
034: }
035:
036: public void removeChildPage(String name) throws Exception {
037: super .removeChildPage(name);
038: File fileToBeDeleted = new File(getFileSystemPath() + "/"
039: + name);
040: FileUtil.deleteFileSystemDirectory(fileToBeDeleted);
041: }
042:
043: public boolean hasChildPage(String pageName) throws Exception {
044: File f = new File(getFileSystemPath() + "/" + pageName);
045: if (f.exists()) {
046: addChildPage(pageName);
047: return true;
048: } else
049: return false;
050: }
051:
052: protected synchronized void saveContent(String content)
053: throws Exception {
054: if (content == null)
055: return;
056:
057: if (content.endsWith("|"))
058: content += "\n";
059:
060: File output = new File(getFileSystemPath() + contentFilename);
061: OutputStreamWriter writer = new OutputStreamWriter(
062: new FileOutputStream(output), "UTF-8");
063: writer.write(content);
064: writer.close();
065: }
066:
067: protected synchronized void saveAttributes(
068: WikiPageProperties attributes) throws Exception {
069: String propertiesFileName = getFileSystemPath()
070: + propertiesFilename;
071: OutputStream output = new FileOutputStream(propertiesFileName);
072: attributes.save(output);
073: output.close();
074: }
075:
076: protected WikiPage createChildPage(String name) throws Exception {
077: FileSystemPage newPage = new FileSystemPage(
078: getFileSystemPath(), name, this );
079: new File(newPage.getFileSystemPath()).mkdirs();
080: return newPage;
081: }
082:
083: private void loadContent(PageData data) throws Exception {
084: String content = "";
085:
086: String name = getFileSystemPath() + contentFilename;
087: File input = new File(name);
088: if (input.exists()) {
089: byte[] bytes = new byte[(int) input.length()];
090: FileInputStream inputStream = new FileInputStream(input);
091: inputStream.read(bytes);
092: inputStream.close();
093:
094: content = new String(bytes, "UTF-8");
095: }
096: data.setContent(content);
097: }
098:
099: protected void loadChildren() throws Exception {
100: File this Dir = new File(getFileSystemPath());
101: if (this Dir.exists()) {
102: String[] subFiles = this Dir.list();
103: for (int i = 0; i < subFiles.length; i++) {
104: String subFile = subFiles[i];
105: if (fileIsValid(subFile, this Dir)
106: && !children.containsKey(subFile))
107: children.put(subFile, getChildPage(subFile));
108: }
109: }
110: }
111:
112: private boolean fileIsValid(String filename, File dir) {
113: if (WikiWordWidget.isWikiWord(filename)) {
114: File f = new File(dir, filename);
115: if (f.isDirectory())
116: return true;
117: }
118: return false;
119: }
120:
121: private String getParentFileSystemPath() throws Exception {
122: return (parent != null) ? ((FileSystemPage) parent)
123: .getFileSystemPath() : path;
124: }
125:
126: public String getFileSystemPath() throws Exception {
127: return getParentFileSystemPath() + "/" + getName();
128: }
129:
130: private void loadAttributes(PageData data) throws Exception {
131: File file = new File(getFileSystemPath() + propertiesFilename);
132: if (file.exists()) {
133: try {
134: attemptToReadPropertiesFile(file, data);
135: } catch (Exception e) {
136: System.err.println("Could not read properties file:"
137: + file.getPath());
138: e.printStackTrace();
139: }
140: }
141: }
142:
143: private void attemptToReadPropertiesFile(File file, PageData data)
144: throws Exception {
145: WikiPageProperties props = new WikiPageProperties();
146: InputStream input = new FileInputStream(file);
147: props.loadFromXmlStream(input);
148: input.close();
149: data.setProperties(props);
150: }
151:
152: public void doCommit(PageData data) throws Exception {
153: data.setLastModificationTime(new Date());
154: saveContent(data.getContent());
155: saveAttributes(data.getProperties());
156: PageVersionPruner.pruneVersions(this , loadVersions());
157: }
158:
159: protected PageData makePageData() throws Exception {
160: PageData pagedata = new PageData(this );
161: loadContent(pagedata);
162: loadAttributes(pagedata);
163: pagedata.addVersions(loadVersions());
164: return pagedata;
165: }
166:
167: public PageData getDataVersion(String versionName) throws Exception {
168: String filename = getFileSystemPath() + "/" + versionName
169: + ".zip";
170: File file = new File(filename);
171: if (!file.exists())
172: throw new NoSuchVersionException("There is no version '"
173: + versionName + "'");
174:
175: PageData data = new PageData(this );
176: ZipFile zipFile = new ZipFile(file);
177: loadVersionContent(zipFile, data);
178: loadVersionAttributes(zipFile, data);
179: data.addVersions(loadVersions());
180: zipFile.close();
181: return data;
182: }
183:
184: private Collection loadVersions() throws Exception {
185: File dir = new File(getFileSystemPath());
186: File[] files = dir.listFiles();
187: Set versions = new HashSet();
188: if (files != null) {
189: for (int i = 0; i < files.length; i++) {
190: File file = files[i];
191: if (isVersionFile(file))
192: versions
193: .add(new VersionInfo(makeVersionName(file)));
194: }
195: }
196: return versions;
197: }
198:
199: protected VersionInfo makeVersion() throws Exception {
200: PageData data = getData();
201: return makeVersion(data);
202: }
203:
204: protected VersionInfo makeVersion(PageData data) throws Exception {
205: VersionInfo version = makeVersionInfo(data);
206:
207: String dirPath = getFileSystemPath();
208: Set filesToZip = getFilesToZip(dirPath);
209:
210: if (filesToZip.size() == 0)
211: return new VersionInfo("first_commit", "", new Date());
212:
213: /*
214: * String filename = makeVersionFileName(version.getName());
215: * ZipOutputStream zos = new ZipOutputStream(new
216: * FileOutputStream(filename));
217: *
218: * for(Iterator iterator = filesToZip.iterator(); iterator.hasNext();)
219: * addToZip((File) iterator.next(), zos);
220: *
221: * zos.finish(); zos.close();
222: */
223:
224: return new VersionInfo(version.getName());
225: }
226:
227: protected VersionInfo makeVersionInfo(PageData data)
228: throws Exception {
229: Date time = data.getLastModificationTime();
230: String versionName = VersionInfo.nextId() + "-"
231: + dateFormat().format(time);
232: String user = data.getAttribute(WikiPage.LAST_MODIFYING_USER);
233: if (user != null && !"".equals(user))
234: versionName = user + "-" + versionName;
235:
236: return new VersionInfo(versionName, user, time);
237: }
238:
239: public static SimpleDateFormat dateFormat() {
240: return new SimpleDateFormat("yyyyMMddHHmmss");
241: }
242:
243: protected String makeVersionFileName(String name) throws Exception {
244: return getFileSystemPath() + "/" + name + ".zip";
245: }
246:
247: protected String makeVersionName(File file) {
248: String name = file.getName();
249: return name.substring(0, name.length() - 4);
250: }
251:
252: protected boolean isVersionFile(File file) {
253: return Pattern.matches("(\\S+)?\\d+\\.zip", file.getName());
254: }
255:
256: protected void removeVersion(String versionName) throws Exception {
257: String versionFileName = makeVersionFileName(versionName);
258: File versionFile = new File(versionFileName);
259: versionFile.delete();
260: }
261:
262: protected Set getFilesToZip(String dirPath) {
263: Set filesToZip = new HashSet();
264: File dir = new File(dirPath);
265: File[] files = dir.listFiles();
266: if (files == null)
267: return filesToZip;
268: for (int i = 0; i < files.length; i++) {
269: File file = files[i];
270: if (!(isVersionFile(file) || file.isDirectory()))
271: filesToZip.add(file);
272: }
273: return filesToZip;
274: }
275:
276: // private void addToZip(File file, ZipOutputStream zos) throws IOException
277: // {
278: // ZipEntry entry = new ZipEntry(file.getName());
279: // zos.putNextEntry(entry);
280: // FileInputStream is = new FileInputStream(file);
281: // int size = (int) file.length();
282: // byte[] bytes = new byte[size];
283: // is.read(bytes);
284: // is.close();
285: // zos.write(bytes, 0, size);
286: // }
287:
288: protected void loadVersionContent(ZipFile zipFile, PageData data)
289: throws Exception {
290: String content = "";
291: ZipEntry contentEntry = zipFile.getEntry("content.txt");
292: if (contentEntry != null) {
293: InputStream contentIS = zipFile
294: .getInputStream(contentEntry);
295: StreamReader reader = new StreamReader(contentIS);
296: content = reader.read((int) contentEntry.getSize());
297: reader.close();
298: }
299: data.setContent(content);
300: }
301:
302: protected void loadVersionAttributes(ZipFile zipFile, PageData data)
303: throws Exception {
304: ZipEntry attributes = zipFile.getEntry("properties.xml");
305: if (attributes != null) {
306: InputStream attributeIS = zipFile
307: .getInputStream(attributes);
308: WikiPageProperties props = new WikiPageProperties(
309: attributeIS);
310: attributeIS.close();
311: data.setProperties(props);
312: }
313: }
314:
315: public String toString() {
316: try {
317: return getClass().getName() + " at "
318: + this .getFileSystemPath();
319: } catch (Exception e) {
320: return super.toString();
321: }
322: }
323: }
|