Clover Coverage Report - Pebble 2.5-SNAPSHOT
Coverage timestamp: Sat Jun 12 2010 09:39:29 EST
../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
136   452   57   6,8
54   226   0,42   20
20     2,85  
1    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  FileManager       Line # 52 136 0% 57 18 91,4% 0.9142857
 
  (108)
 
1    /*
2    * Copyright (c) 2003-2006, Simon Brown
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * - Redistributions of source code must retain the above copyright
9    * notice, this list of conditions and the following disclaimer.
10    *
11    * - Redistributions in binary form must reproduce the above copyright
12    * notice, this list of conditions and the following disclaimer in
13    * the documentation and/or other materials provided with the
14    * distribution.
15    *
16    * - Neither the name of Pebble nor the names of its contributors may
17    * be used to endorse or promote products derived from this software
18    * without specific prior written permission.
19    *
20    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    * POSSIBILITY OF SUCH DAMAGE.
31    */
32    package net.sourceforge.pebble.domain;
33   
34    import net.sourceforge.pebble.comparator.FileMetaDataComparator;
35    import net.sourceforge.pebble.util.FileUtils;
36    import net.sourceforge.pebble.PebbleContext;
37   
38    import java.io.*;
39    import java.util.*;
40   
41    /**
42    * Encapsulates methods for managing and manipulating files under the
43    * following locations:
44    * <ul>
45    * <li>${blog.dir}/images</li>
46    * <li>${blog.dir}/files</li>
47    * <li>${editableTheme}</li>
48    * </ul>
49    *
50    * @author Simon Brown
51    */
 
