From e9536f9bd5fdf1345e94c76cb345bbe2327ddeca Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Fri, 3 Sep 2010 11:47:37 +0000
Subject: [PATCH] [LMS-1690] openbis server side

SVN: 17706
---
 .../web/client/dto/ListMaterialCriteria.java  | 16 ++++++
 .../ListMaterialOriginalDataProvider.java     |  2 +-
 .../openbis/generic/server/CommonServer.java  |  5 +-
 .../generic/server/CommonServerLogger.java    | 10 ++++
 .../bo/materiallister/IMaterialLister.java    |  9 ++--
 .../materiallister/IMaterialListingQuery.java | 12 +++++
 .../bo/materiallister/MaterialLister.java     | 54 +++++++++----------
 .../openbis/generic/shared/ICommonServer.java |  5 +-
 .../plugin/generic/server/GenericServer.java  |  5 +-
 .../generic/server/CommonServerTest.java      |  6 ++-
 .../bo/materiallister/MaterialListerTest.java | 45 ++++++++++++++--
 .../MaterialListingQueryTest.java             | 23 +++++++-
 .../shared/ICommonServer.java.expected        |  5 +-
 13 files changed, 148 insertions(+), 49 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
index af95ed0bcb7..c07d3eaffab 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
 
+import java.util.Collection;
+
 import com.google.gwt.user.client.rpc.IsSerializable;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
@@ -31,18 +33,32 @@ public final class ListMaterialCriteria extends DefaultResultSetConfig<String, M
 {
     private MaterialType materialType;
 
+    private Collection<Long> materialIdsOrNull;
+
     // GWT only
     public ListMaterialCriteria()
     {
     }
 
     public ListMaterialCriteria(MaterialType materialType)
+    {
+        this(materialType, null);
+    }
+
+    public ListMaterialCriteria(MaterialType materialType, Collection<Long> materialIdsOrNull)
     {
         this.materialType = materialType;
+        this.materialIdsOrNull = materialIdsOrNull;
     }
 
     public MaterialType getMaterialType()
     {
         return materialType;
     }
+
+    public Collection<Long> getMaterialIdsOrNull()
+    {
+        return materialIdsOrNull;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
index cea2940e6be..90f072b3f06 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
@@ -46,7 +46,7 @@ final class ListMaterialOriginalDataProvider extends AbstractOriginalDataProvide
     public final List<Material> getOriginalData()
     {
         final List<Material> materials =
-                commonServer.listMaterials(sessionToken, listCriteria.getMaterialType(), true);
+                commonServer.listMaterials(sessionToken, listCriteria, true);
         return materials;
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 665dc9aff2c..7ee833e9dae 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.authentication.IAuthenticationService;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAttachmentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAuthorizationGroupBO;
@@ -826,12 +827,12 @@ public final class CommonServer extends AbstractCommonServer<ICommonServer> impl
         }
     }
 
-    public List<Material> listMaterials(String sessionToken, MaterialType materialType,
+    public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
             boolean withProperties)
     {
         final Session session = getSession(sessionToken);
         final IMaterialLister materialLister = businessObjectFactory.createMaterialLister(session);
-        return materialLister.list(materialType, withProperties);
+        return materialLister.list(criteria, withProperties);
     }
 
     public void registerSampleType(String sessionToken, SampleType entityType)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index f4c4e9f313d..930626ced02 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -25,6 +25,7 @@ import org.apache.log4j.Level;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
@@ -446,6 +447,15 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
         return null;
     }
 
