Bug 518093 - Unable to deploy via web interface when file's path is part of the file name
diff --git a/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java b/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
index eacbce0..3be4788 100644
--- a/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
+++ b/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
@@ -10,13 +10,13 @@
  *******************************************************************************/
 package org.eclipse.virgo.management.console;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.management.ManagementFactory;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
@@ -27,136 +27,152 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
- * 
+ *
  *
  */
 public class UploadServlet extends HttpServlet {
 
-	private static final String[] DEPLOYMENT_IDENTITY_FIELDS = new String[]{"type", "symbolicName", "version"};
+    private static final String[] DEPLOYMENT_IDENTITY_FIELDS = new String[]{"type", "symbolicName", "version"};
 
-	private static final int HTTP_RESPONSE_INTERNAL_SERVER_ERROR = 500;
+    private static final int HTTP_RESPONSE_INTERNAL_SERVER_ERROR = 500;
 
     private static final String ORG_ECLIPSE_VIRGO_KERNEL_HOME = "org.eclipse.virgo.kernel.home";
-    
+
     private static final String DEPLOYER_MBEAN_NAME = "org.eclipse.virgo.kernel:category=Control,type=Deployer";
-	
-	private static final long serialVersionUID = 1L;
-	
-	private static final String STAGING_DIR = "/work/org.eclipse.virgo.apps.admin.web.UploadServlet";
-	
-	private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
 
-	private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
-	
-	private String serverHome = null;
-	
-	private BundleContext bundleContext = null;
+    private static final long serialVersionUID = 1L;
 
-	public UploadServlet() {
-	}
-	
-	public UploadServlet(BundleContext bundleContext) {
-		this.bundleContext = bundleContext;
-	}
+    private static final String STAGING_DIR = "/work/org.eclipse.virgo.apps.admin.web.UploadServlet";
 
-	/**
-	 * Do not use this method with the HTTPService unless the BundleContext has already been set.
-	 */
-    public void init(ServletConfig config) throws ServletException {
-    	super.init(config);
-    	if(bundleContext == null){
-    		this.bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
-    	}
-		this.serverHome = this.bundleContext.getProperty(ORG_ECLIPSE_VIRGO_KERNEL_HOME);
+    private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
+
+    private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+
+    private String serverHome = null;
+
+    private BundleContext bundleContext = null;
+
+    public UploadServlet() {
     }
-	
-	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
-		try {
-		    File stagingDir = createStagingDirectory();
-			FileItemFactory factory = new DiskFileItemFactory();
-			ServletFileUpload upload = new ServletFileUpload(factory);
-		    response.setContentType("text/html");
-			List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
-			List<File> uploadedFiles = new ArrayList<File>();
-			for (FileItem fileItem : items) {
-				File uploadedFile = this.doUpload(fileItem, stagingDir);
-				if(uploadedFile != null){
-					uploadedFiles.add(uploadedFile);
-				}
-			}
-			doDeployment(uploadedFiles, response);
-		} catch (IllegalArgumentException ea){
-		    PrintWriter writer = response.getWriter();
-	        writer.append("<ol id=\"uploadResults\"><li>File name contains '/' or '\\', this is not allowed.</ol>");
-			writer.close();
-		} catch (Exception e) {
-		    log.error(e.toString());
-			response.sendError(HTTP_RESPONSE_INTERNAL_SERVER_ERROR, e.toString());
-		}
-	}
-	
-	File doUpload(FileItem fileItem, File stagingDir) throws Exception{
-		if (!fileItem.isFormField()) {
-			String name = fileItem.getName();
-			if(name != null && name.length() > 0){
-				if(name.contains("\\") || name.contains("/")){
-					throw new IllegalArgumentException("Security violation, file name contains '/' or '\\'");
-				}
-				File uploadedFile = new File(stagingDir, name);
-				fileItem.write(uploadedFile);
-				log.info(String.format("Uploaded artifact of size (%db) to %s", fileItem.getSize(), uploadedFile.getPath()));
-				return uploadedFile;
-			}
-		}
-		return null;
-	}
-	
-	private void doDeployment(List<File> uploadedFiles, HttpServletResponse response) throws MalformedObjectNameException, NullPointerException, IOException{
-		ObjectName objectName = new ObjectName(DEPLOYER_MBEAN_NAME);
-	    PrintWriter writer = response.getWriter();
+
+    public UploadServlet(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    /**
+     * Do not use this method with the HTTPService unless the BundleContext has already been set.
+     */
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        if (bundleContext == null) {
+            this.bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
+        }
+        this.serverHome = this.bundleContext.getProperty(ORG_ECLIPSE_VIRGO_KERNEL_HOME);
+    }
+
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        try {
+            File stagingDir = createStagingDirectory();
+            FileItemFactory factory = new DiskFileItemFactory();
+            ServletFileUpload upload = new ServletFileUpload(factory);
+            response.setContentType("text/html");
+            List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
+            List<File> uploadedFiles = new ArrayList<File>();
+            for (FileItem fileItem : items) {
+                File uploadedFile = this.doUpload(fileItem, stagingDir);
+                if (uploadedFile != null) {
+                    uploadedFiles.add(uploadedFile);
+                }
+            }
+            doDeployment(uploadedFiles, response);
+        } catch (IllegalArgumentException ea) {
+            PrintWriter writer = response.getWriter();
+            writer.append("<ol id=\"uploadResults\"><li>File name contains '/' or '\\', this is not allowed.</ol>");
+            writer.close();
+        } catch (Exception e) {
+            log.error(e.toString());
+            response.sendError(HTTP_RESPONSE_INTERNAL_SERVER_ERROR, e.toString());
+        }
+    }
+
+    File doUpload(FileItem fileItem, File stagingDir) throws Exception {
+        if (!fileItem.isFormField()) {
+            String name = fileItem.getName();
+            if (name != null && name.length() > 0) {
+                if (name.contains("\\") || name.contains("/")) {
+                    name = getFileNameFromPath(name);
+                }
+                File uploadedFile = new File(stagingDir, name);
+                fileItem.write(uploadedFile);
+                log.info(String.format("Uploaded artifact of size (%db) to %s", fileItem.getSize(), uploadedFile.getPath()));
+                return uploadedFile;
+            }
+        }
+        return null;
+    }
+
+    private String getFileNameFromPath(String fileName) {
+
+        String strippedFileName = fileName;
+
+        if (fileName.contains("\\") && fileName.contains("/")) {
+            throw new IllegalArgumentException("Security violation, file name contains '/' and '\\'");
+        } else if (fileName.contains("\\")) {
+            String[] fileNameParts = fileName.split("\\\\");
+            strippedFileName = fileNameParts[fileNameParts.length - 1];
+        } else if (fileName.contains("/")) {
+            String[] fileNameParts = fileName.split("/");
+            strippedFileName = fileNameParts[fileNameParts.length - 1];
+        }
+
+        return strippedFileName;
+    }
+
+    private void doDeployment(List<File> uploadedFiles, HttpServletResponse response) throws MalformedObjectNameException, NullPointerException, IOException {
+        ObjectName objectName = new ObjectName(DEPLOYER_MBEAN_NAME);
+        PrintWriter writer = response.getWriter();
         writer.append("<ol id=\"uploadResults\">");
         for (File file : uploadedFiles) {
-			URI uri = file.toURI();
-			try {
-				Object invoke = this.mBeanServer.invoke(objectName, "deploy", new Object[]{uri.toString()}, new String[]{String.class.getName()});
-				writer.append("<li>" + file.getName() + " deployed as " + getDeploymentIdentity(invoke) + "</li>");
-			} catch (Exception e) {
-				writer.append("<li>" + file.getName() + " failed to deploy '" + e.getMessage() + "'</li>");
-			}
-			writer.append("<li />");
-		}
+            URI uri = file.toURI();
+            try {
+                Object invoke = this.mBeanServer.invoke(objectName, "deploy", new Object[]{uri.toString()}, new String[]{String.class.getName()});
+                writer.append("<li>" + file.getName() + " deployed as " + getDeploymentIdentity(invoke) + "</li>");
+            } catch (Exception e) {
+                writer.append("<li>" + file.getName() + " failed to deploy '" + e.getMessage() + "'</li>");
+            }
+            writer.append("<li />");
+        }
         writer.append("</ol>");
-		writer.close();
-	}
-	
-	private String getDeploymentIdentity(Object deploymentIdentity) {
-		StringBuilder builder = new StringBuilder();
-		if(deploymentIdentity instanceof CompositeDataSupport){
-			CompositeDataSupport deploymentIdentityInstance = (CompositeDataSupport) deploymentIdentity;
-			Object[] all = deploymentIdentityInstance.getAll(DEPLOYMENT_IDENTITY_FIELDS);
-			builder.append(all[0]);
-			builder.append(" - ").append(all[1]);
-			builder.append(": ").append(all[2]);
-		}
-		return builder.toString();
-	}
+        writer.close();
+    }
+
+    private String getDeploymentIdentity(Object deploymentIdentity) {
+        StringBuilder builder = new StringBuilder();
+        if (deploymentIdentity instanceof CompositeDataSupport) {
+            CompositeDataSupport deploymentIdentityInstance = (CompositeDataSupport) deploymentIdentity;
+            Object[] all = deploymentIdentityInstance.getAll(DEPLOYMENT_IDENTITY_FIELDS);
+            builder.append(all[0]);
+            builder.append(" - ").append(all[1]);
+            builder.append(": ").append(all[2]);
+        }
+        return builder.toString();
+    }
 
     private File createStagingDirectory() throws IOException {
         File pathReference = new File(String.format("%s%s", this.serverHome, STAGING_DIR));
         if (!pathReference.exists()) {
-        	if (!pathReference.mkdirs()) {
-        		throw new IOException("Unable to create directory " + pathReference.getAbsolutePath());
-        	}
+            if (!pathReference.mkdirs()) {
+                throw new IOException("Unable to create directory " + pathReference.getAbsolutePath());
+            }
         }
         return pathReference.getAbsoluteFile();
     }