52    public class FileManager {
53   
54    /** the type of files being managed */
55    private String type;
56   
57    /** the root directory for the particular file type */
58    private File root;
59   
60    /**
61    * Creates a new instande for the specified blog and type.
62    *
63    * @param blog the blog that this manager refers to
64    * @param type the type of files to manage
65    */
 
66  136 toggle public FileManager(Blog blog, String type) {
67  136 this.type = type;
68   
69    // which directory are we looking at?
70  136 if (type.equals(FileMetaData.BLOG_IMAGE)) {
71  12 this.root = new File(blog.getImagesDirectory());
72  124 } else if (type.equals(FileMetaData.THEME_FILE)) {
73  8 this.root = blog.getEditableTheme().getPathToLiveTheme();
74  116 } else if (type.equals(FileMetaData.BLOG_DATA)) {
75  6 this.root = new File(blog.getRoot());
76    } else {
77  110 this.root = new File(blog.getFilesDirectory());
78    }
79    }
80   
81    /**
82    * Gets the root directory that this class is managing.
83    *
84    * @return a File instance
85    */
 
86  10 toggle public File getRootDirectory() {
87  10 return this.root;
88    }
89   
90    /**
91    * Gets meta data about a specific file or directory.
92    *
93    * @param path the path of the file/directory
94    * @return a FileMetaData object
95    */
 
96  474 toggle public FileMetaData getFileMetaData(String path) {
97  474 FileMetaData metaData = new FileMetaData(this, path);
98  474 metaData.setType(type);
99   
100    // is it a directory?
101  474 File file = getFile(metaData);
102  474 if (file.exists()) {
103  448 if (file.isDirectory()) {
104  298 metaData.setDirectory(true);
105  298 try {
106  298 List files = getFiles(metaData, true);
107  290 long size = 0;
108  290 Iterator it = files.iterator();
109  468 while (it.hasNext()) {
110  178 size += ((FileMetaData)it.next()).getSize();
111    }
112  290 metaData.setSize(size);
113    } catch (IllegalFileAccessException ifae) {
114    // do nothing
115    }
116    } else {
117  150 metaData.setSize(file.length());
118    }
119   
120  448 metaData.setLastModified(new Date(file.lastModified()));
121    }
122   
123  474 return metaData;
124    }
125   
 
126  16 toggle public FileMetaData getParent(FileMetaData file) {
127  16 if (file.getAbsolutePath().equals("/")) {
128  12 return null;
129    } else {
130  4 return getFileMetaData(file.getPath());
131    }
132    }
133   
134    /**
135    * Gets meta data about a specific file or directory.
136    *
137    * @param path the path of the file/directory
138    * @param name the name of the file/directory
139    * @return a FileMetaData object
140    */
 
141  228 toggle public FileMetaData getFileMetaData(String path, String name) {
142  228 if (path != null && path.endsWith("/")) {
143  206 return getFileMetaData(path + name);
144    } else {
145  22 return getFileMetaData(path + "/" + name);
146    }
147    }
148   
149    /**
150    * Gets a java.io.File reference to the specified path, regardless
151    * of whether it represents a file or directory.
152    *
153    * @param path an absolute path from the root
154    * @return a java.io.File instance
155    */
 
156  20 toggle public File getFile(String path) {
157  20 String relativePath;
158  20 if (path != null && path.startsWith("/")) {
159  12 relativePath = path.substring(1);
160    } else {
161  8 relativePath = path;
162    }
163   
164  20 return new File(root, relativePath);
165    }
166   
167    /**
168    * Convenience method to get a java.io.File reference to the file represented
169    * by the specified FileMetaData object.
170    *
171    * @param file the FileMetaData object representing the path
172    * @return a java.io.File instance
173    */
 
174  990 toggle private File getFile(FileMetaData file) {
175  990 String relativePath = file.getAbsolutePath().substring(1);
176  990 return new File(root, relativePath);
177    }
178   
179    /**
180    * Determines whether the specified file is underneath the root directory
181    * for this file manager.
182    *
183    * @param file the java.io.File to test
184    * @return true if the file is underneath the root, false otherwise
185    */
 
186  514 toggle public boolean isUnderneathRootDirectory(File file) {
187  514 return FileUtils.underneathRoot(root, file);
188    }
189   
190    /**
191    * Creates a new directory with the specified name underneath the given path.
192    *
193    * @param path the path under which to create the directory
194    * @param name the name of the directory
195    * @return a java.io.File instance representing the new directory
196    */
 
197  18 toggle public File createDirectory(String path, String name) throws IllegalFileAccessException {
198  18 FileMetaData subDirectory = getFileMetaData(path);
199   
200  18 File newDirectory = new File(getFile(subDirectory), name);
201  18 if (!isUnderneathRootDirectory(newDirectory)) {
202  4 throw new IllegalFileAccessException();
203    } else {
204  14 newDirectory.mkdirs();
205    }
206   
207  14 return newDirectory;
208    }
209   
210    /**
211    * Copies a file.
212    *
213    * @param path the path under which the file exists
214    * @param name the name of the file
215    * @param newName the new name of the file
216    * @return a java.io.File instance representing the new file, or null
217    * if the file isn't copied because no new name was given, or the
218    * new name is the same as the old name
219    */
 
220  16 toggle public File copyFile(String path, String name, String newName) throws IOException, IllegalFileAccessException {
221  16 if (newName != null && newName.length() > 0 && !newName.equals(name)) {
222  10 FileMetaData subDirectory = getFileMetaData(path);
223  10 File originalFile = new File(getFile(subDirectory), name);
224  10 File newFile = new File(getFile(subDirectory), newName);
225   
226  10 if (!isUnderneathRootDirectory(originalFile) || !isUnderneathRootDirectory(newFile)) {
227  6 throw new IllegalFileAccessException();
228    }
229   
230  4 FileUtils.copyFile(originalFile, newFile);
231   
232  4 return newFile;
233    } else {
234  6 return null;
235    }
236    }
237   
238    /**
239    * Renames a file.
240    *
241    * @param path the path under which the file exists
242    * @param name the name of the file
243    * @param newName the new name of the file
244    * @return a java.io.File instance representing the new file, or null
245    * if the file isn't copied because no new name was given, or the
246    * new name is the same as the old name
247    */
 
248  14 toggle public File renameFile(String path, String name, String newName) throws IllegalFileAccessException {
249  14 if (newName != null && newName.length() > 0 && !newName.equals(name)) {
250  8 FileMetaData subDirectory = getFileMetaData(path);
251  8 File originalFile = new File(getFile(subDirectory), name);
252  8 File newFile = new File(getFile(subDirectory), newName);
253   
254    // check that newFile is underneath the root directory
255  8 if (!isUnderneathRootDirectory(originalFile) || !isUnderneathRootDirectory(newFile)) {
256  4 throw new IllegalFileAccessException();
257    }
258   
259  4 originalFile.renameTo(newFile);
260  4 return newFile;
261    } else {
262  6 return null;
263    }
264    }
265   
266    /**
267    * Deletes a file.
268    *
269    * @param path the path under which the file exists
270    * @param name the name of the file
271    */
 
272  38 toggle public void deleteFile(String path, String name) throws IllegalFileAccessException {
273  38 FileMetaData subDirectory = getFileMetaData(path);
274  38 File fileToDelete = new File(getFile(subDirectory), name);
275   
276  38 if (!isUnderneathRootDirectory(fileToDelete)) {
277  4 throw new IllegalFileAccessException();
278    }
279   
280  34 FileUtils.deleteFile(fileToDelete);
281    }
282   
283    /**
284    * Loads a file into a String.
285    *
286    * @param path the path under which the file exists
287    * @param name the name of the file
288    * @return a String containing the content of the specified file
289    */
 
290  12 toggle public String loadFile(String path, String name) throws IllegalFileAccessException {
291  12 StringBuffer content = new StringBuffer();
292   
293  12 FileMetaData subDirectory = getFileMetaData(path);
294  12 File fileToLoad = new File(getFile(subDirectory), name);
295   
296  12 if (!isUnderneathRootDirectory(fileToLoad)) {
297  4 throw new IllegalFileAccessException();
298    }
299   
300  8 try {
301  8 BufferedReader reader = new BufferedReader(new FileReader(fileToLoad));
302  8 String line = reader.readLine();
303  20 while (line != null) {
304  12 content.append(line);
305   
306  12 line = reader.readLine();
307  12 if (line != null) {
308  4 content.append(System.getProperty("line.separator"));
309    }
310    }
311  8 reader.close();
312    } catch (IOException ioe) {
313  0 ioe.printStackTrace();
314    }
315   
316  8 return content.toString();
317    }
318   
319    /**
320    * Saves a file with the given content.
321    *
322    * @param path the path under which the file exists
323    * @param name the name of the file
324    * @param content the content as a String
325    */
 
326  28 toggle public void saveFile(String path, String name, String content) throws IOException, IllegalFileAccessException {
327  28 FileMetaData subDirectory = getFileMetaData(path);
328  28 File fileToSave = new File(getFile(subDirectory), name);
329   
330  28 if (!isUnderneathRootDirectory(fileToSave)) {
331  4 throw new IllegalFileAccessException();
332    }
333   
334  24 BufferedWriter writer = new BufferedWriter(new FileWriter(fileToSave));
335  24 writer.write(content);
336  24 writer.flush();
337  24 writer.close();
338    }
339   
340    /**
341    * Saves a file with the given binary content.
342    *
343    * @param name the name of the file
344    * @param content the binary content
345    * @return a FileMetaData instance representing the saved file
346    */
 
347  0 toggle public FileMetaData saveFile(String name, byte[] content) throws IOException, IllegalFileAccessException {
348  0 FileMetaData file = getFileMetaData(name);
349  0 File fileToSave = getFile(name);
350   
351  0 if (!isUnderneathRootDirectory(fileToSave)) {
352  0 throw new IllegalFileAccessException();
353    }
354   
355  0 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileToSave));
356  0 out.write(content);
357  0 out.flush();
358  0 out.close();
359   
360  0 return file;
361    }
362   
363    /**
364    * Gets a list of files that reside under a given path.
365    *
366    * @param path the path under which the file exists
367    * @return a List of FileMetaData instances
368    * @throws IllegalFileAccessException if trying to access a file outside the root
369    */
 
