- reorder methods
- add getFilename extracting from header

git-svn-id: https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/parser@1844542 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fulcrum/parser/DefaultParameterParser.java b/src/java/org/apache/fulcrum/parser/DefaultParameterParser.java
index ac14deb..8419e7b 100644
--- a/src/java/org/apache/fulcrum/parser/DefaultParameterParser.java
+++ b/src/java/org/apache/fulcrum/parser/DefaultParameterParser.java
@@ -26,6 +26,8 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import javax.servlet.http.HttpServletRequest;
@@ -151,29 +153,7 @@
 
         uploadData = null;
 
-        String enc = request.getCharacterEncoding();
-        
-        if (enc == null && !parserService.getParameterEncoding().equals(ParserService.PARAMETER_ENCODING_DEFAULT )) {
-            try
-            {  
-                // no-op if data was read (parameter, POST..) 
-                request.setCharacterEncoding( parserService.getParameterEncoding() );
-                enc = request.getCharacterEncoding();
-                if (enc != null) {
-                    getLogger().debug("Set the request encoding successfully to parameterEncoding of parser: "+enc );
-                } else {
-                    getLogger().warn("Unsuccessfully (data read happened) tried to set the request encoding to "+ parserService.getParameterEncoding()  );
-                }
-            }
-            catch ( UnsupportedEncodingException e )
-            {
-                getLogger().error("Found only unsupported encoding "+ e.getMessage());
-            }
-        }
-        
-        setCharacterEncoding(enc != null
-                ? enc
-                : parserService.getParameterEncoding());
+        handleEncoding( request );
 
         String contentType = request.getHeader("Content-type");
 
@@ -210,6 +190,22 @@
                     request.getParameterValues(paramName));
         }
 
+        handlePathInfo( request );
+
+        this.request = request;
+
+        if (getLogger().isDebugEnabled())
+        {
+            getLogger().debug("Parameters found in the Request:");
+            for (String key : keySet())
+            {
+                getLogger().debug("Key: " + key + " -> " + getString(key));
+            }
+        }
+    }
+
+    private void handlePathInfo( HttpServletRequest request )
+    {
         // Also cache any pathinfo variables that are passed around as
         // if they are query string data.
         try
@@ -245,17 +241,33 @@
             // things that depend on it being right will fail later
             // and should be caught later.
         }
+    }
 
-        this.request = request;
-
-        if (getLogger().isDebugEnabled())
-        {
-            getLogger().debug("Parameters found in the Request:");
-            for (String key : keySet())
+    private void handleEncoding( HttpServletRequest request )
+    {
+        String enc = request.getCharacterEncoding();
+        
+        if (enc == null && !parserService.getParameterEncoding().equals(ParserService.PARAMETER_ENCODING_DEFAULT )) {
+            try
+            {  
+                // no-op if data was read (parameter, POST..) 
+                request.setCharacterEncoding( parserService.getParameterEncoding() );
+                enc = request.getCharacterEncoding();
+                if (enc != null) {
+                    getLogger().debug("Set the request encoding successfully to parameterEncoding of parser: "+enc );
+                } else {
+                    getLogger().warn("Unsuccessfully (data read happened) tried to set the request encoding to "+ parserService.getParameterEncoding()  );
+                }
+            }
+            catch ( UnsupportedEncodingException e )
             {
-                getLogger().debug("Key: " + key + " -> " + getString(key));
+                getLogger().error("Found only unsupported encoding "+ e.getMessage());
             }
         }
+        
+        setCharacterEncoding(enc != null
+                ? enc
+                : parserService.getParameterEncoding());
     }
 
     /**
@@ -340,7 +352,7 @@
         }
         catch ( ClassCastException e )
         {
-            return null;
+            return new Part[0];// empty array
         }
     }
     
@@ -353,4 +365,29 @@
                             collect( Collectors.toList() );
 
     }
+
+    @Override
+    public String getFileName( Part part )
+    {
+        final String partHeader = part.getHeader("content-disposition");
+        Pattern regex = Pattern.compile("filename\\*?=\"?(.[^\"]+)\"?"); // rfc2183, rfc5987 quoted string, but attachments may have not?
+        for (String content : partHeader.split(";")) {
+            if (content.trim().contains( "filename" )) { // could also filename*=<encoding>''<value>
+                String fnTmp = "";
+                String srcStr = content.trim();
+                Matcher regexMatcher = regex.matcher(srcStr);
+                if (regexMatcher.find()) {
+                    fnTmp = regexMatcher.group(1);
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug( "matched fileName:" + fnTmp );
+                    }
+                } else { // last resort
+                    fnTmp  = srcStr.substring(srcStr.indexOf('=')+1).replace( "\"", "" );
+                    getLogger().debug( "second fileName match:" + fnTmp );
+                }
+                return fnTmp.trim();
+            }
+        }
+        return null;
+    }
 }
diff --git a/src/java/org/apache/fulcrum/parser/ParameterParser.java b/src/java/org/apache/fulcrum/parser/ParameterParser.java
index 331de69..c55edfc 100644
--- a/src/java/org/apache/fulcrum/parser/ParameterParser.java
+++ b/src/java/org/apache/fulcrum/parser/ParameterParser.java
@@ -128,4 +128,12 @@
      * @return Collection<Part>
      */
     Collection<Part> getParts();
+    
+    /**
+     * Convenience fileName utility, which extracts the filename from header
+     *  
+     * 
+     * @return the fileName String object.
+     */
+    String getFileName(Part part);
 }
