From 51a5208ec480a619bcd7109c14e8b96629f7c13e Mon Sep 17 00:00:00 2001 From: Yannick Marcon Date: Fri, 20 Sep 2024 17:29:26 +0200 Subject: [PATCH] feat: removed RQL parser, as it was not used anymore (table values are not indexed) (#3933) --- opal-search/pom.xml | 4 - .../opal/search/SearchQueryWhereClause.java | 19 +- .../DatasourcesEntitiesSearchResource.java | 63 +-- .../search/TableValueSetsSearchResource.java | 167 -------- .../search/support/RQLCriterionParser.java | 206 ---------- .../support/RQLIdentifierCriterionParser.java | 28 -- .../web/search/support/RQLParserFactory.java | 48 --- .../RQLValueSetVariableCriterionParser.java | 74 ---- .../support/RQLCriterionParserTest.java | 383 ------------------ pom.xml | 13 - 10 files changed, 4 insertions(+), 1001 deletions(-) delete mode 100644 opal-search/src/main/java/org/obiba/opal/web/search/TableValueSetsSearchResource.java delete mode 100644 opal-search/src/main/java/org/obiba/opal/web/search/support/RQLCriterionParser.java delete mode 100644 opal-search/src/main/java/org/obiba/opal/web/search/support/RQLIdentifierCriterionParser.java delete mode 100644 opal-search/src/main/java/org/obiba/opal/web/search/support/RQLParserFactory.java delete mode 100644 opal-search/src/main/java/org/obiba/opal/web/search/support/RQLValueSetVariableCriterionParser.java delete mode 100644 opal-search/src/test/java/org/obiba/opal/web/search/support/RQLCriterionParserTest.java diff --git a/opal-search/pom.xml b/opal-search/pom.xml index 46ebcb43b3..1fb2cd4735 100644 --- a/opal-search/pom.xml +++ b/opal-search/pom.xml @@ -69,10 +69,6 @@ org.apache.lucene lucene-queryparser - - net.jazdw - rql-parser - org.slf4j slf4j-api diff --git a/opal-search/src/main/java/org/obiba/opal/search/SearchQueryWhereClause.java b/opal-search/src/main/java/org/obiba/opal/search/SearchQueryWhereClause.java index 2754801d25..3bec3a49e7 100644 --- a/opal-search/src/main/java/org/obiba/opal/search/SearchQueryWhereClause.java +++ b/opal-search/src/main/java/org/obiba/opal/search/SearchQueryWhereClause.java @@ -10,17 +10,15 @@ package org.obiba.opal.search; -import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.obiba.magma.Initialisable; import org.obiba.magma.ValueSet; import org.obiba.magma.ValueTable; import org.obiba.magma.VariableEntity; -import org.obiba.magma.support.VariableEntityBean; import org.obiba.magma.views.View; +import org.obiba.opal.core.DeprecatedOperationException; import org.obiba.opal.core.magma.QueryWhereClause; import org.obiba.opal.search.service.ValuesIndexManager; -import org.obiba.opal.web.search.support.RQLParserFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -48,20 +46,7 @@ public class SearchQueryWhereClause extends AbstractSearchUtility implements Que @Override public void initialise() { - if (!entities.isEmpty() || allEntities) return; // already initialised - try { - String esQuery = RQLParserFactory.parse(query, opalSearchService.getValuesIndexManager()); - if (Strings.isNullOrEmpty(esQuery)) { - allEntities = true; - return; - } - String safeQuery = "reference:\"" + valueTable.getTableReference() + "\" AND " + esQuery; - opalSearchService.executeAllIdentifiersQuery( - buildQuerySearch(safeQuery, 0, Integer.MAX_VALUE, Lists.newArrayList("identifier"), null, null, null), - getSearchPath()).forEach(id -> entities.add(new VariableEntityBean(valueTable.getEntityType(), id))); - } catch(Exception e) { - log.error("Failed querying: {}", query, e); - } + throw new DeprecatedOperationException("Unsupported operation: since Opal 5 values are not indexed"); } @Override diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/DatasourcesEntitiesSearchResource.java b/opal-search/src/main/java/org/obiba/opal/web/search/DatasourcesEntitiesSearchResource.java index 2fac7694be..e6005f559f 100644 --- a/opal-search/src/main/java/org/obiba/opal/web/search/DatasourcesEntitiesSearchResource.java +++ b/opal-search/src/main/java/org/obiba/opal/web/search/DatasourcesEntitiesSearchResource.java @@ -11,27 +11,19 @@ package org.obiba.opal.web.search; import com.google.common.base.Strings; -import com.google.common.collect.Lists; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.Response; -import net.jazdw.rql.parser.ASTNode; import org.obiba.magma.VariableEntity; import org.obiba.magma.support.VariableEntityBean; +import org.obiba.opal.core.DeprecatedOperationException; import org.obiba.opal.core.service.IdentifiersTableService; import org.obiba.opal.search.AbstractSearchUtility; import org.obiba.opal.search.service.ContingencyService; -import org.obiba.opal.search.service.QuerySettings; import org.obiba.opal.search.service.SearchException; import org.obiba.opal.web.model.Identifiers; -import org.obiba.opal.web.model.Search; -import org.obiba.opal.web.search.support.RQLIdentifierCriterionParser; -import org.obiba.opal.web.search.support.RQLParserFactory; -import org.obiba.opal.web.search.support.RQLValueSetVariableCriterionParser; -import org.obiba.opal.web.search.support.ValueSetVariableCriterionParser; -import org.obiba.opal.web.ws.SortDir; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -96,36 +88,7 @@ public Response search(@QueryParam("query") String query, @QueryParam("offset") @DefaultValue("0") int offset, @QueryParam("limit") @DefaultValue("10") int limit, @QueryParam("counts") @DefaultValue("false") boolean withCounts) throws SearchException { - if (!canQueryEsIndex()) return Response.status(Response.Status.SERVICE_UNAVAILABLE).build(); - if (Strings.isNullOrEmpty(query)) return Response.status(Response.Status.BAD_REQUEST).build(); - this.entityType = entityType; - - final RQLIdentifierCriterionParser idCriterion = Strings.isNullOrEmpty(idQuery) ? null : new RQLIdentifierCriterionParser(idQuery); - - ASTNode queryNode = RQLParserFactory.newParser().parse(query); - List childQueries = extractChildQueries(queryNode); - List partialResults = Lists.newArrayList(); - if (withCounts && childQueries.size() > 1) { - for (ValueSetVariableCriterionParser childQuery : childQueries) { - QuerySettings querySettings = buildHasChildQuerySearch(0, 0); - querySettings.childQuery(childQuery.asChildQuery(idCriterion == null ? null : idCriterion.getQuery())); - partialResults.add(opalSearchService.executeEntitiesQuery(querySettings, getSearchPath(), entityType, childQuery.getOriginalQuery()).build()); - } - } - - // global query - - QuerySettings querySettings = buildHasChildQuerySearch(offset, limit); - querySettings.childQueries(childQueries.stream().map(p -> p.asChildQuery(idCriterion == null ? null : idCriterion.getQuery())).collect(Collectors.toList())); - if (childQueries.size() > 1) querySettings.childQueryOperator(queryNode.getName()); - try { - Search.EntitiesResultDto.Builder dtoResponseBuilder = opalSearchService.executeEntitiesQuery(querySettings, getSearchPath(), entityType, query); - dtoResponseBuilder.addAllPartialResults(partialResults); - return Response.ok().entity(dtoResponseBuilder.build()).build(); - } catch (Exception e) { - // Search engine exception - throw new SearchException("Query failed to be executed: " + query, e.getCause() == null ? e : e.getCause()); - } + throw new DeprecatedOperationException("Unsupported operation: since Opal 5 values are not indexed"); } @GET @@ -149,26 +112,4 @@ protected String getSearchPath() { return opalSearchService.getValuesIndexManager().getName() + "/" + entityType; } - // - // Private methods - // - - private List extractChildQueries(ASTNode queryNode) { - // for now the query must look like: and(q1,q2,...) or or(q1,q2...) or (q1,q2...) or q1,q2,... - if ("and".equals(queryNode.getName()) || "or".equals(queryNode.getName()) || "".equals(queryNode.getName())) - return queryNode.getArguments().stream().map(q -> new RQLValueSetVariableCriterionParser(opalSearchService.getValuesIndexManager(), (ASTNode) q)).collect(Collectors.toList()); - else // single query - return Lists.newArrayList(new RQLValueSetVariableCriterionParser(opalSearchService.getValuesIndexManager(), queryNode)); - } - - private QuerySettings buildHasChildQuerySearch(int offset, int limit) { - QuerySettings querySettings = new QuerySettings(); - querySettings.from(offset).size(limit).sortField("identifier", SortDir.ASC.name()).noDefaultFields(); - return querySettings; - } - - private boolean canQueryEsIndex() { - return searchServiceAvailable() && opalSearchService.getValuesIndexManager().isReady(); - } - } diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/TableValueSetsSearchResource.java b/opal-search/src/main/java/org/obiba/opal/web/search/TableValueSetsSearchResource.java deleted file mode 100644 index fb63298b2d..0000000000 --- a/opal-search/src/main/java/org/obiba/opal/web/search/TableValueSetsSearchResource.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search; - -import com.google.common.base.Function; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import org.obiba.magma.MagmaEngine; -import org.obiba.magma.ValueTable; -import org.obiba.magma.Variable; -import org.obiba.magma.VariableEntity; -import org.obiba.magma.js.views.JavascriptClause; -import org.obiba.magma.support.VariableEntityBean; -import org.obiba.opal.search.AbstractSearchUtility; -import org.obiba.opal.search.service.OpalSearchService; -import org.obiba.opal.search.service.SearchException; -import org.obiba.opal.search.service.ValuesIndexManager; -import org.obiba.opal.web.model.Magma; -import org.obiba.opal.web.model.Search; -import org.obiba.opal.web.search.support.RQLParserFactory; -import org.obiba.opal.web.search.support.VariableEntityValueSetDtoFunction; -import org.obiba.opal.web.ws.SortDir; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; - -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -@Component -@Scope("request") -@Path("/datasource/{ds}/table/{table}/valueSets/_search") -public class TableValueSetsSearchResource extends AbstractSearchUtility { - -// private static final Logger log = LoggerFactory.getLogger(TableVariablesSearchResource.class); - - @PathParam("ds") - private String datasource; - - @PathParam("table") - private String table; - - @GET - @Transactional(readOnly = true) - @SuppressWarnings("PMD.ExcessiveParameterList") - public Response search(@Context UriInfo uriInfo, @QueryParam("ql") @DefaultValue("rql") String queryLanguage, @QueryParam("query") String query, - @QueryParam("offset") @DefaultValue("0") int offset, @QueryParam("limit") @DefaultValue("10") int limit, - @QueryParam("select") String select) throws SearchException { - - String esQuery = query; - - if (!"es".equals(queryLanguage)) - esQuery = RQLParserFactory.parse(query, opalSearchService.getValuesIndexManager()); - - if (!canQueryEsIndex()) return Response.status(Response.Status.SERVICE_UNAVAILABLE).build(); - if (!opalSearchService.getValuesIndexManager().hasIndex(getValueTable())) - return Response.status(Response.Status.NOT_FOUND).build(); - - esQuery = "reference:\"" + getValueTable().getTableReference() + (Strings.isNullOrEmpty(esQuery) ? "\"" : "\" AND " + esQuery); - OpalSearchService.IdentifiersQueryCallback callback = new OpalSearchService.IdentifiersQueryCallback(); - opalSearchService.executeIdentifiersQuery(buildQuerySearch(esQuery, offset, limit, - Lists.newArrayList("identifier"), null, "identifier", SortDir.ASC.name()).noDefaultFields(), getSearchPath(), callback); - Search.ValueSetsResultDto.Builder dtoResponseBuilder = getValueSetsDtoBuilder(uriInfo, select, callback.getTotal(), callback.getIdentifiers()); - return Response.ok().entity(dtoResponseBuilder.build()).build(); - } - - private Search.ValueSetsResultDto.Builder getValueSetsDtoBuilder(UriInfo uriInfo, String select, - int totalIds, List ids) throws SearchException { - Search.ValueSetsResultDto.Builder dtoResponseBuilder = Search.ValueSetsResultDto.newBuilder(); - dtoResponseBuilder.setTotalHits(totalIds); - String entityType = getValueTable().getEntityType(); - Collection entities = ids.stream().map(id -> new VariableEntityBean(entityType, id)).collect(Collectors.toList()); - String path = uriInfo.getPath(); - path = path.substring(0, path.indexOf("/_search")); - dtoResponseBuilder.setValueSets(getValueSetsDto(path, select, entities)); - return dtoResponseBuilder; - } - - // - // Protected methods - // - - @Override - protected String getSearchPath() { - ValuesIndexManager manager = opalSearchService.getValuesIndexManager(); - return manager.getName() + "/" + manager.getIndex(getValueTable()).getIndexType(); - } - - // - // Private methods - // - - private boolean canQueryEsIndex() { - return searchServiceAvailable() && opalSearchService.getValuesIndexManager().isReady() && - opalSearchService.getValuesIndexManager().isIndexUpToDate(getValueTable()); - } - - private ValueTable getValueTable() { - return MagmaEngine.get().getDatasource(datasource).getValueTable(table); - } - - private Magma.ValueSetsDto getValueSetsDto(String uriInfoPath, String select, - Iterable variableEntities) { - Iterable variables = filterVariables(select); - - Magma.ValueSetsDto.Builder builder = Magma.ValueSetsDto.newBuilder().setEntityType(getValueTable().getEntityType()); - - builder.addAllVariables(Iterables.transform(variables, new Function() { - - @Override - public String apply(Variable from) { - return from.getName(); - } - - })); - - ImmutableList.Builder valueSetDtoBuilder = ImmutableList.builder(); - Iterable transform = Iterables.transform(getValueTable().getValueSets(variableEntities), - new VariableEntityValueSetDtoFunction(getValueTable(), variables, uriInfoPath, true)); - - for (Magma.ValueSetsDto.ValueSetDto valueSetDto : transform) { - valueSetDtoBuilder.add(valueSetDto); - } - - builder.addAllValueSets(valueSetDtoBuilder.build()); - - return builder.build(); - } - - protected Iterable filterVariables(String script) { - List filteredVariables; - - if (StringUtils.isEmpty(script)) { - filteredVariables = Lists.newArrayList(getValueTable().getVariables()); - } else { - JavascriptClause jsClause = new JavascriptClause(script); - jsClause.initialise(); - - filteredVariables = new ArrayList<>(); - for (Variable variable : getValueTable().getVariables()) { - if (jsClause.select(variable)) { - filteredVariables.add(variable); - } - } - } - - return filteredVariables; - } - -} diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLCriterionParser.java b/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLCriterionParser.java deleted file mode 100644 index 0939890b42..0000000000 --- a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLCriterionParser.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search.support; - -import com.google.common.base.Joiner; -import com.google.common.base.Strings; -import net.jazdw.rql.parser.ASTNode; -import org.joda.time.DateTime; -import org.obiba.magma.ValueType; -import org.obiba.magma.support.VariableNature; -import org.obiba.magma.type.TextType; - -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Criterion for filtering values based on a variable field, expressed in RQL. - */ -public class RQLCriterionParser { - - private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); - - /** - * RQL query object. - */ - private ASTNode queryNode; - - /** - * RQL query string. - */ - private final String rqlQuery; - - /** - * ES query string. - */ - private String query; - - public RQLCriterionParser(String rqlQuery) { - this.rqlQuery = rqlQuery; - } - - public RQLCriterionParser(ASTNode queryNode) { - this.queryNode = queryNode; - this.rqlQuery = toString(queryNode); - } - - public String getOriginalQuery() { - return rqlQuery; - } - - public String getQuery() { - if (Strings.isNullOrEmpty(query)) { - this.query = queryNode == null ? parseNode(RQLParserFactory.newParser().parse(rqlQuery)) - : parseNode(queryNode); - } - return query; - } - - private String toString(ASTNode node) { - StringBuilder builder = new StringBuilder(node.getName()).append("("); - for (int i=0; i0) builder.append(","); - append(builder, node.getArgument(i)); - } - builder.append(")"); - return builder.toString(); - } - - private void append(StringBuilder builder, Object arg) { - if (arg instanceof ASTNode) builder.append(toString((ASTNode)arg)); - else if (arg instanceof Collection) { - builder.append("("); - Collection values = (Collection) arg; - int i=0; - for (Object value : values) { - if (i>0) builder.append(","); - append(builder, value); - i++; - } - builder.append(")"); - } - else if (arg instanceof DateTime) builder.append(normalizeDate((DateTime)arg)); - else builder.append(arg.toString().replace("%","%25")); - } - - private String parseNode(ASTNode node) { - switch (node.getName()) { - case "not": - return "NOT " + parseNode((ASTNode) node.getArgument(0)); - case "exists": - return "_exists_:" + parseField(node.getArgument(0).toString()); - case "all": - parseField(node.getArgument(0).toString()); - return ""; - case "in": - return parseField(node.getArgument(0).toString()) + ":(" + parseValue(node.getArgument(1)) + ")"; - case "like": - String valueStr = parseValue(node.getArgument(1)); - if (Strings.isNullOrEmpty(valueStr)) - valueStr = "''"; - return "(" + parseField(node.getArgument(0).toString()) + ":(" + valueStr + ") OR " - + parseFieldLike(node.getArgument(0).toString()) + ":(" + valueStr + "))"; - case "range": - return parseField(node.getArgument(0).toString()) + ":[" + parseRange(node.getArgument(1)) + "]"; - case "and": - return parseAnd(node.getArguments()); - case "or": - return parseOr(node.getArguments()); - } - return node.toString(); - } - - protected String parseField(String path) { - return path; - } - - protected String parseFieldLike(String path) { - return path + ".analyzed"; - } - - protected ValueType getValueType() { - return TextType.get(); - } - - protected VariableNature getNature() { - return VariableNature.UNDETERMINED; - } - - protected String join(String on, Collection args) { - String nOn = on; - boolean toQuote = getNature().equals(VariableNature.CATEGORICAL); - List nArgs = args.stream().map(arg -> { - String nArg = arg instanceof DateTime ? normalizeDate((DateTime) arg) : arg.toString(); - if (toQuote) return quote(nArg); - else return normalizeString(nArg); - }).collect(Collectors.toList()); - - return Joiner.on(nOn).join(nArgs); - } - - // - // Private methods - // - - private String parseValue(Object value) { - if (value instanceof ASTNode) return parseNode((ASTNode) value); - if (value instanceof Collection) { - Collection values = (Collection) value; - if (values.size() == 1 && getValueType().isDateTime()) return parseSingleDate(values.iterator().next()); - return parseOr(values); - } - if (value instanceof DateTime) return parseSingleDate(value); - return getNature().equals(VariableNature.CATEGORICAL) ? quote(value) : normalizeString(value.toString()); - } - - private String normalizeString(String str) { - return str.replace(" ","+"); - } - - private String normalizeDate(DateTime date) { - return DATE_FORMAT.format(date.toDate()); - } - - private String quote(Object value) { - String valueStr = value.toString(); - if (valueStr.contains("*")) return normalizeString(valueStr); - if (valueStr.startsWith("\"") && valueStr.endsWith("\"")) return valueStr; - valueStr = valueStr.replace("+", " "); - if (valueStr.contains(" ") || valueStr.startsWith("-")) return "\"" + valueStr + "\""; - return valueStr; - } - - private String parseRange(Object value) { - if (value instanceof Collection) { - return join(" TO ", (Collection) value); - } - return value + " TO *"; - } - - private String parseSingleDate(Object value) { - if (value instanceof DateTime) { - String dateString = DATE_FORMAT.format(((DateTime) value).toDate()); - return ">=" + dateString + " AND " + "<=" + dateString; - } - return normalizeString(value.toString()); - } - - private String parseAnd(Collection args) { - return join(" AND ", args.stream().map(arg -> parseValue(arg)).collect(Collectors.toList())); - } - - private String parseOr(Collection args) { - return join(" OR ", args.stream().map(arg -> parseValue(arg)).collect(Collectors.toList())); - } - -} diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLIdentifierCriterionParser.java b/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLIdentifierCriterionParser.java deleted file mode 100644 index 68bacd816d..0000000000 --- a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLIdentifierCriterionParser.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search.support; - - -public class RQLIdentifierCriterionParser extends RQLCriterionParser { - - private static final String ID_FIELD = "identifier"; - - public RQLIdentifierCriterionParser(String rqlQuery) { - super(rqlQuery); - } - - @Override - protected String parseField(String path) { - if (!ID_FIELD.equals(path)) throw new IllegalArgumentException("ID field is expected to be '" + ID_FIELD + "'"); - return super.parseField(path); - } - -} diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLParserFactory.java b/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLParserFactory.java deleted file mode 100644 index ce170f8652..0000000000 --- a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLParserFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search.support; - - -import com.google.common.base.Strings; -import net.jazdw.rql.parser.ASTNode; -import net.jazdw.rql.parser.RQLParser; -import org.obiba.opal.search.service.ValuesIndexManager; - -import java.util.stream.Collectors; - -public class RQLParserFactory { - - public static RQLParser newParser() { - return new RQLParser(); - } - - /** - * Converts a RQL query to a ES query. - * - * @param rqlQuery - * @param valuesIndexManager - * @return - */ - public static String parse(String rqlQuery, ValuesIndexManager valuesIndexManager) { - String esQuery; - ASTNode queryNode = newParser().parse(rqlQuery); - if ("and".equals(queryNode.getName()) || "or".equals(queryNode.getName()) || "".equals(queryNode.getName())) { - esQuery = queryNode.getArguments().stream() - .map(qn -> new RQLValueSetVariableCriterionParser(valuesIndexManager, (ASTNode) qn).getQuery()) - .filter(q -> !Strings.isNullOrEmpty(q)) - .collect(Collectors.joining("or".equals(queryNode.getName()) ? " OR " : " AND ")); - } else { // single query - esQuery = new RQLValueSetVariableCriterionParser(valuesIndexManager, queryNode).getQuery(); - } - return esQuery; - } - -} diff --git a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLValueSetVariableCriterionParser.java b/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLValueSetVariableCriterionParser.java deleted file mode 100644 index 6951920382..0000000000 --- a/opal-search/src/main/java/org/obiba/opal/web/search/support/RQLValueSetVariableCriterionParser.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search.support; - -import com.google.common.base.Strings; -import net.jazdw.rql.parser.ASTNode; -import org.obiba.magma.*; -import org.obiba.magma.support.MagmaEngineVariableResolver; -import org.obiba.magma.support.VariableNature; -import org.obiba.magma.type.TextType; -import org.obiba.opal.search.service.QuerySettings; -import org.obiba.opal.search.service.ValuesIndexManager; - -/** - * Criterion for filtering values based on a variable field, expressed in RQL. - */ -public class RQLValueSetVariableCriterionParser extends RQLCriterionParser implements ValueSetVariableCriterionParser { - - private final ValuesIndexManager valuesIndexManager; - - private ValueTable table; - - private Variable variable; - - public RQLValueSetVariableCriterionParser(ValuesIndexManager valuesIndexManager, ASTNode rqlNode) { - super(rqlNode); - this.valuesIndexManager = valuesIndexManager; - } - - @Override - public QuerySettings.ChildQuery asChildQuery(String idQuery) { - String query = getQuery(); // make sure ES query is built - if (!Strings.isNullOrEmpty(query)) query = " AND " + query; - if (!Strings.isNullOrEmpty(idQuery)) query = " AND " + idQuery + query; - query = "reference:\"" + table.getTableReference() + "\"" + query; - return new QuerySettings.ChildQuery(valuesIndexManager.getIndex(table).getIndexType(), query); - } - - @Override - protected String parseField(String variablePath) { - MagmaEngineVariableResolver resolver = MagmaEngineVariableResolver.valueOf(variablePath); - if (resolver.hasTableName()) { - table = MagmaEngine.get().getDatasource(resolver.getDatasourceName()).getValueTable(resolver.getTableName()); - variable = table.getVariable(resolver.getVariableName()); - String field = valuesIndexManager.getIndex(table).getFieldName(resolver.getVariableName()); - field = field.replace("{","\\{").replace("}","\\}").replace("[","\\[").replace("]","\\]"); - return field; - } else return variablePath; - } - - @Override - protected String parseFieldLike(String path) { - // variable fields are always analyzed - return parseField(path); - } - - @Override - protected ValueType getValueType() { - return variable == null ? TextType.get() : variable.getValueType(); - } - - @Override - protected VariableNature getNature() { - return variable == null ? VariableNature.UNDETERMINED : VariableNature.getNature(variable); - } -} diff --git a/opal-search/src/test/java/org/obiba/opal/web/search/support/RQLCriterionParserTest.java b/opal-search/src/test/java/org/obiba/opal/web/search/support/RQLCriterionParserTest.java deleted file mode 100644 index 81931873fe..0000000000 --- a/opal-search/src/test/java/org/obiba/opal/web/search/support/RQLCriterionParserTest.java +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2021 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.opal.web.search.support; - -import net.jazdw.rql.parser.ASTNode; -import net.jazdw.rql.parser.RQLParser; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.obiba.magma.MagmaEngine; -import org.obiba.magma.ValueType; -import org.obiba.magma.support.VariableNature; -import org.obiba.magma.type.DateTimeType; -import org.obiba.magma.type.DateType; - -import static org.fest.assertions.api.Assertions.assertThat; - -public class RQLCriterionParserTest { - - @Before - public void setUp() throws Exception { - new MagmaEngine(); - } - - @After - public void tearDown() { - MagmaEngine.get().shutdown(); - } - - @Test - public void test_in_single() { - String rql = "in(field,1)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1)"); - } - - @Test - public void test_in_single_with_percent() { - String rql = "in(field,1%25)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1%)"); - assertThat(parser.getOriginalQuery()).isEqualTo("in(field,1%25)"); - parser = new RQLCriterionParser(RQLParserFactory.newParser().parse(rql)); - assertThat(parser.getQuery()).isEqualTo("field:(1%)"); - assertThat(parser.getOriginalQuery()).isEqualTo("in(field,1%25)"); - } - - @Test - public void test_in_single_with_space() { - String rql = "in(field,1 )"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1+)"); - } - - @Test - public void test_in_single_categorical() { - String rql = "in(field,1)"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(1)"); - } - - - @Test - public void test_in_single_categorical_wildcard() { - String rql = "in(field,*)"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(*)"); - } - - @Test - public void test_in_single_spaced() { - String rql = "in(field,1 2)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1+2)"); - } - - @Test - public void test_in_single_wildcard() { - String rql = "in(field,*)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(*)"); - } - - @Test - public void test_not_in_single() { - String rql = "not(in(field,1))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("NOT field:(1)"); - } - - @Test - public void test_in_singleton() { - String rql = "in(field,(1))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1)"); - } - - @Test - public void test_in_multiple() { - String rql = "in(field,(1,2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1 OR 2)"); - } - - @Test - public void test_in_multiple_categorical() { - String rql = "in(field,(1,2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(1 OR 2)"); - } - - @Test - public void test_in_multiple_categorical_with_spaces() { - String rql = "in(field,(\"Visit 1\",\"Visit 2\"))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(\"Visit 1\" OR \"Visit 2\")"); - } - - @Test - public void test_in_multiple_categorical_with_spaces2() { - String rql = "in(field,(Visit 1,Visit 2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(\"Visit 1\" OR \"Visit 2\")"); - } - - @Test - public void test_in_multiple_categorical_wildcard() { - String rql = "in(field,(1*,2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected VariableNature getNature() { - return VariableNature.CATEGORICAL; - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(1* OR 2)"); - } - - @Test - public void test_in_multiple_spaced() { - String rql = "in(field,(1 2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1+2)"); - } - - @Test - public void test_in_multiple_or() { - String rql = "in(field,or(1,2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1 OR 2)"); - } - - @Test - public void test_in_multiple_and() { - String rql = "in(field,and(1,2))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:(1 AND 2)"); - } - - @Test - public void test_all() { - String rql = "all(field)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo(""); - } - - @Test - public void test_exists() { - String rql = "exists(field)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("_exists_:field"); - } - - @Test - public void test_not_exists() { - String rql = "not(exists(field))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("NOT _exists_:field"); - } - - @Test - public void test_range() { - String rql = "range(field,(1,10))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:[1 TO 10]"); - } - - @Test - public void test_range_wildcard_right() { - String rql = "range(field,(1,*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:[1 TO *]"); - } - - @Test - public void test_range_wildcard_left() { - String rql = "range(field,(*,10))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:[* TO 10]"); - } - @Test - public void test_range_wildcards() { - String rql = "range(field,(*,*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("field:[* TO *]"); - } - - @Test - public void test_range_date() { - String rql = "range(field,(2017-06-01,2017-06-15))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:[2017-06-01 TO 2017-06-15]"); - } - - @Test - public void test_range_date_wildcard_right() { - String rql = "range(field,(2017-06-01,*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:[2017-06-01 TO *]"); - } - - @Test - public void test_range_date_wildcard_left() { - String rql = "range(field,(*,2017-06-01))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:[* TO 2017-06-01]"); - } - - @Test - public void test_range_date_wildcards() { - String rql = "range(field,(*,*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:[* TO *]"); - } - - @Test - public void test_range_datetime() { - String rql = "range(field,(2017-06-01,2017-06-15))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateTimeType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:[2017-06-01 TO 2017-06-15]"); - } - - @Test - public void test_in_singleton_date() { - String rql = "in(field,(2017-06-01))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(>=2017-06-01 AND <=2017-06-01)"); - } - - @Test - public void test_in_singleton_date_wildcard() { - String rql = "in(field,(*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(*)"); - } - - @Test - public void test_in_single_date() { - String rql = "in(field,2017-06-01)"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(>=2017-06-01 AND <=2017-06-01)"); - } - - @Test - public void test_in_single_date_wildcard() { - String rql = "in(field,*)"; - RQLCriterionParser parser = new RQLCriterionParser(rql) { - @Override - protected ValueType getValueType() { - return DateType.get(); - } - }; - assertThat(parser.getQuery()).isEqualTo("field:(*)"); - } - - @Test - public void test_like_single() { - String rql = "like(field,1)"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("(field:(1) OR field.analyzed:(1))"); - } - - @Test - public void test_like_multiple() { - String rql = "like(field,(1,2*))"; - RQLCriterionParser parser = new RQLCriterionParser(rql); - assertThat(parser.getQuery()).isEqualTo("(field:(1 OR 2*) OR field.analyzed:(1 OR 2*))"); - } - - @Test - public void test_query_node() { - test_query_node_tostring("in(field1,1)"); - test_query_node_tostring("in(field1,(1,2))"); - test_query_node_tostring("in(field1,(1 OR 2))"); - test_query_node_tostring("not(in(field1,(1,2)))"); - test_query_node_tostring("exists(field2)"); - test_query_node_tostring("not(exists(field2))"); - test_query_node_tostring("range(field3,(100,200))"); - test_query_node_tostring("not(range(field3,(100,200)))"); - test_query_node_tostring("range(field2,(2009-04-12,*))"); - test_query_node_tostring("in(field2,2009-04-12)"); - test_query_node_tostring("in(field2,(2009-04-12))"); - } - - private void test_query_node_tostring(String rql) { - ASTNode node = new RQLParser().parse(rql); - RQLCriterionParser parser = new RQLCriterionParser(node); - assertThat(parser.getOriginalQuery()).isEqualTo(rql); - - } -} diff --git a/pom.xml b/pom.xml index 1b566edd57..d3ee6e1f6e 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,6 @@ 6.2.8.Final 3.1.2.Final 1.7.7.1 - 0.3.1 1.13.0 1.0.0 1.1.0 @@ -1275,18 +1274,6 @@ jackson-dataformat-xml ${jackson.version} - - - net.jazdw - rql-parser - ${rql-parser.version} - - - commons-logging - commons-logging - - -