From 6e44eafd1df9de94fccb4b85424b4f04a91b2d32 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Tue, 6 May 2008 12:05:18 +0000
Subject: [PATCH] LMS-401 new line after table row in HTNLDirectoryRenderer,
 sorting of table, unit tests for servlet

SVN: 5915
---
 .../DatasetDownloadServlet.java               |  20 +-
 .../HTMLDirectoryRenderer.java                |   2 +-
 .../DatasetDownloadServletTest.java           | 311 +++++++++++++++---
 3 files changed, 292 insertions(+), 41 deletions(-)

diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
index 93c01d52e3c..69ddd24ce1a 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
@@ -23,6 +23,8 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Comparator;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -66,6 +68,19 @@ public class DatasetDownloadServlet extends HttpServlet
 
     protected static final Logger notificationLog =
             LogFactory.getLogger(LogCategory.NOTIFY, DatasetDownloadServlet.class);
+    
+    private static final Comparator<File> FILE_COMPARATOR = new Comparator<File>()
+        {
+            public int compare(File file1, File file2)
+            {
+                return createSortableName(file1).compareTo(createSortableName(file2));
+            }
+
+            private String createSortableName(File file)
+            {
+                return (file.isDirectory() ? "D" : "F") + file.getName().toUpperCase();
+            }
+        };
 
     private ApplicationContext applicationContext;
     
