KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snipsnap > snip > storage > FileSnipStorage


1 /*
2  * This file is part of "SnipSnap Wiki/Weblog".
3  *
4  * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel
5  * All Rights Reserved.
6  *
7  * Please visit http://snipsnap.org/ for updates and contact.
8  *
9  * --LICENSE NOTICE--
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  * --LICENSE NOTICE--
24  */

25
26 package org.snipsnap.snip.storage;
27
28 import org.radeox.util.logging.Logger;
29 import org.snipsnap.app.Application;
30 import org.snipsnap.interceptor.Aspects;
31 import org.snipsnap.snip.Links;
32 import org.snipsnap.snip.Snip;
33 import org.snipsnap.snip.SnipFactory;
34 import org.snipsnap.snip.attachment.Attachments;
35 import org.snipsnap.snip.label.Labels;
36 import org.snipsnap.user.Permissions;
37 import org.snipsnap.util.ApplicationAwareMap;
38 import org.snipsnap.versioning.VersionInfo;
39 import org.snipsnap.versioning.VersionStorage;
40
41 import java.io.File JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.OutputStream JavaDoc;
44 import java.io.InputStream JavaDoc;
45 import java.sql.Timestamp JavaDoc;
46 import java.util.*;
47
48 /**
49  * SnipStorage backend that uses files for persisting data. This storage
50  * has limitations in the snip name length and possibly characters as well
51  * since not all filesystems can store UTF-8 file names.
52  *
53  * This Storage navigates to the correct directory. Sub classes should
54  * then persist the snip to one or several files.
55  *
56  * @author Stephan J. Schmidt
57  * @version $Id: FileSnipStorage.java 1606 2004-05-17 10:56:18Z leo $
58  */

59
60 public abstract class FileSnipStorage implements CacheableStorage, VersionStorage, SnipStorage {
61   public static final String JavaDoc NOT_SUPPORTED_EXCEPTION_MSG =
62       "Method not supported, do not call FileSnipStorage directly";
63
64   protected ApplicationAwareMap cache;
65
66   private SnipSerializer serializer = SnipSerializer.getInstance();
67
68   // Cacheable Storage
69
public void setCache(ApplicationAwareMap cache) {
70     this.cache = cache;
71   }
72
73   /**
74    * Return the directory where all snips are stored
75    *
76    * @return
77    */

78   public File JavaDoc getWorkingDir() {
79     Application app = Application.get();
80     return new File JavaDoc(app.getConfiguration().getFileStore(), "snips");
81   }
82
83   /**
84    * Return the directory where all snips are stored
85    *
86    * @param applicationOid
87    * @return
88    */

89   public File JavaDoc getWorkingDir(String JavaDoc applicationOid) {
90     Application app = Application.get();
91     return app.getConfiguration().getFilePath(applicationOid);
92   }
93
94   public void storageRemove(Snip snip) {
95     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), snip.getName());
96     storageRemoveFile(snip, snipDir);
97   }
98
99   /**
100    * Remove one or more files from the given directory.
101    * Subclasses should employ strategies like backup etc.
102    *
103    * @param snip Snip to remove
104    * @param snipDir Directory with the stored snips
105    */

106   protected abstract void storageRemoveFile(Snip snip, File JavaDoc snipDir);
107
108   protected abstract Map createSnipFromFile(File JavaDoc snipDir) throws IOException JavaDoc;
109
110   /**
111    * Load the snip from a directory. Navigate to
112    * the correct directory then load and create
113    * the snip
114    *
115    * @param name Name of Snip to load
116    * @return
117    */

118   public Snip storageLoad(String JavaDoc name) {
119     Snip snip = null;
120     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), name);
121     try {
122       snip = parseSnip(createSnipFromFile(snipDir));
123     } catch (IOException JavaDoc e) {
124       Logger.log("unable to load snip", e);
125     }
126     return snip;
127   }
128
129   // VersionStorage
130

131   /**
132    * Store a version of the snip to the
133    * file system with the given directory
134    *
135    * @param snip
136    * @param versionDir
137    */

138   protected abstract void storeVersion(Snip snip, File JavaDoc versionDir);
139
140
141   /**
142    * Stora a version of a snip in the storage.
143    * Navigates to a directory for the version
144    * files, then calls storeVersion() which is
145    * implemented in subclasses.
146    *
147    * @param snip Snip to store
148    */

149   public void storeVersion(Snip snip) {
150     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), snip.getName());
151     File JavaDoc versionDir = new File JavaDoc(snipDir, "version");
152     storeVersion(snip, versionDir);
153   }
154
155   /**
156    * Return a list of VersionInfo objects for the
157    * given snip. Objects should be ordered by decreasing version.
158    * Navigates to the directory and scans for versions of snips
159    *
160    * @param snip Snip for which the revision should be loaded
161    * @return
162    */

