Author: wesw
Date: Wed Jun 3 21:30:06 2009
New Revision: 781587
URL: http://svn.apache.org/viewvc?rev=781587&view=rev
Log:
first commit, wanted to get it in before leaving, still need to add a
struts-plugin.xml file that wires the beans together and then build an action
that demonstrates ajax usage with a progress bar
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/
struts/sandbox/trunk/struts2-fileupload-plugin/pom.xml
struts/sandbox/trunk/struts2-fileupload-plugin/src/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/BasicProgressListener.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/DiskFileItemFactoryWrapper.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/EnhancedJakartaMultiPartRequest.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileItemFactoryWrapper.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileUploadConstants.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatus.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatusHolder.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/resources/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/BasicProgressListenerTest.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusHolderTest.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusTest.java
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/resources/
Added: struts/sandbox/trunk/struts2-fileupload-plugin/pom.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/pom.xml?rev=781587&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-fileupload-plugin/pom.xml (added)
+++ struts/sandbox/trunk/struts2-fileupload-plugin/pom.xml Wed Jun 3 21:30:06
2009
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ $Id$
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-plugins</artifactId>
+ <version>2.1.7-SNAPSHOT</version>
+ </parent>
+ <groupId>struts2-fileupload-plugin</groupId>
+ <artifactId>struts2-fileupload-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <name>Struts 2 Advanced File Upload Plugin</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ <version>1.2.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <version>2.1.7-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- I need the following for the mock objects to work -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.5.6</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-idea-plugin</artifactId>
+ <configuration>
+ <jdkName>1.5</jdkName>
+ <exclude>target,test-output,.clover</exclude>
+ <useFullNames>false</useFullNames>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/BasicProgressListener.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/BasicProgressListener.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/BasicProgressListener.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/BasicProgressListener.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,80 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts2.fileupload;
+
+import org.apache.commons.fileupload.ProgressListener;
+import org.apache.struts2.ServletActionContext;
+import com.opensymphony.xwork2.inject.Inject;
+
+/**
+ * Just a simple ProgressListener for Jakarta FileUpload. It will store
+ * file progress in a HashMap that gets cleaned out once in a while.
+ * The HashMap will key the upload status off of the HttpSession.getId(),
+ * which means that you can't have multiple uploads going to the same
+ * server from different browser windows or tabs.
+ *
+ * @author Wes W
+ */
+public class BasicProgressListener implements ProgressListener {
+
+ private int updateFrequency = 2048; // magic number for a default
+ private UploadStatusHolder holder = new UploadStatusHolder();
+ private long lastUpdate = -1L; //
+
+ /**
+ *
+ * @param updateFrequency
+ */
+ @Inject(FileUploadConstants.LISTENER_UPDATE_FREQUENCY)
+ public void setUpdateFrequency(String updateFrequency) {
+ try {
+ this.updateFrequency = Integer.parseInt(updateFrequency);
+ }
+ catch (NumberFormatException nfe) {
+ // come on people, how hard is it to specify an integer
+ // if you flubbed it up, you can get the default
+ }
+ }
+
+ /**
+ *
+ * @param bytesRead
+ * @param contentLength
+ * @param item
+ */
+ public void update(long bytesRead, long contentLength, int item) {
+ if ( bytesRead / updateFrequency > lastUpdate) {
+ lastUpdate = bytesRead / updateFrequency;
+ if (lastUpdate == 0 ) {
+ // we could get stuck here if we leave it
+ lastUpdate = 1L;
+ }
+ // I wonder if this will ever NPE
+ String sessionId =
ServletActionContext.getRequest().getSession(true).getId();
+ UploadStatus status = new UploadStatus();
+ status.setBytesRead(bytesRead);
+ status.setContentLength(contentLength);
+ status.setItem(item);
+ holder.addUploadStatus(sessionId, status);
+ }
+ }
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/DiskFileItemFactoryWrapper.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/DiskFileItemFactoryWrapper.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/DiskFileItemFactoryWrapper.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/DiskFileItemFactoryWrapper.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,120 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.FileItemFactory;
+import com.opensymphony.xwork2.inject.Inject;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * This class basically wraps the DiskFileItemFactory which is the
+ * default FileItemFactory for Jakarta FileUpload. The threshold
+ * setting specifies how large a file can get before it gets flushed
+ * from memory onto disk.
+ *
+ * TODO: Someone mentioned that google app engine won't let you
+ * write to the filesystem. It should be documented that you could
+ * potentially set the threshold to match your max upload size and then
+ * keep all files in memory. I don't know if it will work, since the
+ * MultiPartRequest interface insists that Files be used and I don't
+ * know what will happen, but it is worth trying.
+ *
+ * @author Wes W
+ */
+public class DiskFileItemFactoryWrapper implements FileItemFactoryWrapper {
+
+ protected DiskFileItemFactory factory;
+
+ /**
+ *
+ * @param sizeThreshold
+ * @param repositoryPath
+ */
+ public DiskFileItemFactoryWrapper(
+ @Inject(FileUploadConstants.SIZE_THRESHOLD)
+ String sizeThreshold,
+ @Inject(FileUploadConstants.FILE_REPOSITORY_PATH)
+ String repositoryPath ) {
+
+ int threshold ;
+ try {
+ threshold = Integer.parseInt(sizeThreshold);
+ }
+ catch (NumberFormatException nfe) {
+ // how hard is it to specify a valid integer?
+ }
+ finally {
+ threshold = 256; // I guess this is a magic number
+ }
+
+ File repoPath = convertStringToFile(repositoryPath);
+
+ factory = new DiskFileItemFactory(threshold, repoPath);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public FileItemFactory getFileItemFactory() {
+ return factory;
+ }
+
+ /**
+ *
+ * @param threshold
+ */
+ public void setSizeThreshold(int threshold) {
+ this.factory.setSizeThreshold(threshold);
+ }
+
+ /**
+ *
+ * @param repo
+ */
+ public void setRepositoryPath(String repo) {
+ this.factory.setRepository(convertStringToFile(repo));
+ }
+
+ private File convertStringToFile(String path) {
+ File repoPath = new File(path);
+ if (repoPath == null || !repoPath.isDirectory()) {
+ File tempFile = null;
+ try {
+ tempFile = File.createTempFile("","");
+ }
+ catch (IOException ioe) {
+ // I guess we're just sort of screwed, punt
+ repoPath = null;
+ }
+ if (tempFile != null ) {
+ repoPath = tempFile.getParentFile();
+ tempFile.delete();
+ }
+ }
+ return repoPath;
+ }
+
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/EnhancedJakartaMultiPartRequest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/EnhancedJakartaMultiPartRequest.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/EnhancedJakartaMultiPartRequest.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/EnhancedJakartaMultiPartRequest.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,189 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
+import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;
+import org.apache.commons.fileupload.ProgressListener;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.RequestContext;
+import org.apache.commons.fileupload.portlet.PortletFileUpload;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.inject.Inject;
+
+/**
+ * Using Jakarta Commons File Upload, handle multipart requests. This class
+ * acts mostly the same as the original JakartaMultiPartRequest.
+ *
+ * @author WesW
+ */
+public class EnhancedJakartaMultiPartRequest
+ extends JakartaMultiPartRequest
+ implements MultiPartRequest {
+
+ static final Logger LOG = LoggerFactory.getLogger(MultiPartRequest.class);
+
+ protected ProgressListener progressListener;
+ protected FileItemFactory fileItemFactory;
+ protected boolean portletUpload;
+
+ /**
+ *
+ * @param progressListener
+ */
+ @Inject(FileUploadConstants.PROGRESS_LISTENER)
+ public void setProgressListener(ProgressListener progressListener) {
+ this.progressListener = progressListener;
+ }
+
+ /**
+ *
+ * @param fileItemFactory
+ */
+ @Inject(FileUploadConstants.FILE_ITEM_FACTORY)
+ public void setFileItemFactory(FileItemFactory fileItemFactory) {
+ this.fileItemFactory = fileItemFactory;
+ }
+
+ /**
+ *
+ * @param portletUpload
+ */
+ @Inject(FileUploadConstants.IS_PORTLET)
+ public void setPortletUpload(String portletUpload) {
+ this.portletUpload = "true".equalsIgnoreCase(portletUpload);
+ }
+
+ /**
+ *
+ * @param request
+ * @param saveDir
+ * @throws IOException
+ */
+ public void parse(HttpServletRequest request, String saveDir) throws
IOException {
+ // Parse the request mostly copy/paste from JakartaMuliPartRequest
+ try {
+
+ FileUpload upload ;
+ if (portletUpload) {
+ upload = new PortletFileUpload(fileItemFactory);
+ }
+ else {
+ upload = new ServletFileUpload(fileItemFactory);
+ }
+
+ upload.setSizeMax(maxSize);
+ upload.setProgressListener(progressListener);
+
+ List items = upload.parseRequest(createRequestContext(request));
+
+ for (Object item1 : items) {
+ FileItem item = (FileItem) item1;
+ if (LOG.isDebugEnabled()) LOG.debug("Found item " +
item.getFieldName());
+ if (item.isFormField()) {
+ LOG.debug("Item is a normal form field");
+ List<String> values;
+ if (params.get(item.getFieldName()) != null) {
+ values = params.get(item.getFieldName());
+ } else {
+ values = new ArrayList<String>();
+ }
+
+ // note: see http://jira.opensymphony.com/browse/WW-633
+ // basically, in some cases the charset may be null, so
+ // we're just going to try to "other" method (no idea if
this
+ // will work)
+ String charset = request.getCharacterEncoding();
+ if (charset != null) {
+ values.add(item.getString(charset));
+ } else {
+ values.add(item.getString());
+ }
+ params.put(item.getFieldName(), values);
+ } else {
+ LOG.debug("Item is a file upload");
+
+ // Skip file uploads that don't have a file name - meaning
that no file was selected.
+ if (item.getName() == null ||
item.getName().trim().length() < 1) {
+ LOG.debug("No file has been uploaded for the field: "
+ item.getFieldName());
+ continue;
+ }
+
+ List<FileItem> values;
+ if (files.get(item.getFieldName()) != null) {
+ values = files.get(item.getFieldName());
+ } else {
+ values = new ArrayList<FileItem>();
+ }
+
+ values.add(item);
+ files.put(item.getFieldName(), values);
+ }
+ }
+ } catch (FileUploadException e) {
+ LOG.warn("Unable to parse request", e);
+ errors.add(e.getMessage());
+ }
+ }
+
+ /**
+ * Creates a RequestContext needed by Jakarta Commons Upload.
+ * (copy/pasta from JakartaMultiPartRequest)
+ *
+ * @param req the request.
+ * @return a new request context.
+ */
+ private RequestContext createRequestContext(final HttpServletRequest req) {
+ return new RequestContext() {
+ public String getCharacterEncoding() {
+ return req.getCharacterEncoding();
+ }
+
+ public String getContentType() {
+ return req.getContentType();
+ }
+
+ public int getContentLength() {
+ return req.getContentLength();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ InputStream in = req.getInputStream();
+ if (in == null) {
+ throw new IOException("Missing content in the request");
+ }
+ return req.getInputStream();
+ }
+ };
+ }
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileItemFactoryWrapper.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileItemFactoryWrapper.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileItemFactoryWrapper.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileItemFactoryWrapper.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import org.apache.commons.fileupload.FileItemFactory;
+
+/**
+ * Quick interface to allow DiskFileItemFactoryWrapper to be
+ * wired in or replaced.
+ *
+ * @author Wes W
+ */
+public interface FileItemFactoryWrapper {
+
+ public FileItemFactory getFileItemFactory();
+
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileUploadConstants.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileUploadConstants.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileUploadConstants.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/FileUploadConstants.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+/**
+ * Holder for constants
+ *
+ * @author Wes Wannemacher
+ */
+public final class FileUploadConstants {
+
+ /**
+ *
+ */
+ public static final String PROGRESS_LISTENER =
"struts.fileuploadplugin.progressListener";
+
+ /**
+ *
+ */
+ public static final String FILE_ITEM_FACTORY =
"struts.fileuploadplugin.fileitemfactory";
+
+ /**
+ *
+ */
+ public static final String SIZE_THRESHOLD =
"struts.fileuploadplugin.sizethreshold";
+
+ /**
+ *
+ */
+ public static final String FILE_REPOSITORY_PATH =
"struts.fileuploadplugin.repositorypath";
+
+ /**
+ *
+ */
+ public static final String IS_PORTLET =
"struts.fileuploadplugin.isportletupload";
+
+ /**
+ *
+ */
+ public static final String LISTENER_UPDATE_FREQUENCY =
"struts.fileuploadplugin.listenerupdatefrequency";
+
+ /**
+ *
+ */
+ public static final String TIME_TO_KEEP_STATUS =
"struts.fileupload.timetokeepstatus";
+
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatus.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatus.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatus.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatus.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,110 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import java.util.Calendar;
+
+/**
+ * POJO for holding the status of a running upload. Instance access
+ * time is recorded to allow for simple cleanup.
+ *
+ * @author Wes W
+ */
+public class UploadStatus {
+
+ private long lastAccess ;
+ private long bytesRead ;
+ private long contentLength ;
+ private long item ;
+
+ /**
+ *
+ */
+ public UploadStatus() {
+ updateLastAccess() ;
+ bytesRead = 0;
+ contentLength = 0;
+ item = 0;
+ }
+
+ /**
+ *
+ */
+ public long getLastAccess() {
+ return lastAccess;
+ }
+
+ /**
+ *
+ */
+ public long getBytesRead() {
+ updateLastAccess();
+ return bytesRead;
+ }
+
+ /**
+ *
+ */
+ public void setBytesRead(long bytesRead) {
+ updateLastAccess();
+ this.bytesRead = bytesRead;
+ }
+
+ /**
+ *
+ */
+ public long getContentLength() {
+ updateLastAccess();
+ return contentLength;
+ }
+
+ /**
+ *
+ */
+ public void setContentLength(long contentLength) {
+ updateLastAccess();
+ this.contentLength = contentLength;
+ }
+
+ /**
+ *
+ */
+ public long getItem() {
+ updateLastAccess();
+ return item;
+ }
+
+ /**
+ *
+ */
+ public void setItem(long item) {
+ updateLastAccess();
+ this.item = item;
+ }
+
+ /**
+ *
+ */
+ private void updateLastAccess() {
+ lastAccess = Calendar.getInstance().getTimeInMillis() / 1000 ;
+ }
+
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatusHolder.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatusHolder.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatusHolder.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/main/java/org/apache/struts2/fileupload/UploadStatusHolder.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import com.opensymphony.xwork2.inject.Inject;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Calendar;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The UploadStatusHolder simply holds UploadStatuses. It will
+ * clean them up if an UploadStatus has not been accessed within
+ * the configured amount of time (in seconds).
+ *
+ * @author Wes W
+ */
+public class UploadStatusHolder {
+
+ private int secondsToKeep = 600 ; //default to ten minutes
+ public static Map<String,UploadStatus> statuses = new
HashMap<String,UploadStatus>();
+
+ private long lastRun = 0; // keep track so we aren't cleaning up all the
time
+
+ /**
+ *
+ * @param secondsToKeep
+ */
+ @Inject(FileUploadConstants.TIME_TO_KEEP_STATUS)
+ public void setSecondsToKeep(String secondsToKeep) {
+ try {
+ this.secondsToKeep = Integer.parseInt(secondsToKeep);
+ }
+ catch (NumberFormatException nfe) {
+ // come on people, how hard is it to specify an integer
+ // if you flubbed it up, you can get the default
+ }
+ }
+
+ /**
+ *
+ * @param key
+ * @param status
+ */
+ public void addUploadStatus(String key, UploadStatus status ) {
+ statuses.put(key,status);
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ */
+ public UploadStatus getUploadStatus(String key) {
+ long now = Calendar.getInstance().getTimeInMillis() / 1000 ;
+ if ( now - lastRun > secondsToKeep) {
+ // time to clean up
+ List<String> keys2del = new ArrayList<String>();
+ for (String cleanUpKey : statuses.keySet()) {
+ if ( now - statuses.get(cleanUpKey).getLastAccess() >
secondsToKeep ) {
+ keys2del.add(cleanUpKey);
+ }
+ }
+ for (String key2del : keys2del) {
+ statuses.remove(key2del);
+ }
+ }
+
+ return statuses.get(key);
+ }
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/BasicProgressListenerTest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/BasicProgressListenerTest.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/BasicProgressListenerTest.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/BasicProgressListenerTest.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,117 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts2.fileupload;
+
+import org.junit.Test;
+import org.junit.Before;
+import static org.junit.Assert.assertTrue;
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.StrutsStatics;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import com.opensymphony.xwork2.ActionContext;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Unit test for BasicProgressListener
+ *
+ * @author Wes W
+ */
+public class BasicProgressListenerTest implements StrutsStatics {
+
+ ActionContext actionContext;
+ // ServletActionContext servletActionContext;
+ private MockServletContext servletContext;
+ private HttpServletRequest request;
+ private HttpServletResponse response;
+
+ /**
+ *
+ */
+ @Before
+ public void setUp() {
+ Map extraContext = new HashMap();
+
+ servletContext = new MockServletContext();
+
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+
+ extraContext.put(HTTP_REQUEST, request);
+ extraContext.put(HTTP_RESPONSE, response);
+ extraContext.put(SERVLET_CONTEXT, servletContext);
+
+ actionContext = new ActionContext(extraContext);
+ ServletActionContext.setContext(actionContext);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUpdate() {
+ BasicProgressListener listener = new BasicProgressListener();
+ listener.setUpdateFrequency("1");
+ listener.update(10L,10L,1);
+
+ UploadStatusHolder holder = new UploadStatusHolder();
+
+ String key = request.getSession().getId();
+ System.err.println("key - " + key);
+
+ UploadStatus status = holder.getUploadStatus(key );
+
+ assertTrue(status.getBytesRead() == 10L);
+ assertTrue(status.getContentLength() == 10L);
+ assertTrue(status.getItem() == 1);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testDontUpdate() {
+ BasicProgressListener listener = new BasicProgressListener();
+ // listener.setUpdateFrequency("1000"); // let default of 2048 take
over
+ listener.update(10L,10L,1);
+ listener.update(100L,100L,1);
+
+ UploadStatusHolder holder = new UploadStatusHolder();
+
+ String key = request.getSession().getId();
+ System.err.println("key - " + key);
+
+ UploadStatus status = holder.getUploadStatus(key );
+
+ assertTrue(status.getBytesRead() == 10L);
+ assertTrue(status.getContentLength() == 10L);
+ assertTrue(status.getItem() == 1);
+
+ }
+}
\ No newline at end of file
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusHolderTest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusHolderTest.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusHolderTest.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusHolderTest.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit Test for UploadStatusHolder
+ *
+ * @author Wes W
+ */
+public class UploadStatusHolderTest {
+
+ /**
+ *
+ */
+ @Test
+ public void testStatusHolding() {
+ UploadStatusHolder holder1 = new UploadStatusHolder();
+ UploadStatus status1 = new UploadStatus();
+ status1.setBytesRead(1L);
+ status1.setContentLength(1L);
+ status1.setItem(1L);
+ holder1.addUploadStatus("status1",status1);
+
+ UploadStatusHolder holder2 = new UploadStatusHolder();
+ UploadStatus status2 = holder2.getUploadStatus("status1");
+
+ assertTrue(status1.getBytesRead() == status2.getBytesRead());
+ assertTrue(status1.getContentLength() == status2.getContentLength());
+ assertTrue(status1.getItem() == status2.getItem());
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testStatusHoldingGetsRemoved() throws Exception {
+ UploadStatusHolder holder1 = new UploadStatusHolder();
+ holder1.setSecondsToKeep("1");
+ UploadStatus status1 = new UploadStatus();
+ status1.setBytesRead(1L);
+ status1.setContentLength(1L);
+ status1.setItem(1L);
+ holder1.addUploadStatus("status1",status1);
+ Thread.sleep(5000L);
+ UploadStatus status2 = holder1.getUploadStatus("status1");
+ assertTrue(status2 == null);
+ }
+}
Added:
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusTest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusTest.java?rev=781587&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusTest.java
(added)
+++
struts/sandbox/trunk/struts2-fileupload-plugin/src/test/java/org/apache/struts2/fileupload/UploadStatusTest.java
Wed Jun 3 21:30:06 2009
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.fileupload;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit Test for UploadStatus
+ *
+ * @author Wes W
+ */
+public class UploadStatusTest {
+
+ /**
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLastAccessChange() throws Exception {
+ UploadStatus stat = new UploadStatus() ;
+ long firstAccess = stat.getLastAccess();
+ stat.setBytesRead(1L);
+ stat.setContentLength(1L);
+ stat.setItem(1L);
+ Thread.sleep(5000L);
+ assertTrue(1 == stat.getBytesRead());
+ assertTrue(1 == stat.getContentLength());
+ assertTrue(1 == stat.getItem());
+ assertTrue(firstAccess < stat.getLastAccess());
+ }
+}