Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
Fixed boolean operators (and, or) and introduced wildcard() function (#…
Browse files Browse the repository at this point in the history
…72)

* Fixed boolean operators (and, or) and introduced wildcard() function

* Update to use latest api-search-query-lexer SNAPSHOT

* Like operator

Co-authored-by: Eugene <[email protected]>
Co-authored-by: Jordan Padams <[email protected]>
  • Loading branch information
3 people authored Sep 28, 2021
1 parent ee41fcd commit 900fd0e
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 115 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ POSSIBILITY OF SUCH DAMAGE.
<dependency>
<groupId>gov.nasa.pds</groupId>
<artifactId>api-search-query-lexer</artifactId>
<version>0.2.0</version>
<version>1.0.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ protected ResponseEntity<Object> getProductsResponseEntity(String q, String keyw
List<String> fields, List<String> sort, boolean onlySummary)
{
String accept = this.request.getHeader("Accept");
log.info("accept value is " + accept);
log.debug("accept value is " + accept);
if ((accept != null &&
(accept.contains("application/json")
|| accept.contains("application/pds4+json")
Expand Down Expand Up @@ -236,7 +236,7 @@ protected ResponseEntity<Object> getProductsResponseEntity(String q, String keyw
protected ResponseEntity<Object> getAllProductsResponseEntity(String lidvid, int start, int limit)
{
String accept = this.request.getHeader("Accept");
log.info("accept value is " + accept);
log.debug("accept value is " + accept);
if ((accept != null && (accept.contains("application/json") || accept.contains("text/html")
|| accept.contains("application/xml") || accept.contains("*/*"))) || (accept == null))
{
Expand Down Expand Up @@ -370,10 +370,9 @@ protected URL getBaseURL() {
baseURL = new URL(this.context.getScheme(), this.context.getServerName(), this.context.getServerPort(), this.contextPath);
}

MyProductsApiBareController.log.info("baseUrl is " + baseURL.toString());
log.debug("baseUrl is " + baseURL.toString());
return baseURL;


} catch (MalformedURLException e) {
log.error("Server URL was not retrieved");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ enum operation { eq, ge, gt, le, lt, ne };
private static final Logger log = LoggerFactory.getLogger(Antlr4SearchListener.class);

private BoolQueryBuilder query = new BoolQueryBuilder();
private boolean wildcard = false;

private conjunctions conjunction = conjunctions.AND;
final private Deque<conjunctions> stack_conjunction = new ArrayDeque<conjunctions>();
final private Deque<BoolQueryBuilder> stack_queries = new ArrayDeque<BoolQueryBuilder>();
final private Deque<List<QueryBuilder>> stack_musts = new ArrayDeque<List<QueryBuilder>>();
final private Deque<List<QueryBuilder>> stack_nots = new ArrayDeque<List<QueryBuilder>>();
final private Deque<List<QueryBuilder>> stack_shoulds = new ArrayDeque<List<QueryBuilder>>();

int depth = 0;
private List<QueryBuilder> musts = new ArrayList<QueryBuilder>();
private List<QueryBuilder> nots = new ArrayList<QueryBuilder>();
Expand Down Expand Up @@ -115,68 +116,108 @@ public void enterOrStatement(SearchParser.OrStatementContext ctx)
this.conjunction = conjunctions.OR;
}

@Override
public void enterComparison(SearchParser.ComparisonContext ctx)
{
this.wildcard = ctx.VALUE() != null && (ctx.VALUE().getSymbol().getText().contains("*") || ctx.VALUE().getSymbol().getText().contains("?"));
}

@Override
public void exitComparison(SearchParser.ComparisonContext ctx)
{
final String left = ElasticSearchUtil.jsonPropertyToElasticProperty (ctx.FIELD(0).getSymbol().getText());
String right;
QueryBuilder comparator = null;

// the second term of the comparison can be first tokenized as FIELD (string without quote) since FIELD is before VALUE (string with optional wildcard, no quote) in the ANTLR4 grammar.
if (ctx.FIELD(1) != null) right = ctx.FIELD(1).getSymbol().getText();
else if (ctx.NUMBER() != null) right = ctx.NUMBER().getSymbol().getText();
else if (ctx.STRINGVAL() != null)
{
right = ctx.STRINGVAL().getSymbol().getText();
right = right.substring(1, right.length()-1);
}
else if (ctx.VALUE() != null) right = ctx.VALUE().getSymbol().getText();
else
{
log.error("Panic, there are more data types than this version of the lexer knows about.");
throw new ParseCancellationException(); // PANIC: listener out of sync with the grammar
}
@Override
public void enterComparison(SearchParser.ComparisonContext ctx)
{
}

if (this.operator == operation.eq || this.operator == operation.ne)
{
if (this.wildcard) comparator = new WildcardQueryBuilder(left, right);
else comparator = new MatchQueryBuilder(left, right);
}
else
{
comparator = new RangeQueryBuilder(left);

if (this.operator == operation.ge) ((RangeQueryBuilder)comparator).gte(right);
else if (this.operator == operation.gt) ((RangeQueryBuilder)comparator).gt(right);
else if (this.operator == operation.le) ((RangeQueryBuilder)comparator).lte(right);
else if (this.operator == operation.lt) ((RangeQueryBuilder)comparator).lt(right);
else
{
log.error("Panic, there are more range operators than this version of the lexer knows about");
throw new ParseCancellationException(); // PANIC: listener out of sync with the grammar
}
}

if (this.operator == operation.ne) this.nots.add(comparator);
else if (this.conjunction == conjunctions.AND) this.musts.add(comparator);
else this.shoulds.add(comparator);
}
@Override
public void exitComparison(SearchParser.ComparisonContext ctx)
{
final String left = ElasticSearchUtil.jsonPropertyToElasticProperty(ctx.FIELD().getSymbol().getText());

String right;
QueryBuilder comparator = null;

if (ctx.NUMBER() != null)
{
right = ctx.NUMBER().getSymbol().getText();
}
else if (ctx.STRINGVAL() != null)
{
right = ctx.STRINGVAL().getSymbol().getText();
right = right.substring(1, right.length() - 1);
}
else
{
log.error("Panic, there are more data types than this version of the lexer knows about.");
throw new ParseCancellationException(); // PANIC: listener out of sync with the grammar
}

if (this.operator == operation.eq || this.operator == operation.ne)
{
comparator = new MatchQueryBuilder(left, right);
}
else
{
comparator = new RangeQueryBuilder(left);

if (this.operator == operation.ge)
((RangeQueryBuilder) comparator).gte(right);
else if (this.operator == operation.gt)
((RangeQueryBuilder) comparator).gt(right);
else if (this.operator == operation.le)
((RangeQueryBuilder) comparator).lte(right);
else if (this.operator == operation.lt)
((RangeQueryBuilder) comparator).lt(right);
else
{
log.error("Panic, there are more range operators than this version of the lexer knows about");
throw new ParseCancellationException(); // PANIC: listener out of sync with the grammar
}
}

if (this.operator == operation.ne)
{
this.nots.add(comparator);
}
else if (this.conjunction == conjunctions.AND)
{
this.musts.add(comparator);
}
else
{
this.shoulds.add(comparator);
}
}


@Override
public void enterLikeComparison(SearchParser.LikeComparisonContext ctx)
{
}


@Override
public void exitLikeComparison(SearchParser.LikeComparisonContext ctx)
{
final String left = ElasticSearchUtil.jsonPropertyToElasticProperty(ctx.FIELD().getText());

String right = ctx.STRINGVAL().getText();
right = right.substring(1, right.length() - 1);

QueryBuilder comparator = new WildcardQueryBuilder(left, right);

if("not".equalsIgnoreCase(ctx.getChild(1).getText()))
{
this.nots.add(comparator);
}
else if(this.conjunction == conjunctions.AND)
{
this.musts.add(comparator);
}
else
{
this.shoulds.add(comparator);
}
}


@Override
public void enterOperator(SearchParser.OperatorContext ctx)
{
if (this.wildcard && ctx.EQ() == null && ctx.NE() == null)
{
log.warn("Cannot use wildcards with <, <=, >=, or >");
throw new ParseCancellationException();
}

if (ctx.EQ() != null) this.operator = operation.eq;
else if (ctx.GE() != null) this.operator = operation.ge;
else if (ctx.GT() != null) this.operator = operation.gt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,15 @@ static private Product addPropertiesFromESEntity(
}

static public ProductWithXmlLabel ESentityProductToAPIProduct(EntitytProductWithBlob ep, URL baseURL) {
ElasticSearchUtil.log.info("convert ES object to API object with XML label");
log.debug("convert ES object to API object with XML label");
ProductWithXmlLabel product = new ProductWithXmlLabel();
product.setLabelXml(ep.getPDS4XML());
return (ProductWithXmlLabel)addPropertiesFromESEntity(product, ep, baseURL);
}


static public Product ESentityProductToAPIProduct(EntityProduct ep, URL baseURL) {
ElasticSearchUtil.log.info("convert ES object to API object without XML label");
log.debug("convert ES object to API object without XML label");

Product product = new Product();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package gov.nasa.pds.api.engineering.serializer;

import gov.nasa.pds.model.Product;
import gov.nasa.pds.api.model.xml.ProductWithXmlLabel;
import gov.nasa.pds.model.Metadata;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
Expand All @@ -18,11 +14,6 @@
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;


public class Pds4XmlProductSerializer extends AbstractHttpMessageConverter<ProductWithXmlLabel> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ private BoolQueryBuilder run (String query)
}

@Test
public void testEqualWildcard()
public void testLikeWildcard()
{
String qs = "lid eq *pdart14_meap";
String qs = "lid like \"*pdart14_meap\"";
BoolQueryBuilder query = this.run(qs);

Assertions.assertEquals (query.must().size(), 1);
Expand All @@ -66,20 +66,22 @@ public void testEqualWildcard()
Assertions.assertEquals (((WildcardQueryBuilder)query.must().get(0)).value(), "*pdart14_meap");
}

@Test
public void testNotEqualWildchar()
{
String qs = "lid ne pdart14_meap?";
BoolQueryBuilder query = this.run(qs);

Assertions.assertEquals (query.must().size(), 0);
Assertions.assertEquals (query.mustNot().size(), 1);
Assertions.assertEquals (query.should().size(), 0);
Assertions.assertTrue (query.mustNot().get(0) instanceof WildcardQueryBuilder);
Assertions.assertEquals (((WildcardQueryBuilder)query.mustNot().get(0)).fieldName(), "lid");
Assertions.assertEquals (((WildcardQueryBuilder)query.mustNot().get(0)).value(), "pdart14_meap?");
}


@Test
public void testNotLikeWildchar()
{
String qs = "lid not like \"pdart14_meap?\"";
BoolQueryBuilder query = this.run(qs);

Assertions.assertEquals(query.must().size(), 0);
Assertions.assertEquals(query.mustNot().size(), 1);
Assertions.assertEquals(query.should().size(), 0);
Assertions.assertTrue(query.mustNot().get(0) instanceof WildcardQueryBuilder);
Assertions.assertEquals(((WildcardQueryBuilder) query.mustNot().get(0)).fieldName(), "lid");
Assertions.assertEquals(((WildcardQueryBuilder) query.mustNot().get(0)).value(), "pdart14_meap?");
}


@Test
public void testEscape()
{
Expand All @@ -94,20 +96,6 @@ public void testEscape()
Assertions.assertEquals (((MatchQueryBuilder)query.must().get(0)).value(), "*pdart14_meap?");
}

@Test
public void testGroup()
{
String qs = "( lid eq *pdart14_meap* )";
BoolQueryBuilder query = this.run(qs);

Assertions.assertEquals (query.must().size(), 1);
Assertions.assertEquals (query.mustNot().size(), 0);
Assertions.assertEquals (query.should().size(), 0);
Assertions.assertTrue (query.must().get(0) instanceof WildcardQueryBuilder);
Assertions.assertEquals (((WildcardQueryBuilder)query.must().get(0)).fieldName(), "lid");
Assertions.assertEquals (((WildcardQueryBuilder)query.must().get(0)).value(), "*pdart14_meap*");

}

@Test
public void testGroupedStatementAndExclusiveInequality()
Expand Down Expand Up @@ -227,19 +215,6 @@ public void testNestedGrouping()
Assertions.assertFalse (((RangeQueryBuilder)nest.must().get(1)).includeUpper());
}

@Test
public void testNoWildcard()
{
String qs = "ref_lid_target eq urn:nasa:pds:context:target:planet.mercury";
BoolQueryBuilder query = this.run(qs);

Assertions.assertEquals (query.must().size(), 1);
Assertions.assertEquals (query.mustNot().size(), 0);
Assertions.assertEquals (query.should().size(), 0);
Assertions.assertTrue (query.must().get(0) instanceof MatchQueryBuilder);
Assertions.assertEquals (((MatchQueryBuilder)query.must().get(0)).fieldName(), "ref_lid_target");
Assertions.assertEquals (((MatchQueryBuilder)query.must().get(0)).value(), "urn:nasa:pds:context:target:planet.mercury");
}

@Test
public void testNoWildcardQuoted()
Expand Down

0 comments on commit 900fd0e

Please sign in to comment.