/** * 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.sparql.expr; import org.apache.jena.atlas.junit.BaseTest ; import org.apache.jena.atlas.lib.StrUtils ; import org.apache.jena.atlas.logging.LogCtl ; import org.apache.jena.graph.Graph ; import org.apache.jena.query.* ; import org.apache.jena.rdf.model.Model ; import org.apache.jena.rdf.model.ModelFactory ; import org.apache.jena.sparql.algebra.Algebra ; import org.apache.jena.sparql.algebra.Op ; import org.apache.jena.sparql.engine.binding.Binding ; import org.apache.jena.sparql.expr.Expr ; import org.apache.jena.sparql.expr.ExprEvalException ; import org.apache.jena.sparql.expr.ExprList ; import org.apache.jena.sparql.expr.NodeValue ; import org.apache.jena.sparql.expr.aggregate.* ; import org.apache.jena.sparql.function.FunctionEnv ; import org.apache.jena.sparql.graph.NodeConst ; import org.apache.jena.sparql.sse.SSE ; import org.junit.AfterClass ; import org.junit.BeforeClass ; import org.junit.Test ; public class TestCustomAggregates extends BaseTest { public static final String aggIRI = "http://example.test/agg" ; public static final String aggIRI2 = "http://example.test/aggUnRegistered" ; static AccumulatorFactory myAccumulatorFactory = new AccumulatorFactory() { @Override public Accumulator createAccumulator(AggCustom agg, boolean distinct) { return new MyAccumulator(agg, distinct) ; } } ; static class MyAccumulator implements Accumulator { int count = 0 ; private AggCustom agg ; MyAccumulator(AggCustom agg, boolean ignored) { this.agg = agg ; } @Override public void accumulate(Binding binding, FunctionEnv functionEnv) { ExprList exprList = agg.getExprList() ; for(Expr expr: exprList) { try { NodeValue nv = expr.eval(binding, functionEnv) ; // Evaluation succeeded. if ( nv.isLiteral()) count ++ ; } catch (ExprEvalException ex) {} } } @Override public NodeValue getValue() { return NodeValue.makeInteger(count) ; }} @BeforeClass public static void setup() { AggregateRegistry.register(aggIRI, myAccumulatorFactory, NodeConst.nodeMinusOne); } @AfterClass public static void clearup() { AggregateRegistry.unregister(aggIRI); } @Test public void customAgg_1() { assertTrue(AggregateRegistry.isRegistered(aggIRI)) ; } @Test public void customAgg_2() { assertFalse(AggregateRegistry.isRegistered(aggIRI2)) ; } @Test public void customAgg_10() { String qs = "SELECT (AGG <"+aggIRI+">(?o) AS ?x) {?s ?p ?o } GROUP BY ?s" ; Query q = QueryFactory.create(qs, Syntax.syntaxARQ) ; String qs2 = q.serialize(Syntax.syntaxARQ) ; Query q2 = QueryFactory.create(qs2, Syntax.syntaxARQ) ; assertEquals(q, q2) ; } @Test public void customAgg_11() { String qs = "SELECT (<"+aggIRI+">(?o) AS ?x) {?s ?p ?o } GROUP BY ?s" ; Query q = QueryFactory.create(qs) ; String qs2 = q.serialize() ; Query q2 = QueryFactory.create(qs2) ; assertEquals(q, q2) ; } @Test public void customAgg_12() { LogCtl.setError(AggregatorFactory.class); try { String qs = "SELECT (AGG <"+aggIRI2+">(?o) AS ?x) {?s ?p ?o } GROUP BY ?s" ; Query q = QueryFactory.create(qs, Syntax.syntaxARQ) ; String qs2 = q.serialize(Syntax.syntaxARQ) ; Query q2 = QueryFactory.create(qs2, Syntax.syntaxARQ) ; assertEquals(q, q2) ; } finally { LogCtl.setInfo(AggregatorFactory.class); } } @Test public void customAgg_20() { Graph g = SSE.parseGraph("(graph (:s :p :o) (:s :p 1))") ; Model m = ModelFactory.createModelForGraph(g) ; String qs = "SELECT (<"+aggIRI+">(?o) AS ?x) {?s ?p ?o } GROUP BY ?s" ; Query q = QueryFactory.create(qs, Syntax.syntaxARQ) ; try (QueryExecution qExec = QueryExecutionFactory.create(q, m) ) { ResultSet rs = qExec.execSelect() ; QuerySolution soln = rs.nextSolution() ; assertFalse(rs.hasNext()); int v = soln.getLiteral("x").getInt() ; assertEquals(1, v) ; } } @Test public void customAgg_21() { Graph g = SSE.parseGraph("(graph (:s :p :o) (:s :p 1))") ; Model m = ModelFactory.createModelForGraph(g) ; String qs = "SELECT (<"+aggIRI+">(?o) AS ?x) {?s ?p ?o FILTER (false) } GROUP BY ?s" ; Query q = QueryFactory.create(qs, Syntax.syntaxARQ) ; try (QueryExecution qExec = QueryExecutionFactory.create(q, m) ) { ResultSet rs = qExec.execSelect() ; QuerySolution soln = rs.nextSolution() ; assertFalse(rs.hasNext()); int v = soln.getLiteral("x").getInt() ; assertEquals(-1, v) ; } } @Test public void customAgg_22() { String qs = "SELECT (<"+aggIRI+">(?o) AS ?x) {?s ?p ?o }" ; Query q = QueryFactory.create(qs, Syntax.syntaxARQ) ; Op op = Algebra.compile(q) ; String x = StrUtils.strjoinNL ("(project (?x)" ," (extend ((?x ?.0))" ," (group () ((?.0 (agg <http://example.test/agg> ?o)))" ," (bgp (triple ?s ?p ?o)))))" ) ; Op op2 = SSE.parseOp(x) ; assertEquals(op2, op); } }