From b1a898fa688a85a7eea08c16913cd44de61a9be4 Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Tue, 5 Jul 2011 11:40:55 +0000
Subject: [PATCH] LMS-2333 Extended API to allow downloading transformed
 images.

SVN: 21978
---
 .../v1/IScreeningOpenbisServiceFacade.java    | 42 ++++++----
 .../api/v1/ScreeningOpenbisServiceFacade.java | 52 ++++++++++++
 .../v1/ScreeningOpenbisServiceFacadeTest.java | 84 ++++++++++++++++---
 3 files changed, 151 insertions(+), 27 deletions(-)

diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
index 92e8d670cb4..a758ecdd6cf 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.IDataSetFilter;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.TypeBasedDataSetFilter;
 import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacade.IImageOutputStreamProvider;
@@ -64,7 +65,7 @@ public interface IScreeningOpenbisServiceFacade
 
     /** Closes connection with the server. After calling this method this facade cannot be used. */
     public void logout();
-    
+
     /**
      * Removes all images loaded by {@link #loadImageWellCaching(PlateImageReference, ImageSize)}
      * and {@link #loadThumbnailImageWellCaching(PlateImageReference)} from the image cache, thus
@@ -88,7 +89,7 @@ public interface IScreeningOpenbisServiceFacade
      * Each returned plate has at least one data set with the specified analysis procedure.
      */
     public List<Plate> listPlates(ExperimentIdentifier experiment, String analysisProcedure);
-    
+
     /**
      * Return the list of all visible experiments, along with their hierarchical context (space,
      * project).
@@ -126,7 +127,7 @@ public interface IScreeningOpenbisServiceFacade
      */
     public List<FeatureVectorDatasetReference> listFeatureVectorDatasets(
             List<? extends PlateIdentifier> plates, String analysisProcedureOrNull);
-    
+
     /**
      * For a given set of plates provides the list of all connected data sets containing images
      * which are not segmentation images.
@@ -151,7 +152,7 @@ public interface IScreeningOpenbisServiceFacade
     @Deprecated
     public List<ImageDatasetReference> listSegmentationImageDatasets(
             List<? extends PlateIdentifier> plates);
-    
+
     /**
      * For a given set of plates provides the list of all connected data sets containing
      * segmentation images (overlays) and calculated by specified analysis procedure.
@@ -211,7 +212,7 @@ public interface IScreeningOpenbisServiceFacade
     public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier,
             String datasetTypeCodePattern) throws IllegalStateException,
             EnvironmentFailureException;
-    
+
     /**
      * Gets proxies to the data sets owned by specified well and passing specified filter..
      * 
@@ -219,10 +220,9 @@ public interface IScreeningOpenbisServiceFacade
      * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
      *             the server.
      */
-    public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier,
-            IDataSetFilter dataSetFilter) throws IllegalStateException,
-            EnvironmentFailureException;
-    
+    public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, IDataSetFilter dataSetFilter)
+            throws IllegalStateException, EnvironmentFailureException;
+
     public IDataSetDss getDataSet(String dataSetCode) throws IllegalStateException,
             EnvironmentFailureException;
 
@@ -267,9 +267,8 @@ public interface IScreeningOpenbisServiceFacade
      *             the server.
      */
     public List<IDataSetDss> getDataSets(PlateIdentifier plateIdentifier,
-            IDataSetFilter dataSetFilter) throws IllegalStateException,
-            EnvironmentFailureException;
-    
+            IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException;
+
     /**
      * Upload a new data set to the DSS for a plate.
      * 
@@ -440,7 +439,7 @@ public interface IScreeningOpenbisServiceFacade
     public List<FeatureVectorWithDescription> loadFeaturesForPlateWells(
             ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier,
             String analysisProcedureOrNull, List<String> featureCodesOrNull);
-    
+
     /**
      * For the given <var>materialIdentifier</var> find all plate locations that are connected to it
      * and load the feature vectors for the given feature code if not <code>null</code>, or all
@@ -481,7 +480,7 @@ public interface IScreeningOpenbisServiceFacade
     public List<FeatureVectorWithDescription> loadFeaturesForPlateWells(
             MaterialIdentifier materialIdentifier, String analysisProcedureOrNull,
             List<String> featureCodesOrNull);
-    
+
     /**
      * Converts the given <var>WellIdentifiers</var> to <var>WellPositions</var>
      */
