diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java index 6286b79010e9f3206423ee64cd25ee0305709f89..c494714294d010c001a9f26bca3a0663c416095e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java @@ -21,29 +21,28 @@ import java.util.List; import com.extjs.gxt.ui.client.event.KeyboardEvents; import com.extjs.gxt.ui.client.widget.VerticalPanel; +import com.google.gwt.user.client.Element; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriterion; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection; /** - * Widget for {@link DetailedSearchCriteria} management. + * Abstract widget for management of detailed search criteria (main criteria or sub criteria). * * @author Izabela Adamczyk * @author Piotr Buczek */ -public class DetailedSearchCriteriaWidget extends VerticalPanel +abstract public class DetailedSearchCriteriaWidget extends VerticalPanel { public static final String FIRST_ID_SUFFIX = "_first"; private final List<DetailedSearchCriterionWidget> criteriaWidgets; - private final MatchCriteriaRadio matchRadios; - private final IViewContext<ICommonClientServiceAsync> viewContext; private final EntityKind entityKind; @@ -55,13 +54,25 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel this.entityKind = entityKind; setLayoutOnChange(true); criteriaWidgets = new ArrayList<DetailedSearchCriterionWidget>(); - add(matchRadios = - new MatchCriteriaRadio(viewContext.getMessage(Dict.MATCH_ALL), viewContext - .getMessage(Dict.MATCH_ANY))); + } + + protected abstract SearchCriteriaConnection getConnection(); + + protected abstract void setConnection(SearchCriteriaConnection connection); + + protected void addInitialWidgets() + { addCriterion(new DetailedSearchCriterionWidget(viewContext, this, FIRST_ID_SUFFIX, this.entityKind)); } + @Override + protected void onRender(Element parent, int pos) + { + super.onRender(parent, pos); + addInitialWidgets(); + } + private void enableRemovalIfOneExists(final boolean enable) { if (criteriaWidgets.size() == 1) @@ -126,11 +137,10 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel /** * @return <b>search criteria</b> extracted from criteria widgets and "match" radio buttons<br> - * <b>null</b> if no criteria were selected + * <b>NOTE:</b> criterion list of resulting criteria may be empty */ - public DetailedSearchCriteria tryGetCriteria() + public DetailedSearchCriteria extractCriteria() { - List<DetailedSearchCriterion> criteria = new ArrayList<DetailedSearchCriterion>(); for (DetailedSearchCriterionWidget cw : criteriaWidgets) { @@ -140,24 +150,19 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel criteria.add(value); } } - if (criteria.size() > 0) - { - final DetailedSearchCriteria result = new DetailedSearchCriteria(); - result.setUseWildcardSearchMode(viewContext.getDisplaySettingsManager() - .isUseWildcardSearchMode()); - result.setConnection(matchRadios.getSelected()); - result.setCriteria(criteria); - return result; - } - return null; - + final DetailedSearchCriteria result = new DetailedSearchCriteria(); + result.setUseWildcardSearchMode(viewContext.getDisplaySettingsManager() + .isUseWildcardSearchMode()); + result.setConnection(getConnection()); + result.setCriteria(criteria); + return result; } /** description of the search criteria for the user */ public String getCriteriaDescription() { StringBuffer sb = new StringBuffer(); - sb.append(matchRadios.getSelectedLabel()); + sb.append(getConnection().getLabel()); sb.append(": "); boolean first = true; for (DetailedSearchCriterionWidget cw : criteriaWidgets) @@ -178,13 +183,25 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel return sb.toString(); } + public boolean isCriteriaFilled() + { + for (DetailedSearchCriterionWidget cw : criteriaWidgets) + { + DetailedSearchCriterion value = cw.tryGetValue(); + if (value != null) + { + return true; + } + } + return false; + } + /** * Resets "match criteria" radio buttons to initial values, removes unnecessary criteria widgets * and resets the remaining ones. */ public void reset() { - matchRadios.reset(); List<DetailedSearchCriterionWidget> list = new ArrayList<DetailedSearchCriterionWidget>(criteriaWidgets); for (DetailedSearchCriterionWidget cw : list) @@ -220,7 +237,7 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel addCriterion(widget); } - matchRadios.setValue(searchCriteria.getConnection()); + setConnection(searchCriteria.getConnection()); } void onEnterKey() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java new file mode 100644 index 0000000000000000000000000000000000000000..a8b797bd989578d8ffa6ad6ae51caa7e66bbab24 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java @@ -0,0 +1,70 @@ +/* + * 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.client.application.ui.search; + +import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection; + +/** + * Widget for {@link DetailedSearchCriteria} management. + * + * @author Izabela Adamczyk + * @author Piotr Buczek + */ +public class DetailedSearchMainCriteriaWidget extends DetailedSearchCriteriaWidget +{ + private final MatchCriteriaRadio matchRadios; + + public DetailedSearchMainCriteriaWidget(IViewContext<ICommonClientServiceAsync> viewContext, + EntityKind entityKind) + { + super(viewContext, entityKind); + matchRadios = + new MatchCriteriaRadio(viewContext.getMessage(Dict.MATCH_ALL), + viewContext.getMessage(Dict.MATCH_ANY)); + } + + @Override + protected void addInitialWidgets() + { + add(matchRadios); + super.addInitialWidgets(); + } + + @Override + public void reset() + { + matchRadios.reset(); + super.reset(); + } + + @Override + protected SearchCriteriaConnection getConnection() + { + return matchRadios.getSelected(); + } + + @Override + protected void setConnection(SearchCriteriaConnection connection) + { + matchRadios.setValue(connection); + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java new file mode 100644 index 0000000000000000000000000000000000000000..8998f04c74dd88503ce1e5359db21ce04d7237e0 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java @@ -0,0 +1,76 @@ +/* + * 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.client.application.ui.search; + +import com.extjs.gxt.ui.client.widget.Label; + +import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AssociatedEntityKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection; + +/** + * Widget for {@link DetailedSearchSubCriteria} management. + * + * @author Piotr Buczek + */ +public class DetailedSearchSubCriteriaWidget extends DetailedSearchCriteriaWidget +{ + private AssociatedEntityKind association; + + private SearchCriteriaConnection connection; + + public DetailedSearchSubCriteriaWidget(IViewContext<ICommonClientServiceAsync> viewContext, + AssociatedEntityKind association) + { + super(viewContext, association.getEntityKind()); + this.association = association; + setConnection(SearchCriteriaConnection.MATCH_ALL); + } + + @Override + protected void addInitialWidgets() + { + add(new Label(association.getDescription())); + super.addInitialWidgets(); + } + + @Override + protected SearchCriteriaConnection getConnection() + { + return connection; + } + + @Override + protected void setConnection(SearchCriteriaConnection connection) + { + this.connection = connection; + } + + @Override + public String getCriteriaDescription() + { + return association.getDescription() + "(" + super.getCriteriaDescription() + ")"; + } + + public DetailedSearchSubCriteria extractSubCriteria() + { + return new DetailedSearchSubCriteria(association, extractCriteria()); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java index 99914a13c11f13c5335a718383de1a7f6d4c739f..a5181449e0b45c3c70f8e1349039b6ced047b4cf 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java @@ -1,5 +1,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.extjs.gxt.ui.client.Style.Scroll; @@ -12,8 +14,7 @@ import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.widget.Dialog; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.button.ButtonBar; -import com.extjs.gxt.ui.client.widget.layout.FitData; -import com.extjs.gxt.ui.client.widget.layout.FitLayout; +import com.extjs.gxt.ui.client.widget.layout.FillLayout; import com.google.gwt.event.dom.client.KeyCodes; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; @@ -22,7 +23,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte import ch.systemsx.cisd.openbis.generic.client.web.client.application.help.HelpPageIdentifier; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetSearchHitGrid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.DialogWithOnlineHelpUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AssociatedEntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; @@ -36,7 +39,7 @@ public class DetailedSearchWindow extends Dialog { public static final String SEARCH_BUTTON_ID = DataSetSearchHitGrid.BROWSER_ID + "search_button"; - private static final int MARGIN = 5; + // private static final int MARGIN = 5; private static final int HEIGHT = 400; @@ -44,6 +47,9 @@ public class DetailedSearchWindow extends Dialog private DetailedSearchCriteriaWidget criteriaWidget; + private List<DetailedSearchSubCriteriaWidget> subCriteriaWidgets = + new ArrayList<DetailedSearchSubCriteriaWidget>(); + private DetailedSearchToolbar updateListener; public DetailedSearchWindow(final IViewContext<ICommonClientServiceAsync> viewContext, @@ -52,10 +58,18 @@ public class DetailedSearchWindow extends Dialog setSize(WIDTH, HEIGHT); setModal(true); setScrollMode(Scroll.AUTOY); - setLayout(new FitLayout()); + setLayout(new FillLayout()); setResizable(false); - add(criteriaWidget = new DetailedSearchCriteriaWidget(viewContext, entityKind), - new FitData(MARGIN)); + add(criteriaWidget = new DetailedSearchMainCriteriaWidget(viewContext, entityKind)); + for (AssociatedEntityKind association : getAssociatedEntityKinds(entityKind)) + { + DetailedSearchSubCriteriaWidget subCriteriaWidget = + new DetailedSearchSubCriteriaWidget(viewContext, association); + subCriteriaWidgets.add(subCriteriaWidget); + add(subCriteriaWidget); + } + // new FitData(MARGIN)); + // new FitData(MARGIN)); addEnterListener(); final ButtonBar bar = getButtonBar(); bar.removeAll(); @@ -75,6 +89,10 @@ public class DetailedSearchWindow extends Dialog public void componentSelected(ButtonEvent ce) { criteriaWidget.reset(); + for (DetailedSearchCriteriaWidget widget : subCriteriaWidgets) + { + widget.reset(); + } } })); final Button searchButton = @@ -114,6 +132,7 @@ public class DetailedSearchWindow extends Dialog } }); + // TODO improve } @Override @@ -125,12 +144,46 @@ public class DetailedSearchWindow extends Dialog public DetailedSearchCriteria tryGetCriteria() { - return criteriaWidget.tryGetCriteria(); + final DetailedSearchCriteria mainCriteria = criteriaWidget.extractCriteria(); + for (DetailedSearchSubCriteriaWidget subCriteriaWidget : subCriteriaWidgets) + { + if (subCriteriaWidget.isCriteriaFilled()) + { + final DetailedSearchSubCriteria subCriteria = + subCriteriaWidget.extractSubCriteria(); + mainCriteria.addSubCriteria(subCriteria); + } + } + + if (mainCriteria.isEmpty()) + { + return null; + } else + { + return mainCriteria; + } } public String getCriteriaDescription() { - return criteriaWidget.getCriteriaDescription(); + StringBuilder sb = new StringBuilder(); + if (criteriaWidget.isCriteriaFilled()) + { + sb.append(criteriaWidget.getCriteriaDescription()); + } + for (DetailedSearchCriteriaWidget subCriteriaWidget : subCriteriaWidgets) + { + if (subCriteriaWidget.isCriteriaFilled()) + { + sb.append(", "); + sb.append(subCriteriaWidget.getCriteriaDescription()); + } + } + if (criteriaWidget.isCriteriaFilled() == false) + { + sb.delete(0, 2); + } + return sb.toString(); } public void setUpdateListener(DetailedSearchToolbar toolbar) @@ -169,8 +222,22 @@ public class DetailedSearchWindow extends Dialog { hide(); List<PropertyType> availablePropertyTypes = criteriaWidget.getAvailablePropertyTypes(); - DetailedSearchCriteria criteria = criteriaWidget.tryGetCriteria(); - String criteriaDescription = criteriaWidget.getCriteriaDescription(); + DetailedSearchCriteria criteria = tryGetCriteria(); + String criteriaDescription = getCriteriaDescription(); updateListener.updateSearchResults(criteria, criteriaDescription, availablePropertyTypes); } + + private static List<AssociatedEntityKind> getAssociatedEntityKinds(final EntityKind sourceEntity) + { + // TODO 2011-05-06, Piotr Buczek: use + // AssociatedEntityKind.getAssociatedEntityKinds(sourceEntity) + // after extending data set search + if (sourceEntity == EntityKind.SAMPLE) + { + return AssociatedEntityKind.getAssociatedEntityKinds(sourceEntity); + } else + { + return Collections.emptyList(); + } + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java index cb9d71fc0d766c218c41b05fa3ba690e1051707f..c7ecf7a1b7d2557f9b4429a6814b8d639f819c2c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java @@ -1,12 +1,10 @@ package ch.systemsx.cisd.openbis.generic.client.web.server; -import java.util.Collections; import java.util.List; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria; import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; /** @@ -39,8 +37,7 @@ final class ListSamplesOriginalDataProvider extends AbstractOriginalDataProvider case BROWSE: return commonServer.listSamples(sessionToken, criteria.getBrowseCriteria()); case SEARCH: - return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria(), - Collections.<DetailedSearchSubCriteria> emptyList()); + return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria()); } return null; // not possible } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java index 19bab51b8f9b8e4d258d9d5ff6e42871a18b6c06..c1bd667814bd9bfd1e076169e4589e0e373ede2d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java @@ -34,7 +34,6 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridC import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SPACE; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SUBCODE; -import java.util.Collections; import java.util.List; import java.util.Set; @@ -44,7 +43,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayC import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; @@ -204,8 +202,7 @@ public class SampleProvider extends AbstractCommonTableModelProvider<Sample> case BROWSE: return commonServer.listSamples(sessionToken, criteria.getBrowseCriteria()); case SEARCH: - return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria(), - Collections.<DetailedSearchSubCriteria> emptyList()); + return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria()); } return null; // not possible } 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 4d6c378db8e1a9611a80de3bfb7fb23caf1b5422..daaac03b22b104011ab5753fb6e44e1079eeef29 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 @@ -470,6 +470,20 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt return sampleLister.list(new ListOrSearchSampleCriteria(criteria)); } + public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria) + { + final Session session = getSession(sessionToken); + try + { + final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); + final IHibernateSearchDAO searchDAO = getDAOFactory().getHibernateSearchDAO(); + return new DetailedSearchManager(searchDAO, sampleLister).searchForSamples(criteria); + } catch (final DataAccessException ex) + { + throw createUserFailureException(ex); + } + } + public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria, List<DetailedSearchSubCriteria> subCriterias) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java index 74e1501b10d974346bbcd00e610f1af4cdafcfea..59cddcbfed58c8949d6b3290aa109a778cf5bf1e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java @@ -57,6 +57,54 @@ public class DetailedSearchManager this.sampleLister = sampleLister; } + public List<Sample> searchForSamples(DetailedSearchCriteria criteria) + throws DataAccessException + { + final DetailedSearchCriteria parentCriteria = new DetailedSearchCriteria(); + final DetailedSearchCriteria childCriteria = new DetailedSearchCriteria(); + final List<DetailedSearchSubCriteria> otherSubCriterias = + new ArrayList<DetailedSearchSubCriteria>(); + groupSampleSubCriteria(criteria.getSubCriterias(), parentCriteria, childCriteria, + otherSubCriterias); + + final List<Long> mainSampleIds = findSampleIds(criteria, otherSubCriterias); + + final Set<Long> filteredSampleIds = new HashSet<Long>(); + if (false == parentCriteria.isEmpty()) + { + final List<Long> parentSampleIds = + findSampleIds(parentCriteria, + Collections.<DetailedSearchSubCriteria> emptyList()); + if (mainSampleIds.size() > parentSampleIds.size()) + { + listParentsChildrenAndFilterChildren(mainSampleIds, parentSampleIds, + filteredSampleIds); + } else + { + listChildrensParentsAndFilterChildren(mainSampleIds, parentSampleIds, + filteredSampleIds); + } + } else if (false == childCriteria.isEmpty()) + { + final List<Long> childSampleIds = + findSampleIds(childCriteria, + Collections.<DetailedSearchSubCriteria> emptyList()); + if (mainSampleIds.size() > childSampleIds.size()) + { + listChildrensParentsAndFilterParents(childSampleIds, mainSampleIds, + filteredSampleIds); + } else + { + listParentsChildrenAndFilterParents(childSampleIds, mainSampleIds, + filteredSampleIds); + } + } else + { + filteredSampleIds.addAll(mainSampleIds); + } + return sampleLister.list(new ListOrSearchSampleCriteria(filteredSampleIds)); + } + public List<Sample> searchForSamples(DetailedSearchCriteria criteria, List<DetailedSearchSubCriteria> subCriterias) throws DataAccessException { 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 2c3f884e7c96cad1125d1a00ea253e4d2aafcb62..de4d0ad93a618d5f2d5a3508e091eb64a4afd84a 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 @@ -577,6 +577,14 @@ public interface ICommonServer extends IServer public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria, List<DetailedSearchSubCriteria> subCriterias); + /** + * Performs an <i>Hibernate Search</i> based on given parameters. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @ReturnValueFilter(validatorClass = SampleValidator.class) + public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria); + /** * Returns all data sets related to specified entities. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java index e50c8df8b0efa856f8712613fefce5079c999e13..e85d5ca516236e4e7ae72d536e7cdf321176d05b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java @@ -16,6 +16,11 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; /** @@ -26,24 +31,29 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; */ public enum AssociatedEntityKind implements ISerializable { - SAMPLE("Sample", EntityKind.SAMPLE), + SAMPLE("Sample", EntityKind.SAMPLE, EnumSet.of(EntityKind.DATA_SET)), - EXPERIMENT("Experiment", EntityKind.EXPERIMENT), + EXPERIMENT("Experiment", EntityKind.EXPERIMENT, EnumSet.of(EntityKind.SAMPLE, + EntityKind.DATA_SET)), - SAMPLE_CONTAINER("Container", EntityKind.SAMPLE), + SAMPLE_CONTAINER("Container", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE)), - SAMPLE_PARENT("Parent", EntityKind.SAMPLE), + SAMPLE_PARENT("Parent", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE)), - SAMPLE_CHILD("Child", EntityKind.SAMPLE); + SAMPLE_CHILD("Child", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE)); private final String description; private final EntityKind entityKind; - private AssociatedEntityKind(final String description, final EntityKind entityKind) + private final Set<EntityKind> sourceEntityKinds; + + private AssociatedEntityKind(final String description, final EntityKind entityKind, + final Set<EntityKind> sourceEntityKinds) { this.description = description; this.entityKind = entityKind; + this.sourceEntityKinds = sourceEntityKinds; } public final String getDescription() @@ -56,4 +66,17 @@ public enum AssociatedEntityKind implements ISerializable return entityKind; } + public static List<AssociatedEntityKind> getAssociatedEntityKinds(EntityKind sourceEntity) + { + List<AssociatedEntityKind> result = new ArrayList<AssociatedEntityKind>(); + for (AssociatedEntityKind associatedEntityKind : values()) + { + if (associatedEntityKind.sourceEntityKinds.contains(sourceEntity)) + { + result.add(associatedEntityKind); + } + } + return result; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java index a266675ba0ab7e293ef30241be79580529c1f3b4..3dad9cfe52e68c87c48155e22077b08eae3b9b04 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto; +import java.util.ArrayList; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; @@ -36,6 +37,9 @@ public class DetailedSearchCriteria implements ISerializable private boolean useWildcardSearchMode; + private List<DetailedSearchSubCriteria> subCriterias = + new ArrayList<DetailedSearchSubCriteria>(); + public DetailedSearchCriteria() { } @@ -50,6 +54,21 @@ public class DetailedSearchCriteria implements ISerializable this.criteria = criteria; } + public List<DetailedSearchSubCriteria> getSubCriterias() + { + return subCriterias; + } + + public void setSubCriterias(List<DetailedSearchSubCriteria> subCriterias) + { + this.subCriterias = subCriterias; + } + + public void addSubCriteria(DetailedSearchSubCriteria subCriteria) + { + subCriterias.add(subCriteria); + } + public SearchCriteriaConnection getConnection() { return connection; @@ -72,7 +91,7 @@ public class DetailedSearchCriteria implements ISerializable public boolean isEmpty() { - return criteria == null || criteria.isEmpty(); + return (criteria == null || criteria.isEmpty()) && subCriterias.isEmpty(); } @Override @@ -90,6 +109,14 @@ public class DetailedSearchCriteria implements ISerializable sb.append(element); } } + for (DetailedSearchSubCriteria subCriteria : subCriterias) + { + if (sb.length() > 0) + { + sb.append(", "); + } + sb.append(subCriteria.getTargetEntityKind() + ": " + subCriteria.toString()); + } sb.append(" (" + (isUseWildcardSearchMode() ? "with" : "without") + " wildcards)"); return sb.toString(); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java index 979ce58dc59e380057cc49b8c8fb4d0c31e397cd..1206e5b54322fa53a181587fcf280006b21f0f63 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java @@ -57,4 +57,9 @@ public class DetailedSearchSubCriteria implements ISerializable return sb.toString(); } + // GWT only + @SuppressWarnings("unused") + private DetailedSearchSubCriteria() + { + } } 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 2c3f884e7c96cad1125d1a00ea253e4d2aafcb62..de4d0ad93a618d5f2d5a3508e091eb64a4afd84a 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 @@ -577,6 +577,14 @@ public interface ICommonServer extends IServer public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria, List<DetailedSearchSubCriteria> subCriterias); + /** + * Performs an <i>Hibernate Search</i> based on given parameters. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @ReturnValueFilter(validatorClass = SampleValidator.class) + public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria); + /** * Returns all data sets related to specified entities. */