From 77f685beb2350bd224a0011626f6dffa17b50b1d Mon Sep 17 00:00:00 2001
From: tpylak <tpylak>
Date: Fri, 27 Feb 2009 13:09:15 +0000
Subject: [PATCH] LMS-733 Use client OS newline characters for exporting

SVN: 10036
---
 .../cisd/common/utilities/OSUtilities.java    | 23 ++++++-
 .../web/client/ICommonClientService.java      | 11 ++--
 .../web/client/ICommonClientServiceAsync.java |  5 +-
 .../web/server/CommonClientService.java       | 10 +--
 .../web/server/FileExportServiceServlet.java  |  7 ++-
 .../client/web/server/util/HttpUtils.java     | 61 +++++++++++++++++++
 .../client/web/server/util/TSVRenderer.java   | 25 +++++---
 .../ui/sample/ExportSamplesTestCommand.java   |  8 ++-
 .../web/server/util/TSVRendererTest.java      |  6 +-
 9 files changed, 129 insertions(+), 27 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/HttpUtils.java

diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/OSUtilities.java b/common/source/java/ch/systemsx/cisd/common/utilities/OSUtilities.java
index ac6223d51bc..cd1c7ea793d 100644
--- a/common/source/java/ch/systemsx/cisd/common/utilities/OSUtilities.java
+++ b/common/source/java/ch/systemsx/cisd/common/utilities/OSUtilities.java
@@ -84,7 +84,7 @@ public class OSUtilities
     {
         return System.getProperty("os.arch");
     }
-    
+
     /**
      * @return The name of the operating system.
      */
@@ -92,7 +92,7 @@ public class OSUtilities
     {
         return System.getProperty("os.name");
     }
-    
+
     /**
      * @return The name of the computer platform (CPU architecture and OS name).
      */
@@ -254,4 +254,23 @@ public class OSUtilities
         }
     }
 