163   public List getVersionHistory(Snip snip) {
164     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), snip.getName());
165     File JavaDoc versionDir = new File JavaDoc(snipDir, "version");
166     List versions = getVersionHistory(snip, versionDir);
167     return versions;
168   }
169
170   /**
171    * Return the checker object for this file storage.
172    * Depends on the filename that is used by the
173    * storage to store snip versions.
174    *
175    * @return
176    */

177   protected abstract VersionFileNameChecker getVersionFileNameChecker();
178
179   /**
180    * Read snips from the directory and return a list of
181    * VersionInfo objects.
182    *
183    * @param snip Snip to get version history
184    * @param versionDir Directory to read versions from
185    * @return
186    */

187
188   protected List getVersionHistory(Snip snip, File JavaDoc versionDir) {
189     VersionFileNameChecker checker = getVersionFileNameChecker();
190
191     String JavaDoc[] files = versionDir.list(checker);
192
193 // System.out.println("Version files="+Arrays.asList(files));
194
List versions = new ArrayList();
195     try {
196       for (int i = 0; i < files.length; i++) {
197         String JavaDoc fileName = files[i];
198         int version = checker.getVersion(fileName);
199         Map map = loadVersion(snip, versionDir, version);
200         VersionInfo info = new VersionInfo();
201         info.setVersion(version);
202         info.setViewCount(Integer.parseInt((String JavaDoc) map.get(SnipSerializer.SNIP_VIEWCOUNT)));
203         info.setMUser((String JavaDoc) map.get(SnipSerializer.SNIP_MUSER));
204         info.setMTime(new Timestamp JavaDoc(Long.parseLong((String JavaDoc) map.get(SnipSerializer.SNIP_MTIME))));
205         info.setSize(((String JavaDoc) map.get(SnipSerializer.SNIP_CONTENT)).length());
206         versions.add(info);
207       }
208     } catch (Exception JavaDoc e) {
209       Logger.log("TwoFileSnipStorage: unable read version history of snip" + snip.getName(), e);
210     }
211     Collections.sort(versions, new Comparator() {
212       public int compare(Object JavaDoc o1, Object JavaDoc o2) {
213         return ((VersionInfo) o1).getVersion() > ((VersionInfo) o2).getVersion() ? -1 : 1;
214       }
215     });
216
217     return versions;
218   }
219
220   /**
221    * Load a version of a snip from the file system
222    * and the given directory
223    *
224    * @param snip
225    * @param versionDir
226    * @return
227    */

228   protected abstract Map loadVersion(Snip snip, File JavaDoc versionDir, int version) throws IOException JavaDoc;
229
230   /**
231    * Load a version of a snip from the storage
232    *
233    * @param snip Example of a snip to load
234    * @param version Version number
235    * @return
236    */

237   public Snip loadVersion(Snip snip, int version) {
238     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), snip.getName());
239     File JavaDoc versionDir = new File JavaDoc(snipDir, "version");
240     String JavaDoc name = snip.getName();
241     try {
242       Snip newSnip = SnipFactory.createSnip(name, "");
243       return serializer.deserialize(loadVersion(snip, versionDir, version), newSnip);
244     } catch (IOException JavaDoc e) {
245       Logger.log("FileSnipStorage: Unable to load version snip " + snip.getName() + " " + version);
246     }
247     return null;
248   }
249
250   /**
251    * Store a snip to a given directory. Subclasses should
252    * implement this and store the snip to one or more files.
253    *
254    * @param snip Snip to store
255    * @param snipDir Directory to store the snip in
256    */

257   protected abstract void storeSnip(Snip snip, File JavaDoc snipDir);
258
259   /**
260    * Stors a version of a snip in the storage.
261    * Navigates to a directory then calls storeSnip() from
262    * a subclass to store the snip.
263    *
264    * @param snip Snip to store
265    */

