From e9331c4ae5820c00c6b1ec47c9f4a93b9347fe2e Mon Sep 17 00:00:00 2001 From: anttil <anttil> Date: Fri, 29 Jan 2016 12:35:12 +0000 Subject: [PATCH] SSDM-3078: Global search should have only one row per entity, and only one column for the match SVN: 35594 --- .../application/MatchingEntitiesPanel.java | 18 +- .../web/client/application/SearchWidget.java | 2 +- .../dto/MatchingEntitiesPanelColumnIDs.java | 10 +- .../resultset/MatchingEntitiesProvider.java | 15 +- .../openbis/generic/server/CommonServer.java | 177 +++++++----------- .../dataaccess/db/HibernateSearchDAO.java | 163 +++++++++++----- .../shared/basic/dto/MatchingEntity.java | 46 +++-- .../dto/ExperimentGlobalSearchBridge.java | 2 +- .../shared/dto/GlobalSearchBridge.java | 17 +- .../shared/dto/SampleGlobalSearchBridge.java | 3 +- .../openbis/generic/shared/util/IColumn.java | 5 + .../shared/util/TypedTableModelBuilder.java | 15 +- .../cisd/openbis/public/common-dictionary.js | 4 +- .../dataaccess/db/HibernateSearchDAOTest.java | 8 +- 14 files changed, 273 insertions(+), 212 deletions(-) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java index 1dc81bfc053..3caa574e185 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java @@ -18,7 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.ENTITY_TYPE; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.IDENTIFIER; -import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.MATCHING_FIELD; +import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.MATCH; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.REGISTRATOR; import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.createOrDelete; import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.edit; @@ -189,6 +189,7 @@ public final class MatchingEntitiesPanel extends TypedTableGrid<MatchingEntity> super.createColumnsDefinition(); schema.setGridCellRendererFor(REGISTRATOR, PersonRenderer.REGISTRATOR_RENDERER); schema.setGridCellRendererFor(IDENTIFIER, createInternalLinkCellRenderer()); + schema.setGridCellRendererFor(MATCH, createMultilineStringCellRenderer()); return schema; } @@ -221,19 +222,18 @@ public final class MatchingEntitiesPanel extends TypedTableGrid<MatchingEntity> @Override protected List<String> getColumnIdsOfFilters() { - return Arrays.asList(ENTITY_TYPE, IDENTIFIER, MATCHING_FIELD); + return Arrays.asList(ENTITY_TYPE, IDENTIFIER, MATCH); } @Override public DatabaseModificationKind[] getRelevantModifications() { - return new DatabaseModificationKind[] - { createOrDelete(ObjectKind.MATERIAL), edit(ObjectKind.MATERIAL), - createOrDelete(ObjectKind.SAMPLE), edit(ObjectKind.SAMPLE), - createOrDelete(ObjectKind.EXPERIMENT), edit(ObjectKind.EXPERIMENT), - createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT), - edit(ObjectKind.PROPERTY_TYPE_ASSIGNMENT), - createOrDelete(ObjectKind.VOCABULARY_TERM), edit(ObjectKind.VOCABULARY_TERM) }; + return new DatabaseModificationKind[] { createOrDelete(ObjectKind.MATERIAL), edit(ObjectKind.MATERIAL), + createOrDelete(ObjectKind.SAMPLE), edit(ObjectKind.SAMPLE), + createOrDelete(ObjectKind.EXPERIMENT), edit(ObjectKind.EXPERIMENT), + createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT), + edit(ObjectKind.PROPERTY_TYPE_ASSIGNMENT), + createOrDelete(ObjectKind.VOCABULARY_TERM), edit(ObjectKind.VOCABULARY_TERM) }; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java index 31ddd6c5c1d..d7edba1a04c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java @@ -198,7 +198,7 @@ public final class SearchWidget extends LayoutContainer boolean onlyWildcard = true; for (final char c : queryText.toCharArray()) { - if (c != '*' && c != '?') + if (c != '*' && c != '?' && c != '|') // '|||' is a delimiter in field global_search in index { onlyWildcard = false; break; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/MatchingEntitiesPanelColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/MatchingEntitiesPanelColumnIDs.java index e3354f0e4a2..f5b5278be6a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/MatchingEntitiesPanelColumnIDs.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/MatchingEntitiesPanelColumnIDs.java @@ -26,9 +26,15 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.MatchingEn public class MatchingEntitiesPanelColumnIDs { public static final String ENTITY_KIND = "ENTITY_KIND"; + public static final String ENTITY_TYPE = "ENTITY_TYPE"; + public static final String IDENTIFIER = "IDENTIFIER"; + public static final String REGISTRATOR = "REGISTRATOR"; - public static final String MATCHING_FIELD = "MATCHING_FIELD"; - public static final String MATCHING_TEXT = "MATCHING_TEXT"; + + public static final String MATCH = "MATCH"; + + public static final String RANK = "RANK"; + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/MatchingEntitiesProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/MatchingEntitiesProvider.java index d802dad3198..2e59f5df2d7 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/MatchingEntitiesProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/MatchingEntitiesProvider.java @@ -19,13 +19,14 @@ package ch.systemsx.cisd.openbis.generic.client.web.server.resultset; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.ENTITY_KIND; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.ENTITY_TYPE; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.IDENTIFIER; -import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.MATCHING_FIELD; -import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.MATCHING_TEXT; +import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.MATCH; +import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.RANK; import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntitiesPanelColumnIDs.REGISTRATOR; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MatchingEntity; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableModel; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity; @@ -69,8 +70,9 @@ public class MatchingEntitiesProvider implements ITableModelProvider<MatchingEnt builder.addColumn(ENTITY_TYPE); builder.addColumn(IDENTIFIER).withDefaultWidth(140); builder.addColumn(REGISTRATOR); - builder.addColumn(MATCHING_FIELD).withDefaultWidth(140); - builder.addColumn(MATCHING_TEXT).withDefaultWidth(200); + builder.addColumn(MATCH).withDefaultWidth(200).withDataType(DataTypeCode.MULTILINE_VARCHAR); + builder.addColumn(RANK); + long rank = 1; for (MatchingEntity matchingEntity : entities) { builder.addRow(matchingEntity); @@ -78,8 +80,9 @@ public class MatchingEntitiesProvider implements ITableModelProvider<MatchingEnt builder.column(ENTITY_TYPE).addString(matchingEntity.getEntityType().getCode()); builder.column(IDENTIFIER).addString(matchingEntity.getIdentifier()); builder.column(REGISTRATOR).addPerson(matchingEntity.getRegistrator()); - builder.column(MATCHING_FIELD).addString(matchingEntity.getFieldDescription()); - builder.column(MATCHING_TEXT).addString(matchingEntity.getTextFragment()); + builder.column(MATCH).addMultilineValue(matchingEntity.getMatch()); + builder.column(RANK).addInteger(rank); + rank++; } return builder.getModel(); } 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 4eddb96b3fd..15a389b0e4d 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 @@ -249,7 +249,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils; -public final class CommonServer extends AbstractCommonServer<ICommonServerForInternalUse> implements +public final class CommonServer extends AbstractCommonServer<ICommonServerForInternalUse>implements ICommonServerForInternalUse { private final LastModificationState lastModificationState; @@ -401,7 +401,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Capability("UPDATE_SPACE") public void updateSpace(final String sessionToken, @AuthorizationGuard(guardClass = SpaceUpdatesPredicate.class) - final ISpaceUpdates updates) + final ISpaceUpdates updates) { assert sessionToken != null : "Unspecified session token"; assert updates != null : "Unspecified updates"; @@ -431,8 +431,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN) public void registerSpaceRole(String sessionToken, RoleCode roleCode, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - SpaceIdentifier spaceIdentifier, Grantee grantee) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) SpaceIdentifier spaceIdentifier, Grantee grantee) { final Session session = getSession(sessionToken); @@ -467,8 +466,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN) public void deleteSpaceRole(String sessionToken, RoleCode roleCode, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - SpaceIdentifier spaceIdentifier, Grantee grantee) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) SpaceIdentifier spaceIdentifier, Grantee grantee) { final Session session = getSession(sessionToken); @@ -619,7 +617,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @ReturnValueFilter(validatorClass = SampleValidator.class) public List<Sample> listSamples(final String sessionToken, @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class) - final ListSampleCriteria criteria) + final ListSampleCriteria criteria) { final Session session = getSession(sessionToken); final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); @@ -660,7 +658,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @ReturnValueFilter(validatorClass = SampleValidator.class) public List<Sample> listSamplesOnBehalfOfUser(final String sessionToken, @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class) - final ListSampleCriteria criteria, String userId) + final ListSampleCriteria criteria, String userId) { final Session session = getSession(sessionToken); @@ -703,7 +701,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @ReturnValueFilter(validatorClass = ExternalDataValidator.class) public List<AbstractExternalData> listSampleExternalData(final String sessionToken, @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) - final TechId sampleId, final boolean showOnlyDirectlyConnected) + final TechId sampleId, final boolean showOnlyDirectlyConnected) { final Session session = getSession(sessionToken); final IDatasetLister datasetLister = createDatasetLister(session); @@ -718,7 +716,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @ReturnValueFilter(validatorClass = ExternalDataValidator.class) public List<AbstractExternalData> listExperimentExternalData(final String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) - final TechId experimentId, boolean showOnlyDirectlyConnected) + final TechId experimentId, boolean showOnlyDirectlyConnected) { final Session session = getSession(sessionToken); final IDatasetLister datasetLister = createDatasetLister(session); @@ -762,7 +760,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @ReturnValueFilter(validatorClass = ExternalDataValidator.class) public List<AbstractExternalData> listDataSetRelationships(final String sessionToken, @AuthorizationGuard(guardClass = DataSetTechIdPredicate.class) - final TechId datasetId, final DataSetRelationshipRole role) + final TechId datasetId, final DataSetRelationshipRole role) { final Session session = getSession(sessionToken); final IDatasetLister datasetLister = createDatasetLister(session); @@ -910,6 +908,14 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt useWildcardSearchMode, list.size(), maxSize); list.addAll(entities); } + Collections.sort(list, new Comparator<MatchingEntity>() + { + @Override + public int compare(MatchingEntity o1, MatchingEntity o2) + { + return new Double(o2.getScore()).compareTo(o1.getScore()); + } + }); return list; } @@ -954,8 +960,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperiments(final String sessionToken, ExperimentType experimentType, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - ProjectIdentifier projectIdentifier) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier) { List<ProjectIdentifier> projectIdentifiers = projectIdentifier != null ? Collections.singletonList(projectIdentifier) : null; return listExperiments(sessionToken, experimentType, null, projectIdentifiers, false, false); @@ -965,8 +970,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperiments(final String sessionToken, ExperimentType experimentType, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - List<ProjectIdentifier> projectIdentifiers) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ProjectIdentifier> projectIdentifiers) { return listExperiments(sessionToken, experimentType, null, projectIdentifiers, false, false); } @@ -975,8 +979,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperimentsHavingSamples(final String sessionToken, ExperimentType experimentType, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - List<ProjectIdentifier> projectIdentifiers) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ProjectIdentifier> projectIdentifiers) { return listExperiments(sessionToken, experimentType, null, projectIdentifiers, true, false); } @@ -985,8 +988,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperimentsHavingDataSets(final String sessionToken, ExperimentType experimentType, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - List<ProjectIdentifier> projectIdentifiers) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ProjectIdentifier> projectIdentifiers) { return listExperiments(sessionToken, experimentType, null, projectIdentifiers, false, true); } @@ -995,8 +997,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperiments(final String sessionToken, ExperimentType experimentType, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - SpaceIdentifier spaceIdentifier) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) SpaceIdentifier spaceIdentifier) { return listExperiments(sessionToken, experimentType, spaceIdentifier, null, false, false); } @@ -1004,8 +1005,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Experiment> listExperiments(final String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - List<ExperimentIdentifier> experimentIdentifiers) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ExperimentIdentifier> experimentIdentifiers) { Session session = getSession(sessionToken); IExperimentTable experimentTable = businessObjectFactory.createExperimentTable(session); @@ -1575,8 +1575,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("REGISTER_PROJECT") public void registerProject(String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - ProjectIdentifier projectIdentifier, String description, String leaderId, + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier, String description, String leaderId, Collection<NewAttachment> attachments) { final Session session = getSession(sessionToken); @@ -1675,8 +1674,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public AbstractExternalData getDataSetInfo(String sessionToken, - @AuthorizationGuard(guardClass = DataSetTechIdPredicate.class) - TechId datasetId) + @AuthorizationGuard(guardClass = DataSetTechIdPredicate.class) TechId datasetId) { final Session session = getSession(sessionToken); final IDataBO datasetBO = businessObjectFactory.createDataBO(session); @@ -1698,8 +1696,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("WRITE_DATASET") public DataSetUpdateResult updateDataSet(String sessionToken, - @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class) - DataSetUpdatesDTO updates) + @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class) DataSetUpdatesDTO updates) { final Session session = getSession(sessionToken); final IDataBO dataSetBO = businessObjectFactory.createDataBO(session); @@ -2038,8 +2035,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_DATASET") public void deleteDataSets(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> dataSetCodes, String reason, DeletionType type, boolean isTrashEnabled) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes, String reason, DeletionType type, + boolean isTrashEnabled) { deleteDataSetsCommon(sessionToken, dataSetCodes, reason, type, false, isTrashEnabled); } @@ -2048,8 +2045,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.INSTANCE_DISABLED) @Capability("FORCE_DELETE_DATASET") public void deleteDataSetsForced(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> dataSetCodes, String reason, DeletionType type, boolean isTrashEnabled) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes, String reason, DeletionType type, + boolean isTrashEnabled) { deleteDataSetsCommon(sessionToken, dataSetCodes, reason, type, true, isTrashEnabled); } @@ -2100,8 +2097,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_SAMPLE") public void deleteSamples(String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdCollectionPredicate.class) - List<TechId> sampleIds, String reason, DeletionType deletionType) + @AuthorizationGuard(guardClass = SampleTechIdCollectionPredicate.class) List<TechId> sampleIds, String reason, DeletionType deletionType) { Session session = getSession(sessionToken); switch (deletionType) @@ -2125,8 +2121,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_EXPERIMENT") public void deleteExperiments(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdCollectionPredicate.class) - List<TechId> experimentIds, String reason, DeletionType deletionType) + @AuthorizationGuard(guardClass = ExperimentTechIdCollectionPredicate.class) List<TechId> experimentIds, String reason, + DeletionType deletionType) { Session session = getSession(sessionToken); IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2176,8 +2172,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_PROJECT") public void deleteProjects(String sessionToken, - @AuthorizationGuard(guardClass = ProjectTechIdCollectionPredicate.class) - List<TechId> projectIds, String reason) + @AuthorizationGuard(guardClass = ProjectTechIdCollectionPredicate.class) List<TechId> projectIds, String reason) { Session session = getSession(sessionToken); IProjectBO projectBO = businessObjectFactory.createProjectBO(session); @@ -2191,8 +2186,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN) @Capability("DELETE_SPACE") public void deleteSpaces(String sessionToken, - @AuthorizationGuard(guardClass = SpaceTechIdCollectionPredicate.class) - List<TechId> spaceIds, String reason) + @AuthorizationGuard(guardClass = SpaceTechIdCollectionPredicate.class) List<TechId> spaceIds, String reason) { Session session = getSession(sessionToken); ISpaceBO spaceBO = businessObjectFactory.createSpaceBO(session); @@ -2239,8 +2233,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_EXPERIMENT_ATTACHMENT") public void deleteExperimentAttachments(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) - TechId experimentId, List<String> fileNames, String reason) + @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId, List<String> fileNames, String reason) { Session session = getSession(sessionToken); IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2279,8 +2272,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_SAMPLE_ATTACHMENT") public void deleteSampleAttachments(String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) - TechId sampleId, List<String> fileNames, String reason) + @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) TechId sampleId, List<String> fileNames, String reason) { Session session = getSession(sessionToken); ISampleBO sampleBO = businessObjectFactory.createSampleBO(session); @@ -2292,8 +2284,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_PROJECT_ATTACHMENT") public void deleteProjectAttachments(String sessionToken, - @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) - TechId projectId, List<String> fileNames, String reason) + @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) TechId projectId, List<String> fileNames, String reason) { Session session = getSession(sessionToken); IProjectBO projectBO = businessObjectFactory.createProjectBO(session); @@ -2311,8 +2302,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Attachment> listExperimentAttachments(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) - TechId experimentId) + @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId) { Session session = getSession(sessionToken); IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2325,8 +2315,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Attachment> listSampleAttachments(String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) - TechId sampleId) + @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) TechId sampleId) { Session session = getSession(sessionToken); ISampleBO sampleBO = businessObjectFactory.createSampleBO(session); @@ -2338,8 +2327,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public List<Attachment> listProjectAttachments(String sessionToken, - @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) - TechId projectId) + @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) TechId projectId) { Session session = getSession(sessionToken); IProjectBO projectBO = businessObjectFactory.createProjectBO(session); @@ -2406,7 +2394,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public SampleParentWithDerived getSampleInfo(final String sessionToken, @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) - final TechId sampleId) throws UserFailureException + final TechId sampleId) throws UserFailureException { assert sessionToken != null : "Unspecified session token."; assert sampleId != null : "Unspecified sample techId."; @@ -2422,15 +2410,15 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt session.tryGetPerson(), sample); return SampleTranslator.translate(getSampleTypeSlaveServerPlugin(sample.getSampleType()) .getSampleInfo(session, sample), session.getBaseIndexURL(), MetaprojectTranslator - .translate(metaprojectPEs), managedPropertyEvaluatorFactory); + .translate(metaprojectPEs), + managedPropertyEvaluatorFactory); } @Override @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_SAMPLE") public SampleUpdateResult updateSample(String sessionToken, - @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) - SampleUpdatesDTO updates) + @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) SampleUpdatesDTO updates) { final Session session = getSession(sessionToken); final ISampleBO sampleBO = businessObjectFactory.createSampleBO(session); @@ -2448,8 +2436,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public Experiment getExperimentInfo(String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - ExperimentIdentifier identifier) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ExperimentIdentifier identifier) { final Session session = getSession(sessionToken); final IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2476,8 +2463,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public Experiment getExperimentInfo(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) - TechId experimentId) + @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId) { final Session session = getSession(sessionToken); final IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2500,8 +2486,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_EXPERIMENT_SAMPLE") public ExperimentUpdateResult updateExperiment(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentUpdatesPredicate.class) - ExperimentUpdatesDTO updates) + @AuthorizationGuard(guardClass = ExperimentUpdatesPredicate.class) ExperimentUpdatesDTO updates) { final Session session = getSession(sessionToken); final IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session); @@ -2517,8 +2502,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public Project getProjectInfo(String sessionToken, - @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) - TechId projectId) + @AuthorizationGuard(guardClass = ProjectTechIdPredicate.class) TechId projectId) { final Session session = getSession(sessionToken); final IProjectBO bo = businessObjectFactory.createProjectBO(session); @@ -2531,8 +2515,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public Project getProjectInfo(String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) - ProjectIdentifier projectIdentifier) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier) { final Session session = getSession(sessionToken); final IProjectBO bo = businessObjectFactory.createProjectBO(session); @@ -2668,8 +2651,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("WRITE_PROJECT") public int updateProject(String sessionToken, - @AuthorizationGuard(guardClass = ProjectUpdatesPredicate.class) - ProjectUpdatesDTO updates) + @AuthorizationGuard(guardClass = ProjectUpdatesPredicate.class) ProjectUpdatesDTO updates) { final Session session = getSession(sessionToken); final IProjectBO bo = businessObjectFactory.createProjectBO(session); @@ -2780,7 +2762,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt "[%s]\n%s%s\n", entityType.getCode(), firstSection ? "# Comments must be located after the type declaration ('[TYPE]').\n" - : "", section); + : "", + section); } sb.append(section); firstSection = false; @@ -3051,8 +3034,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public TableModel createReportFromDatasets(String sessionToken, DatastoreServiceDescription serviceDescription, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3063,8 +3045,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public TableModel createReportFromDatasets(String sessionToken, String serviceKey, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3086,8 +3067,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) public void processDatasets(String sessionToken, DatastoreServiceDescription serviceDescription, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3099,8 +3079,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("ARCHIVE_DATASET") public int archiveDatasets(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes, boolean removeFromDataStore) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes, boolean removeFromDataStore) { return super.archiveDatasets(sessionToken, datasetCodes, removeFromDataStore); } @@ -3109,8 +3088,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("UNARCHIVE_DATASET") public int unarchiveDatasets(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { return super.unarchiveDatasets(sessionToken, datasetCodes); } @@ -3349,8 +3327,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_FILTER") public void deleteFilters(String sessionToken, - @AuthorizationGuard(guardClass = DeleteGridCustomFilterPredicate.class) - List<TechId> filterIds) + @AuthorizationGuard(guardClass = DeleteGridCustomFilterPredicate.class) List<TechId> filterIds) { IGridCustomFilterOrColumnBO bo = createGridCustomFilterBO(sessionToken); deleteFiltersOrColumns(filterIds, bo); @@ -3360,8 +3337,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("WRITE_FILTER") public void updateFilter(String sessionToken, - @AuthorizationGuard(guardClass = UpdateGridCustomFilterPredicate.class) - IExpressionUpdates updates) + @AuthorizationGuard(guardClass = UpdateGridCustomFilterPredicate.class) IExpressionUpdates updates) { assert updates != null : "Unspecified updates"; createGridCustomFilterBO(sessionToken).update(updates); @@ -3382,8 +3358,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("DELETE_CUSTOM_COLUMN") public void deleteGridCustomColumns(String sessionToken, - @AuthorizationGuard(guardClass = DeleteGridCustomColumnPredicate.class) - List<TechId> columnIds) + @AuthorizationGuard(guardClass = DeleteGridCustomColumnPredicate.class) List<TechId> columnIds) { IGridCustomFilterOrColumnBO bo = createGridCustomColumnBO(sessionToken); deleteFiltersOrColumns(columnIds, bo); @@ -3393,8 +3368,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_POWER_USER) @Capability("WRITE_CUSTOM_COLUMN") public void updateGridCustomColumn(String sessionToken, - @AuthorizationGuard(guardClass = UpdateGridCustomColumnPredicate.class) - IExpressionUpdates updates) + @AuthorizationGuard(guardClass = UpdateGridCustomColumnPredicate.class) IExpressionUpdates updates) { assert updates != null : "Unspecified updates"; createGridCustomColumnBO(sessionToken).update(updates); @@ -3435,8 +3409,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN) public int lockDatasets(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3447,8 +3420,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN) public int unlockDatasets(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) - List<String> datasetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3460,8 +3432,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public LinkModel retrieveLinkFromDataSet(String sessionToken, DatastoreServiceDescription serviceDescription, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) - String dataSetCode) + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String dataSetCode) { Session session = getSession(sessionToken); IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); @@ -3566,8 +3537,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public IEntityInformationHolderWithPermId getEntityInformationHolder(String sessionToken, - @AuthorizationGuard(guardClass = BasicEntityDescriptionPredicate.class) - BasicEntityDescription info) + @AuthorizationGuard(guardClass = BasicEntityDescriptionPredicate.class) BasicEntityDescription info) { Session session = getSession(sessionToken); IEntityInformationWithPropertiesHolder entity = getEntity(info, session); @@ -3784,8 +3754,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_DATASET_PROPERTIES") public void updateDataSetProperties(String sessionToken, - @AuthorizationGuard(guardClass = DataSetTechIdPredicate.class) - TechId entityId, List<PropertyUpdates> modifiedProperties) + @AuthorizationGuard(guardClass = DataSetTechIdPredicate.class) TechId entityId, List<PropertyUpdates> modifiedProperties) { checkSession(sessionToken); AbstractExternalData dataSet = getDataSetInfo(sessionToken, entityId); @@ -3823,8 +3792,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_EXPERIMENT_PROPERTIES") public void updateExperimentProperties(String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) - TechId entityId, List<PropertyUpdates> modifiedProperties) + @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId entityId, List<PropertyUpdates> modifiedProperties) { checkSession(sessionToken); Experiment experiment = getExperimentInfo(sessionToken, entityId); @@ -3849,8 +3817,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_SAMPLE_PROPERTIES") public void updateSampleProperties(String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) - TechId entityId, List<PropertyUpdates> modifiedProperties) + @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) TechId entityId, List<PropertyUpdates> modifiedProperties) { checkSession(sessionToken); Map<String, String> properties = createPropertiesMap(modifiedProperties); @@ -3915,7 +3882,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Capability("RESTORE") public void revertDeletions(final String sessionToken, @AuthorizationGuard(guardClass = RevertDeletionPredicate.class) - final List<TechId> deletionIds) + final List<TechId> deletionIds) { final Session session = getSession(sessionToken); @@ -3969,7 +3936,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Capability("PURGE") public void deletePermanently(final String sessionToken, @AuthorizationGuard(guardClass = DeletionTechIdCollectionPredicate.class) - final List<TechId> deletionIds) + final List<TechId> deletionIds) { deletePermanentlyCommon(sessionToken, deletionIds, false); } @@ -3979,7 +3946,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt @Capability("FORCE_PURGE") public void deletePermanentlyForced(final String sessionToken, @AuthorizationGuard(guardClass = DeletionTechIdCollectionPredicate.class) - final List<TechId> deletionIds) + final List<TechId> deletionIds) { deletePermanentlyCommon(sessionToken, deletionIds, true); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java index 62db41c5eaa..ee2cc96e765 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java @@ -26,6 +26,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -338,10 +340,13 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate String[] fields = headerField.stringValue().split(splitString); String[] content = dataField.stringValue().split(splitString); - String[] metaprojects = metaprojectField.stringValue().split(" "); + String[] metaprojects = new String[0]; - String matchingField = "unknown"; - String matchingText = ""; + String mpfs = metaprojectField.stringValue(); + if (mpfs.trim().length() > 0) + { + metaprojects = metaprojectField.stringValue().split(" "); + } List<String> query = new ArrayList<>(); if (useWildcardSearchMode) @@ -361,62 +366,144 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate } } - List<MatchingEntity> result = new ArrayList<>(); + Map<String, String> matchingFields = new HashMap<>(); + double score = 0.0; for (int i = 0; i < content.length; i++) { for (String q : query) { + double currentScore = score; + if (useWildcardSearchMode) { - if (content[i].toLowerCase().matches("(?s).*" + q.toLowerCase().replace("*", ".*").replace("?", ".?") + ".*")) + Pattern pattern = Pattern.compile("(?s)" + q.toLowerCase().replace("*", ".*").replace("?", ".?")); + Matcher matcher = pattern.matcher(content[i].toLowerCase()); + + while (matcher.find()) { - matchingField = (fields.length == content.length) ? fields[i] : "Unknown"; - matchingText = content[i]; - MatchingEntity me = createMatchingEntity(((Document) tuple[1]), matchingText); - me.setFieldDescription(matchingField); - result.add(me); + int start = matcher.start(); + int end = matcher.end(); + score += getScore(content[i].toLowerCase(), start, end, fields[i], useWildcardSearchMode); } } else { - if (content[i].toLowerCase().contains(q.toLowerCase())) + String rest = content[i].toLowerCase(); + while (rest.length() > 0) { - matchingField = (fields.length == content.length) ? fields[i] : "Unknown"; - matchingText = content[i]; - MatchingEntity me = createMatchingEntity(((Document) tuple[1]), matchingText); - me.setFieldDescription(matchingField); - result.add(me); + int start = rest.indexOf(q.toLowerCase()); + if (start == -1) + { + rest = ""; + } else + { + int end = start + q.length(); + rest = rest.substring(end); + score += getScore(content[i].toLowerCase(), start, end, fields[i], useWildcardSearchMode); + } } } + + if (score > currentScore) + { + matchingFields.put(fields[i], content[i]); + } } } + Set<String> matchingMetaprojects = new HashSet<>(); for (int i = 0; i < metaprojects.length; i++) { + String mp = metaprojects[i].substring(1); + String user = mp.substring(0, mp.indexOf("/")); + if (!user.equals(userId)) + { + continue; + } + String value = metaprojects[i].substring(metaprojects[i].lastIndexOf("/") + 1); for (String q : query) { if (useWildcardSearchMode) { - if (value.toLowerCase().matches(".*" + q.toLowerCase().replace("*", ".*").replace("?", ".?") + ".*")) + Pattern pattern = Pattern.compile(q.toLowerCase().replace("*", ".*").replace("?", ".?")); + Matcher matcher = pattern.matcher(value.toLowerCase()); + + while (matcher.find()) { - MatchingEntity me = createMatchingEntity(((Document) tuple[1]), value); - me.setFieldDescription("Tag"); - result.add(me); + matchingMetaprojects.add(value); + int start = matcher.start(); + int end = matcher.end(); + score += getScore(value, start, end, "Tag", useWildcardSearchMode) * 5; } } else { - if (value.toLowerCase().contains(q.toLowerCase())) + String rest = value.toLowerCase(); + while (rest.length() > 0) { - MatchingEntity me = createMatchingEntity(((Document) tuple[1]), value); - me.setFieldDescription("Tag"); - result.add(me); + int start = rest.indexOf(q.toLowerCase()); + if (start == -1) + { + rest = ""; + } else + { + matchingMetaprojects.add(value); + int end = start + q.length(); + rest = rest.substring(end); + score += getScore(value, start, end, "Tag", useWildcardSearchMode) * 5; + } } } } } - return result; + if (matchingMetaprojects.size() > 0) + { + List<String> mps = new ArrayList<>(matchingMetaprojects); + Collections.sort(mps); + matchingFields.put("Tags", StringUtils.join(mps, ",")); + } + + if (matchingFields.containsKey("Code") || + matchingFields.containsKey("Project code") || + matchingFields.containsKey("Space code")) + { + matchingFields.remove("Identifier"); + } + + List<String> keys = new ArrayList<String>(matchingFields.keySet()); + Collections.sort(keys); + + String text = ""; + for (String key : keys) + { + text = text + key + ": " + matchingFields.get(key) + "\n"; + } + + return createMatchingEntity((Document) tuple[1], text, score); + } + + private double getScore(String text, int start, int end, String field, boolean wildcard) + { + boolean fullmatch = (start == 0 || !StringUtils.isAlphanumeric(text.substring(start - 1, start))) && + (end == text.length() || !StringUtils.isAlphanumeric(text.substring(end, end + 1))) && + !wildcard; // full/partial matching not relevant for wildcard mode + if (field.equals("Perm ID") || field.equals("Identifier") || field.equals("Code")) + { + if (fullmatch) + { + return 200; + } else + { + return 100; + } + } else if (fullmatch) + { + return 10; + } else + { + return 1; + } } @Override @@ -430,13 +517,13 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate return result; } - private MatchingEntity createMatchingEntity(final Document doc, final String matchingText) + private MatchingEntity createMatchingEntity(final Document doc, final String matchingText, double score) { final MatchingEntity result = new MatchingEntity(); // search properties - result.setFieldDescription(fieldName); - result.setTextFragment(matchingText); + result.setMatch(matchingText); + result.setScore(score); // IIdentifiable properties // NOTE: for contained sample this code is full code with container code part @@ -512,29 +599,11 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate }); List<?> list = hibernateQuery.list(); - final List<List<MatchingEntity>> nestedResult = AbstractDAO.cast(list); - List<MatchingEntity> result = new ArrayList<>(); - for (List<MatchingEntity> entities : nestedResult) - { - result.addAll(entities); - } + List<MatchingEntity> result = AbstractDAO.cast(list); return filterNulls(result); } - // we need this for higlighter when wildcards are used - private static Query rewriteQuery(IndexReader indexReader, Query query) - { - try - { - return query.rewrite(indexReader); - } catch (IOException ex) - { - logSearchHighlightingError(ex); - return query; - } - } - // detailed search @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MatchingEntity.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MatchingEntity.java index 2b44c60693a..034ec9e9d23 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MatchingEntity.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MatchingEntity.java @@ -22,8 +22,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWit import ch.systemsx.cisd.openbis.generic.shared.basic.IRegistratorHolder; /** - * An entity that matches the <i>Hibernate Search</i> query and which has been returned by the - * server. + * An entity that matches the <i>Hibernate Search</i> query and which has been returned by the server. * * @author Christian Ribeaud */ @@ -48,9 +47,9 @@ public final class MatchingEntity implements Serializable, IEntityInformationHol private Space spaceOrNull; - private String fieldDescription; + private String match; - private String textFragment; + private double score; @Override public final EntityKind getEntityKind() @@ -95,26 +94,6 @@ public final class MatchingEntity implements Serializable, IEntityInformationHol this.spaceOrNull = spaceOrNull; } - public String getFieldDescription() - { - return fieldDescription; - } - - public void setFieldDescription(String fieldDescription) - { - this.fieldDescription = fieldDescription; - } - - public String getTextFragment() - { - return textFragment; - } - - public void setTextFragment(String textFragment) - { - this.textFragment = textFragment; - } - public final String getIdentifier() { return identifier; @@ -207,4 +186,23 @@ public final class MatchingEntity implements Serializable, IEntityInformationHol return getIdentifier(); } + public String getMatch() + { + return match; + } + + public void setMatch(String match) + { + this.match = match; + } + + public double getScore() + { + return score; + } + + public void setScore(double score) + { + this.score = score; + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentGlobalSearchBridge.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentGlobalSearchBridge.java index 69cc8e5496d..71c51d7534e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentGlobalSearchBridge.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentGlobalSearchBridge.java @@ -11,8 +11,8 @@ public class ExperimentGlobalSearchBridge extends GlobalSearchBridge<ExperimentP Map<String, String> values = new HashMap<>(); values.put("Perm ID", experiment.getPermId()); - values.put("Identifier", experiment.getIdentifier()); values.put("Code", experiment.getCode()); + values.put("Identifier", experiment.getIdentifier()); values.put("Registration date", dateFormat.format(experiment.getRegistrationDate())); values.put("Modification date", dateFormat.format(experiment.getModificationDate())); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GlobalSearchBridge.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GlobalSearchBridge.java index 21421169db8..c6a8db15181 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GlobalSearchBridge.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GlobalSearchBridge.java @@ -73,11 +73,9 @@ public abstract class GlobalSearchBridge<T extends IEntityWithMetaprojects> impl if (person != null) { values.put("User id of " + role, person.getUserId()); - values.put("First name of " + role, person.getFirstName()); - values.put("Last name of " + role, person.getLastName()); + values.put("Name of " + role, person.getLastName() + ", " + person.getFirstName()); values.put("Email of " + role, person.getEmail()); } - } @Override @@ -93,8 +91,17 @@ public abstract class GlobalSearchBridge<T extends IEntityWithMetaprojects> impl List<String> values = new ArrayList<>(); for (Map.Entry<String, String> entry : data.entrySet()) { + if (entry.getValue() == null) + { + continue; + } keys.add(entry.getKey()); - values.add(entry.getValue()); + String val = entry.getValue(); + while (val.indexOf(" ||| ") != -1) + { + val = val.replace(" ||| ", " \\|\\|\\| "); + } + values.add(val); } String indexedValue = StringUtils.joinList(values, " ||| "); @@ -144,7 +151,7 @@ public abstract class GlobalSearchBridge<T extends IEntityWithMetaprojects> impl } catch (Exception e) { - e.printStackTrace(); // WHAT SHOULD BE DONE HERE?! + e.printStackTrace(); } } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGlobalSearchBridge.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGlobalSearchBridge.java index 46cb585f051..a811c7669b0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGlobalSearchBridge.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGlobalSearchBridge.java @@ -11,11 +11,10 @@ public class SampleGlobalSearchBridge extends GlobalSearchBridge<SamplePE> Map<String, String> values = new HashMap<>(); values.put("Perm ID", sample.getPermId()); - values.put("Identifier", sample.getIdentifier()); values.put("Code", sample.getCode()); + values.put("Identifier", sample.getIdentifier()); values.put("Registration date", dateFormat.format(sample.getRegistrationDate())); values.put("Modification date", dateFormat.format(sample.getModificationDate())); - values.put("Sample type", sample.getSampleType().getCode()); if (sample.getExperiment() != null) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumn.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumn.java index d2f6966d3d4..8c7f5f8eed5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumn.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumn.java @@ -84,6 +84,11 @@ public interface IColumn */ public void addString(String valueOrNull); + /** + * Adds a multiline string value to the column. + */ + public void addMultilineValue(String valueOrNull); + /** * Adds an integer value to the column. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java index 111d2391d8d..db1d64f6cdc 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java @@ -423,6 +423,15 @@ public class TypedTableModelBuilder<T extends Serializable> addValue(value); } + @Override + public void addMultilineValue(String valueOrNull) + { + setDataType(DataTypeCode.MULTILINE_VARCHAR); + StringTableCell value = + valueOrNull == null ? EMPTY_CELL : new StringTableCell(valueOrNull); + addValue(value); + } + @Override public void addInteger(Long valueOrNull) { @@ -580,8 +589,7 @@ public class TypedTableModelBuilder<T extends Serializable> /** * Adds a column with specified id. * - * @return an {@link IColumnMetaData} instance which allows to set title, default width, and/or - * data type. + * @return an {@link IColumnMetaData} instance which allows to set title, default width, and/or data type. * @throws IllegalArgumentException if a column with specified is has already been added. */ public IColumnMetaData addColumn(String id) @@ -595,8 +603,7 @@ public class TypedTableModelBuilder<T extends Serializable> } /** - * Adds a row with optional row object. This method has to be called before adding values to - * columns. + * Adds a row with optional row object. This method has to be called before adding values to columns. */ public void addRow(T objectOrNull) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js index b1ab502d902..b3c36d0d9b0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js @@ -278,8 +278,8 @@ var common = { no_match: "No results found for '{0}'.<br><br><br>Note, that you are {1} using wildcard search mode. Try to turn it {2} in your user settings.", entity_type: "Entity Type", entity_kind: "Entity Kind", - matching_text: "Matching Text", - matching_field: "Matching Field", + match: "Match", + rank: "Rank", too_generic: "Query string '{0}' is too generic.", show_related_datasets: "Show Related Data Sets", show_related_datasets_message: "Select between showing Data Sets related to selected ({0}) entities or to all entities from the table and click on OK button.", diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java index 3ddf7b0343c..2ca6abbebe2 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java @@ -132,9 +132,9 @@ public final class HibernateSearchDAOTest extends AbstractDAOTest { assertEquals(lastName, matchingEntity.getRegistrator().getFirstName()); - String fieldDescription = matchingEntity.getFieldDescription(); - if (fieldDescription.contains("First name of registrator") == false - && fieldDescription.contains("First name of modifier") == false) + String fieldDescription = matchingEntity.getMatch(); + if (fieldDescription.contains("Name of registrator") == false + && fieldDescription.contains("Name of modifier") == false) { fail("Field description '" + fieldDescription + "' neither contains 'First name of registrator' " + "nor 'First name of modifier'."); @@ -162,7 +162,7 @@ public final class HibernateSearchDAOTest extends AbstractDAOTest for (MatchingEntity matchingEntity : hits) { AssertionUtil.assertContainsInsensitive(querySubstring, matchingEntity.getCode()); - assertEquals("code", matchingEntity.getFieldDescription()); + assertEquals("Code", matchingEntity.getMatch().substring(0, matchingEntity.getMatch().indexOf(":"))); } } -- GitLab