@@ -162,7 +177,7 @@ public class DatasetDownloadServlet extends HttpServlet
     {
         if (operationLog.isInfoEnabled())
         {
-            operationLog.info("For data set ' " + dataSet.getCode() + "' show directory "
+            operationLog.info("For data set '" + dataSet.getCode() + "' show directory "
                     + file.getAbsolutePath());
         }
         IDirectoryRenderer directoryRenderer = new HTMLDirectoryRenderer(renderingContext);
@@ -179,6 +194,7 @@ public class DatasetDownloadServlet extends HttpServlet
                 directoryRenderer.printLinkToParentDirectory(relativeParentPath);
             }
             File[] children = file.listFiles();
+            Arrays.sort(children, FILE_COMPARATOR);
             for (File child : children)
             {
                 String name = child.getName();
@@ -208,7 +224,7 @@ public class DatasetDownloadServlet extends HttpServlet
         long size = file.length();
         if (operationLog.isInfoEnabled())
         {
-            operationLog.info("For data set ' " + dataSet.getCode() + "' deliver file "
+            operationLog.info("For data set '" + dataSet.getCode() + "' deliver file "
                     + file.getAbsolutePath() + " (" + size + " bytes).");
         }
         response.setContentLength((int) size);
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
index da8bb4ad109..d0e8ab3c929 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
@@ -99,7 +99,7 @@ class HTMLDirectoryRenderer implements IDirectoryRenderer
         template.bind("path", urlPrefix + relativePath);
         template.bind("name", name);
         template.bind("size", fileSize);
-        writer.print(template.createText());
+        writer.println(template.createText());
     }
     
     private String renderFileSize(long size)
diff --git a/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java b/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
index 9eae4575f34..a6f0068797a 100644
--- a/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
+++ b/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
@@ -18,11 +18,14 @@ package ch.systemsx.cisd.openbis.datasetdownload;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Properties;
 
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -49,11 +52,30 @@ import ch.systemsx.cisd.lims.base.LocatorType;
  */
 public class DatasetDownloadServletTest 
 {
+    private static final String LOGGER_NAME =
+            "OPERATION.ch.systemsx.cisd.openbis.datasetdownload.DatasetDownloadServlet";
+
+    private static final String LOG_INFO = "INFO  " + LOGGER_NAME + " - ";
+    
+    private static final String LOG_ERROR = "ERROR " + LOGGER_NAME + " - ";
+
     private static final File TEST_FOLDER = new File("targets/unit-test/store");
     
     private static final String EXAMPLE_DATA_SET_FOLDER_NAME = "data-set-123";
 
-    private static final File EXAMPLE_DATA_SET_FOLDER = new File(TEST_FOLDER, EXAMPLE_DATA_SET_FOLDER_NAME);
+    private static final File EXAMPLE_DATA_SET_FOLDER =
+            new File(TEST_FOLDER, EXAMPLE_DATA_SET_FOLDER_NAME);
+    
+    private static final String EXAMPLE_FILE_NAME = "readme.txt";
+    
+    private static final File EXAMPLE_FILE = new File(EXAMPLE_DATA_SET_FOLDER, EXAMPLE_FILE_NAME);
+    
+    private static final String EXAMPLE_FILE_CONTENT = "Hello world!";
+    
+    private static final String EXAMPLE_DATA_SET_SUB_FOLDER_NAME = "sub";
+    
+    private static final File EXAMPLE_DATA_SET_SUB_FOLDER =
+            new File(EXAMPLE_DATA_SET_FOLDER, EXAMPLE_DATA_SET_SUB_FOLDER_NAME);
     
     private static final String EXAMPLE_SESSION_ID = "AV76CF";
 
@@ -82,6 +104,8 @@ public class DatasetDownloadServletTest
         httpSession = context.mock(HttpSession.class);
         TEST_FOLDER.mkdirs();
         EXAMPLE_DATA_SET_FOLDER.mkdir();
+        FileUtilities.writeToFile(EXAMPLE_FILE, EXAMPLE_FILE_CONTENT);
+        EXAMPLE_DATA_SET_SUB_FOLDER.mkdir();
     }
 
     @AfterMethod
@@ -93,67 +117,270 @@ public class DatasetDownloadServletTest
         // Otherwise one do not known which test failed.
         context.assertIsSatisfied();
     }
+    
+    @Test
+    public void testInitialDoGet() throws Exception
+    {
+        final StringWriter writer = new StringWriter();
+        final ExternalData externalData = createExternalData();
+        prepareForObtainingDataSetFromServer(externalData, true);
+        prepareForGettingDataSetFromSession(externalData, null);
+        prepareForCreatingHTML(writer);
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        assertEquals("<html><body>" + OSUtilities.LINE_SEPARATOR + "<h1>Data Set 1234-1</h1>"
+                + OSUtilities.LINE_SEPARATOR
+                + "<table border=\'0\' cellpadding=\'5\' cellspacing=\'0\'>"
+                + OSUtilities.LINE_SEPARATOR + "<tr><td><a href='download/sub'>sub</td><td></td></tr>"
+                + OSUtilities.LINE_SEPARATOR
+                + "<tr><td><a href='download/readme.txt'>readme.txt</td><td>12 Bytes</td></tr>"
+                + OSUtilities.LINE_SEPARATOR + "</table></body></html>"
+                + OSUtilities.LINE_SEPARATOR, writer.toString());
+        assertEquals(LOG_INFO + "Data set '1234-1' obtained from openBIS server."
+                + OSUtilities.LINE_SEPARATOR + LOG_INFO
+                + "For data set '1234-1' show directory <wd>/data-set-123",
+                getNormalizedLogContent());
+        
+        context.assertIsSatisfied();
+    }
 
     @Test
-    public void testDoGet() throws Exception
+    public void testInitialDoGetButDataSetNotFoundInStore() throws Exception
     {
         final StringWriter writer = new StringWriter();
-        final ExternalData externalData = new ExternalData();
-        externalData.setCode(EXAMPLE_DATA_SET_CODE);
-        externalData.setLocatorType(new LocatorType(LocatorType.DEFAULT_LOCATOR_TYPE_CODE));
-        externalData.setLocation(EXAMPLE_DATA_SET_FOLDER_NAME);
+        final ExternalData externalData = createExternalData();
+        externalData.setLocatorType(new LocatorType("unknown"));
+        prepareForObtainingDataSetFromServer(externalData, false);
         context.checking(new Expectations()
             {
                 {
-                    one(request).getParameter(DatasetDownloadServlet.DATASET_CODE_KEY);
-                    will(returnValue(EXAMPLE_DATA_SET_CODE));
-                    
-                    one(request).getParameter(DatasetDownloadServlet.SESSION_ID_KEY);
-                    will(returnValue(EXAMPLE_SESSION_ID));
-                    
                     one(response).getWriter();
                     will(returnValue(new PrintWriter(writer)));
+                }
+            });
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        String pageContent = writer.toString();
+        String snippet = "Data set '1234-1' not found in store";
+        assertEquals("Text snippet >" + snippet + "< not found in following page content: "
+                + pageContent, true, pageContent.indexOf(snippet) > 0);
+        String logContent = logRecorder.getLogContent();
+        assertEquals("Text snippet >" + snippet + "< not found in following page content: "
+                + logContent, true, logContent.indexOf(snippet) > 0);
+        
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testDoGetSubFolder() throws Exception
+    {
+        final StringWriter writer = new StringWriter();
+        final ExternalData externalData = createExternalData();
+        prepareForNotObtainingDataSetFromServer();
+        prepareForGettingDataSetFromSession(externalData, EXAMPLE_DATA_SET_SUB_FOLDER_NAME);
+        prepareForCreatingHTML(writer);
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        assertEquals("<html><body>" + OSUtilities.LINE_SEPARATOR + "<h1>Data Set 1234-1</h1>"
+                + OSUtilities.LINE_SEPARATOR + "Folder: sub"
+                + OSUtilities.LINE_SEPARATOR
+                + "<table border=\'0\' cellpadding=\'5\' cellspacing=\'0\'>"
+                + OSUtilities.LINE_SEPARATOR + "<tr><td><a href='download/'>..</td><td></td></tr>"  
+                + OSUtilities.LINE_SEPARATOR + "</table></body></html>"
+                + OSUtilities.LINE_SEPARATOR, writer.toString());
+        assertEquals(LOG_INFO + "For data set '1234-1' show directory <wd>/data-set-123/sub",
+                getNormalizedLogContent());
+        
+        context.assertIsSatisfied();
+    }
+    
+    @Test
+    public void testDoGetFile() throws Exception
+    {
+        final ExternalData externalData = createExternalData();
+        prepareForNotObtainingDataSetFromServer();
+        prepareForGettingDataSetFromSession(externalData, EXAMPLE_FILE_NAME);
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        context.checking(new Expectations()
+            {
+                {
+                    one(response).setContentLength(EXAMPLE_FILE_CONTENT.length());
+                    one(response).setHeader("Content-Disposition",
+                            "inline; filename=" + EXAMPLE_FILE_NAME);
+                    one(response).getOutputStream();
+                    will(returnValue(new ServletOutputStream()
+                        {
+                            @Override
+                            public void write(int b) throws IOException
+                            {
+                                outputStream.write(b);
+                            }
+                        }));
+                }
+            });
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        assertEquals("Hello world!", outputStream.toString());
+        assertEquals(LOG_INFO
+                + "For data set '1234-1' deliver file <wd>/data-set-123/readme.txt (12 bytes).",
+                getNormalizedLogContent());
+        
+        context.assertIsSatisfied();
+    }
+    
+    @Test
+    public void testDoGetNonExistingFile() throws Exception
+    {
+        final StringWriter writer = new StringWriter();
+        final ExternalData externalData = createExternalData();
+        prepareForNotObtainingDataSetFromServer();
+        prepareForGettingDataSetFromSession(externalData, "blabla");
+        context.checking(new Expectations()
+            {
+                {
+                    one(request).getRequestURL();
+                    will(returnValue(new StringBuffer("requestURL")));
                     
-                    one(dataSetService).getDataSet(EXAMPLE_SESSION_ID, EXAMPLE_DATA_SET_CODE);
-                    will(returnValue(externalData));
-                    
-                    one(request).getSession(true);
-                    will(returnValue(httpSession));
-                    
-                    one(httpSession).setMaxInactiveInterval(120);
-                    one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_KEY, externalData);
-                    one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_ROOT_DIR_KEY, EXAMPLE_DATA_SET_FOLDER);
-                    
+                    one(request).getQueryString();
+                    will(returnValue("queryString"));
+
+                    one(response).getWriter();
+                    will(returnValue(new PrintWriter(writer)));
+                }
+            });
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        assertEquals("<html><body><h1>Error</h1>" + OSUtilities.LINE_SEPARATOR
+                + "File 'blabla' does not exist." + OSUtilities.LINE_SEPARATOR + "</body></html>"
+                + OSUtilities.LINE_SEPARATOR, writer.toString());
+        String logContent = getNormalizedLogContent();
+        assertEquals("The following string does not start as expected: " + logContent, true,
+                logContent.startsWith(LOG_ERROR
+                        + "Request requestURL?queryString caused an exception:"));
+        
+        context.assertIsSatisfied();
+    }
+    
+    @Test
+    public void testDoGetForExpiredSession() throws Exception
+    {
+        final StringWriter writer = new StringWriter();
+        prepareForNotObtainingDataSetFromServer();
+        context.checking(new Expectations()
+            {
+                {
+                    one(request).getSession(false);
+                    will(returnValue(null));
+
+                    one(response).getWriter();
+                    will(returnValue(new PrintWriter(writer)));
+                }
+            });
+        
+        DatasetDownloadServlet servlet = createServlet();
+        servlet.doGet(request, response);
+        assertEquals("<html><body>Download session expired.</body></html>", writer.toString());
+        assertEquals("", getNormalizedLogContent());
+        
+        context.assertIsSatisfied();
+    }
+
+    private void prepareForGettingDataSetFromSession(final ExternalData externalData,
+            final String path)
+    {
+        context.checking(new Expectations()
+            {
+                {
                     one(request).getSession(false);
                     will(returnValue(httpSession));
-                    
+
                     one(httpSession).getAttribute(DatasetDownloadServlet.DATA_SET_KEY);
                     will(returnValue(externalData));
-                    
+
                     one(httpSession).getAttribute(DatasetDownloadServlet.DATA_SET_ROOT_DIR_KEY);
                     will(returnValue(EXAMPLE_DATA_SET_FOLDER));
-                    
+
                     one(request).getPathInfo();
-                    will(returnValue(null));
-                    
+                    will(returnValue(path));
+
                     one(request).getRequestURI();
-                    will(returnValue("uri"));
+                    will(returnValue("download/" + (path == null ? "" : path)));
+
+                }
+            });
+    }
+    
+    private void prepareForNotObtainingDataSetFromServer()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(request).getParameter(DatasetDownloadServlet.DATASET_CODE_KEY);
+                    will(returnValue(EXAMPLE_DATA_SET_CODE));
+
+                    one(request).getParameter(DatasetDownloadServlet.SESSION_ID_KEY);
+                    will(returnValue(null));
+                }
+            });
+    }
+
+    private void prepareForObtainingDataSetFromServer(final ExternalData externalData,
+            final boolean fileExists)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(request).getParameter(DatasetDownloadServlet.DATASET_CODE_KEY);
+                    will(returnValue(EXAMPLE_DATA_SET_CODE));
+
+                    one(request).getParameter(DatasetDownloadServlet.SESSION_ID_KEY);
+                    will(returnValue(EXAMPLE_SESSION_ID));
+
+                    one(dataSetService).getDataSet(EXAMPLE_SESSION_ID, EXAMPLE_DATA_SET_CODE);
+                    will(returnValue(externalData));
+
+                    if (fileExists)
+                    {
+                        one(request).getSession(true);
+                        will(returnValue(httpSession));
+
+                        one(httpSession).setMaxInactiveInterval(120);
+                        one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_KEY,
+                                externalData);
+                        one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_ROOT_DIR_KEY,
+                                EXAMPLE_DATA_SET_FOLDER);
+                    }
+                }
+            });
+    }
+    
+    private void prepareForCreatingHTML(final StringWriter writer) throws IOException
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(response).getWriter();
+                    will(returnValue(new PrintWriter(writer)));
                     
                     one(response).setContentType("text/html");
                 }
             });
