Author: germuska
Date: Mon Apr  2 12:29:21 2007
New Revision: 524895

URL: http://svn.apache.org/viewvc?view=rev&rev=524895
Log:
STR-487 - support upload of multiple files with a single HTTP parameter name.  
The ActionForm class receiving multiple files must use java.util.List for the 
property type.


Modified:
    
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/upload/CommonsMultipartRequestHandler.java
    
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/util/RequestUtils.java

Modified: 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/upload/CommonsMultipartRequestHandler.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/upload/CommonsMultipartRequestHandler.java?view=diff&rev=524895&r1=524894&r2=524895
==============================================================================
--- 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/upload/CommonsMultipartRequestHandler.java
 (original)
+++ 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/upload/CommonsMultipartRequestHandler.java
 Mon Apr  2 12:29:21 2007
@@ -41,6 +41,7 @@
 import java.io.InputStream;
 import java.io.Serializable;
 
+import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
@@ -244,10 +245,16 @@
     public void rollback() {
         Iterator iter = elementsFile.values().iterator();
 
+        Object o;
         while (iter.hasNext()) {
-            FormFile formFile = (FormFile) iter.next();
-
-            formFile.destroy();
+            o = iter.next();
+            if (o instanceof List) {
+                for (Iterator i = ((List)o).iterator(); i.hasNext(); ) {
+                    ((FormFile)i.next()).destroy();
+                }
+            } else {
+                ((FormFile)o).destroy();
+            }
         }
     }
 
@@ -448,8 +455,22 @@
     protected void addFileParameter(FileItem item) {
         FormFile formFile = new CommonsFormFile(item);
 
-        elementsFile.put(item.getFieldName(), formFile);
-        elementsAll.put(item.getFieldName(), formFile);
+        String name = item.getFieldName();
+        if (elementsFile.containsKey(name)) {
+            Object o = elementsFile.get(name);
+            if (o instanceof List) {
+                ((List)o).add(formFile);
+            } else {
+                List list = new ArrayList();
+                list.add((FormFile)o);
+                list.add(formFile);
+                elementsFile.put(name, list);
+                elementsAll.put(name, list);
+            }
+        } else {
+            elementsFile.put(name, formFile);
+            elementsAll.put(name, formFile);
+        }
     }
 
     // ---------------------------------------------------------- Inner Classes

Modified: 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/util/RequestUtils.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/util/RequestUtils.java?view=diff&rev=524895&r1=524894&r2=524895
==============================================================================
--- 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/util/RequestUtils.java
 (original)
+++ 
struts/struts1/branches/STRUTS_1_3_BRANCH/core/src/main/java/org/apache/struts/util/RequestUtils.java
 Mon Apr  2 12:29:21 2007
@@ -21,6 +21,7 @@
 package org.apache.struts.util;
 
 import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.struts.Globals;
@@ -32,6 +33,7 @@
 import org.apache.struts.config.FormBeanConfig;
 import org.apache.struts.config.ForwardConfig;
 import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.upload.FormFile;
 import org.apache.struts.upload.MultipartRequestHandler;
 import org.apache.struts.upload.MultipartRequestWrapper;
 
@@ -40,13 +42,16 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
+import java.lang.reflect.InvocationTargetException;
 import java.net.MalformedURLException;
 import java.net.URL;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -451,6 +456,7 @@
 
             if (isMultipart) {
                 parameterValue = multipartParameters.get(name);
+                parameterValue = rationalizeMultipleFileProperty(bean, name, 
parameterValue);
             } else {
                 parameterValue = request.getParameterValues(name);
             }
@@ -479,6 +485,46 @@
     }
 
     /**
+     * <p>If the given form bean can accept multiple FormFile objects but the 
user only uploaded a single, then 
+     * the property will not match the form bean type.  This method performs 
some simple checks to try to accommodate
+     * that situation.</p>
+     * @param bean
+     * @param name
+     * @param parameterValue
+     * @return 
+     * @throws ServletException if the introspection has any errors.
+     */
+    private static Object rationalizeMultipleFileProperty(Object bean, String 
name, Object parameterValue) throws ServletException {
+       if (!(parameterValue instanceof FormFile)) return parameterValue;
+
+       FormFile formFileValue = (FormFile) parameterValue;
+       try {
+                       Class propertyType = 
PropertyUtils.getPropertyType(bean, name);
+
+                       if (propertyType.isAssignableFrom(List.class)) {
+                               ArrayList list = new ArrayList(1);
+                               list.add(formFileValue);
+                               return list;
+                       }
+
+                       if (propertyType.isArray() && 
propertyType.getComponentType().equals(FormFile.class)) {
+                               return new FormFile[] { formFileValue };
+                       }
+
+       } catch (IllegalAccessException e) {
+                       throw new ServletException(e);
+               } catch (InvocationTargetException e) {
+                       throw new ServletException(e);
+               } catch (NoSuchMethodException e) {
+                       throw new ServletException(e);
+               }
+       
+               // no changes
+       return parameterValue;
+       
+       }
+
+       /**
      * <p>Try to locate a multipart request handler for this request. First,
      * look for a mapping-specific handler stored for us under an attribute.
      * If one is not present, use the global multipart handler, if there is


Reply via email to