Coverage Report - net.sourceforge.pebble.web.action.UploadFileAction
 
Classes in this File Line Coverage Branch Coverage Complexity
UploadFileAction
0%
0/59
0%
0/30
6.25
 
 1  
 /*
 2  
  * Copyright (c) 2003-2011, 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.web.action;
 33  
 
 34  
 import net.sourceforge.pebble.Constants;
 35  
 import net.sourceforge.pebble.PebbleContext;
 36  
 import net.sourceforge.pebble.domain.FileManager;
 37  
 import net.sourceforge.pebble.domain.FileMetaData;
 38  
 import net.sourceforge.pebble.domain.Blog;
 39  
 import net.sourceforge.pebble.domain.BlogManager;
 40  
 import net.sourceforge.pebble.web.view.RedirectView;
 41  
 import net.sourceforge.pebble.web.view.View;
 42  
 import net.sourceforge.pebble.web.view.impl.FileTooLargeView;
 43  
 import net.sourceforge.pebble.web.view.impl.NotEnoughSpaceView;
 44  
 import org.apache.commons.fileupload.DiskFileUpload;
 45  
 import org.apache.commons.fileupload.FileItem;
 46  
 import org.apache.commons.fileupload.FileUpload;
 47  
 import org.apache.commons.fileupload.FileUploadBase;
 48  
 import org.apache.commons.logging.Log;
 49  
 import org.apache.commons.logging.LogFactory;
 50  
 
 51  
 import javax.servlet.ServletException;
 52  
 import javax.servlet.http.HttpServletRequest;
 53  
 import javax.servlet.http.HttpServletResponse;
 54  
 import java.io.File;
 55  
 import java.util.Iterator;
 56  
 import java.util.List;
 57  
 
 58  
 /**
 59  
  * Superclass for actions that allow the user to upload a file.
 60  
  *
 61  
  * @author    Simon Brown
 62  
  */
 63  0
 public abstract class UploadFileAction extends AbstractFileAction {
 64  
 
 65  0
   private static final Log log = LogFactory.getLog(UploadFileAction.class);
 66  
 
 67  
   /**
 68  
    * Peforms the processing associated with this action.
 69  
    *
 70  
    * @param request  the HttpServletRequest instance
 71  
    * @param response the HttpServletResponse instance
 72  
    * @return the name of the next view
 73  
    */
 74  
   public View process(HttpServletRequest request, HttpServletResponse response) throws ServletException {
 75  0
     Blog blog = (Blog)getModel().get(Constants.BLOG_KEY);
 76  
 
 77  0
     String type = getType();
 78  0
     String path = "";
 79  0
     String[] filenames = new String[10];
 80  
 
 81  0
     FileManager fileManager = new FileManager(blog, type);
 82  
 
 83  
     try {
 84  0
       boolean isMultipart = FileUpload.isMultipartContent(request);
 85  
 
 86  0
       if (isMultipart) {
 87  0
         DiskFileUpload upload = new DiskFileUpload();
 88  0
         long sizeInBytes = PebbleContext.getInstance().getConfiguration().getFileUploadSize() * 1024; // convert to bytes
 89  0
         upload.setSizeMax(sizeInBytes);
 90  0
         upload.setSizeThreshold((int)sizeInBytes/4);
 91  0
         upload.setRepositoryPath(System.getProperty("java.io.tmpdir"));
 92  
 
 93  
         List items;
 94  
         try {
 95  0
           items = upload.parseRequest(request);
 96  0
         } catch (FileUploadBase.SizeLimitExceededException e) {
 97  0
           return new FileTooLargeView();
 98  0
         }
 99  
 
 100  
         // find the form fields first
 101  0
         Iterator it = items.iterator();
 102  0
         while (it.hasNext()) {
 103  0
           FileItem item = (FileItem)it.next();
 104  0
           if (item.isFormField() && item.getFieldName().startsWith("filename")) {
 105  0
             int index = Integer.parseInt(item.getFieldName().substring(item.getFieldName().length()-1));
 106  0
             filenames[index] = item.getString();
 107  0
             log.debug("index is " + index + ", filename is " + filenames[index]);
 108  0
           } else if (item.isFormField() && item.getFieldName().equals("path")) {
 109  0
             path = item.getString();
 110  
           }
 111  0
         }
 112  
 
 113  
         // now the actual files
 114  0
         it = items.iterator();
 115  0
         while (it.hasNext()) {
 116  0
           FileItem item = (FileItem)it.next();
 117  
 
 118  0
           if (!item.isFormField() && item.getSize() > 0 && item.getFieldName().startsWith("file")) {
 119  0
             int index = Integer.parseInt(item.getFieldName().substring(item.getFieldName().length()-1));
 120  
 
 121  
             // if the filename hasn't been specified, use that from the file
 122  
             // being uploaded
 123  0
             if (filenames[index] == null || filenames[index].length() == 0) {
 124  0
               filenames[index] = item.getName();
 125  
             }
 126  
 
 127  0
             File destinationDirectory = fileManager.getFile(path);
 128  0
             File file = new File(destinationDirectory, filenames[index]);
 129  0
             if (!fileManager.isUnderneathRootDirectory(file)) {
 130  0
               response.setStatus(HttpServletResponse.SC_FORBIDDEN);
 131  0
               return null;
 132  
             }
 133  
 
 134  0
             long itemSize = item.getSize()/1024;
 135  0
             if (FileManager.hasEnoughSpace(blog, itemSize)) {
 136  0
               log.debug("Writing file " + filenames[index] + ", size is " + item.getSize());
 137  0
               writeFile(fileManager, path, filenames[index], item);
 138  
 
 139  
               // if it's a theme file, also create a copy in blog.dir/theme
 140  0
               if (type.equals(FileMetaData.THEME_FILE)) {
 141  0
                 writeFile(new FileManager(blog, FileMetaData.BLOG_DATA), "/theme" + path, filenames[index], item);
 142  
               }
 143  
             } else {
 144  0
               return new NotEnoughSpaceView();
 145  
             }
 146  
           }
 147  0
         }
 148  
       }
 149  
 
 150  0
       blog.info("Files uploaded.");
 151  0
     } catch (Exception e) {
 152  0
       throw new ServletException(e);
 153  0
     }
 154  
 
 155  0
     FileMetaData directory = fileManager.getFileMetaData(path);
 156  
 
 157  0
     return new RedirectView(blog.getUrl() + directory.getUrl());
 158  
   }
 159  
 
 160  
   /**
 161  
    * Helper method to write a file.
 162  
    *
 163  
    * @param fileManager   a FileManager instance
 164  
    * @param path          the path where to save the file
 165  
    * @param filename      the filename
 166  
    * @param item          the uploaded item
 167  
    * @throws Exception    if something goes wrong writing the file
 168  
    */
 169  
   private void writeFile(FileManager fileManager, String path, String filename, FileItem item) throws Exception {
 170  0
     File destinationDirectory = fileManager.getFile(path);
 171  0
     destinationDirectory.mkdirs();
 172  
 
 173  0
     File file = new File(destinationDirectory, filename);
 174  0
     item.write(file);
 175  0
   }
 176  
 
 177  
   /**
 178  
    * Gets the type of this upload (blog image, blog file or theme file).
 179  
    *
 180  
    * @return    a String representing the type
 181  
    * @see       net.sourceforge.pebble.domain.FileMetaData
 182  
    */
 183  
   protected abstract String getType();
 184  
 
 185  
   /**
 186  
    * Gets a list of all roles that are allowed to access this action.
 187  
    *
 188  
    * @return  an array of Strings representing role names
 189  
    */
 190  
   public abstract String[] getRoles(HttpServletRequest request);
 191  
 
 192  
 }