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 e21ed5eeae6ef856988b130f28a0f467a9120221..5c09d2b7ae42421dd823d7c66c58c028b6c06fd9 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 @@ -75,6 +75,7 @@ import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleTec import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleUpdatesPredicate; import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SpaceIdentifierPredicate; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DeletionValidator; +import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExpressionValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExternalDataValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.MatchingEntityValidator; @@ -1416,6 +1417,20 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt } + @Override + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @ReturnValueFilter(validatorClass = ExperimentByIdentiferValidator.class) + public List<Experiment> searchForExperiments(String sessionToken, + DetailedSearchCriteria criteria) + { + final Session session = getSession(sessionToken); + SearchHelper searchHelper = + new SearchHelper(session, businessObjectFactory, getDAOFactory()); + String userId = session.getUserName(); + List<ExperimentPE> experiments = searchHelper.searchForExperiments(userId, criteria); + return translateExperiments(sessionToken, experiments); + } + @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) @ReturnValueFilter(validatorClass = ExternalDataValidator.class) @@ -3478,8 +3493,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt if (defaultPutDataStoreServerCodeOrNull == null) { throw ConfigurationFailureException - .fromTemplate - ("There are %d Data Store Servers registered in openBIS, but property dss-rpc.put.dss-code is not set.", + .fromTemplate( + "There are %d Data Store Servers registered in openBIS, but property dss-rpc.put.dss-code is not set.", dataStores.size()); } for (DataStorePE store : dataStores) 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 a1df72d1564cbd8a297a4ed92e47bcfcec6dfda0..32f00e6e4cbbabc005a6ac14f04e51ffe75812c2 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 @@ -631,6 +631,14 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe projectIdentifier, abbreviate(attachments)); } + @Override + public List<Experiment> searchForExperiments(String sessionToken, + DetailedSearchCriteria criteria) + { + logAccess(sessionToken, "search_for_experiments", "criteria(%s)", criteria); + return null; + } + @Override public List<ExternalData> searchForDataSets(String sessionToken, DetailedSearchCriteria criteria) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java index c0057edf7d440febbaa271911874d4e5e7a70e97..3f5fda76bac2becd1e3903dc3d9659d1b77f3cb6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java @@ -19,10 +19,12 @@ package ch.systemsx.cisd.openbis.generic.server; import java.util.List; import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory; +import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; import ch.systemsx.cisd.openbis.generic.server.business.search.DataSetSearchManager; +import ch.systemsx.cisd.openbis.generic.server.business.search.ExperimentSearchManager; import ch.systemsx.cisd.openbis.generic.server.business.search.MaterialSearchManager; import ch.systemsx.cisd.openbis.generic.server.business.search.SampleSearchManager; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; @@ -31,6 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** @@ -89,4 +92,13 @@ class SearchHelper return new MaterialSearchManager(searchDAO, materialLister).searchForMaterials(userId, detailedSearchCriteria); } + + public List<ExperimentPE> searchForExperiments(String userId, + DetailedSearchCriteria detailedSearchCriteria) + { + IHibernateSearchDAO searchDAO = daoFactory.getHibernateSearchDAO(); + IExperimentTable experimentTable = businessObjectFactory.createExperimentTable(session); + return new ExperimentSearchManager(searchDAO, experimentTable).searchForExperiments(userId, + detailedSearchCriteria); + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java index b04b45e4ccf48f4e6dc76eed53f5a7e4cdde4310..29db281fdfadf5a5966e8ea2df4a82e5f375c7a6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java @@ -120,7 +120,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; public class GeneralInformationService extends AbstractServer<IGeneralInformationService> implements IGeneralInformationService { - public static final int MINOR_VERSION = 20; + public static final int MINOR_VERSION = 21; @Resource(name = ch.systemsx.cisd.openbis.generic.shared.ResourceNames.COMMON_SERVER) private ICommonServer commonServer; @@ -957,6 +957,22 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio return Translator.translateExperiments(experiments); } + @Override + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @ReturnValueFilter(validatorClass = ExperimentByIdentiferValidator.class) + public List<Experiment> searchForExperiments(String sessionToken, SearchCriteria searchCriteria) + { + checkSession(sessionToken); + + DetailedSearchCriteria detailedSearchCriteria = + SearchCriteriaToDetailedSearchCriteriaTranslator.convert(getDAOFactory(), + SearchableEntityKind.EXPERIMENT, searchCriteria); + List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment> experiments = + commonServer.searchForExperiments(sessionToken, detailedSearchCriteria); + return Translator.translateExperiments(experiments); + } + @Override @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java index 608b0dfb4b87f77fe6be86692ddb4ecc771e4c4e..31172b3ef92f3b875b981a4dce3323abb0cffff1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java @@ -297,6 +297,13 @@ class GeneralInformationServiceLogger extends AbstractServerLogger implements return null; } + @Override + public List<Experiment> searchForExperiments(String sessionToken, SearchCriteria searchCriteria) + { + logAccess(sessionToken, "search-for-experiments", "SEARCH_CRITERIA(%s)", searchCriteria); + return null; + } + @Override public List<Experiment> filterExperimentsVisibleToUser(String sessionToken, List<Experiment> allExperiments, String userId) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java index 1430f1805efa1fb86a0e5f1b540b008a64021d23..15d9937e7170ed9162dbc4bc27c843e8a629cbc5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java @@ -85,6 +85,12 @@ public final class ExperimentTable extends AbstractBusinessObject implements IEx // IExperimentTable // + @Override + public void loadByIds(Collection<Long> experimentIds) + { + experiments = getExperimentDAO().listByIDs(experimentIds); + } + @Override public final void load(final String experimentTypeCode, final ProjectIdentifier projectIdentifier) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExperimentTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExperimentTable.java index da93f0993481e70fc2aaf4fe19f046e4eee42826..30d9d78940a690d92c5474f226c0827a89f57301 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExperimentTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExperimentTable.java @@ -35,6 +35,11 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; */ public interface IExperimentTable { + /** + * Loads all experiments specified by their ids. + */ + public void loadByIds(Collection<Long> experimentIds); + /** * Loads all experiments of given type and from given project together with all their * properties. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/ExperimentSearchManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/ExperimentSearchManager.java new file mode 100644 index 0000000000000000000000000000000000000000..f833fe22094af1a36bc775557af3c8549d20e982 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/search/ExperimentSearchManager.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013 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.server.business.search; + +import static ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.EXPERIMENT; + +import java.util.Collections; +import java.util.List; + +import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchAssociationCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; + +/** + * Search manager for experiments. + * + * @author Franz-Josef Elmer + */ +public class ExperimentSearchManager extends AbstractSearchManager<IExperimentTable> +{ + + public ExperimentSearchManager(IHibernateSearchDAO searchDAO, IExperimentTable lister) + { + super(searchDAO, lister); + } + + public List<ExperimentPE> searchForExperiments(String userId, DetailedSearchCriteria criteria) + { + List<Long> experimentIds = + searchDAO.searchForEntityIds(userId, criteria, EXPERIMENT, + Collections.<DetailedSearchAssociationCriteria> emptyList()); + lister.loadByIds(experimentIds); + return lister.getExperiments(); + } + +} 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 b9cfa0e0749c6dd63a0c9a9f4ca1064a7e30a4bf..7e55bcb392332305265913a4f39cd1dd325e43c5 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 @@ -615,7 +615,14 @@ public interface ICommonServer extends IServer String description, String leaderId, Collection<NewAttachment> attachments); /** - * Searches for samples that fulfill the specified search criteria. + * Searches for experiments that fulfill the specified search criteria. + */ + @Transactional(readOnly = true) + public List<Experiment> searchForExperiments(String sessionToken, + DetailedSearchCriteria criteria); + + /** + * Searches for data sets that fulfill the specified search criteria. */ @Transactional(readOnly = true) public List<ExternalData> searchForDataSets(String sessionToken, DetailedSearchCriteria criteria); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java index 7d1d6a8fbbcc16a514fae641534ef9f78474698d..c4bbdbbf07107371b81332efbe9e7de71661e1e2 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java @@ -16,7 +16,7 @@ package ch.systemsx.cisd.openbis.remoteapitest.api.v1; -import static junit.framework.Assert.assertEquals; +import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; @@ -29,6 +29,7 @@ import java.util.Comparator; import java.util.EnumSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.testng.annotations.AfterMethod; @@ -150,6 +151,32 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase fail("result didn't contain project " + expectedSampleIdentifier); } + @Test + public void testSearchForExperiments() + { + SearchCriteria searchCriteria = new SearchCriteria(); + searchCriteria.addMatchClause(MatchClause.createPropertyMatch("GENDER", "FEMALE")); + + List<Experiment> experiments = + generalInformationService.searchForExperiments(sessionToken, searchCriteria); + + assertEquals("/CISD/NEMO/EXP-TEST-2", experiments.get(0).getIdentifier()); + assertEquals("SIRNA_HCS", experiments.get(0).getExperimentTypeCode()); + List<Entry<String, String>> list = + new ArrayList<Entry<String, String>>(experiments.get(0).getProperties().entrySet()); + Collections.sort(list, new Comparator<Entry<String, String>>() + { + @Override + public int compare(Entry<String, String> e1, Entry<String, String> e2) + { + return e1.getKey().compareTo(e2.getKey()); + } + }); + assertEquals("[DESCRIPTION=very important expertiment, GENDER=FEMALE, " + + "PURCHASE_DATE=2009-02-09 00:00:00 +0100]", list.toString()); + assertEquals(1, experiments.size()); + } + @Test public void testSearchForSamples() { diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java index dc72fd147bb7486aa59cbd25af975ce0a384e9ea..388df743eef71bff144c84a782fcd877a4f0b944 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java @@ -31,6 +31,7 @@ import java.util.Date; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; +import java.util.Map.Entry; import org.springframework.beans.factory.annotation.Autowired; import org.testng.annotations.AfterMethod; @@ -1153,6 +1154,58 @@ public class GeneralInformationServiceTest extends SystemTestCase dataSets.toString()); } + @Test + public void testSearchForExperimentsByCode() + { + SearchCriteria searchCriteria = new SearchCriteria(); + searchCriteria.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.CODE, + "EXP1*")); + + List<Experiment> experiments = + generalInformationService.searchForExperiments(sessionToken, searchCriteria); + + assertEntities("[/CISD/NEMO/EXP1, /CISD/NEMO/EXP10, /CISD/NEMO/EXP11]", experiments); + } + + @Test + public void testSearchForExperimentsByProject() + { + SearchCriteria searchCriteria = new SearchCriteria(); + searchCriteria.addMatchClause(MatchClause.createAttributeMatch( + MatchClauseAttribute.PROJECT, "NOE")); + + List<Experiment> experiments = + generalInformationService.searchForExperiments(sessionToken, searchCriteria); + + assertEntities("[/CISD/NOE/EXP-TEST-2]", experiments); + } + + @Test + public void testSearchForExperimentsByProperty() + { + SearchCriteria searchCriteria = new SearchCriteria(); + searchCriteria.addMatchClause(MatchClause.createPropertyMatch("GENDER", "FEMALE")); + + List<Experiment> experiments = + generalInformationService.searchForExperiments(sessionToken, searchCriteria); + + assertEquals("/CISD/NEMO/EXP-TEST-2", experiments.get(0).getIdentifier()); + assertEquals("SIRNA_HCS", experiments.get(0).getExperimentTypeCode()); + List<Entry<String, String>> list = + new ArrayList<Entry<String, String>>(experiments.get(0).getProperties().entrySet()); + Collections.sort(list, new Comparator<Entry<String, String>>() + { + @Override + public int compare(Entry<String, String> e1, Entry<String, String> e2) + { + return e1.getKey().compareTo(e2.getKey()); + } + }); + assertEquals("[DESCRIPTION=very important expertiment, GENDER=FEMALE, " + + "PURCHASE_DATE=2009-02-09 00:00:00 +0100]", list.toString()); + assertEquals(1, experiments.size()); + } + @Test public void testGetDefaultPutDataStoreBaseURL() { diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java index 800f30a27252bab2da81e3f46e24df98028d782c..3fd3e8b30a64615039b3c7f245320491c9d74d84 100644 --- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java +++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java @@ -439,6 +439,14 @@ public interface IGeneralInformationService extends IRpcService * @since 1.9 */ public List<Experiment> listExperiments(String sessionToken, List<String> experimentIdentifiers); + + /** + * Returns all experiments matching specified search criteria. Note, that sub criterias are not + * supported. + * + * @since 1.21 + */ + public List<Experiment> searchForExperiments(String sessionToken, SearchCriteria searchCriteria); /** * Returns all available projects.