370  28 toggle public List getFiles(String path) throws IllegalFileAccessException {
371  28 return getFiles(path, false);
372    }
373   
 
374  86 toggle public List getFiles(String path, boolean includeChildren) throws IllegalFileAccessException {
375  86 FileMetaData subDirectory = getFileMetaData(path);
376  86 return getFiles(subDirectory, includeChildren);
377    }
378   
 
379  384 toggle private List getFiles(FileMetaData path, boolean includeChildren) throws IllegalFileAccessException {
380  384 File directoryToView = getFile(path);
381   
382  384 if (!isUnderneathRootDirectory(directoryToView)) {
383  12 throw new IllegalFileAccessException();
384    }
385   
386  372 List directoriesAndFiles = new ArrayList();
387  372 List files = new ArrayList();
388  372 List directories = new ArrayList();
389  372 File f[] = directoryToView.listFiles();
390  372 if (f != null) {
391  368 File file;
392  578 for (int i = 0; i < f.length; i++) {
393  210 file = f[i];
394  210 if (file.isDirectory()) {
395  64 FileMetaData metaData = getFileMetaData(path.getAbsolutePath(), file.getName());
396  64 directories.add(metaData);
397   
398  64 if (includeChildren) {
399  56 directories.addAll(getFiles(metaData.getAbsolutePath(), true));
400    } else {
401  8 Collections.sort(directories, new FileMetaDataComparator());
402    }
403    }
404    }
405   
406  578 for (int i = 0; i < f.length; i++) {
407  210 file = f[i];
408  210 if (file.isFile()) {
409  146 FileMetaData metaData = getFileMetaData(path.getAbsolutePath(), file.getName());
410  146 files.add(metaData);
411    }
412    }
413   
414  368 Collections.sort(files, new FileMetaDataComparator());
415    }
416   
417  372 directoriesAndFiles.addAll(directories);
418  372 directoriesAndFiles.addAll(files);
419   
420  372 return directoriesAndFiles;
421    }
422   
423    /**
424    * Determines how much space is being used in files, images and theme.
425    *
426    * @param blog the blog to check against
427    * @return the number of KB
428    */
 
429  0 toggle public static double getCurrentUsage(Blog blog) {
430  0 FileManager imagesFileManager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
431  0 FileManager filesFileManager = new FileManager(blog, FileMetaData.BLOG_FILE);
432  0 FileManager themeFileManager = new FileManager(blog, FileMetaData.THEME_FILE);
433  0 return imagesFileManager.getFileMetaData("/").getSizeInKB() +
434    filesFileManager.getFileMetaData("/").getSizeInKB() +
435    themeFileManager.getFileMetaData("/").getSizeInKB();
436    }
437   
438   
439    /**
440    * Determines whether there is enough space to store the given number of KB.
441    *
442    * @param blog the blog to check against
443    * @param itemSize the size of the item to be written
444    * @return true if there is enough space or quotas aren't active
445    */
 
446  4 toggle public static boolean hasEnoughSpace(Blog blog, double itemSize) {
447  4 long quota = PebbleContext.getInstance().getConfiguration().getFileUploadQuota();
448   
449  4 return (quota == -1) || ((quota - getCurrentUsage(blog)) > itemSize);
450    }
451   
452    }