/* Copyright (c) 2003 eInnovation Inc. All rights reserved This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ /* * FileUploadAction.java * * Created on July 31, 2002, 11:41 AM */ package org.entermedia.upload; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileCleaningTracker; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openedit.Data; import org.openedit.data.Searcher; import org.openedit.data.SearcherManager; import com.openedit.OpenEditException; import com.openedit.WebPageRequest; import com.openedit.hittracker.HitTracker; import com.openedit.hittracker.SearchQuery; import com.openedit.page.Page; import com.openedit.page.manage.PageManager; /** * DOCUMENT ME! * * @author cnelson */ public class FileUpload { protected PageManager fieldPageManager; protected File fieldRoot; /** Defaults to 1MB */ public static final int BUFFER_SIZE = 1000000; protected SearcherManager fieldSearcherManager; public SearcherManager getSearcherManager() { return fieldSearcherManager; } public void setSearcherManager(SearcherManager inSearcherManager) { fieldSearcherManager = inSearcherManager; } private static final Log log = LogFactory.getLog(FileUpload.class); /* (non-Javadoc) * @see com.openedit.action.Command#execute(java.util.Map, java.util.Map) */ public UploadRequest uploadFiles(WebPageRequest inContext) throws OpenEditException { if (inContext.getUser() == null) { throw new OpenEditException("You must be logged in to upload files"); } // Object canUpload = inContext.getPageValue("canupload"); // if (!Boolean.parseBoolean(String.valueOf(canUpload))) // { // throw new OpenEditException("You don't have enough permissions to upload files"); // } // UploadRequest props = parseArguments(inContext); if( props == null) { return null; } saveFiles(inContext, props); return props; } public void saveFiles(WebPageRequest inContext, UploadRequest props) throws OpenEditException { String home = (String)inContext.getPageValue("home"); for (Iterator iterator = props.getUploadItems().iterator(); iterator.hasNext();) { FileUploadItem item = (FileUploadItem) iterator.next(); if( item.getSavedPage() == null) { props.saveFile(item,home,inContext); } //Page page = saveFile( props, finalpath, inContext ); } inContext.putPageValue("uploadrequest",props); //inContext.setRequestParameter("path", page.getPath()); } /** * @param inContext * @return */ public UploadRequest parseArguments(WebPageRequest inContext) throws OpenEditException { final UploadRequest upload = new UploadRequest(); upload.setPageManager(getPageManager()); upload.setRoot(getRoot()); //upload.setProperties(inContext.getParameterMap()); if ( inContext.getRequest() == null) //used in unit tests { return upload; } String type = inContext.getRequest().getContentType(); if ( type == null || !type.startsWith("multipart")) { addAlreadyUploaded(inContext, upload); return upload; } String uploadid = inContext.getRequestParameter("uploadid"); String catalogid = inContext.findValue("catalogid"); if(uploadid != null && catalogid != null) { upload.setUploadId(uploadid); upload.setCatalogId(catalogid); upload.setUserName(inContext.getUserName()); upload.setUploadQueueSearcher(loadQueueSearcher(catalogid)); } //Our factory will track these items as they are made. Each time some data comes in look over all the files and update the size FileItemFactory factory = (FileItemFactory)inContext.getPageValue("uploadfilefactory"); if( factory == null) { DiskFileItemFactory dfactory = new DiskFileItemFactory(); // { // public org.apache.commons.fileupload.FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) // { // if( !isFormField ) // { // upload.track(fieldName, contentType, isFormField, fileName); // } // return super.createItem(fieldName, contentType, isFormField, fileName); // }; // } factory = dfactory; } ServletFileUpload uploadreader = new ServletFileUpload(factory); //upload.setSizeThreshold(BUFFER_SIZE); if( uploadid != null) { uploadreader.setProgressListener(upload); } HttpServletRequest req = inContext.getRequest(); String encode = req.getCharacterEncoding(); if ( encode == null) { //log.info("Encoding not set."); encode = "UTF-8"; } //log.info("Encoding is set to " + encode); uploadreader.setHeaderEncoding(encode); //upload.setHeaderEncoding() //Content-Transfer-Encoding: binary //upload.setRepositoryPath(repository.pathToFile("admin uploadreader.setSizeMax(-1); try { readParameters(inContext, uploadreader, upload, encode); } catch (UnsupportedEncodingException e) { throw new OpenEditException(e); } if( uploadid != null) { expireOldUploads(catalogid); } return upload; } protected Searcher loadQueueSearcher(String catalogid) { return getSearcherManager().getSearcher(catalogid, "uploadqueue"); } protected void expireOldUploads(String inCatalogId) { Searcher searcher = loadQueueSearcher(inCatalogId); SearchQuery q = searcher.createSearchQuery(); Calendar cal = new GregorianCalendar(); cal.add(Calendar.HOUR, -48); q.addBefore("date", cal.getTime()); //child.addMatches("status", "complete"); HitTracker hits = searcher.search(q); for (Iterator iterator = hits.iterator(); iterator.hasNext();) { Data queue = (Data) iterator.next(); searcher.delete(queue, null); } } protected void readParameters(WebPageRequest inContext, ServletFileUpload uploadreader, UploadRequest upload, String encoding) throws UnsupportedEncodingException { List fileItems; FileItemIterator itemIterator; try { fileItems = uploadreader.parseRequest(inContext.getRequest()); // This is a multipart MIME-encoded request, so the request // parameters must all be parsed from the POST body, not // gotten directly off the HttpServletRequest. for (int i = 0; i < fileItems.size(); i++) { org.apache.commons.fileupload.FileItem tmp = (org.apache.commons.fileupload.FileItem) fileItems.get(i); int count = 0; if (!tmp.isFormField()) { FileUploadItem foundUpload = new FileUploadItem(); foundUpload.setFileItem(tmp); String name = tmp.getName(); if( name != null && name.contains("\\")) { name = name.substring(name.lastIndexOf("\\")+1); } foundUpload.setName(name); //String num = "0"; //int index = tmp.getFieldName().indexOf("."); // if( index > -1) // { // num = tmp.getFieldName().substring(index+1); // } foundUpload.setCount(count); count++; upload.addUploadItem(foundUpload); } } } catch (Exception e) { throw new OpenEditException(e); } //TODO: Find out why Apache creates tmp files for each parameter attached to the body of the upload Map arguments = inContext.getParameterMap(); for (int i = 0; i < fileItems.size(); i++) { org.apache.commons.fileupload.FileItem tmp = (org.apache.commons.fileupload.FileItem) fileItems.get(i); if (tmp.isFormField() ) { Object vals = arguments.get(tmp.getFieldName()); String[] values = null;//(String[]) if( vals instanceof String) { values = new String[1]; values[0] = (String)vals; //the old value? } else if ( vals != null) { values = (String[])vals; } if( values == null) { values = new String[1]; } else { //grow by one String[] newvalues = new String[values.length + 1]; System.arraycopy(values,0, newvalues,0, values.length); values = newvalues; } values[values.length -1] = tmp.getString(encoding).trim(); arguments.put(tmp.getFieldName(), values); } } for (Iterator iterator = arguments.keySet().iterator(); iterator.hasNext();) { String param = (String)iterator.next(); Object vals = arguments.get(param); if( vals instanceof String[]) { inContext.setRequestParameter(param, (String[])vals); } } addAlreadyUploaded(inContext, upload); } private void addAlreadyUploaded(WebPageRequest inContext, UploadRequest upload) { // These file where already uploaded recently using the applet. String[] paths = inContext.getRequestParameters("uploadpath"); if (paths != null) { for (int i = 0; i < paths.length; i++) { String name = paths[i].replace('\\', '/'); Page page = getPageManager().getPage(name); FileUploadItem item = new FileUploadItem(); item.setSavedPage(page); item.setCount(i); item.setName(page.getName()); upload.addUploadItem(item); } } } public PageManager getPageManager() { return fieldPageManager; } public void setPageManager( PageManager pageManager ) { fieldPageManager = pageManager; } public File getRoot() { return fieldRoot; } public void setRoot(File inRoot) { fieldRoot = inRoot; } }