@@ -631,6 +630,19 @@ public interface IScreeningOpenbisServiceFacade
     public void loadImages(List<PlateImageReference> imageReferences, ImageSize imageSizeOrNull,
             IPlateImageHandler plateImageHandler) throws IOException;
 
+    /**
+     * Loads images where the desired properties of the images are specified by a
+     * LoadImageConfiguration. The options and their behavior are described in the
+     * {@link LoadImageConfiguration} documentation.
+     * 
+     * @param configuration The configuration of the images to load.
+     * @param plateImageHandler Handler for the delivered images.
+     * @see LoadImageConfiguration
+     */
+    public void loadImages(List<PlateImageReference> imageReferences,
+            LoadImageConfiguration configuration, IPlateImageHandler plateImageHandler)
+            throws IOException;
+
     /**
      * Loads the PNG-encoded image for the specified <var>imageReference</var>.
      * <p>
@@ -707,7 +719,7 @@ public interface IScreeningOpenbisServiceFacade
     public List<PlateWellMaterialMapping> listPlateMaterialMapping(
             List<? extends PlateIdentifier> plates,
             MaterialTypeIdentifier materialTypeIdentifierOrNull);
-    
+
     /**
      * Returns an alphabetically sorted list of analysis procedure codes of all data sets of the
      * specified experiment.
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
index 6f9fc4d0d10..e78e07db901 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
@@ -37,6 +37,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetO
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO;
 import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationChangingService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet;
@@ -1686,4 +1687,55 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa
         }
     }
 
+    public void loadImages(List<PlateImageReference> imageReferences,
+            final LoadImageConfiguration configuration, final IPlateImageHandler plateImageHandler)
+            throws IOException
+    {
+        plateImageReferencesMultiplexer.process(imageReferences,
+                new IReferenceHandler<PlateImageReference>()
+                    {
+                        public void handle(DssServiceRpcScreeningHolder dssService,
+                                List<PlateImageReference> references)
+                        {
+                            checkDSSMinimalMinorVersion(dssService, "loadImages", List.class,
+                                    LoadImageConfiguration.class);
+                            final InputStream stream =
+                                    dssService.getService().loadImages(sessionToken, references,
+                                            configuration);
+                            try
+                            {
+                                final ConcatenatedFileOutputStreamWriter imagesWriter =
+                                        new ConcatenatedFileOutputStreamWriter(stream);
+                                int index = 0;
+                                long size;
+                                do
+                                {
+                                    final ByteArrayOutputStream outputStream =
+                                            new ByteArrayOutputStream();
+                                    size = imagesWriter.writeNextBlock(outputStream);
+                                    if (size > 0)
+                                    {
+                                        plateImageHandler.handlePlateImage(references.get(index),
+                                                outputStream.toByteArray());
+                                    }
+                                    index++;
+                                } while (size >= 0);
+                            } catch (IOException ex)
+                            {
+                                throw new WrappedIOException(ex);
+                            } finally
+                            {
+                                try
+                                {
+                                    stream.close();
+                                } catch (IOException ex)
+                                {
+                                    throw new WrappedIOException(ex);
+                                }
+                            }
+
+                        }
+                    });
+    }
+
 }
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java
index 7058b3a14ca..41b058e6a37 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java
@@ -50,6 +50,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetO
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO;
 import ch.systemsx.cisd.openbis.dss.screening.server.DssServiceRpcScreening;
 import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationChangingService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet;
@@ -629,8 +630,8 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas
                 new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null,
                         properties, null);
         final ImageDatasetReference r2 =
-                new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null,
-                        null, null);
+                new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, null,
+                        null);
         context.checking(new Expectations()
             {
                 {
@@ -639,27 +640,28 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas
                 }
             });
 
-        List<ImageDatasetReference> dataSets = facade.listSegmentationImageDatasets(plates, "AP-42");
+        List<ImageDatasetReference> dataSets =
+                facade.listSegmentationImageDatasets(plates, "AP-42");
 
         assertSame(r1, dataSets.get(0));
         assertEquals(1, dataSets.size());
         context.assertIsSatisfied();
     }
-    
+
     @Test
     public void testListSegmentationImageDataSetsWithUnspecifiedAnalysisProcedure()
     {
         final Plate plate =
-            new Plate("p1", "s", "s-12", new ExperimentIdentifier("e", "p1", "s", "e-13"));
+                new Plate("p1", "s", "s-12", new ExperimentIdentifier("e", "p1", "s", "e-13"));
         final List<Plate> plates = Arrays.asList(plate);
         HashMap<String, String> properties = new HashMap<String, String>();
         properties.put(ScreeningConstants.ANALYSIS_PROCEDURE, "AP-42");
         final ImageDatasetReference r1 =
-            new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null,
-                    properties, null);
+                new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null,
+                        properties, null);
         final ImageDatasetReference r2 =
-            new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null,
-                    null, null);
+                new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, null,
+                        null);
         context.checking(new Expectations()
             {
                 {
@@ -667,15 +669,15 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas
                     will(returnValue(Arrays.asList(r1, r2)));
                 }
             });
-        
+
         List<ImageDatasetReference> dataSets = facade.listSegmentationImageDatasets(plates, null);
-        
+
         assertSame(r1, dataSets.get(0));
         assertSame(r2, dataSets.get(1));
         assertEquals(2, dataSets.size());
         context.assertIsSatisfied();
     }
-    
+
     @Test
     public void testListPlateWells()
     {
@@ -740,6 +742,64 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas
         context.assertIsSatisfied();
     }
 
+    @Test
+    public void testLoadImagesUsingConfiguration() throws IOException
+    {
+        final LoadImageConfiguration config = new LoadImageConfiguration();
+        config.setDesiredImageFormatPng(true);
+
+        final PlateImageReference r1 = new PlateImageReference(1, 2, 1, "c1", i1id);
+        final PlateImageReference r2 = new PlateImageReference(12, 22, 1, "c1", i2id);
+        final ByteArrayOutputStream stream1 = new ByteArrayOutputStream();
+        final ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
+        context.checking(new Expectations()
+            {
+                {
+                    one(dssService1).loadImages(SESSION_TOKEN, Arrays.asList(r1), config);
+                    ConcatenatedContentInputStream s1 =
+                            new ConcatenatedContentInputStream(true, Arrays
+                                    .<IContent> asList(new ByteArrayBasedContent("hello 1"
+                                            .getBytes(), "h1")));
+                    will(returnValue(s1));
+
+                    one(dssService2).loadImages(SESSION_TOKEN, Arrays.asList(r2), config);
+                    ConcatenatedContentInputStream s2 =
+                            new ConcatenatedContentInputStream(true, Arrays
+                                    .<IContent> asList(new ByteArrayBasedContent("hello 2"
+                                            .getBytes(), "h2")));
+                    will(returnValue(s2));
+                }
+            });
+
+        IPlateImageHandler handler = new IPlateImageHandler()
+            {
+
+                public void handlePlateImage(PlateImageReference plateImageReference,
+                        byte[] imageFileBytes)
+                {
+
+                    try
+                    {
+                        if (r1.equals(plateImageReference))
+                        {
+                            stream1.write(imageFileBytes);
+                        } else if (r2.equals(plateImageReference))
+                        {
+                            stream2.write(imageFileBytes);
+                        }
+                    } catch (IOException ex)
+                    {
+                        ex.printStackTrace();
+                    }
+                }
+            };
+        facade.loadImages(Arrays.asList(r1, r2), config, handler);
+
+        assertEquals("hello 1", stream1.toString());
+        assertEquals("hello 2", stream2.toString());
+        context.assertIsSatisfied();
+    }
+
     @Test
     public void testListImageMetaData()
     {
-- 
GitLab