KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > business > FileManagerImpl


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. The ASF licenses this file to You
4  * under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. For additional information regarding
15  * copyright in this work, please see the NOTICE file in the top level
16  * directory of this distribution.
17  */

18
19 package org.apache.roller.business;
20
21 import java.io.File JavaDoc;
22 import java.io.FileOutputStream JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.math.BigDecimal JavaDoc;
26 import java.util.Map JavaDoc;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.roller.RollerException;
31 import org.apache.roller.config.RollerConfig;
32 import org.apache.roller.config.RollerRuntimeConfig;
33 import org.apache.roller.model.FileManager;
34 import org.apache.roller.model.Roller;
35 import org.apache.roller.model.RollerFactory;
36 import org.apache.roller.pojos.RollerPropertyData;
37 import org.apache.roller.util.RollerMessages;
38
39
40 /**
41  * Responsible for managing website resources. This base implementation
42  * writes resources to a filesystem.
43  */

44 public class FileManagerImpl implements FileManager {
45     
46     private String JavaDoc upload_dir = null;
47     private String JavaDoc upload_url = null;
48     
49     private static Log mLogger = LogFactory.getLog(FileManagerImpl.class);
50     
51     
52     /**
53      * Create file manager.
54      */

55     public FileManagerImpl() {
56         String JavaDoc uploaddir = RollerConfig.getProperty("uploads.dir");
57         String JavaDoc uploadurl = RollerConfig.getProperty("uploads.url");
58         
59         // Note: System property expansion is now handled by RollerConfig.
60

61         if(uploaddir == null || uploaddir.trim().length() < 1)
62             uploaddir = System.getProperty("user.home") + File.separator+"roller_data"+File.separator+"uploads";
63         
64         if( ! uploaddir.endsWith(File.separator))
65             uploaddir += File.separator;
66         
67         if(uploadurl == null || uploadurl.trim().length() < 1)
68             uploadurl = File.separator+"resources";
69         
70         this.upload_dir = uploaddir.replace('/',File.separatorChar);
71         this.upload_url = uploadurl;
72     }
73     
74     
75     /**
76      * Get the upload directory being used by this file manager
77      **/

78     public String JavaDoc getUploadDir() {
79         return this.upload_dir;
80     }
81     
82     
83     /**
84      * Get the upload path being used by this file manager
85      **/

86     public String JavaDoc getUploadUrl() {
87         return this.upload_url;
88     }
89     
90     
91     /**
92      * Determine if file can be saved given current RollerConfig settings.
93      */

94     public boolean canSave(String JavaDoc weblogHandle, String JavaDoc name, String JavaDoc contentType,
95                            long size, RollerMessages messages)
96             throws RollerException {
97         
98         Roller mRoller = RollerFactory.getRoller();
99         Map JavaDoc config = mRoller.getPropertiesManager().getProperties();
100         
101         if (!((RollerPropertyData)config.get("uploads.enabled")).getValue().equalsIgnoreCase("true")) {
102             messages.addError("error.upload.disabled");
103             return false;
104         }
105         
106         String JavaDoc allows = ((RollerPropertyData)config.get("uploads.types.allowed")).getValue();
107         String JavaDoc forbids = ((RollerPropertyData)config.get("uploads.types.forbid")).getValue();
108         String JavaDoc[] allowFiles = StringUtils.split(StringUtils.deleteWhitespace(allows), ",");
109         String JavaDoc[] forbidFiles = StringUtils.split(StringUtils.deleteWhitespace(forbids), ",");
110         if (!checkFileType(allowFiles, forbidFiles, name, contentType)) {
111             messages.addError("error.upload.forbiddenFile", allows);
112             return false;
113         }
114         
115         BigDecimal JavaDoc maxDirMB = new BigDecimal JavaDoc(
116                 ((RollerPropertyData)config.get("uploads.dir.maxsize")).getValue());
117         int maxDirBytes = (int)(1024000 * maxDirMB.doubleValue());
118         int userDirSize = getWebsiteDirSize(weblogHandle, this.upload_dir);
119         if (userDirSize + size > maxDirBytes) {
120             messages.addError("error.upload.dirmax", maxDirMB.toString());
121             return false;
122         }
123         
124         BigDecimal JavaDoc maxFileMB = new BigDecimal JavaDoc(
125                 ((RollerPropertyData)config.get("uploads.file.maxsize")).getValue());
126         int maxFileBytes = (int)(1024000 * maxFileMB.doubleValue());
127         mLogger.debug(""+maxFileBytes);
128         mLogger.debug(""+size);
129         if (size > maxFileBytes) {
130             messages.addError("error.upload.filemax", maxFileMB.toString());
131             return false;
132         }
133         
134         return true;
135     }
136     
137     
138     public boolean overQuota(String JavaDoc weblogHandle) throws RollerException {
139         
140         String JavaDoc maxDir = RollerRuntimeConfig.getProperty("uploads.dir.maxsize");
141         String JavaDoc maxFile = RollerRuntimeConfig.getProperty("uploads.file.maxsize");
142         BigDecimal JavaDoc maxDirSize = new BigDecimal JavaDoc(maxDir); // in megabytes
143
BigDecimal JavaDoc maxFileSize = new BigDecimal JavaDoc(maxFile); // in megabytes
144

145         // determine the number of bytes in website's directory
146
int maxDirBytes = (int)(1024000 * maxDirSize.doubleValue());
147         int userDirSize = 0;
148         String JavaDoc dir = getUploadDir();
149         File JavaDoc d = new File JavaDoc(dir + weblogHandle);
150         if (d.mkdirs() || d.exists()) {
151             File JavaDoc[] files = d.listFiles();
152             long dirSize = 0l;
153             for (int i=0; i<files.length; i++) {
154                 if (!files[i].isDirectory()) {
155                     dirSize = dirSize + files[i].length();
156                 }
157             }
158             userDirSize = new Long JavaDoc(dirSize).intValue();
159         }
160         return userDirSize > maxDirBytes;
161     }
162     
163     
164     /**
165      * Get collection files in website's resource directory.
166      * @param site Website
167      * @return Collection of files in website's resource directory
168      */

169     public File JavaDoc[] getFiles(String JavaDoc weblogHandle) throws RollerException {
170         String JavaDoc dir = this.upload_dir + weblogHandle;
171         File JavaDoc uploadDir = new File JavaDoc(dir);
172         return uploadDir.listFiles();
173     }
174     
175     
176     /**
177      * Delete named file from website's resource area.
178      */

179     public void deleteFile(String JavaDoc weblogHandle, String JavaDoc name)
180             throws RollerException {
181         String JavaDoc dir = this.upload_dir + weblogHandle;
182         File JavaDoc f = new File JavaDoc(dir + File.separator + name);
183         f.delete();
184     }
185     
186     
187     /**
188      * Save file to website's resource directory.
189      * @param site Website to save to
190      * @param name Name of file to save
191      * @param size Size of file to be saved
192      * @param is Read file from input stream
193      */

194     public void saveFile(String JavaDoc weblogHandle, String JavaDoc name, String JavaDoc contentType,
195                          long size, InputStream JavaDoc is)
196             throws RollerException {
197         
198         if (!canSave(weblogHandle, name, contentType, size, new RollerMessages())) {
199             throw new RollerException("ERROR: upload denied");
200         }
201         
202         byte[] buffer = new byte[8192];
203         int bytesRead = 0;
204         String JavaDoc dir = this.upload_dir;
205         
206         File JavaDoc dirPath = new File JavaDoc(dir + File.separator + weblogHandle);
207         if (!dirPath.exists()) {
208             dirPath.mkdirs();
209         }
210         OutputStream JavaDoc bos = null;
211         try {
212             bos = new FileOutputStream JavaDoc(
213                     dirPath.getAbsolutePath() + File.separator + name);
214             while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
215                 bos.write(buffer, 0, bytesRead);
216             }
217         } catch (Exception JavaDoc e) {
218             throw new RollerException("ERROR uploading file", e);
219         } finally {
220             try {
221                 bos.flush();
222                 bos.close();
223             } catch (Exception JavaDoc ignored) {}
224         }
225         if (mLogger.isDebugEnabled()) {
226             mLogger.debug("The file has been written to \"" + dir + weblogHandle + "\"");
227         }
228     }
229     
230     
231     /**
232      * Returns current size of file uploads owned by specified weblog handle.
233      * @param username User
234      * @param dir Upload directory
235      * @return Size of user's uploaded files in bytes.
236      */