diff --git a/src/test/org/apache/fulcrum/parser/ParameterParserTest.java b/src/test/org/apache/fulcrum/parser/ParameterParserTest.java
index 9625f38..abda103 100644
--- a/src/test/org/apache/fulcrum/parser/ParameterParserTest.java
+++ b/src/test/org/apache/fulcrum/parser/ParameterParserTest.java
@@ -47,7 +47,7 @@
 {
     private ParameterParser parameterParser = null;
     
-    private Part test;
+    private Part mockTest;
 
     @Before
     public void setUpBefore() throws Exception
@@ -57,7 +57,7 @@
             ParserService parserService = (ParserService)this.lookup(ParserService.ROLE);
             parameterParser = parserService.getParser(DefaultParameterParser.class);
             
-            test = new Part()
+            mockTest = new Part()
             {
 
                 @Override
@@ -104,6 +104,11 @@
                 @Override
                 public String getHeader(String name)
                 {
+                    if (name.equals( "content-disposition")) {
+                        //return "form-data; name=\"file\"; filename*=utf-8''%c2%a3%20uploadedFileName.ext";
+                        //return "attachment; filename=genome.jpeg;";
+                        return "form-data; name=\"file\"; filename=\"uploadedFileName.ext\"";
+                    }
                     return null;
                 }
 
@@ -158,7 +163,7 @@
         assertEquals("keySet() is not empty!", 0, parameterParser.keySet().size());
 
         // Push this into the parser using DefaultParameterParser's add() method.
-        ((DefaultParameterParser) parameterParser).add("upload-field", test);
+        ((DefaultParameterParser) parameterParser).add("upload-field", mockTest);
 
         assertEquals("Part not found in keySet()!", 1, parameterParser.keySet().size());
 
@@ -185,6 +190,30 @@
         assertNull("The returned should be null because a String is not a Part", parameterParser.getPart( "other-field" ));
         Part uploadField = parameterParser.getPart( "upload-field" );
         assertTrue(uploadField.getName().equals( "upload-field" ));
+
+    }
+    
+    /**
+     * This Test method checks the DefaultParameterParser which filename convenience mapping from Part.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testFilename4Path() throws Exception
+    {
+        assertEquals("keySet() is not empty!", 0, parameterParser.keySet().size());
+        
+        // Push this into the parser using DefaultParameterParser's add() method.
+        ((DefaultParameterParser) parameterParser).add("upload-field", mockTest);
+        
+        assertTrue(parameterParser.containsKey("upload-field"));
+        
+        Part uploadField = parameterParser.getPart( "upload-field" );
+        assertEquals("upload-field", uploadField.getName());
+        
+        String fileName = parameterParser.getFileName( uploadField );
+        assertEquals("uploadedFileName.ext",fileName);
+        
     }
 
 }