From 353ccfb908425b1cceef5c43a883f760d79d140c Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Tue, 29 Apr 2008 13:59:28 +0000
Subject: [PATCH] LMS-401 first version

SVN: 5861
---
 dataset_download/.classpath                   |   1 +
 .../datasetdownload/ConfigParameters.java     |  16 +-
 .../DatasetDownloadService.java               |   2 +-
 .../DatasetDownloadServlet.java               | 164 +++++++++++++++++-
 .../HTMLDirectoryRenderer.java                | 126 ++++++++++++++
 .../datasetdownload/IDirectoryRenderer.java   |  44 +++++
 .../DatasetDownloadServletTest.java           |  83 ++++++++-
 7 files changed, 420 insertions(+), 16 deletions(-)
 create mode 100644 dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
 create mode 100644 dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java

diff --git a/dataset_download/.classpath b/dataset_download/.classpath
index af9bc418829..2127245367c 100644
--- a/dataset_download/.classpath
+++ b/dataset_download/.classpath
@@ -17,5 +17,6 @@
 	<classpathentry kind="lib" path="/libraries/jetty/jetty-util.jar" sourcepath="/libraries/jetty/src/jetty-util.zip"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/lims_base"/>
 	<classpathentry kind="lib" path="/libraries/commons-io/commons-io.jar" sourcepath="/libraries/commons-io/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/>
 	<classpathentry kind="output" path="targets/classes"/>
 </classpath>
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/ConfigParameters.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/ConfigParameters.java
index 8bd22c32a73..812e41c3712 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/ConfigParameters.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/ConfigParameters.java
@@ -25,6 +25,12 @@ import java.util.Properties;
  */
 class ConfigParameters
 {
+    static final String PASSWORD_KEY = "password";
+    static final String USERNAME_KEY = "username";
+    static final String SERVER_URL_KEY = "server-url";
+    static final String PORT_KEY = "port";
+    static final String STOREROOT_DIR_KEY = "storeroot-dir";
+
     private final String storePath;
     
     private final int port;
@@ -37,11 +43,11 @@ class ConfigParameters
     
     public ConfigParameters(Properties properties)
     {
-        storePath = properties.getProperty("storeroot-dir");
-        port = Integer.parseInt(properties.getProperty("port"));
-        serverURL = properties.getProperty("server-url");
-        userName = properties.getProperty("username");
-        password = properties.getProperty("password");
+        storePath = properties.getProperty(STOREROOT_DIR_KEY);
+        port = Integer.parseInt(properties.getProperty(PORT_KEY));
+        serverURL = properties.getProperty(SERVER_URL_KEY);
+        userName = properties.getProperty(USERNAME_KEY);
+        password = properties.getProperty(PASSWORD_KEY);
     }
 
     public final String getStorePath()
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadService.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadService.java
index f90b26fcb83..132d961e5d1 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadService.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadService.java
@@ -60,7 +60,7 @@ public class DatasetDownloadService
         Server server = new Server(applicationContext.getConfigParameters().getPort());
         Context context = new Context(server, "/", Context.SESSIONS);
         context.setAttribute(APPLICATION_CONTEXT_KEY, applicationContext);
-        context.addServlet(DatasetDownloadServlet.class, "/dataset-download");
+        context.addServlet(DatasetDownloadServlet.class, "/dataset-download/*");
         server.start();
         
         selfTest(applicationContext);
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 a57ebe73ad2..07dc928146c 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
@@ -18,27 +18,40 @@ package ch.systemsx.cisd.openbis.datasetdownload;
 
 import static ch.systemsx.cisd.openbis.datasetdownload.DatasetDownloadService.APPLICATION_CONTEXT_KEY;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.FileUtilities;
 import ch.systemsx.cisd.lims.base.ExternalData;
+import ch.systemsx.cisd.lims.base.LocatorType;
 
 /**
  * @author Franz-Josef Elmer
  */
 public class DatasetDownloadServlet extends HttpServlet
 {
+    static final String DATA_SET_ROOT_DIR_KEY = "data-set-root-dir";
+
+    static final String DATA_SET_KEY = "data-set";
+
     static final String DATASET_CODE_KEY = "dataSetCode";
     
     static final String SESSION_ID_KEY = "sessionID";
@@ -53,6 +66,15 @@ public class DatasetDownloadServlet extends HttpServlet
 
     private ApplicationContext applicationContext;
     
+    public DatasetDownloadServlet()
+    {
+    }
+
+    DatasetDownloadServlet(ApplicationContext applicationContext)
+    {
+        this.applicationContext = applicationContext;
+    }
+    
     @Override
     public final void init(final ServletConfig servletConfig) throws ServletException
     {
@@ -73,12 +95,144 @@ public class DatasetDownloadServlet extends HttpServlet
     protected final void doGet(final HttpServletRequest request, final HttpServletResponse response)
             throws ServletException, IOException
     {
-        final String dataSetCode = request.getParameter(DATASET_CODE_KEY);
-        final String sessionID = request.getParameter(SESSION_ID_KEY);
-        ExternalData dataSet = applicationContext.getDataSetService().getDataSet(sessionID, dataSetCode);
-        final PrintWriter writer = response.getWriter();
-        writer.write("<html><body>Download dataset " + dataSetCode + " (sessionID:" + sessionID + "):" + dataSet + "</body></html>");
+        try
+        {
+            obtainDataSetFromServer(request);
+            
+            HttpSession session = request.getSession(false);
+            if (session == null)
+            {
+                printSessionExpired(response);
+            } else
+            {
+                ExternalData dataSet = (ExternalData) session.getAttribute(DATA_SET_KEY);
+                File rootDir = (File) session.getAttribute(DATA_SET_ROOT_DIR_KEY);
+                String pathInfo = request.getPathInfo();
+                if (pathInfo != null && pathInfo.startsWith("/"))
+                {
+                    pathInfo = pathInfo.substring(1);
+                }
+                String requestURI = request.getRequestURI();
+                renderPage(response, dataSet, rootDir, requestURI, pathInfo);
+            }
+            
+        } catch (Exception e)
+        {
+            PrintWriter writer = response.getWriter();
+            writer.println("<html><body><h1>Error</h1>");
+            String message = e.getMessage();
+            writer.println(StringUtils.isBlank(message) ? e.toString() : message);
+            writer.println("</body></html>");
+            writer.flush();
+            writer.close();
+        }
+    }
+
+    private void renderPage(final HttpServletResponse response, ExternalData dataSet, File rootDir,
+            String requestURI, String relativePathOrNull) throws IOException
+    {
+        File file = rootDir;
+        String urlPrefix = requestURI;
+        String relativeParentPath = null;
+        if (relativePathOrNull != null && relativePathOrNull.length() > 0)
+        {
+            file = new File(rootDir, relativePathOrNull);
+            urlPrefix = requestURI.substring(0, requestURI.length() - relativePathOrNull.length());
+            relativeParentPath = FileUtilities.getRelativeFile(rootDir, file.getParentFile());
+            if (relativeParentPath == null)
+            {
+                relativeParentPath = "";
+            }
+        }
+        if (file.exists() == false)
+        {
+            throw new EnvironmentFailureException("File '" + file.getName() + "' does not exist.");
+        }
+        if (file.isDirectory())
+        {
+            IDirectoryRenderer directoryRenderer = new HTMLDirectoryRenderer(urlPrefix, relativePathOrNull);
+            response.setContentType(directoryRenderer.getContentType());
+            PrintWriter writer = response.getWriter();
+            directoryRenderer.setWriter(writer);
+            directoryRenderer.printHeader(dataSet);
+            if (relativeParentPath != null)
+            {
+                directoryRenderer.printLinkToParentDirectory(relativeParentPath);
+            }
+            File[] children = file.listFiles();
+            for (File child : children)
+            {
+                String name = child.getName();
+                String relativePath = FileUtilities.getRelativeFile(rootDir, child);
+                String normalizedRelativePath = relativePath.replace('\\', '/');
+                if (child.isDirectory())
+                {
+                    directoryRenderer.printDirectory(name, normalizedRelativePath);
+                } else
+                {
+                    directoryRenderer.printFile(name, normalizedRelativePath, child.length());
+                }
+            }
+            directoryRenderer.printFooter();
+            writer.flush();
+            writer.close();
+        } else
+        {
+            long size = file.length();
+            response.setContentLength((int) size);
+            response.setHeader("Content-Disposition", "inline; filename=" + file.getName());
+            ServletOutputStream outputStream = null;
+            FileInputStream fileInputStream = null;
+            try
+            {
+                outputStream = response.getOutputStream();
+                fileInputStream = new FileInputStream(file);
+                IOUtils.copy(fileInputStream, outputStream);
+                
+            } finally
+            {
+                IOUtils.closeQuietly(fileInputStream);
+                IOUtils.closeQuietly(outputStream);
+            }
+        }
+    }
+
+    private void printSessionExpired(final HttpServletResponse response) throws IOException
+    {
+        PrintWriter writer = response.getWriter();
+        writer.write("<html><body>Download session expired.</body></html>");
         writer.flush();
         writer.close();
     }
+
+    private void obtainDataSetFromServer(final HttpServletRequest request)
+    {
+        final String dataSetCode = request.getParameter(DATASET_CODE_KEY);
+        final String sessionID = request.getParameter(SESSION_ID_KEY);
+        if (dataSetCode != null && sessionID != null)
+        {
+            ExternalData dataSet = applicationContext.getDataSetService().getDataSet(sessionID, dataSetCode);
+            File dataSetRootDirectory = new File(createDataSetPath(dataSet));
+            if (dataSetRootDirectory.exists() == false)
+            {
+                throw new EnvironmentFailureException("Data set '" + dataSetCode
+                        + "' not found in store at '" + dataSetRootDirectory.getAbsolutePath()
+                        + "'.");
+            }
+            HttpSession session = request.getSession(true);
+            session.setAttribute(DATA_SET_KEY, dataSet);
+            session.setAttribute(DATA_SET_ROOT_DIR_KEY, dataSetRootDirectory);
+        }
+    }
+
+    private String createDataSetPath(ExternalData dataSet)
+    {
+        String location = dataSet.getLocation();
+        LocatorType locatorType = dataSet.getLocatorType();
+        if (locatorType.getCode().equals(LocatorType.DEFAULT_LOCATOR_TYPE_CODE))
+        {
+            return applicationContext.getConfigParameters().getStorePath() + "/" + location;
+        }
+        return location;
+    }
 }
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
new file mode 100644
index 00000000000..448eb6afdf1
--- /dev/null
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.datasetdownload;
+
+import java.io.PrintWriter;
+import java.text.DecimalFormat;
+
+import org.apache.commons.lang.StringUtils;
+
+import ch.systemsx.cisd.common.utilities.Template;
+import ch.systemsx.cisd.lims.base.ExternalData;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+class HTMLDirectoryRenderer implements IDirectoryRenderer
+{
+    private static final DecimalFormat FORMAT_KB = new DecimalFormat("0.0 KB");
+    private static final DecimalFormat FORMAT_MB = new DecimalFormat("0.0 MB");
+    private static final DecimalFormat FORMAT_GB = new DecimalFormat("0.0 GB");
+
+    private static final int UNIT_KB = 1024;
+
+    private static final int UNIT_MB = UNIT_KB * UNIT_KB;
+
+    private static final int UNIT_GB = UNIT_MB * UNIT_KB;
+
+    private static final Template ROW_TEMPLATE 
+        = new Template("<tr><td><a href='${path}'>${name}</td><td>${size}</td></tr>");
+    
+    private PrintWriter writer;
+
+    private final String urlPrefix;
+
+    private final String relativePathOrNull;
+
+    HTMLDirectoryRenderer(String urlPrefix, String relativePathOrNull)
+    {
+        this.relativePathOrNull = relativePathOrNull;
+        this.urlPrefix = urlPrefix.endsWith("/") ? urlPrefix : urlPrefix + "/";
+    }
+
+    public void setWriter(PrintWriter writer)
+    {
+        this.writer = writer;
+    }
+
+    public String getContentType()
+    {
+        return "text/html";
+    }
+
+    public void printHeader(ExternalData dataSet)
+    {
+        writer.println("<html><body>");
+        writer.println("<h1>Data Set " + dataSet.getCode() + "</h1>");
+        if (StringUtils.isNotBlank(relativePathOrNull))
+        {
+            writer.println("Folder: " + relativePathOrNull);
+        }
+        writer.println("<table border='0' cellpadding='5' cellspacing='0'>");
+    }
+    
+    public void printLinkToParentDirectory(String relativePath)
+    {
+        printRow("..", relativePath, "");
+    }
+
+    public void printDirectory(String name, String relativePath)
+    {
+        printRow(name, relativePath, "");
+    }
+    
+    public void printFile(String name, String relativePath, long size)
+    {
+        printRow(name, relativePath, renderFileSize(size));
+    }
+
+    private void printRow(String name, String relativePath, String fileSize)
+    {
+        Template template = ROW_TEMPLATE.createFreshCopy();
+        template.bind("path", urlPrefix + relativePath);
+        template.bind("name", name);
+        template.bind("size", fileSize);
+        writer.print(template.createText());
+    }
+    
+    private String renderFileSize(long size)
+    {
+        if (size < 10 * UNIT_KB)
+        {
+            return Long.toString(size) + " Bytes";
+        }
+        if (size < 10 * UNIT_MB)
+        {
+            return FORMAT_KB.format(size / (double) UNIT_KB);
+        }
+        if (size < 10 * UNIT_GB)
+        {
+            return FORMAT_MB.format(size / (double) UNIT_MB);
+        }
+        return FORMAT_GB.format(size / (double) UNIT_GB);
+    }
+
+    public void printFooter()
+    {
+        writer.println("</table></body></html>");
+    }
+
+}
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java
new file mode 100644
index 00000000000..a19803b6cc8
--- /dev/null
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.datasetdownload;
+
+import java.io.PrintWriter;
+
+import ch.systemsx.cisd.lims.base.ExternalData;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IDirectoryRenderer
+{
+    public String getContentType();
+    
+    public void setWriter(PrintWriter writer);
+    
+    public void printHeader(ExternalData dataSet);
+    
+    public void printLinkToParentDirectory(String relativePath);
+    
+    public void printDirectory(String name, String relativePath);
+    
+    public void printFile(String name, String relativePath, long size);
+    
+    public void printFooter();
+    
+}
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 0f3507ea1b7..e2a69c34785 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.File;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.Properties;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
 import org.apache.log4j.Level;
 import org.jmock.Expectations;
@@ -32,6 +35,11 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.logging.BufferedAppender;
+import ch.systemsx.cisd.common.utilities.FileUtilities;
+import ch.systemsx.cisd.common.utilities.OSUtilities;
+import ch.systemsx.cisd.lims.base.ExternalData;
+import ch.systemsx.cisd.lims.base.IDataSetService;
+import ch.systemsx.cisd.lims.base.LocatorType;
 
 
 /**
@@ -41,6 +49,16 @@ import ch.systemsx.cisd.common.logging.BufferedAppender;
  */
 public class DatasetDownloadServletTest 
 {
+    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 String EXAMPLE_SESSION_ID = "AV76CF";
+
+    private static final String EXAMPLE_DATA_SET_CODE = "1234-1";
+
     private BufferedAppender logRecorder;
     
     private Mockery context;
@@ -48,6 +66,10 @@ public class DatasetDownloadServletTest
     private HttpServletRequest request;
 
     private HttpServletResponse response;
+
+    private IDataSetService dataSetService;
+
+    private HttpSession httpSession;
     
     @BeforeMethod
     public void setUp()
@@ -56,12 +78,17 @@ public class DatasetDownloadServletTest
         context = new Mockery();
         request = context.mock(HttpServletRequest.class);
         response = context.mock(HttpServletResponse.class);
+        dataSetService = context.mock(IDataSetService.class);
+        httpSession = context.mock(HttpSession.class);
+        TEST_FOLDER.mkdirs();
+        EXAMPLE_DATA_SET_FOLDER.mkdir();
     }
 
     @AfterMethod
     public void tearDown()
     {
         logRecorder.reset();
+        FileUtilities.deleteRecursively(TEST_FOLDER);
         // To following line of code should also be called at the end of each test method.
         // Otherwise one do not known which test failed.
         context.assertIsSatisfied();
@@ -71,25 +98,71 @@ public class DatasetDownloadServletTest
     public void testDoGet() 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);
         context.checking(new Expectations()
             {
                 {
                     one(request).getParameter(DatasetDownloadServlet.DATASET_CODE_KEY);
-                    will(returnValue("1234-1"));
+                    will(returnValue(EXAMPLE_DATA_SET_CODE));
                     
                     one(request).getParameter(DatasetDownloadServlet.SESSION_ID_KEY);
-                    will(returnValue("AV76CF"));
+                    will(returnValue(EXAMPLE_SESSION_ID));
                     
                     one(response).getWriter();
                     will(returnValue(new PrintWriter(writer)));
+                    
+                    one(dataSetService).getDataSet(EXAMPLE_SESSION_ID, EXAMPLE_DATA_SET_CODE);
+                    will(returnValue(externalData));
+                    
+                    one(request).getSession(true);
+                    will(returnValue(httpSession));
+                    
+                    one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_KEY, externalData);
+                    one(httpSession).setAttribute(DatasetDownloadServlet.DATA_SET_ROOT_DIR_KEY, EXAMPLE_DATA_SET_FOLDER);
+                    
+                    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));
+                    
+                    one(request).getRequestURI();
+                    will(returnValue("uri"));
+                    
+                    one(response).setContentType("text/html");
                 }
             });
-        DatasetDownloadServlet servlet = new DatasetDownloadServlet();
-        servlet.init();
         
+        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());
         
-        assertEquals("<html><body>Download dataset 1234-1 (sessionID:AV76CF)</body></html>", writer.toString());
+        context.assertIsSatisfied();
+    }
+
+    private DatasetDownloadServlet createServlet()
+    {
+        Properties properties = new Properties();
+        properties.setProperty(ConfigParameters.STOREROOT_DIR_KEY, TEST_FOLDER.toString());
+        properties.setProperty(ConfigParameters.PORT_KEY, "8080");
+        properties.setProperty(ConfigParameters.SERVER_URL_KEY, "http://localhost");
+        properties.setProperty(ConfigParameters.USERNAME_KEY, "demo");
+        properties.setProperty(ConfigParameters.PASSWORD_KEY, "pwd");
+        ConfigParameters configParameters = new ConfigParameters(properties);
+        return new DatasetDownloadServlet(new ApplicationContext(dataSetService, configParameters));
     }
     
 }
-- 
GitLab