-        
-        DatasetDownloadServlet servlet = createServlet();
-        servlet.doGet(request, response);
-        assertEquals("<html><body>" + OSUtilities.LINE_SEPARATOR + "<h1>Data Set 1234-1</h1>"
-                + OSUtilities.LINE_SEPARATOR
-                + "<table border=\'0\' cellpadding=\'5\' cellspacing=\'0\'>"
-                + OSUtilities.LINE_SEPARATOR + "</table></body></html>"
-                + OSUtilities.LINE_SEPARATOR, writer.toString());
-        
-        context.assertIsSatisfied();
     }
 
+    private ExternalData createExternalData()
+    {
+        final ExternalData externalData = new ExternalData();
+        externalData.setCode(EXAMPLE_DATA_SET_CODE);
+        externalData.setLocatorType(new LocatorType(LocatorType.DEFAULT_LOCATOR_TYPE_CODE));
+        externalData.setLocation(EXAMPLE_DATA_SET_FOLDER_NAME);
+        return externalData;
+    }
+    
     private DatasetDownloadServlet createServlet()
     {
         Properties properties = new Properties();
@@ -167,4 +394,12 @@ public class DatasetDownloadServletTest
         return new DatasetDownloadServlet(new ApplicationContext(dataSetService, configParameters));
     }
     
+    private String getNormalizedLogContent()
+    {
+        String logContent = logRecorder.getLogContent();
+        logContent = logContent.replace(TEST_FOLDER.getAbsolutePath(), "<wd>");
+        logContent = logContent.replace('\\', '/');
+        return logContent;
+    }
+
 }
-- 
GitLab