1 package com.icesoft.faces.webapp.http.servlet; 2 3 import com.icesoft.faces.application.D2DViewHandler; 4 import com.icesoft.faces.context.BridgeFacesContext; 5 import com.icesoft.faces.webapp.http.common.Configuration; 6 import org.apache.commons.fileupload.FileItemIterator; 7 import org.apache.commons.fileupload.FileItemStream; 8 import org.apache.commons.fileupload.ProgressListener; 9 import org.apache.commons.fileupload.servlet.ServletFileUpload; 10 import org.apache.commons.fileupload.util.Streams; 11 import org.apache.commons.logging.Log; 12 import org.apache.commons.logging.LogFactory; 13 14 import javax.servlet.ServletContext ; 15 import javax.servlet.http.HttpServletRequest ; 16 import javax.servlet.http.HttpServletResponse ; 17 import java.io.IOException ; 18 import java.util.Map ; 19 20 public class UploadServlet implements PseudoServlet { 21 private static final Log Log = LogFactory.getLog(UploadServlet.class); 22 private Map views; 23 private long maxSize; 24 private String uploadDirectory; 25 private boolean uploadDirectoryAbsolute; 26 private ServletContext servletContext; 27 28 public UploadServlet(Map views, Configuration configuration, ServletContext servletContext) { 29 this.views = views; 30 this.maxSize = configuration.getAttributeAsLong("uploadMaxFileSize", 3 * 1024 * 1024); this.uploadDirectory = configuration.getAttribute("uploadDirectory", ""); 33 this.uploadDirectoryAbsolute = configuration.getAttributeAsBoolean("uploadDirectoryAbsolute", false); 34 this.servletContext = servletContext; 35 } 36 37 public void service(HttpServletRequest request, HttpServletResponse response) throws Exception { 38 final ServletFileUpload uploader = new ServletFileUpload(); 39 final ProgressCalculator progressCalculator = new ProgressCalculator(); 40 uploader.setFileSizeMax(maxSize); 41 uploader.setProgressListener(new ProgressListener() { 42 public void update(long read, long total, int chunkIndex) { 43 progressCalculator.progress(read, total); 44 } 45 }); 46 47 FileItemIterator iter = uploader.getItemIterator(request); 48 String viewIdentifier = null; 49 String componentID = null; 50 while (iter.hasNext()) { 51 FileItemStream item = iter.next(); 52 if (item.isFormField()) { 53 String name = item.getFieldName(); 54 if ("componentID".equals(name)) { 55 componentID = Streams.asString(item.openStream()); 56 } else if ("viewNumber".equals(name)) { 57 viewIdentifier = Streams.asString(item.openStream()); 58 } 59 } else { 60 ServletView view = (ServletView) views.get(viewIdentifier); 61 BridgeFacesContext context = view.getFacesContext(); 62 FileUploadComponent component = (FileUploadComponent) D2DViewHandler.findComponent(componentID, context.getViewRoot()); 63 progressCalculator.setListenerAndContext(component, context); 64 try { 65 view.makeCurrent(); 66 component.upload( 67 item, 68 uploadDirectory, 69 uploadDirectoryAbsolute, 70 maxSize, 71 context, 72 servletContext, 73 request.getRequestedSessionId()); 74 } catch (IOException e) { 75 try { 76 progressCalculator.reset(); 77 } catch (Throwable tr) { 78 } 80 } catch (Throwable t) { 81 try { 82 progressCalculator.reset(); 83 } catch (Throwable tr) { 84 } 86 Log.warn("File upload failed", t); 87 } finally { 88 response.setContentType("text/html"); 89 response.setHeader("Connection", "close"); 90 component.renderIFrame(response.getWriter(), context); 91 } 92 } 93 } 94 } 95 96 public void shutdown() { 97 } 98 99 private static class ProgressCalculator { 100 private final int GRANULARITY = 10; 101 private FileUploadComponent listener; 102 private BridgeFacesContext context; 103 private int lastGranularlyNotifiablePercent = -1; 104 105 public void progress(long read, long total) { 106 if (total > 0) { 107 int percentage = (int) ((read * 100L) / total); 108 int percentageAboveGranularity = percentage % GRANULARITY; 109 int granularNotifiablePercentage = percentage - percentageAboveGranularity; 110 boolean shouldNotify = granularNotifiablePercentage > lastGranularlyNotifiablePercent; 111 lastGranularlyNotifiablePercent = granularNotifiablePercentage; 112 if (shouldNotify) 113 potentiallyNotify(); 114 } 115 } 116 117 public void setListenerAndContext( 118 FileUploadComponent listener, BridgeFacesContext context) { 119 this.listener = listener; 120 this.context = context; 121 potentiallyNotify(); 122 } 123 124 public void reset() { 125 BridgeFacesContext ctx = context; 126 FileUploadComponent component = listener; 127 context = null; 128 listener = null; 129 if (ctx != null && component != null) { 130 ctx.setCurrentInstance(); 131 component.setProgress(0); 132 } 133 } 134 135 protected void potentiallyNotify() { 136 if (listener != null && lastGranularlyNotifiablePercent >= 0) { 137 context.setCurrentInstance(); 138 listener.setProgress(lastGranularlyNotifiablePercent); 139 } 140 } 141 } 142 } 143 | Popular Tags |