diff --git a/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java b/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
index ca6c9f5..884d821 100644
--- a/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
+++ b/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
@@ -10,43 +10,68 @@
  *******************************************************************************/
 package org.eclipse.virgo.management.console;
 
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-import java.io.IOException;
-
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.disk.DiskFileItem;
 import org.junit.Test;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 public class UploadServletTests {
 
-	@Test
-	public void testDoPost() throws IOException {
-		UploadServlet uploadServlet = new UploadServlet();
-		MockHttpServletRequest request = new MockHttpServletRequest("POST", null);
-		uploadServlet.doPost(request, new MockHttpServletResponse());
-	}
-	
-	@Test(expected=RuntimeException.class)
-	public void testDoUploadFail() throws Exception {
-		UploadServlet uploadServlet = new UploadServlet();
-		FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources/test.upload", 500, new File("build"));
-		File stagingDir = new File("build");
-		fileItem.getOutputStream();
-		uploadServlet.doUpload(fileItem, stagingDir);
-	}
-	
-	@Test
-	public void testDoUpload() throws Exception {
-		UploadServlet uploadServlet = new UploadServlet();
-		FileItem fileItem = new DiskFileItem("foo", "json/application", false, "test.upload", 500, new File("build"));
-		File stagingDir = new File("src/test/resources");
-		fileItem.getOutputStream();
-		File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
-		assertNotNull(doUpload);
-	}
+    @Test
+    public void testDoPost() throws IOException {
+        UploadServlet uploadServlet = new UploadServlet();
+        MockHttpServletRequest request = new MockHttpServletRequest("POST", null);
+        uploadServlet.doPost(request, new MockHttpServletResponse());
+    }
 
+    @Test(expected = RuntimeException.class)
+    public void testDoUploadFail() throws Exception {
+        UploadServlet uploadServlet = new UploadServlet();
+        FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources\\test.upload", 500, new File("build"));
+        File stagingDir = new File("build");
+        fileItem.getOutputStream();
+        uploadServlet.doUpload(fileItem, stagingDir);
+    }
+
+    @Test
+    public void testDoUpload() throws Exception {
+        UploadServlet uploadServlet = new UploadServlet();
+        FileItem fileItem = new DiskFileItem("foo", "json/application", false, "test.upload", 500, new File("build"));
+        File stagingDir = new File("src/test/resources");
+        fileItem.getOutputStream();
+        File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+        assertNotNull(doUpload);
+        assertTrue("test.upload".equals(doUpload.getName()));
+    }
+
+    @Test
+    public void testDoUploadWithFullPathUnix() throws Exception {
+        UploadServlet uploadServlet = new UploadServlet();
+        FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources/test.upload", 500, new File("build"));
+        File stagingDir = new File("src/test/resources");
+        fileItem.getOutputStream();
+        File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+        System.out.println(doUpload.getName());
+        assertNotNull(doUpload);
+        assertTrue("test.upload".equals(doUpload.getName()));
+    }
+
+
+    @Test
+    public void testDoUploadWithFullPathWin() throws Exception {
+        UploadServlet uploadServlet = new UploadServlet();
+        FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src\\test\\resources\\test.upload", 500, new File("build"));
+        File stagingDir = new File("src/test/resources");
+        fileItem.getOutputStream();
+        File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+        assertNotNull(doUpload);
+        assertTrue("test.upload".equals(doUpload.getName()));
+    }
 }