From 2dc5008bfb0f481549137ee41f151a38ebf4e04b Mon Sep 17 00:00:00 2001 From: Chris Tomlinson Date: Wed, 27 Dec 2017 11:03:18 -0600 Subject: [PATCH 1/4] resolve JENA 1453 ; reduce Lucene docs; add graph output arg --- .../org/apache/jena/query/text/TextHit.java | 10 ++++- .../jena/query/text/TextIndexLucene.java | 7 +++- .../jena/query/text/TextQueryFuncs.java | 3 -- .../apache/jena/query/text/TextQueryPF.java | 38 ++++++++++++------- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java b/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java index a59cf414992..f70890f4c74 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java @@ -26,11 +26,13 @@ public class TextHit private Node node; private float score; private Node literal; + private Node graph; - public TextHit(Node node, float score, Node literal) { + public TextHit(Node node, float score, Node literal, Node graph) { this.node = node; this.score = score; this.literal = literal; + this.graph = graph; } public Node getNode() { @@ -44,9 +46,13 @@ public float getScore() { public Node getLiteral() { return this.literal; } + + public Node getGraph() { + return this.graph; + } @Override public String toString() { - return "TextHit[node="+node+" literal="+literal+ " score="+score+"]"; + return "TextHit[node="+node+" literal="+literal+" score="+score+" graph="+graph+"]"; } } diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java index e530165a30e..9f50722dbe2 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java @@ -273,7 +273,7 @@ protected Document doc(Entity entity) { String graphField = docDef.getGraphField() ; if ( graphField != null ) { - Field gField = new Field(graphField, entity.getGraph(), ftString) ; + Field gField = new Field(graphField, entity.getGraph(), ftIRI) ; doc.add(gField) ; } @@ -461,8 +461,11 @@ public List query(Node property, String qs, String graphURI, String lan } } + String graf = docDef.getGraphField() != null ? doc.get(docDef.getGraphField()) : null ; + Node graph = graf != null ? TextQueryFuncs.stringToNode(graf) : null; + Node subject = TextQueryFuncs.stringToNode(entity) ; - TextHit hit = new TextHit(subject, sd.score, literal); + TextHit hit = new TextHit(subject, sd.score, literal, graph); results.add(hit) ; } return results ; diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryFuncs.java b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryFuncs.java index 695ba69a847..0a5e1e77cb8 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryFuncs.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryFuncs.java @@ -85,9 +85,6 @@ public static Entity entityFromQuad(EntityDefinition defn , Node g , Node s , No String language = o.getLiteral().language() ; RDFDatatype datatype = o.getLiteral().getDatatype() ; Entity entity = new Entity(x, graphText, language, datatype) ; - String graphField = defn.getGraphField() ; - if ( defn.getGraphField() != null ) - entity.put(graphField, graphText) ; entity.put(field, o.getLiteralLexicalForm()) ; return entity ; diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java index 4ff1a9ad645..0021e3dbd8f 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java @@ -77,8 +77,8 @@ public void build(PropFuncArg argSubject, Node predicate, PropFuncArg argObject, if (argSubject.isList()) { int size = argSubject.getArgListSize(); - if (size != 2 && size != 3) { - throw new QueryBuildException("Subject has "+argSubject.getArgList().size()+" elements, not 2 or 3: "+argSubject); + if (size > 4) { + throw new QueryBuildException("Subject has "+argSubject.getArgList().size()+" elements, greater than 4: "+argSubject); } } @@ -167,20 +167,29 @@ public QueryIterator exec(Binding binding, PropFuncArg argSubject, Node predicat Node s = null; Node score = null; Node literal = null; + Node graph = null; if (argSubject.isList()) { // Length checked in build() s = argSubject.getArg(0); - score = argSubject.getArg(1); - - if (!score.isVariable()) - throw new QueryExecException("Hit score is not a variable: "+argSubject) ; + + if (argSubject.getArgListSize() > 1) { + score = argSubject.getArg(1); + if (!score.isVariable()) + throw new QueryExecException("Hit score is not a variable: "+argSubject) ; + } if (argSubject.getArgListSize() > 2) { literal = argSubject.getArg(2); if (!literal.isVariable()) throw new QueryExecException("Hit literal is not a variable: "+argSubject) ; } + + if (argSubject.getArgListSize() > 3) { + graph = argSubject.getArg(3); + if (!graph.isVariable()) + throw new QueryExecException("Hit graph is not a variable: "+argSubject) ; + } } else { s = argSubject.getArg() ; } @@ -198,18 +207,19 @@ public QueryIterator exec(Binding binding, PropFuncArg argSubject, Node predicat // ---- QueryIterator qIter = (Var.isVar(s)) - ? variableSubject(binding, s, score, literal, match, execCxt) - : concreteSubject(binding, s, score, literal, match, execCxt) ; + ? variableSubject(binding, s, score, literal, graph, match, execCxt) + : concreteSubject(binding, s, score, literal, graph, match, execCxt) ; if (match.getLimit() >= 0) qIter = new QueryIterSlice(qIter, 0, match.getLimit(), execCxt) ; return qIter ; } - private QueryIterator resultsToQueryIterator(Binding binding, Node s, Node score, Node literal, Collection results, ExecutionContext execCxt) { + private QueryIterator resultsToQueryIterator(Binding binding, Node s, Node score, Node literal, Node graph, Collection results, ExecutionContext execCxt) { log.trace("resultsToQueryIterator: {}", results) ; Var sVar = Var.isVar(s) ? Var.alloc(s) : null ; Var scoreVar = (score==null) ? null : Var.alloc(score) ; Var literalVar = (literal==null) ? null : Var.alloc(literal) ; + Var graphVar = (graph==null) ? null : Var.alloc(graph) ; Function converter = (TextHit hit) -> { if (score == null && literal == null) @@ -221,6 +231,8 @@ private QueryIterator resultsToQueryIterator(Binding binding, Node s, Node score bmap.add(scoreVar, NodeFactoryExtra.floatToNode(hit.getScore())); if (literalVar != null) bmap.add(literalVar, hit.getLiteral()); + if (graphVar != null && hit.getGraph() != null) + bmap.add(graphVar, hit.getGraph()); return bmap; } ; @@ -229,14 +241,14 @@ private QueryIterator resultsToQueryIterator(Binding binding, Node s, Node score return qIter ; } - private QueryIterator variableSubject(Binding binding, Node s, Node score, Node literal, StrMatch match, ExecutionContext execCxt) { + private QueryIterator variableSubject(Binding binding, Node s, Node score, Node literal, Node graph, StrMatch match, ExecutionContext execCxt) { log.trace("variableSubject: {}", match) ; ListMultimap results = query(match.getProperty(), match.getQueryString(), match.getLang(), match.getLimit(), execCxt) ; Collection r = results.values(); - return resultsToQueryIterator(binding, s, score, literal, r, execCxt); + return resultsToQueryIterator(binding, s, score, literal, graph, r, execCxt); } - private QueryIterator concreteSubject(Binding binding, Node s, Node score, Node literal, StrMatch match, ExecutionContext execCxt) { + private QueryIterator concreteSubject(Binding binding, Node s, Node score, Node literal, Node graph, StrMatch match, ExecutionContext execCxt) { log.trace("concreteSubject: {}", match) ; ListMultimap x = query(match.getProperty(), match.getQueryString(), match.getLang(), -1, execCxt) ; @@ -245,7 +257,7 @@ private QueryIterator concreteSubject(Binding binding, Node s, Node score, Node List r = x.get(TextQueryFuncs.subjectToString(s)); - return resultsToQueryIterator(binding, s, score, literal, r, execCxt); + return resultsToQueryIterator(binding, s, score, literal, graph, r, execCxt); } private ListMultimap query(Node property, String queryString, String lang, int limit, ExecutionContext execCxt) { From 66c842db42e42687beb8e2dad817bc605546d62f Mon Sep 17 00:00:00 2001 From: Chris Tomlinson Date: Thu, 28 Dec 2017 13:19:46 -0600 Subject: [PATCH 2/4] added unit tests for jena-text and graphs --- .../org/apache/jena/query/text/TS_Text.java | 1 + .../query/text/TestTextGraphIndexExtra2.java | 335 ++++++++++++++++++ 2 files changed, 336 insertions(+) create mode 100644 jena-text/src/test/java/org/apache/jena/query/text/TestTextGraphIndexExtra2.java diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TS_Text.java b/jena-text/src/test/java/org/apache/jena/query/text/TS_Text.java index 7a16cbe4970..d8d2b196e1e 100644 --- a/jena-text/src/test/java/org/apache/jena/query/text/TS_Text.java +++ b/jena-text/src/test/java/org/apache/jena/query/text/TS_Text.java @@ -50,6 +50,7 @@ , TestDatasetWithComplexPhraseQueryParser.class , TestGenericAnalyzerAssembler.class , TestTextGraphIndexExtra.class + , TestTextGraphIndexExtra2.class }) public class TS_Text diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestTextGraphIndexExtra2.java b/jena-text/src/test/java/org/apache/jena/query/text/TestTextGraphIndexExtra2.java new file mode 100644 index 00000000000..136d1df7cc1 --- /dev/null +++ b/jena-text/src/test/java/org/apache/jena/query/text/TestTextGraphIndexExtra2.java @@ -0,0 +1,335 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.query.text; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.Reader ; +import java.io.StringReader ; +import java.util.Arrays ; +import java.util.HashMap ; +import java.util.HashSet ; +import java.util.Map ; +import java.util.Set ; + +import org.apache.jena.assembler.Assembler ; +import org.apache.jena.atlas.lib.StrUtils ; +import org.apache.jena.query.Dataset ; +import org.apache.jena.query.Query ; +import org.apache.jena.query.QueryExecution ; +import org.apache.jena.query.QueryExecutionFactory ; +import org.apache.jena.query.QueryFactory ; +import org.apache.jena.query.QuerySolution ; +import org.apache.jena.query.ReadWrite ; +import org.apache.jena.query.ResultSet ; +import org.apache.jena.query.text.assembler.TextAssembler ; +import org.apache.jena.rdf.model.Model ; +import org.apache.jena.rdf.model.ModelFactory ; +import org.apache.jena.rdf.model.Resource ; +import org.junit.After ; +import org.junit.Before ; +import org.junit.Test ; + +public class TestTextGraphIndexExtra2 extends AbstractTestDatasetWithTextIndexBase { + + private static final String SPEC_BASE = "http://example.org/spec#"; + private static final String SPEC_ROOT_LOCAL = "lucene_text_dataset"; + private static final String SPEC_ROOT_URI = SPEC_BASE + SPEC_ROOT_LOCAL; + private static final String SPEC; + static { + SPEC = StrUtils.strjoinNL( + "prefix rdfs: ", + "prefix ja: ", + "prefix tdb: ", + "prefix text: ", + "prefix : <" + SPEC_BASE + ">", + "", + "[] ja:loadClass \"org.apache.jena.query.text.TextQuery\" .", + "text:TextDataset rdfs:subClassOf ja:RDFDataset .", + "text:TextIndexLucene rdfs:subClassOf text:TextIndex .", + + ":" + SPEC_ROOT_LOCAL, + " a text:TextDataset ;", + " text:dataset :dataset ;", + " text:index :indexLucene ;", + " .", + "", + ":dataset", + " a tdb:DatasetTDB ;", + " tdb:location \"--mem--\" ;", + " tdb:unionDefaultGraph true ;", + ".", + "", + ":indexLucene", + " a text:TextIndexLucene ;", + " text:directory \"mem\" ;", + " text:storeValues true ;", + " text:entityMap :entMap ;", + " .", + "", + ":entMap", + " a text:EntityMap ;", + " text:entityField \"uri\" ;", + " text:defaultField \"label\" ;", + " text:langField \"lang\" ;", + " text:graphField \"graph\" ;", + " text:map (", + " [ text:field \"label\" ; text:predicate rdfs:label ]", + " [ text:field \"comment\" ; text:predicate rdfs:comment ]", + " ) ." + ); + } + + @Before + public void before() { + Reader reader = new StringReader(SPEC); + Model specModel = ModelFactory.createDefaultModel(); + specModel.read(reader, "", "TURTLE"); + TextAssembler.init(); + Resource root = specModel.getResource(SPEC_ROOT_URI); + dataset = (Dataset) Assembler.general.open(root); + } + + @After + public void after() { + dataset.close(); + } + + private void putTurtleInModel(String turtle, String modelName) { + Model model = modelName != null ? dataset.getNamedModel(modelName) : dataset.getDefaultModel() ; + Reader reader = new StringReader(turtle) ; + dataset.begin(ReadWrite.WRITE) ; + try { + model.read(reader, "", "TURTLE") ; + dataset.commit() ; + } + finally { + dataset.end(); + } + } + + protected Map doTestSearchWithGraphs(String queryString, Set expectedEntityURIs) { + Map graphs = new HashMap<>(); + Query query = QueryFactory.create(queryString) ; + dataset.begin(ReadWrite.READ); + try(QueryExecution qexec = QueryExecutionFactory.create(query, dataset)) { + ResultSet results = qexec.execSelect() ; + assertEquals(expectedEntityURIs.size() > 0, results.hasNext()); + int count; + for (count=0; results.hasNext(); count++) { + QuerySolution soln = results.nextSolution(); + String entityUri = soln.getResource("s").getURI(); + assertTrue(expectedEntityURIs.contains(entityUri)); + String grafURI = soln.getResource("g").getURI(); + assertNotNull(grafURI); + graphs.put(entityUri, grafURI); + } + assertEquals(expectedEntityURIs.size(), count); + } + finally { + dataset.end() ; + } + return graphs; + } + + @Test + public void testIterAllGraphs1() { + final String turtleA = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelA>", + " rdfs:label 'bar testResultOne barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultTwoInModelA>", + " rdfs:label 'bar testResultTwo barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultThreeInModelA>", + " rdfs:label 'bar testResultThree barfoo foo'", + "." + ); + putTurtleInModel(turtleA, "http://example.org/modelA") ; + final String turtleB = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelB>", + " rdfs:label 'bar testResultOne barfoo foo'", + "." + ); + putTurtleInModel(turtleB, "http://example.org/modelB") ; + String queryString = StrUtils.strjoinNL( + QUERY_PROLOG, + "SELECT ?s", + "WHERE {", + " GRAPH ?s { ?subj text:query ( rdfs:label 'testResultOne' 10 ) . }", + "}" + ); + Set expectedURIs = new HashSet<>() ; + expectedURIs.addAll( Arrays.asList("http://example.org/modelA", "http://example.org/modelB")) ; + doTestQuery(dataset, "", queryString, expectedURIs, expectedURIs.size()) ; + } + + @Test + public void testIterAllGraphs2() { + final String turtleA = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelA>", + " rdfs:label 'bar testResultOne barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultTwoInModelA>", + " rdfs:label 'bar testResultTwo barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultThreeInModelA>", + " rdfs:label 'bar testResultThree barfoo foo'", + "." + ); + putTurtleInModel(turtleA, "http://example.org/modelA") ; + final String turtleB = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelB>", + " rdfs:label 'bar testResultOne barfoo foo'", + "." + ); + putTurtleInModel(turtleB, "http://example.org/modelB") ; + String queryString = StrUtils.strjoinNL( + QUERY_PROLOG, + "SELECT ?s", + "WHERE {", + " GRAPH ?s { ?subj text:query ( rdfs:label 'testResultThree' 10 ) . }", + "}" + ); + Set expectedURIs = new HashSet<>() ; + expectedURIs.addAll( Arrays.asList("http://example.org/modelA")) ; + doTestQuery(dataset, "", queryString, expectedURIs, expectedURIs.size()) ; + } + + @Test + public void testIterAllGraphsWithLangOpt() { + final String turtleA = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelA>", + " rdfs:label 'bar testResultOne barfoo foo'@en", + ".", + "<" + RESOURCE_BASE + "testResultTwoInModelA>", + " rdfs:label 'bar testResultTwo barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultThreeInModelA>", + " rdfs:label 'bar testResultThree barfoo foo'", + "." + ); + putTurtleInModel(turtleA, "http://example.org/modelA") ; + final String turtleB = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelB>", + " rdfs:label 'bar testResultOne barfoo foo'@en", + "." + ); + putTurtleInModel(turtleB, "http://example.org/modelB") ; + String queryString = StrUtils.strjoinNL( + QUERY_PROLOG, + "SELECT ?s", + "WHERE {", + " GRAPH ?s { ?subj text:query ( rdfs:label 'testResultOne' 10 'lang:en' ) . }", + "}" + ); + Set expectedURIs = new HashSet<>() ; + expectedURIs.addAll( Arrays.asList("http://example.org/modelA", "http://example.org/modelB")) ; + doTestQuery(dataset, "", queryString, expectedURIs, expectedURIs.size()) ; + } + + @Test + public void testTextQueryPFGraphsOutputArg1() { + final String turtleA = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelA>", + " rdfs:label 'bar testResultOne barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultTwoInModelA>", + " rdfs:label 'bar testResultTwo barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultThreeInModelA>", + " rdfs:label 'bar testResultThree barfoo foo'", + "." + ); + putTurtleInModel(turtleA, "http://example.org/modelA") ; + final String turtleB = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelB>", + " rdfs:label 'bar testResultOne barfoo foo'", + "." + ); + putTurtleInModel(turtleB, "http://example.org/modelB") ; + String queryString = StrUtils.strjoinNL( + QUERY_PROLOG, + "SELECT ?s ?g", + "WHERE {", + " (?s ?sc ?lit ?g) text:query ( rdfs:label 'testResultThree' 10 ) . ", + "}" + ); + Set expectedURIs = new HashSet<>() ; + expectedURIs.addAll( Arrays.asList(RESOURCE_BASE + "testResultThreeInModelA")) ; + + Map grafs = doTestSearchWithGraphs(queryString, expectedURIs) ; + assertEquals(1, grafs.size()); + String graf = grafs.get(RESOURCE_BASE + "testResultThreeInModelA"); + assertNotNull(graf); + assertEquals("http://example.org/modelA", graf); + } + + @Test + public void testTextQueryPFGraphsOutputArg2() { + final String turtleA = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelA>", + " rdfs:label 'bar testResultOne barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultTwoInModelA>", + " rdfs:label 'bar testResultTwo barfoo foo'", + ".", + "<" + RESOURCE_BASE + "testResultThreeInModelA>", + " rdfs:label 'bar testResultThree barfoo foo'", + "." + ); + putTurtleInModel(turtleA, "http://example.org/modelA") ; + final String turtleB = StrUtils.strjoinNL( + TURTLE_PROLOG, + "<" + RESOURCE_BASE + "testResultOneInModelB>", + " rdfs:label 'bar testResultOne barfoo foo'", + "." + ); + putTurtleInModel(turtleB, "http://example.org/modelB") ; + String queryString = StrUtils.strjoinNL( + QUERY_PROLOG, + "SELECT ?s ?g", + "WHERE {", + " (?s ?sc ?lit ?g) text:query ( rdfs:label 'testResultOne' 10 ) . ", + "}" + ); + Set expectedURIs = new HashSet<>() ; + expectedURIs.addAll( Arrays.asList(RESOURCE_BASE + "testResultOneInModelA", RESOURCE_BASE + "testResultOneInModelB")) ; + + Map grafs = doTestSearchWithGraphs(queryString, expectedURIs) ; + assertEquals(2, grafs.size()); + String graf = grafs.get(RESOURCE_BASE + "testResultOneInModelA"); + assertNotNull(graf); + assertEquals("http://example.org/modelA", graf); + graf = grafs.get(RESOURCE_BASE + "testResultOneInModelB"); + assertNotNull(graf); + assertEquals("http://example.org/modelB", graf); + } +} From 59dcb8ee9f07fa0d7c9664c50689004ba440e1ca Mon Sep 17 00:00:00 2001 From: Chris Tomlinson Date: Fri, 29 Dec 2017 08:30:20 -0600 Subject: [PATCH 3/4] ensure subject arg list has at least one element --- .../src/main/java/org/apache/jena/query/text/TextQueryPF.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java index 0021e3dbd8f..10517623df3 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextQueryPF.java @@ -77,8 +77,8 @@ public void build(PropFuncArg argSubject, Node predicate, PropFuncArg argObject, if (argSubject.isList()) { int size = argSubject.getArgListSize(); - if (size > 4) { - throw new QueryBuildException("Subject has "+argSubject.getArgList().size()+" elements, greater than 4: "+argSubject); + if (size == 0 || size > 4) { + throw new QueryBuildException("Subject has "+argSubject.getArgList().size()+" elements, must be at least 1 and not greater than 4: "+argSubject); } } From 3a9af3bbaadeb431a0f0c6ba87bdbb5eb089d5f6 Mon Sep 17 00:00:00 2001 From: Chris Tomlinson Date: Fri, 29 Dec 2017 10:31:52 -0600 Subject: [PATCH 4/4] add back constructor without graph arg for jena-text-es --- .../src/main/java/org/apache/jena/query/text/TextHit.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java b/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java index f70890f4c74..dd2843b7ff1 100644 --- a/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java +++ b/jena-text/src/main/java/org/apache/jena/query/text/TextHit.java @@ -28,6 +28,13 @@ public class TextHit private Node literal; private Node graph; + public TextHit(Node node, float score, Node literal) { + this.node = node; + this.score = score; + this.literal = literal; + this.graph = null; + } + public TextHit(Node node, float score, Node literal, Node graph) { this.node = node; this.score = score;