KickJava   Java API By Example, From Geeks To Geeks.

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


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.snip.Snip;
30 import org.snipsnap.versioning.VersionInfo;
31
32 import java.io.*;
33 import java.util.*;
34 import java.sql.Timestamp JavaDoc;
35
36 /**
37  * SnipStorage backend that uses files for persisting data. This storage
38  * has limitations in the snip name length and possibly characters as well
39  * since not all filesystems can store UTF-8 file names.
40  *
41  * This Storage uses two files for persistance, one for the
42  * metadata and one for the content.
43  *
44  * @author Stephan J. Schmidt
45  * @version $Id: TwoFileSnipStorage.java 1606 2004-05-17 10:56:18Z leo $
46  */

47
48 public abstract class TwoFileSnipStorage extends FileSnipStorage {
49
50   /**
51    * Load the metadata of a snip from an InputStream and
52    * store the metadata in a Map.
53    *
54    * @param in Stream to read from
55    * @return
56    * @throws IOException
57    */

58   protected abstract Map loadMetadata(InputStream in) throws IOException;
59
60   /**
61    * Load the content of a snip from an InputStream
62    *
63    * @param in Stream to read from
64    * @return
65    * @throws IOException
66    */

67
68   protected abstract String JavaDoc loadContent(InputStream in) throws IOException;
69
70   /**
71    * Return the file name of the metadata file. This should
72    * be implemented to return eg. metadata.properties or metadata.xml ...
73    *
74    * @return
75    */

76   protected abstract String JavaDoc getMetadataFileName();
77
78   /**
79    * Return the file name of the content file. This should
80    * be implemented to return eg. content.txt or content.xml ...
81    *
82    * @return
83    */

84
85   protected abstract String JavaDoc getContentFileName();
86
87   /**
88    * Store the content of a snip to
89    * the output stream. Implementations
90    * can store whichever format they choose
91    * (plain text, XML, ...)
92    *
93    * @param snip
94    * @param out
95    */

96
97   protected abstract void storeContent(Snip snip, OutputStream out);
98
99   /**
100    * Store the metadata of a snip to
101    * the output stream. Implementations
102    * can store whichever format they choose
103    * (property, XML, ...)
104    *
105    * @param snip
106    * @param out
107    */

108   protected abstract void storeMetadata(Snip snip, OutputStream out);
109
110   /**
111    * Return the special checker to get the version number
112    * from a file.
113    *
114    * @return
115    */

116   protected VersionFileNameChecker getVersionFileNameChecker() {
117     return new VersionFileNameChecker() {
118       public int getVersion(String JavaDoc fileName) {
119         return Integer.parseInt(fileName.substring(fileName.lastIndexOf("-")+1));
120       }
121       public boolean accept(File dir, String JavaDoc name) {
122         return name.startsWith(getContentFileName()) && (name.indexOf('-') != -1);
123       }
124     };
125   }
126
127    /**
128    * Remove the metadata of snip from the storage.
129    * This implementation stores the metadata to a
130    * .removed backup file
131    *
132    * @param snip
133    */

134   protected void storageRemoveMetadata(Snip snip, File snipDir) {
135     File metadataFile = new File(snipDir, getMetadataFileName());
136     Logger.debug(metadataFile + ": exists? " + metadataFile.exists());
137     if (metadataFile.exists()) {
138       File backup = new File(metadataFile.getPath() + ".removed");
139       metadataFile.renameTo(backup);
140     }
141   }
142
143   /**
144    * Remove the content of snip from the storage.
145    * This implementation stores the content to a
146    * .removed backup file
147    *
148    * @param snip
149    */

150   protected void storageRemoveContent(Snip snip, File snipDir) {
151     File contentFile = new File(snipDir, getContentFileName());
152     Logger.debug(contentFile+": exists? "+contentFile.exists());
153     if (contentFile.exists()) {
154       File backup = new File(contentFile.getPath() + ".removed");
155       contentFile.renameTo(backup);
156     }
157   }
158
159   /**
160    * Remove the snip from the storage.
161    * With a strategy pattern we call this
162    * for metadata removal and content removal
163    *
164    * @param snip Snip to remove
165    */

166   public void storageRemoveFile(Snip snip, File snipDir) {
167     storageRemoveMetadata(snip, snipDir);
168     storageRemoveContent(snip, snipDir);
169   }
170
171   /**
172    * Load a version of a snip from the file system
173    * and the given directory
174    *
175    * @param snip
176    * @param versionDir
177    * @return
178    */

179   protected Map loadVersion(Snip snip, File versionDir, int version) throws IOException {
180     if (!versionDir.exists()) {
181        return null;
182      }
183
184     File metadataFile = new File(versionDir, getMetadataFileName() + "-" + version);
185     if (!metadataFile.exists()) {
186       return null;
187     }
188
189     File contentFile = new File(versionDir, getContentFileName() + "-" + version);
190     if (!contentFile.exists()) {
191       return null;
192     }
193
194     FileInputStream metaIn = null;
195     FileInputStream contentIn = null;
196     Map map = null;
197     try {
198       metaIn = new FileInputStream(metadataFile);
199       contentIn = new FileInputStream(contentFile);
200       map = createSnipFromFile(metaIn, contentIn);
201     } finally {
202       contentIn.close();
203       metaIn.close();
204     }
205     return map;
206   }
207
208   /**
209    * Store a version of the snip to the
210    * file system with the given directory
211    *
212    * @param snip
213    * @param versionDir
214    */

215   protected void storeVersion(Snip snip, File versionDir) {
216     if (!versionDir.exists()) {
217       versionDir.mkdirs();
218     }
219
220     File metadataFile = new File(versionDir, getMetadataFileName() + "-" + snip.getVersion());
221     FileOutputStream out = null;
222     try {
223       out = new FileOutputStream(metadataFile);
224       storeMetadata(snip, out);
225     } catch (IOException e) {
226       Logger.log("TwoFileSnipStorage: unable to store version snip metadata" + snip.getName(), e);
227     } finally {
228       close(out);
229     }
230
231     File contentFile = new File(versionDir, getContentFileName() + "-" + snip.getVersion());
232     try {
233       out = new FileOutputStream(contentFile);
234       storeContent(snip, out);
235     } catch (IOException e) {
236       Logger.log("TwoFileSnipStorage: unable to store version snip content" + snip.getName(), e);
237     } finally {
238       close(out);
239     }
240   }
241
242   /**
243    * Store a snip to a directory
244    *
245    * Create two output streams and write
246    * the metadata and content to those
247    *
248    * @param snip
249    * @param snipDir
250    */

251   protected void storeSnip(Snip snip, File snipDir) {
252     if (!snipDir.exists()) {
253       snipDir.mkdirs();
254     }
255
256     File metadataFile = new File(snipDir, getMetadataFileName());
257     if (metadataFile.exists()) {
258       Logger.log("TwoFileSnipStorage: backing up " + metadataFile.getPath());
259       File backup = new File(metadataFile.getPath() + ".bck");
260       metadataFile.renameTo(backup);
261     }
262
263     FileOutputStream out = null;
264     try {
265       out = new FileOutputStream(metadataFile);
266       storeMetadata(snip, out);
267     } catch (IOException e) {
268       Logger.log("TwoFileSnipStorage: unable to store snip metadata" + snip.getName(), e);
269     } finally {
270       close(out);
271     }
272
273     File contentFile = new File(snipDir, getContentFileName());
274     if (contentFile.exists()) {
275       Logger.log("TwoFileSnipStorage: backing up " + contentFile.getPath());
276       File backup = new File(contentFile.getPath() + ".bck");
277       contentFile.renameTo(backup);
278     }
279
280     try {
281       out = new FileOutputStream(contentFile);
282       storeContent(snip, out);
283       out.close();
284     } catch (IOException e) {
285       Logger.log("TwoFileSnipStorage: unable to store snip content" + snip.getName(), e);
286     } finally {
287       close(out);
288     }
289   }
290
291   /**
292    * Load all snip data from two files in the given directory
293    *
294    * @param snipDir
295    * @return
296    * @throws IOException
297    */

298   protected synchronized Map createSnipFromFile(File snipDir) throws IOException {
299     File metadataFile = new File(snipDir, getMetadataFileName());
300     if (!metadataFile.exists()) {
301       return null;
302     }
303
304     File contentFile = new File(snipDir, getContentFileName());
305     if (!contentFile.exists()) {
306       return null;
307     }
308
309     FileInputStream metaIn = null;
310     FileInputStream contentIn = null;
311     Map map = null;
312     try {
313       metaIn = new FileInputStream(metadataFile);
314       contentIn = new FileInputStream(contentFile);
315       map = createSnipFromFile(metaIn, contentIn);
316     } finally {
317       contentIn.close();
318       metaIn.close();
319     }
320     return map;
321   }
322
323   /**
324    * Load all snip data from two input streams
325    *
326    * @param metadataIn
327    * @param contentIn
328    * @return
329    * @throws IOException
330    */

331   private Map createSnipFromFile(InputStream metadataIn, InputStream contentIn) throws IOException {
332     Map metadata = loadMetadata(metadataIn);
333     metadata.put(SnipSerializer.SNIP_CONTENT, loadContent(contentIn));
334     return metadata;
335   }
336 }
337
Popular Tags