237     private int getWebsiteDirSize(String JavaDoc weblogHandle, String JavaDoc dir) {
238         
239         int userDirSize = 0;
240         File JavaDoc d = new File JavaDoc(dir + File.separator + weblogHandle);
241         if (d.mkdirs() || d.exists()) {
242             File JavaDoc[] files = d.listFiles();
243             long dirSize = 0l;
244             for (int i=0; i<files.length; i++) {
245                 if (!files[i].isDirectory()) {
246                     dirSize = dirSize + files[i].length();
247                 }
248             }
249             userDirSize = new Long JavaDoc(dirSize).intValue();
250         }
251         return userDirSize;
252     }
253     
254     
255     /**
256      * Return true if file is allowed to be uplaoded given specified allowed and
257      * forbidden file types.
258      * @param allowFiles File types (i.e. extensions) that are allowed
259      * @param forbidFiles File types that are forbidden
260      * @param fileName Name of file to be uploaded
261      * @return True if file is allowed to be uploaded
262      */

263     private boolean checkFileType(String JavaDoc[] allowFiles, String JavaDoc[] forbidFiles,
264                                   String JavaDoc fileName, String JavaDoc contentType) {
265         
266         // TODO: Atom Publushing Protocol figure out how to handle file
267
// allow/forbid using contentType.
268
// TEMPORARY SOLUTION: In the allow/forbid lists we will continue to
269
// allow user to specify file extensions (e.g. gif, png, jpeg) but will
270
// now also allow them to specify content-type rules (e.g. */*, image/*,
271
// text/xml, etc.).
272

273         // if content type is invalid, reject file
274
if (contentType == null || contentType.indexOf("/") == -1) {
275             return false;
276         }
277         
278         // default to false
279
boolean allowFile = false;
280         
281         // if this person hasn't listed any allows, then assume they want
282
// to allow *all* filetypes, except those listed under forbid
283
if(allowFiles == null || allowFiles.length < 1) {
284             allowFile = true;
285         }
286         
287         // First check against what is ALLOWED
288

289         // check file against allowed file extensions
290
if (allowFiles != null && allowFiles.length > 0) {
291             for (int y=0; y<allowFiles.length; y++) {
292                 // oops, this allowed rule is a content-type, skip it
293
if (allowFiles[y].indexOf("/") != -1) continue;
294                 if (fileName.toLowerCase().endsWith(
295                         allowFiles[y].toLowerCase())) {
296                     allowFile = true;
297                     break;
298                 }
299             }
300         }
301         
302         // check file against allowed contentTypes
303
if (allowFiles != null && allowFiles.length > 0) {
304             for (int y=0; y<allowFiles.length; y++) {
305                 // oops, this allowed rule is NOT a content-type, skip it
306
if (allowFiles[y].indexOf("/") == -1) continue;
307                 if (matchContentType(allowFiles[y], contentType)) {
308                     allowFile = true;
309                     break;
310                 }
311             }
312         }
313         
314         // First check against what is FORBIDDEN
315

316         // check file against forbidden file extensions, overrides any allows
317
if (forbidFiles != null && forbidFiles.length > 0) {
318             for (int x=0; x<forbidFiles.length; x++) {
319                 // oops, this forbid rule is a content-type, skip it
320
if (forbidFiles[x].indexOf("/") != -1) continue;
321                 if (fileName.toLowerCase().endsWith(
322                         forbidFiles[x].toLowerCase())) {
323                     allowFile = false;
324                     break;
325                 }
326             }
327         }
328         
329         
330         // check file against forbidden contentTypes, overrides any allows
331
if (forbidFiles != null && forbidFiles.length > 0) {
332             for (int x=0; x<forbidFiles.length; x++) {
333                 // oops, this forbid rule is NOT a content-type, skip it
334
if (forbidFiles[x].indexOf("/") == -1) continue;
335                 if (matchContentType(forbidFiles[x], contentType)) {
336                     allowFile = false;
337                     break;
338                 }
339             }
340         }
341         
342         return allowFile;
343     }
344     
345     
346     /**
347      * Super simple contentType range rule matching
348      */

349     private boolean matchContentType(String JavaDoc rangeRule, String JavaDoc contentType) {
350         if (rangeRule.equals("*/*")) return true;
351         if (rangeRule.equals(contentType)) return true;
352         String JavaDoc ruleParts[] = rangeRule.split("/");
353         String JavaDoc typeParts[] = contentType.split("/");
354         if (ruleParts[0].equals(typeParts[0]) && ruleParts[1].equals("*"))
355             return true;
356         
357         return false;
358     }
359     
360     
361     public void release() {
362     }
363     
364 }
365
Popular Tags