266   public void storageStore(Snip snip) {
267     File JavaDoc snipDir = new File JavaDoc(getWorkingDir(), snip.getName());
268     storeSnip(snip, snipDir);
269   }
270
271   public Snip storageCreate(String JavaDoc name, String JavaDoc content) {
272     Application app = Application.get();
273     String JavaDoc applicationOid = (String JavaDoc) app.getObject(Application.OID);
274     String JavaDoc login = app.getUser().getLogin();
275
276     Snip snip = SnipFactory.createSnip(name, content);
277     Timestamp JavaDoc cTime = new Timestamp JavaDoc(new java.util.Date JavaDoc().getTime());
278     Timestamp JavaDoc mTime = (Timestamp JavaDoc) cTime.clone();
279     snip.setCTime(cTime);
280     snip.setMTime(mTime);
281     snip.setCUser(login);
282     snip.setMUser(login);
283     snip.setOUser(login);
284     snip.setPermissions(new Permissions());
285     snip.setBackLinks(new Links());
286     snip.setSnipLinks(new Links());
287     snip.setLabels(new Labels());
288     snip.setAttachments(new Attachments());
289     snip.setApplication(applicationOid);
290     storageStore(snip);
291     return (Snip) Aspects.newInstance(snip, Snip.class);
292   }
293
294   private Snip parseSnip(Map snipMap) {
295     // the application oid is a special for file snip storage
296
String JavaDoc applicationOid = (String JavaDoc) snipMap.get(SnipSerializer.SNIP_APPLICATION);
297     String JavaDoc name = (String JavaDoc) snipMap.get(SnipSerializer.SNIP_NAME);
298     if (cache.getMap(applicationOid).containsKey(name.toUpperCase())) {
299       return (Snip) cache.getMap(applicationOid).get(name.toUpperCase());
300     }
301
302     Snip newSnip = SnipFactory.createSnip(name, (String JavaDoc) snipMap.get(SnipSerializer.SNIP_CONTENT));
303     Snip snip = serializer.deserialize(snipMap, newSnip);
304
305     // Aspects.setTarget(proxy, snip);
306
// return proxy;
307
snip = (Snip) Aspects.newInstance(snip, Snip.class);
308     cache.getMap(applicationOid).put(name.toUpperCase(), snip);
309     return snip;
310   }
311
312   // SnipStorage
313
public List storageAll() {
314     String JavaDoc applicationOid = (String JavaDoc) Application.get().getObject(Application.OID);
315     return storageAll(applicationOid);
316   }
317
318   public int storageCount() {
319     Application app = Application.get();
320     File JavaDoc fileStore = new File JavaDoc(app.getConfiguration().getFileStore());
321     return traverseFileStore(fileStore, new ArrayList()).size();
322   }
323
324   public List storageAll(String JavaDoc applicationOid) {
325     return traverseFileStore(getWorkingDir(applicationOid), new ArrayList());
326   }
327
328   private List traverseFileStore(File JavaDoc root, List list) {
329     try {
330       Map map = createSnipFromFile(root);
331       if (null != map) {
332         list.add(parseSnip(map));
333       }
334     } catch (IOException JavaDoc e) {
335       // ignored because empty dirs may exist
336
}
337
338     File JavaDoc[] files = root.listFiles();
339     for (int entry = 0; files != null && entry < files.length; entry++) {
340       if (files[entry].isDirectory()) {
341         traverseFileStore(files[entry], list);
342       }
343     }
344     return list;
345   }
346
347   /** Helper methods
348    */

349
350   protected void close(OutputStream JavaDoc out) {
351     if (out != null) {
352       try {
353         out.close();
354       } catch (IOException JavaDoc e) {
355         // Intentionelly left empty
356
}
357     }
358   }
359
360   protected void close(InputStream JavaDoc in) {
361     if (in != null) {
362       try {
363         in.close();
364       } catch (IOException JavaDoc e) {
365         // Intentionelly left empty
366
}
367     }
368   }
369
370   /**
371    * Not implemented, should be handled on a higher level
372    * e.g. QuerySnipStorage
373    */

374   public List storageByHotness(int size) {
375     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
376   }
377
378   public List storageByUser(final String JavaDoc login) {
379     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
380   }
381
382   public List storageByDateSince(final Timestamp JavaDoc date) {
383     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
384   }
385
386   public List storageByRecent(String JavaDoc applicationOid, int size) {
387     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG + " : storageByRecent(applicationOid,size)");
388   }
389
390   public List storageByComments(final Snip parent) {
391     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
392   }
393
394   public List storageByParent(final Snip parent) {
395     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
396   }
397
398   public List storageByParentNameOrder(Snip parent, int count) {
399     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
400   }
401
402   public List storageByParentModifiedOrder(Snip parent, int count) {
403     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
404   }
405
406   public List storageByDateInName(String JavaDoc nameSpace, String JavaDoc start, String JavaDoc end) {
407     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
408   }
409
410   public Snip[] match(String JavaDoc pattern) {
411     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
412   }
413
414   public Snip[] match(String JavaDoc start, String JavaDoc end) {
415     throw new MethodNotSupportedException(NOT_SUPPORTED_EXCEPTION_MSG);
416   }
417
418   public class MethodNotSupportedException extends RuntimeException JavaDoc {
419     public MethodNotSupportedException(String JavaDoc s) {
420       super(s);
421     }
422   }
423 }
424
Popular Tags