+    public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
+            boolean withProperties)
+    {
+        logAccess(sessionToken, "list_materials", "TYPE(%s) IDS(%s) withProperties(%s)", criteria
+                .getMaterialType(), criteria.getMaterialIdsOrNull() == null ? "-"
+                : abbreviate(criteria.getMaterialIdsOrNull()), withProperties);
+        return null;
+    }
+
     public void registerMaterialType(String sessionToken, MaterialType entityType)
     {
         logTracking(sessionToken, "register_material_type", "CODE(%s)", entityType.getCode());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java
index 6cc974213ab..cda028941f9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialLister.java
@@ -18,8 +18,8 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister;
 
 import java.util.List;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 
 /**
  * A class for fast material listing.
@@ -28,13 +28,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
  */
 public interface IMaterialLister
 {
-    /** fetches and sets all properties of specified materials */
-    void enrichWithProperties(List<Material> materials);
-
     /**
-     * Returns a sorted list of {@link Material}s of given {@link MaterialType}.
+     * Returns a sorted list of {@link Material}s matching given criteria.
      * 
      * @param withProperties if true material properties will be fetched as well.
      */
-    public List<Material> list(MaterialType materialType, boolean withProperties);
+    public List<Material> list(ListMaterialCriteria criteria, boolean withProperties);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java
index c5208396098..43c87c9e944 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/IMaterialListingQuery.java
@@ -20,6 +20,7 @@ import it.unimi.dsi.fastutil.longs.LongSet;
 import net.lemnik.eodsql.DataIterator;
 import net.lemnik.eodsql.Select;
 import net.lemnik.eodsql.TransactionQuery;
+import net.lemnik.eodsql.TypeMapper;
 
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.GenericEntityPropertyRecord;
@@ -52,6 +53,17 @@ public interface IMaterialListingQuery extends TransactionQuery, IPropertyListin
     public DataIterator<MaterialRecord> getMaterialsForMaterialType(long dbInstanceId,
             long materialTypeId);
 
+    /**
+     * Returns the materials for the given <var>materialTypeId</var> and <var>materialIds</var>
+     */
+    @Select(sql = "select m.id, m.code, m.dbin_id, m.maty_id, "
+            + "           m.registration_timestamp, m.modification_timestamp, m.pers_id_registerer "
+            + "      from materials m where m.dbin_id=?{1} and m.maty_id=?{2} and m.id = any(?{3})"
+            + "  order by m.code", parameterBindings =
+        { TypeMapper.class/* default */, TypeMapper.class/* default */, LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public DataIterator<MaterialRecord> getMaterialsForMaterialTypeWithIds(long dbInstanceId,
+            long materialTypeId, LongSet materialIds);
+
     //
     // Entity Properties
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java
index d26d893e21f..260861533bf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialLister.java
@@ -19,13 +19,16 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister;
 import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
 import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
 import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import net.lemnik.eodsql.DataIterator;
 
 import ch.rinn.restrictions.Friend;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.EntityPropertiesEnricher;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.IEntityPropertiesEnricher;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.IEntityPropertiesHolderResolver;
@@ -110,10 +113,19 @@ public class MaterialLister implements IMaterialLister
     // Listing
     //
 
-    public List<Material> list(MaterialType materialType, boolean withProperties)
+    public List<Material> list(ListMaterialCriteria criteria, boolean withProperties)
     {
+        MaterialType materialType = criteria.getMaterialType();
+        Collection<Long> materialIdsOrNull = criteria.getMaterialIdsOrNull();
         DataIterator<MaterialRecord> materials =
-                query.getMaterialsForMaterialType(databaseInstanceId, materialType.getId());
+                materialIdsOrNull != null ? getIteratorByTypeAndIds(materialType, materialIdsOrNull)
+                        : getIteratorByType(materialType);
+        return convertAndEnrich(materials, materialType, withProperties);
+    }
+
+    private List<Material> convertAndEnrich(DataIterator<MaterialRecord> materials,
+            MaterialType materialType, boolean withProperties)
+    {
         final Long2ObjectMap<Material> materialMap = asMaterials(materials, materialType);
         if (withProperties)
         {
@@ -122,6 +134,18 @@ public class MaterialLister implements IMaterialLister
         return asList(materialMap);
     }
 
+    private DataIterator<MaterialRecord> getIteratorByType(MaterialType materialType)
+    {
+        return query.getMaterialsForMaterialType(databaseInstanceId, materialType.getId());
+    }
+
+    private DataIterator<MaterialRecord> getIteratorByTypeAndIds(MaterialType materialType,
+            Collection<Long> materialIds)
+    {
+        return query.getMaterialsForMaterialTypeWithIds(databaseInstanceId, materialType.getId(),
+                new LongOpenHashSet(materialIds));
+    }
+
     //
     // Enriching
     //
@@ -159,7 +183,7 @@ public class MaterialLister implements IMaterialLister
         material.setRegistrator(getOrCreateRegistrator(record));
         material.setRegistrationDate(record.registration_timestamp);
         material.setModificationDate(record.modification_timestamp);
-        
+
         material.setProperties(new ArrayList<IEntityProperty>());
 
         return material;
@@ -209,28 +233,4 @@ public class MaterialLister implements IMaterialLister
             });
     }
 
-    private static Long2ObjectMap<Material> asMap(Iterable<Material> materials)
-    {
-        Long2ObjectMap<Material> map = new Long2ObjectOpenHashMap<Material>();
-        for (Material material : materials)
-        {
-            map.put(material.getId(), material);
-        }
-        return map;
-    }
-
-    public void enrichWithProperties(List<Material> materials)
-    {
-        setEmptyProperties(materials);
-        enrichWithProperties(asMap(materials));
-    }
-
-    private void setEmptyProperties(List<Material> materials)
-    {
-        for (Material material : materials)
-        {
-            material.setProperties(new ArrayList<IEntityProperty>());
-        }
-    }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index 5a5bf89314b..ac0f4c2b362 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import org.springframework.transaction.annotation.Transactional;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
@@ -548,13 +549,13 @@ public interface ICommonServer extends IServer
     public List<MaterialType> listMaterialTypes(String sessionToken);
 
     /**
-     * Lists materials.
+     * Lists materials using given criteria.
      * 
      * @return a sorted list of {@link Material}.
      */
     @Transactional(readOnly = true)
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public List<Material> listMaterials(String sessionToken, MaterialType materialType,
+    public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
             boolean withProperties);
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index f049e1f1714..92ccf0231b0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.batch.BatchOperationExecutor;
 import ch.systemsx.cisd.openbis.generic.server.batch.IBatchOperation;
@@ -758,7 +759,9 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
                 getDAOFactory().getEntityTypeDAO(EntityKind.MATERIAL).tryToFindEntityTypeByCode(
                         materialTypeCode);
         MaterialType materialType = MaterialTypeTranslator.translateSimple(entityTypePE);
-        List<Material> materials = commonServer.listMaterials(sessionToken, materialType, false);
+        List<Material> materials =
+                commonServer.listMaterials(sessionToken, new ListMaterialCriteria(materialType),
+                        false);
         return asCodeToMaterialMap(materials);
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
index 70e613ed849..a72fe7601e1 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
@@ -29,6 +29,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlugin;
@@ -1209,17 +1210,18 @@ public final class CommonServerTest extends AbstractServerTestCase
         prepareGetSession();
         final MaterialType materialType =
                 MaterialTypeTranslator.translate(CommonTestUtils.createMaterialType(), null);
+        final ListMaterialCriteria criteria = new ListMaterialCriteria(materialType);
         context.checking(new Expectations()
             {
                 {
                     one(commonBusinessObjectFactory).createMaterialLister(SESSION);
                     will(returnValue(materialLister));
 
-                    one(materialLister).list(materialType, true);
+                    one(materialLister).list(criteria, true);
                     will(returnValue(new ArrayList<MaterialTypePE>()));
                 }
             });
-        createServer().listMaterials(SESSION_TOKEN, materialType, true);
+        createServer().listMaterials(SESSION_TOKEN, criteria, true);
         context.assertIsSatisfied();
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListerTest.java
index 9d2ab83a943..5aca0f3d273 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListerTest.java
@@ -17,16 +17,18 @@
 package ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister;
 
 import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertNotNull;
 
 import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import ch.rinn.restrictions.Friend;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.entity.SecondaryEntityDAO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.entity.SecondaryEntityListingQueryTest;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.AbstractDAOTest;
@@ -61,11 +63,44 @@ public class MaterialListerTest extends AbstractDAOTest
     }
 
     @Test
-    public void testListByMaterialTypeId()
+    public void testListByMaterialTypeWithProperties()
     {
         MaterialType materialType = createMaterialType();
-        List<Material> materials = lister.list(materialType, true);
+        boolean withProperties = true;
+        List<Material> materials =
+                lister.list(new ListMaterialCriteria(materialType), withProperties);
         assertEqualsOrGreater(4, materials.size());
+        assertMaterialsProperlyFetched(materials, materialType, withProperties == false);
+
+    }
+
+    @Test
+    public void testListByMaterialTypeWithoutProperties()
+    {
+        MaterialType materialType = createMaterialType();
+        boolean withProperties = false;
+        List<Material> materials =
+                lister.list(new ListMaterialCriteria(materialType), withProperties);
+        assertEqualsOrGreater(4, materials.size());
+        assertMaterialsProperlyFetched(materials, materialType, withProperties == false);
+    }
+
+    @Test
+    public void testListByMaterialTypeAndMaterialIds()
+    {
+        MaterialType materialType = createMaterialType();
+        Collection<Long> materialIds = Arrays.asList(new Long[]
+            { 22L, 34L });
+        boolean withProperties = true;
+        List<Material> materials =
+                lister.list(new ListMaterialCriteria(materialType, materialIds), withProperties);
+        assertEqualsOrGreater(2, materials.size());
+        assertMaterialsProperlyFetched(materials, materialType, withProperties == false);
+    }
+
+    private void assertMaterialsProperlyFetched(List<Material> materials,
+            MaterialType expectedType, boolean emptyProperties)
+    {
         for (Material material : materials)
         {
             assertNotNull(material.getId());
@@ -74,8 +109,8 @@ public class MaterialListerTest extends AbstractDAOTest
             assertNotNull(material.getRegistrationDate());
             assertNotNull(material.getModificationDate());
             assertEquals(databaseInstance, material.getDatabaseInstance());
-            assertEquals(materialType, material.getMaterialType());
-            assertFalse(material.getProperties().isEmpty());
+            assertEquals(expectedType, material.getMaterialType());
+            assertEquals(emptyProperties, material.getProperties().isEmpty());
         }
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListingQueryTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListingQueryTest.java
index aa6e0c09c41..79e167bbda5 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListingQueryTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/materiallister/MaterialListingQueryTest.java
@@ -21,6 +21,7 @@ import static ch.systemsx.cisd.openbis.generic.server.business.bo.common.EntityL
 import static ch.systemsx.cisd.openbis.generic.server.business.bo.common.EntityListingTestUtils.findExactlyOneProperty;
 import static ch.systemsx.cisd.openbis.generic.server.business.bo.common.EntityListingTestUtils.findProperties;
 import static org.testng.AssertJUnit.assertEquals;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
 import it.unimi.dsi.fastutil.longs.LongSet;
 
 import java.sql.SQLException;
@@ -145,7 +146,7 @@ public class MaterialListingQueryTest extends AbstractDAOTest
     }
 
     @Test
-    public void testMaterials()
+    public void testListMaterialsByType()
     {
         Iterable<MaterialRecord> materials =
                 query.getMaterialsForMaterialType(dbInstanceId, BACTERIUM_MATERIAL_TYPE);
@@ -163,4 +164,24 @@ public class MaterialListingQueryTest extends AbstractDAOTest
         assertEquals(0, remainingBacteriumCodes.size());
     }
 
+    public void testListMaterialsByTypeAndId()
+    {
+        LongSet materialIds = new LongOpenHashSet(new long[]
+            { 34L, 22L });
+        Iterable<MaterialRecord> materials =
+                query.getMaterialsForMaterialTypeWithIds(dbInstanceId, BACTERIUM_MATERIAL_TYPE,
+                        materialIds);
+        Set<String> remainingBacteriumCodes = new HashSet<String>(Arrays.asList(new String[]
+            { "BACTERIUM-X", "BACTERIUM1" }));
+        for (MaterialRecord materialRecord : materials)
+        {
+            assertEquals(dbInstanceId, materialRecord.dbin_id);
+            assertEquals(BACTERIUM_MATERIAL_TYPE, materialRecord.maty_id);
+            if (false == remainingBacteriumCodes.remove(materialRecord.code))
+            {
+                AssertJUnit.fail("Unexpected material code: '" + materialRecord.code + "'");
+            }
+        }
+        assertEquals(0, remainingBacteriumCodes.size());
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
index 5a5bf89314b..ac0f4c2b362 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import org.springframework.transaction.annotation.Transactional;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
@@ -548,13 +549,13 @@ public interface ICommonServer extends IServer
     public List<MaterialType> listMaterialTypes(String sessionToken);
 
     /**
-     * Lists materials.
+     * Lists materials using given criteria.
      * 
      * @return a sorted list of {@link Material}.
      */
     @Transactional(readOnly = true)
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public List<Material> listMaterials(String sessionToken, MaterialType materialType,
+    public List<Material> listMaterials(String sessionToken, ListMaterialCriteria criteria,
             boolean withProperties);
 
     /**
-- 
GitLab