+    public enum OSKind
+    {
+        MAC, WINDOWS, UNIX, OTHER
+    }
+
+    public static final String getLineSeparator(OSKind osKind)
+    {
+        switch (osKind)
+        {
+            case MAC:
+            case OTHER:
+            case UNIX:
+                return "/n";
+            case WINDOWS:
+                return "/t/n";
+            default:
+                throw new IllegalStateException("unknown os " + osKind);
+        }
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index 6532e7c4ac2..c5392d53302 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -118,7 +118,7 @@ public interface ICommonClientService extends IClientService
 
     /**
      * Returns a key which can be used be the export servlet (and eventually
-     * {@link #getExportTable(String)}) to reference the export criteria in an easy way.
+     * {@link #getExportTable(String, String)}) to reference the export criteria in an easy way.
      */
     public String prepareExportSamples(final TableExportCriteria<Sample> criteria)
             throws UserFailureException;
@@ -215,11 +215,12 @@ public interface ICommonClientService extends IClientService
             throws UserFailureException;
 
     /**
-     * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)}
-     * or {@link #prepareExportExperiments(TableExportCriteria)} has been invoked before and
-     * returned with an exportDataKey passed here as a parameter.
+     * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)} or
+     * {@link #prepareExportExperiments(TableExportCriteria)} has been invoked before and returned
+     * with an exportDataKey passed here as a parameter.
      */
-    public String getExportTable(String exportDataKey) throws UserFailureException;
+    public String getExportTable(String exportDataKey, String lineSeparator)
+            throws UserFailureException;
 
     /**
      * Removes the session result set associated with given key.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index 1eeb6ba9f8e..ab41fe46718 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -173,9 +173,10 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
             AsyncCallback<String> callback);
 
     /**
-     * @see ICommonClientService#getExportTable(String)
+     * @see ICommonClientService#getExportTable(String, String)
      */
-    public void getExportTable(String exportDataKey, AsyncCallback<String> asyncCallback);
+    public void getExportTable(String exportDataKey, String lineSeparator,
+            AsyncCallback<String> asyncCallback);
 
     /**
      * @see ICommonClientService#removeResultSet(String)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index ebef698c602..3bb5f5451b9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -108,6 +108,7 @@ public final class CommonClientService extends AbstractClientService implements
         ICommonClientService
 {
     private final ICommonServer commonServer;
+
     private final String dataStoreBaseURL;
 
     public CommonClientService(final ICommonServer commonServer,
@@ -204,13 +205,14 @@ public final class CommonClientService extends AbstractClientService implements
      * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)}
      * has been invoked before and returned with an exportDataKey passed here as a parameter.
      */
-    public final String getExportTable(final String exportDataKey)
+    public final String getExportTable(final String exportDataKey, final String lineSeparator)
     {
         // NOTE: no generics in GWT
-        return getGenericExportTable(exportDataKey);
+        return getGenericExportTable(exportDataKey, lineSeparator);
     }
 
-    private final <T> String getGenericExportTable(final String exportDataKey)
+    private final <T> String getGenericExportTable(final String exportDataKey,
+            final String lineSeparator)
     {
         try
         {
@@ -218,7 +220,7 @@ public final class CommonClientService extends AbstractClientService implements
             getSessionToken();
             final TableExportCriteria<T> exportCriteria = getAndRemoveExportCriteria(exportDataKey);
             final List<T> entities = fetchCachedEntities(exportCriteria);
-            return TSVRenderer.createTable(entities, exportCriteria.getColumnDefs());
+            return TSVRenderer.createTable(entities, exportCriteria.getColumnDefs(), lineSeparator);
         } catch (final UserFailureException e)
         {
             throw UserFailureExceptionTranslator.translate(e);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/FileExportServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/FileExportServiceServlet.java
index 65878c5b452..b34fd04621e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/FileExportServiceServlet.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/FileExportServiceServlet.java
@@ -23,8 +23,11 @@ import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.common.utilities.OSUtilities;
+import ch.systemsx.cisd.common.utilities.OSUtilities.OSKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientService;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.server.util.HttpUtils;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
 /**
@@ -46,7 +49,9 @@ public class FileExportServiceServlet extends AbstractFileDownloadServlet
 
         if (StringUtils.isNotBlank(exportDataKey))
         {
-            String fileContent = service.getExportTable(exportDataKey);
+            OSKind osKind = HttpUtils.figureOperatingSystemKind(request);
+            String lineSeparator = OSUtilities.getLineSeparator(osKind);
+            String fileContent = service.getExportTable(exportDataKey, lineSeparator);
             byte[] value = fileContent.getBytes();
             String fileName = "exportedData.txt";
             return new FileContent(value, fileName);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/HttpUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/HttpUtils.java
new file mode 100644
index 00000000000..871cb8cdb46
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/HttpUtils.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2009 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.generic.client.web.server.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+import ch.systemsx.cisd.common.utilities.OSUtilities.OSKind;
+
+/**
+ * Some utilities around <i>Http</i>.
+ * 
+ * @author Tomasz Pylak
+ */
+public final class HttpUtils
+{
+    public static final OSKind figureOperatingSystemKind(final HttpServletRequest request)
+    {
+        String userAgent = request.getHeader("user-agent");
+        return figureOperatingSystemKind(userAgent);
+    }
+
+    private static OSKind figureOperatingSystemKind(String userAgent)
+    {
+        if (userAgent.indexOf("Win") != -1)
+        {
+            return OSKind.WINDOWS;
+        } else if (userAgent.indexOf("Mac") != -1)
+        {
+            return OSKind.MAC;
+        } else if (userAgent.indexOf("OpenBSD") != -1)
+        {
+            return OSKind.UNIX;
+        } else if (userAgent.indexOf("SunOS") != -1)
+        {
+            return OSKind.UNIX;
+        } else if (userAgent.indexOf("Linux") != -1)
+        {
+            return OSKind.UNIX;
+        } else if (userAgent.indexOf("X11") != -1)
+        {
+            return OSKind.UNIX;
+        } else
+        {
+            return OSKind.OTHER;
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRenderer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRenderer.java
index 42d933e4691..80ff3d91849 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRenderer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRenderer.java
@@ -29,14 +29,21 @@ public class TSVRenderer
 {
     private static final String TAB = "\t";
 
-    private static final String NEWLINE = "\n";
+    private final String lineSeparator;
 
     /**
      * @param entities list of entities which will be exported
      * @param columnDefs column definitions. Each definition know column's header and is able to
      *            extract an appropriate value from the entity.
+     * @param lineSeparator character used as a lineSeparator separator
      */
-    public static <T> String createTable(List<T> entities, List<IColumnDefinition<T>> columnDefs)
+    public static <T> String createTable(List<T> entities, List<IColumnDefinition<T>> columnDefs,
+            String lineSeparator)
+    {
+        return new TSVRenderer(lineSeparator).createTable(entities, columnDefs);
+    }
+
+    private <T> String createTable(List<T> entities, List<IColumnDefinition<T>> columnDefs)
     {
         StringBuffer sb = new StringBuffer();
         appendHeader(columnDefs, sb);
@@ -47,8 +54,12 @@ public class TSVRenderer
         return sb.toString();
     }
 
-    private static <T> void appendEntity(T entity, List<IColumnDefinition<T>> columnDefs,
-            StringBuffer sb)
+    private TSVRenderer(String lineSeparator)
+    {
+        this.lineSeparator = lineSeparator;
+    }
+
+    private <T> void appendEntity(T entity, List<IColumnDefinition<T>> columnDefs, StringBuffer sb)
     {
         boolean isFirst = true;
         for (IColumnDefinition<T> column : columnDefs)
@@ -62,10 +73,10 @@ public class TSVRenderer
             }
             sb.append(column.getValue(entity));
         }
-        sb.append(NEWLINE);
+        sb.append(lineSeparator);
     }
 
-    private static <T> void appendHeader(List<IColumnDefinition<T>> columnDefs, StringBuffer sb)
+    private <T> void appendHeader(List<IColumnDefinition<T>> columnDefs, StringBuffer sb)
     {
         boolean isFirst = true;
         for (IColumnDefinition<T> column : columnDefs)
@@ -79,6 +90,6 @@ public class TSVRenderer
             }
             sb.append(column.getHeader());
         }
-        sb.append(NEWLINE);
+        sb.append(lineSeparator);
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ExportSamplesTestCommand.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ExportSamplesTestCommand.java
index 34940eb9b59..82ddc9fec47 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ExportSamplesTestCommand.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ExportSamplesTestCommand.java
@@ -37,6 +37,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.ITestCom
  */
 public class ExportSamplesTestCommand extends AbstractDefaultTestCommand
 {
+    private static final String LINE_SEPARATOR = "\n";
+
     private final Client client;
 
     private String receivedExportedFileContent = null;
@@ -76,8 +78,8 @@ public class ExportSamplesTestCommand extends AbstractDefaultTestCommand
             assert viewContext != null : "viewContext is null";
 
             ICommonClientServiceAsync service = this.viewContext.getCommonService();
-            service.getExportTable(exportDataKey, new SaveExportedContentCallbackTest(
-                    this.viewContext));
+            service.getExportTable(exportDataKey, LINE_SEPARATOR,
+                    new SaveExportedContentCallbackTest(this.viewContext));
         }
     }
 
@@ -142,7 +144,7 @@ public class ExportSamplesTestCommand extends AbstractDefaultTestCommand
 
         private String[] parse(String content)
         {
-            return content.split("\n");
+            return content.split(LINE_SEPARATOR);
         }
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRendererTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRendererTest.java
index b3db5f9261f..ae6ce09cc06 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRendererTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/TSVRendererTest.java
@@ -41,8 +41,8 @@ public class TSVRendererTest
             { "x", "y" });
         entities.add(new String[]
             { "a", "b" });
-        String content = TSVRenderer.createTable(entities, columnDefs);
-        Assert.assertEquals("h0\th1\nx\ty\na\tb\n", content);
+        String content = TSVRenderer.createTable(entities, columnDefs, "#");
+        Assert.assertEquals("h0\th1#x\ty#a\tb#", content);
     }
 
     private static List<IColumnDefinition<String[]>> createColumnDefs(int colNum)
@@ -60,7 +60,7 @@ public class TSVRendererTest
     {
         List<IColumnDefinition<String[]>> columnDefs = createColumnDefs(2);
         List<String[]> entities = new ArrayList<String[]>();
-        String content = TSVRenderer.createTable(entities, columnDefs);
+        String content = TSVRenderer.createTable(entities, columnDefs, "\n");
         Assert.assertEquals("h0\th1\n", content);
     }
 
-- 
GitLab