From cd2d7565a97bbda3ee38e3708f5ff291f25d522e Mon Sep 17 00:00:00 2001 From: bibhas Date: Wed, 18 Jul 2012 16:52:49 +0100 Subject: [PATCH] Added code to recommend property path between two variables #3 Refactored the code to map a query to a DGS query using a Pipeline design pattern --- .../backend/DGSQueryResultProcessor.java | 43 +- .../queryProcessor/AST2TextTranslator.java | 11 +- .../queryProcessor/AddOneHopPropertyPath.java | 156 ++++++ .../queryProcessor/BasicOperation.java | 30 ++ .../ContentRemovalProcessor.java | 12 +- .../queryProcessor/DGSQueryProcessor.java | 150 ------ .../queryProcessor/DeNormalizeAST.java | 18 +- .../analytics/queryProcessor/POFMetadata.java | 64 +++ .../queryProcessor/PipelineObject.java | 148 ++++++ .../queryProcessor/PofNodesMetadata.java | 24 +- .../queryProcessor/PointOfFocusProcessor.java | 53 +- .../RecommendationScopeProcessor.java | 14 +- .../queryProcessor/RecommendationType.java | 27 + .../analytics/queryProcessor/Select2Ask.java | 48 ++ .../queryProcessor/SparqlToDGSQuery.java | 81 --- ...or.java => SparqlToDGSQueryInterface.java} | 91 ++-- .../SparqlToDGSQueryManager.java | 167 ++++++ .../SparqlTranslationProcessor.java | 67 ++- .../ValidateQ4Recommendations.java | 12 +- .../analytics/ranking/BaseLabelRanking.java | 6 +- .../analytics/servlet/JsonResponseWriter.java | 32 +- .../analytics/servlet/ResponseWriter.java | 4 +- .../analytics/servlet/SparqlRecommender.java | 18 +- .../analytics/backend/TestDGSBackend.java | 19 +- .../queryProcessor/TestASTVarProcessor.java | 1 + .../queryProcessor/TestAddOneHopPath.java | 335 ++++++++++++ .../TestContentRemovalProcessor.java | 14 +- .../TestDGSDatasetClauseProcessor.java | 2 + .../TestDeNormalizeASTVisitor.java | 94 ++-- .../queryProcessor/TestPofNodesMetadata.java | 389 +++++++------- .../TestPointOfFocusProcessor.java | 65 ++- .../TestRecommendationScopeProcessor.java | 44 +- .../queryProcessor/TestSelect2Ask.java | 74 +++ .../queryProcessor/TestSparqlToDGSQuery.java | 467 ----------------- .../TestSparqlToDGSQueryManager.java | 494 ++++++++++++++++++ .../TestSparqlTranslationProcessor.java | 118 +++-- .../TestValidateQ4Recommendations.java | 26 +- .../analytics/ranking/TestScoreLabel.java | 4 +- .../TestAssistedSparqlEditorSevlet.java | 11 +- .../HopsBackend/test-data-hops.nt.gz | Bin 0 -> 640 bytes 40 files changed, 2180 insertions(+), 1253 deletions(-) create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AddOneHopPropertyPath.java create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/BasicOperation.java delete mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DGSQueryProcessor.java create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/POFMetadata.java create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PipelineObject.java create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationType.java create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/Select2Ask.java delete mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQuery.java rename recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/{QueryProcessor.java => SparqlToDGSQueryInterface.java} (56%) create mode 100644 recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryManager.java create mode 100644 recommendation-servlet/src/test/java/org/sindice/analytics/queryProcessor/TestAddOneHopPath.java create mode 100644 recommendation-servlet/src/test/java/org/sindice/analytics/queryProcessor/TestSelect2Ask.java delete mode 100644 recommendation-servlet/src/test/java/org/sindice/analytics/queryProcessor/TestSparqlToDGSQuery.java create mode 100644 recommendation-servlet/src/test/java/org/sindice/analytics/queryProcessor/TestSparqlToDGSQueryManager.java create mode 100644 recommendation-servlet/src/test/resources/HopsBackend/test-data-hops.nt.gz diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/backend/DGSQueryResultProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/backend/DGSQueryResultProcessor.java index 748ef56..c76b052 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/backend/DGSQueryResultProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/backend/DGSQueryResultProcessor.java @@ -24,8 +24,8 @@ import org.openrdf.query.Binding; import org.openrdf.query.BindingSet; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; -import org.sindice.analytics.queryProcessor.QueryProcessor; -import org.sindice.analytics.queryProcessor.QueryProcessor.RecommendationType; +import org.sindice.analytics.queryProcessor.RecommendationType; +import org.sindice.analytics.queryProcessor.SparqlToDGSQueryInterface; import org.sindice.analytics.ranking.Label; import org.sindice.analytics.ranking.Label.LabelType; import org.sindice.core.sesame.backend.SesameBackend.QueryIterator.QueryResultProcessor; @@ -50,27 +50,34 @@ public Context getContext() { @Override public Label process(Object o, Context c) { final Label label; - final BindingSet set = (BindingSet) o; // The DGS query is a SELECT query - final Iterator it = set.iterator(); + if(o instanceof BindingSet) { + final BindingSet set = (BindingSet) o; // The DGS query is a SELECT query + final Iterator it = set.iterator(); - final Value pof = set.getValue(SyntaxTreeBuilder.PointOfFocus); - final Value pofCard = set.getValue(QueryProcessor.CARDINALITY_VAR); - final Value pofResource = set.getValue(QueryProcessor.POF_RESOURCE); + final Value pof = set.getValue(SyntaxTreeBuilder.PointOfFocus); + final Value pofCard = set.getValue(SparqlToDGSQueryInterface.CARDINALITY_VAR); + final Value pofResource = set.getValue(SparqlToDGSQueryInterface.POF_RESOURCE); - if (pof != null && pofCard != null && pofResource != null) { - final LabelType type = (pof instanceof URI) ? LabelType.URI : LabelType.LITERAL; - label = new Label(type, pof.stringValue(), Long.valueOf(pofCard.stringValue())); - while (it.hasNext()) { - final Binding binding = it.next(); + if (pof != null && pofCard != null && pofResource != null) { + final LabelType type = (pof instanceof URI) ? LabelType.URI : LabelType.LITERAL; + label = new Label(type, pof.stringValue(), Long.valueOf(pofCard.stringValue())); + while (it.hasNext()) { + final Binding binding = it.next(); - if (!binding.getName().equals(SyntaxTreeBuilder.PointOfFocus) && - !binding.getName().equals(QueryProcessor.CARDINALITY_VAR)) { - label.addContext(binding.getName(), binding.getValue().stringValue()); - } - } - return label; + if (!binding.getName().equals(SyntaxTreeBuilder.PointOfFocus) && + !binding.getName().equals(SparqlToDGSQueryInterface.CARDINALITY_VAR)) { + label.addContext(binding.getName(), binding.getValue().stringValue()); + } + } + return label; + } + } + else if(o instanceof Boolean){ + final Boolean ans = (Boolean) o; + return new Label(LabelType.NONE, ans.toString(), -1); } return new Label(LabelType.NONE, "", -1); + } } diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AST2TextTranslator.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AST2TextTranslator.java index c733bce..c49b23f 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AST2TextTranslator.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AST2TextTranslator.java @@ -151,6 +151,7 @@ public Object visit(ASTAskQuery node, Object data) final StringBuilder sb = (StringBuilder) data; sb.append("ASK\n"); + node.childrenAccept(this, data); return data; } @@ -562,8 +563,14 @@ public Object visit(ASTIRI node, Object data) public Object visit(ASTVar node, Object data) throws VisitorException { final StringBuilder sb = (StringBuilder) data; - - sb.append('?').append(node.getName()).append(' '); + +// if (node.getName().startsWith("?")) { // only the POF can start with '?' +// sb.append(node.getName()).append("< "); +// } + if (node.getName().equals("?POF")) + sb.append(node.getName()).append(' '); + else + sb.append('?').append(node.getName()).append(' '); return data; } diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AddOneHopPropertyPath.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AddOneHopPropertyPath.java new file mode 100644 index 0000000..d475875 --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/AddOneHopPropertyPath.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import java.util.ArrayList; +import java.util.List; + +import org.openrdf.query.MalformedQueryException; +import org.openrdf.sindice.query.parser.sparql.ASTVisitorBase; +import org.openrdf.sindice.query.parser.sparql.ast.ASTBasicGraphPattern; +import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; +import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath; +import org.openrdf.sindice.query.parser.sparql.ast.ASTVar; +import org.openrdf.sindice.query.parser.sparql.ast.ParseException; +import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; +import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants; +import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; +import org.sindice.analytics.backend.DGSQueryResultProcessor.Context; +import org.sindice.analytics.ranking.Label; +import org.sindice.core.sesame.backend.SesameBackendException; +import org.sindice.core.sesame.backend.SesameBackend.QueryIterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author bibhas [Jul 9, 2012] + * @email bibhas.das@deri.org + * + */ +public class AddOneHopPropertyPath implements BasicOperation { + + private static final Logger logger = LoggerFactory.getLogger(AddOneHopPropertyPath.class); + + private final SparqlTranslationProcessor sparql2dgs; + private final Select2Ask selectToAsk = new Select2Ask(); + + public AddOneHopPropertyPath(SparqlTranslationProcessor sparql2dgs) { + this.sparql2dgs = sparql2dgs; + } + + private class HopsVarsPair { + int hops; + final ArrayList varsToProject = new ArrayList(); + + public void reset(int hops) { + this.hops = hops; + varsToProject.clear(); + } + } + + public PipelineObject process(PipelineObject po) + throws VisitorException, MalformedQueryException, ParseException, SesameBackendException { + if (!po.getType().equals(RecommendationType.PREDICATE)) { + return po; + } + + String query = AST2TextTranslator.translate(po.getAst()); + final AddHopVisitor obj = new AddHopVisitor(); + int hops = 1; + final HopsVarsPair hopsVars = new HopsVarsPair(); + while (hops <= po.getMAX_HOPS()) { + po = sparql2dgs.process(po); + ASTQueryContainer ast = selectToAsk.convert(po.getAst()); + QueryIterator qit = po.getBackend().submit( + AST2TextTranslator.translate(ast)); + qit.hasNext(); + if (qit.next().getLabel().equals("true")) { + logger.debug("Property Path Recommendation: Breaking out...."); + break; + } + if (++hops > po.getMAX_HOPS()) + break; + hopsVars.reset(hops); + po.setAst(SyntaxTreeBuilder.parseQuery(query)); + obj.visit(po.getAst(), hopsVars); + query = AST2TextTranslator.translate(po.getAst()); + po.getVarsToProject().addAll(hopsVars.varsToProject); + } + po.setAst(SyntaxTreeBuilder.parseQuery(query)); + return po; + } + + public class AddHopVisitor extends ASTVisitorBase { + public Object visit(ASTBasicGraphPattern node, Object data) + throws VisitorException { + final HopsVarsPair hopsVars = (HopsVarsPair) data; + final int hops = hopsVars.hops; + final ArrayList set = hopsVars.varsToProject; + boolean foundPOF = false; + + final ASTBasicGraphPattern bgpDGS = new ASTBasicGraphPattern(SyntaxTreeBuilderTreeConstants.JJTBASICGRAPHPATTERN); + ASTTriplesSameSubjectPath triple = null; + + // find the ?POF variable in the triple pattern + final List tpList = node + .jjtGetChildren(ASTTriplesSameSubjectPath.class); + while (true) { + triple = tpList.remove(0); + if (triple.jjtGetChild(1).jjtGetChild(0) instanceof ASTVar) { + if (((ASTVar) triple.jjtGetChild(1).jjtGetChild(0)).getName().equals(SyntaxTreeBuilder.PointOfFocus)) { + foundPOF = true; + break; + } + } + bgpDGS.jjtAppendChild(triple); + } + + if (foundPOF) { + for (int i = 2; i < hops; i++) { + bgpDGS.jjtAppendChild(triple); + triple = tpList.remove(0); + } + final ASTVar targetNode = (ASTVar) triple.jjtGetChild(1).jjtGetChild(1) + .jjtGetChild(0); + + // change the existing triple + final ASTVar newObject = ASTVarGenerator.getASTVar("ob"); + set.add(newObject.getName()); + final ASTVar newPOF = ASTVarGenerator.getASTVar(SyntaxTreeBuilder.PointOfFocus); + set.add(newPOF.getName()); + final ASTTriplesSameSubjectPath t1 = ASTProcessorUtil.createTriple(triple + .jjtGetChild(0), triple.jjtGetChild(1).jjtGetChild(0), newObject); + final ASTTriplesSameSubjectPath t2 = ASTProcessorUtil.createTriple(newObject, + newPOF, targetNode); + + bgpDGS.jjtAppendChild(t1); + bgpDGS.jjtAppendChild(t2); + + // add rest of the triples in the BGP + for (ASTTriplesSameSubjectPath tp: tpList) { + bgpDGS.jjtAppendChild(tp); + } + node.jjtReplaceWith(bgpDGS); + } + + return super.visit(node, data); + } + } + +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/BasicOperation.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/BasicOperation.java new file mode 100644 index 0000000..770903e --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/BasicOperation.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import org.sindice.analytics.queryProcessor.PipelineObject; + +/** + * @author bibhas [Jul 11, 2012] + * @email bibhas.das@deri.org + * + */ +public interface BasicOperation { + + public PipelineObject process(PipelineObject obj) throws Exception; +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ContentRemovalProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ContentRemovalProcessor.java index b2f7b13..f2e3c10 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ContentRemovalProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ContentRemovalProcessor.java @@ -29,7 +29,6 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTPathAlternative; import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyList; import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyListPath; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTRDFLiteral; import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath; import org.openrdf.sindice.query.parser.sparql.ast.ASTTrue; @@ -47,15 +46,12 @@ * @email stephane.campinas@deri.org * */ -public final class ContentRemovalProcessor { +public final class ContentRemovalProcessor implements BasicOperation{ - private ContentRemovalProcessor() { - } - - public static void process(ASTQueryContainer ast) - throws VisitorException { + public PipelineObject process(PipelineObject obj) throws VisitorException { final ContentRemovalVisitor c = new ContentRemovalVisitor(); - c.visit(ast, null); + c.visit(obj.getAst(), null); + return obj; } private static class ContentRemovalVisitor extends ASTVisitorBase { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DGSQueryProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DGSQueryProcessor.java deleted file mode 100644 index 5079c2d..0000000 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DGSQueryProcessor.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. - * - * - * This project is a free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This project is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this project. If not, see . - *******************************************************************************/ -/** - * @project sparql-editor-servlet - * @author Campinas Stephane [ 25 Mar 2012 ] - * @link stephane.campinas@deri.org - */ -package org.sindice.analytics.queryProcessor; - -import java.util.List; - -import org.apache.commons.lang.NotImplementedException; -import org.openrdf.query.MalformedQueryException; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; -import org.openrdf.sindice.query.parser.sparql.ast.ParseException; -import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; -import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; -import org.sindice.core.analytics.commons.summary.AnalyticsVocab; -import org.sindice.core.analytics.commons.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - */ -public class DGSQueryProcessor -implements QueryProcessor { - - private static final Logger logger = LoggerFactory.getLogger(QueryProcessor.class); - - private ASTQueryContainer ast; - private String dgsQuery; - private RecommendationType type; - - private POFMetadata pofMetadata; // The Point Of Focus metadata - - @Override - public String getDGSQuery() - throws DGSException { - if (dgsQuery == null) { - try { - dgsQuery = AST2TextTranslator.translate(ast); - } catch (VisitorException e) { - throw new DGSException(e); - } - } - return dgsQuery; - } - - @Override - public void load(String query) - throws DGSException { - this.load(query, null); - } - - @Override - public void load(String query, List varsToProject) - throws DGSException { - try { - dgsQuery = null; - pofMetadata = null; - ast = SyntaxTreeBuilder.parseQuery(query); - pofMetadata = SparqlToDGSQuery.process(ast, varsToProject); - type = SparqlToDGSQuery.getRecommendationType(); - } catch (ParseException e) { - throw new DGSException(e); - } catch (VisitorException e) { - throw new DGSException(e); - } catch (MalformedQueryException e) { - throw new DGSException(e); - } - } - - @Override - public POFMetadata getPofASTMetadata() { - return pofMetadata; - } - - @Override - public String getDomainsQuery(String domain, int limit) - throws DGSException { - throw new NotImplementedException(); - } - - @Override - public String getPropertiesQuery(String domain, int limit) - throws DGSException { - if (domain == null) { - throw new DGSException("The given domain is null"); - } - final StringBuilder sb = new StringBuilder(); - final String d = URIUtil.getSndDomainFromUrl(domain); - if (d == null) { - throw new DGSException("Unable to get second-level domain name from " + domain); - } - domain = d; - sb.append("SELECT DISTINCT ?property FROM <").append(AnalyticsVocab.GRAPH_SUMMARY_GRAPH).append("> WHERE {\n") - .append(" ?edge <").append(AnalyticsVocab.EDGE_PUBLISHED_IN).append("> ") - .append(domain.isEmpty() ? "?domain .\n" : "<" + AnalyticsVocab.DOMAIN_URI_PREFIX + domain + "> .\n") - .append(" ?edge <").append(AnalyticsVocab.LABEL).append("> ?property .\n}\nORDER BY (?property)\n"); - if (limit != 0) { - sb.append("LIMIT ").append(limit); - } - return sb.toString(); - } - - @Override - public String getClassesQuery(String domain, int limit) - throws DGSException { - if (domain == null) { - throw new DGSException("The given domain is null"); - } - final StringBuilder sb = new StringBuilder(); - final String d = URIUtil.getSndDomainFromUrl(domain); - if (d == null) { - throw new DGSException("Unable to get second-level domain name from " + domain); - } - domain = d; - sb.append("SELECT DISTINCT ?class FROM <").append(AnalyticsVocab.GRAPH_SUMMARY_GRAPH).append("> WHERE {\n") - .append(" ?node <").append(AnalyticsVocab.DOMAIN_URI).append("> ") - .append(domain.isEmpty() ? "?domain .\n" : "<" + AnalyticsVocab.DOMAIN_URI_PREFIX + domain + "> .\n") - .append(" ?node <").append(AnalyticsVocab.LABEL).append("> ?l .\n") - .append(" ?l <").append(AnalyticsVocab.LABEL).append("> ?class .\n}\nORDER BY (?class)\n"); - if (limit != 0) { - sb.append("LIMIT ").append(limit); - } - return sb.toString(); - } - - @Override - public RecommendationType getRecommendationType() { - return type; - } - -} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DeNormalizeAST.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DeNormalizeAST.java index b351203..523a13e 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DeNormalizeAST.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/DeNormalizeAST.java @@ -35,7 +35,6 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTIRI; import org.openrdf.sindice.query.parser.sparql.ast.ASTOptionalGraphPattern; import org.openrdf.sindice.query.parser.sparql.ast.ASTQName; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath; import org.openrdf.sindice.query.parser.sparql.ast.Node; import org.openrdf.sindice.query.parser.sparql.ast.SimpleNode; @@ -49,20 +48,17 @@ * @email stephane.campinas@deri.org * */ -public final class DeNormalizeAST { +public final class DeNormalizeAST implements BasicOperation{ - private DeNormalizeAST() { - } - - public static void process(ASTQueryContainer ast) - throws MalformedQueryException, VisitorException { + public PipelineObject process(PipelineObject obj) throws MalformedQueryException, VisitorException { final DeNormalizeASTVisitor deNorm = new DeNormalizeASTVisitor(); final DeNormalizeQualifiedName qname = new DeNormalizeQualifiedName(); - final Map prefixes = PrefixDeclProcessor.process(ast); - qname.visit(ast, prefixes); - BlankNodeVarProcessor.process(ast); - deNorm.visit(ast, null); + final Map prefixes = PrefixDeclProcessor.process(obj.getAst()); + qname.visit(obj.getAst(), prefixes); + BlankNodeVarProcessor.process(obj.getAst()); + deNorm.visit(obj.getAst(), null); + return obj; } private static class DeNormalizeQualifiedName extends ASTVisitorBase { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/POFMetadata.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/POFMetadata.java new file mode 100644 index 0000000..0f42eac --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/POFMetadata.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import org.openrdf.sindice.query.parser.sparql.ast.SimpleNode; + +/** + * @author bibhas [Jul 12, 2012] + * @email bibhas.das@deri.org + * + */ +public class POFMetadata { + // the POF ast node + private SimpleNode pofNode; + /* + * The class attribute of the POF, in case of CLASS recommendation + */ + private SimpleNode pofClassAttribute; + + /** + * @param pofNode + * the pofNode to set + */ + public void setPofNode(SimpleNode pofNode) { + this.pofNode = pofNode; + } + + /** + * @return the pofNode + */ + public SimpleNode getPofNode() { + return pofNode; + } + + /** + * @param pofClassAttribute + * the pofClassAttribute to set + */ + public void setPofClassAttribute(SimpleNode pofClassAttribute) { + this.pofClassAttribute = pofClassAttribute; + } + + /** + * @return the pofClassAttribute + */ + public SimpleNode getPofClassAttribute() { + return pofClassAttribute; + } +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PipelineObject.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PipelineObject.java new file mode 100644 index 0000000..3182694 --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PipelineObject.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import java.util.ArrayList; +import java.util.List; + +import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; +import org.sindice.analytics.backend.DGSQueryResultProcessor; +import org.sindice.analytics.backend.DGSQueryResultProcessor.Context; +import org.sindice.analytics.ranking.Label; +import org.sindice.core.sesame.backend.SesameBackend; + +/** + * @author bibhas [Jul 11, 2012] + * @email bibhas.das@deri.org + * + */ +public class PipelineObject { + private ASTQueryContainer ast; + private List varsToProject; + private RecommendationType type; + private POFMetadata meta; + private int MAX_HOPS; + private SesameBackend backend = null; + + public PipelineObject(ASTQueryContainer ast, List list, + RecommendationType type, POFMetadata meta, int hops, + SesameBackend backend) { + this.setAst(ast); + this.setVarsToProject(list); + this.setType(type); + this.setMeta(meta); + this.setMAX_HOPS(hops); + this.setBackend(backend); + } + + /** + * @param ast + * the ast to set + */ + public void setAst(ASTQueryContainer ast) { + this.ast = ast; + } + + /** + * @return the ast + */ + public ASTQueryContainer getAst() { + return ast; + } + + /** + * @param varsToProject + * the varsToProject to set + */ + public void setVarsToProject(List varsToProject) { + this.varsToProject = varsToProject; + if (this.varsToProject == null) + this.varsToProject = new ArrayList(); + } + + /** + * @return the varsToProject + */ + public List getVarsToProject() { + return varsToProject; + } + + /** + * @param type + * the type to set + */ + public void setType(RecommendationType type) { + this.type = type; + } + + /** + * @return the type + */ + public RecommendationType getType() { + return type; + } + + /** + * @param meta + * the meta to set + */ + public void setMeta(POFMetadata meta) { + this.meta = meta; + if (this.meta == null) + this.meta = new POFMetadata(); + } + + /** + * @return the meta + */ + public POFMetadata getMeta() { + return meta; + } + + /** + * @param mAX_HOPS + * the mAX_HOPS to set + */ + public void setMAX_HOPS(int mAX_HOPS) { + MAX_HOPS = mAX_HOPS; + } + + /** + * @return the mAX_HOPS + */ + public int getMAX_HOPS() { + return MAX_HOPS; + } + + /** + * @param backend + * the backend to set + */ + public void setBackend( + SesameBackend backend) { + this.backend = backend; + } + + /** + * @return the backend + */ + public SesameBackend getBackend() { + return backend; + } + +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PofNodesMetadata.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PofNodesMetadata.java index 485832e..8c2587e 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PofNodesMetadata.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PofNodesMetadata.java @@ -31,32 +31,26 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyList; import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyListPath; import org.openrdf.sindice.query.parser.sparql.ast.ASTQName; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTVar; import org.openrdf.sindice.query.parser.sparql.ast.SimpleNode; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; -import org.sindice.analytics.queryProcessor.QueryProcessor.POFMetadata; -public final class PofNodesMetadata { - - private PofNodesMetadata() { - } +public final class PofNodesMetadata implements BasicOperation{ /** * Retrieve the POF metadata, gathered at the AST creation time. - * To be run after denormalizing the ast + * To be run before denormalizing the ast + * The denormalization is creating new objects and metadata is lost * @param ast * @return * @throws VisitorException * @throws MalformedQueryException */ - public static POFMetadata retrieve(ASTQueryContainer ast) - throws VisitorException, MalformedQueryException { - final POFMetadata meta = new POFMetadata(); + public PipelineObject process(PipelineObject obj) throws VisitorException, MalformedQueryException { RetrievePofASTMetadata retrieve = new RetrievePofASTMetadata(); - List prefixDeclList = ast.getPrefixDeclList(); + List prefixDeclList = obj.getAst().getPrefixDeclList(); // Build a prefix --> IRI map final Map prefixes = new LinkedHashMap(); @@ -67,10 +61,10 @@ public static POFMetadata retrieve(ASTQueryContainer ast) prefixes.put(prefix, iri); } - retrieve.visit(ast, prefixes); - meta.pofNode = retrieve.pofNode; - meta.pofClassAttribute = retrieve.pofClassAttribute; - return meta; + retrieve.visit(obj.getAst(), prefixes); + obj.getMeta().setPofNode(retrieve.pofNode); + obj.getMeta().setPofClassAttribute(retrieve.pofClassAttribute); + return obj; } private static class RetrievePofASTMetadata extends ASTVisitorBase { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PointOfFocusProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PointOfFocusProcessor.java index f2df8c0..3811209 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PointOfFocusProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/PointOfFocusProcessor.java @@ -35,14 +35,12 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTPathElt; import org.openrdf.sindice.query.parser.sparql.ast.ASTProjectionElem; import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyListPath; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTSelect; import org.openrdf.sindice.query.parser.sparql.ast.ASTSelectQuery; import org.openrdf.sindice.query.parser.sparql.ast.ASTVar; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants; import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; -import org.sindice.analytics.queryProcessor.QueryProcessor.RecommendationType; import org.sindice.core.analytics.commons.summary.AnalyticsClassAttributes; /** @@ -52,53 +50,50 @@ * - Add the POF, and any other variables name passed in argument, to the SELECT clause * - Return the type of the recommendation, e.g., predicate or class or graph name. */ -public final class PointOfFocusProcessor { +public final class PointOfFocusProcessor implements BasicOperation{ - private PointOfFocusProcessor() { - } - - public static RecommendationType process(ASTQueryContainer ast, List varsToProject) - throws VisitorException { + public PipelineObject process(PipelineObject obj) throws VisitorException { final List v = new ArrayList(); - if (varsToProject != null) { - v.addAll(varsToProject); + if (obj.getVarsToProject() != null) { + v.addAll(obj.getVarsToProject()); } - if (!(ast.getQuery() instanceof ASTSelectQuery)) { // Change to a SelectQuery + if (!(obj.getAst().getQuery() instanceof ASTSelectQuery)) { // Change to a SelectQuery final ASTSelectQuery selectQuery = new ASTSelectQuery(SyntaxTreeBuilderTreeConstants.JJTSELECTQUERY); final ASTSelect select = new ASTSelect(SyntaxTreeBuilderTreeConstants.JJTSELECT); selectQuery.jjtAppendChild(select); - for (ASTDatasetClause d : ast.getQuery().getDatasetClauseList()) { + for (ASTDatasetClause d : obj.getAst().getQuery().getDatasetClauseList()) { selectQuery.jjtAppendChild(d); } - selectQuery.jjtAppendChild(ast.getQuery().getWhereClause()); - if (!(ast.getQuery() instanceof ASTAskQuery)) { - if (ast.getQuery().getGroupClause() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getGroupClause()); + selectQuery.jjtAppendChild(obj.getAst().getQuery().getWhereClause()); + if (!(obj.getAst().getQuery() instanceof ASTAskQuery)) { + if (obj.getAst().getQuery().getGroupClause() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getGroupClause()); } - if (ast.getQuery().getHavingClause() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getHavingClause()); + if (obj.getAst().getQuery().getHavingClause() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getHavingClause()); } - if (ast.getQuery().getOrderClause() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getOrderClause()); + if (obj.getAst().getQuery().getOrderClause() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getOrderClause()); } - if (ast.getQuery().getLimit() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getLimit()); + if (obj.getAst().getQuery().getLimit() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getLimit()); } - if (ast.getQuery().getOffset() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getOffset()); + if (obj.getAst().getQuery().getOffset() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getOffset()); } } - if (ast.getQuery().getBindingsClause() != null) { - selectQuery.jjtAppendChild(ast.getQuery().getBindingsClause()); + if (obj.getAst().getQuery().getBindingsClause() != null) { + selectQuery.jjtAppendChild(obj.getAst().getQuery().getBindingsClause()); } - ast.getQuery().jjtReplaceWith(selectQuery); + obj.getAst().getQuery().jjtReplaceWith(selectQuery); } final ASTMaterializePointOfFocus matPOF = new ASTMaterializePointOfFocus(); - matPOF.visit(ast, v); + matPOF.visit(obj.getAst(), v); final POFRecType type = new POFRecType(); - return (RecommendationType) type.visit(ast, RecommendationType.NONE); + obj.setType((RecommendationType) type.visit(obj.getAst(), RecommendationType.NONE)); + return obj; } private static class POFRecType extends ASTVisitorBase { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationScopeProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationScopeProcessor.java index f0b8d6d..e686e9f 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationScopeProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationScopeProcessor.java @@ -30,7 +30,6 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTDatasetClause; import org.openrdf.sindice.query.parser.sparql.ast.ASTGraphGraphPattern; import org.openrdf.sindice.query.parser.sparql.ast.ASTIRI; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTRDFLiteral; import org.openrdf.sindice.query.parser.sparql.ast.ASTSelectQuery; import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath; @@ -49,15 +48,11 @@ * @email stephane.campinas@deri.org * */ -public final class RecommendationScopeProcessor { +public final class RecommendationScopeProcessor implements BasicOperation{ private static final Logger logger = LoggerFactory.getLogger(RecommendationScopeProcessor.class); - private RecommendationScopeProcessor() { - } - - public static void process(ASTQueryContainer ast) - throws VisitorException { + public PipelineObject process(PipelineObject obj) throws VisitorException { final ScopedVariables scopedVariables = new ScopedVariables(); final POFConnected scope = new POFConnected(); @@ -66,10 +61,11 @@ public static void process(ASTQueryContainer ast) // Define the recommendation scope do { scopedVariables.updateVars(); - scope.visit(ast, scopedVariables); + scope.visit(obj.getAst(), scopedVariables); } while (!scopedVariables.newConnectedVars.isEmpty()); // Prune disconnected parts of the AST - pruneToScope(ast); + pruneToScope(obj.getAst()); + return obj; } private static class ScopedVariables { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationType.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationType.java new file mode 100644 index 0000000..1e03817 --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/RecommendationType.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +/** + * @author bibhas [Jul 12, 2012] + * @email bibhas.das@deri.org + * + */ +public enum RecommendationType { + NONE, PREDICATE, CLASS, GRAPH +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/Select2Ask.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/Select2Ask.java new file mode 100644 index 0000000..6038252 --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/Select2Ask.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import org.openrdf.sindice.query.parser.sparql.ast.ASTAskQuery; +import org.openrdf.sindice.query.parser.sparql.ast.ASTDatasetClause; +import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; +import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants; +import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; + +/** + * @author bibhas [Jul 2, 2012] + * @email bibhas.das@deri.org + * + */ +public class Select2Ask { + public ASTQueryContainer convert(ASTQueryContainer ast) + throws VisitorException { + ASTQueryContainer newAst = new ASTQueryContainer( + SyntaxTreeBuilderTreeConstants.JJTQUERYCONTAINER); + final ASTAskQuery askQuery = new ASTAskQuery( + SyntaxTreeBuilderTreeConstants.JJTASKQUERY); + for (ASTDatasetClause d : ast.getQuery().getDatasetClauseList()) { + askQuery.jjtAppendChild(d); + } + if (ast.getQuery().getWhereClause() != null) + askQuery.jjtAppendChild(ast.getQuery().getWhereClause()); + if (ast.getQuery().getBindingsClause() != null) + askQuery.jjtAppendChild(ast.getQuery().getBindingsClause()); + newAst.jjtAppendChild(askQuery); + return newAst; + } +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQuery.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQuery.java deleted file mode 100644 index 008eab1..0000000 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQuery.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. - * - * - * This project is a free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This project is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this project. If not, see . - *******************************************************************************/ -/** - * @project sparql-editor-servlet - * @author Campinas Stephane [ 19 Mar 2012 ] - * @link stephane.campinas@deri.org - */ -package org.sindice.analytics.queryProcessor; - -import java.util.List; - -import org.openrdf.query.MalformedQueryException; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; -import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; -import org.sindice.analytics.queryProcessor.QueryProcessor.POFMetadata; -import org.sindice.analytics.queryProcessor.QueryProcessor.RecommendationType; - -/** - * - */ -public final class SparqlToDGSQuery { - - private static RecommendationType type; - - private SparqlToDGSQuery() { - } - - public static POFMetadata process(ASTQueryContainer ast, List varsToProject) - throws MalformedQueryException, VisitorException { - if (!ast.containsQuery()) { - return null; - } - - ASTVarGenerator.reset(); - // Retrieve the POF metadata - final POFMetadata meta = PofNodesMetadata.retrieve(ast); - // expand each TP into simple one: denormalize syntax sugar constructions - DeNormalizeAST.process(ast); - - // Ensure the query is valid for recommendation - ValidateQ4Recommendations.process(ast); - - ASTVarGenerator.addVars(ASTVarProcessor.process(ast)); - /* - * Map SPARQL query to a Data Graph Summary query - */ - // 1. Materialize the POF - type = PointOfFocusProcessor.process(ast, varsToProject); - // 2. Remove Content Elements - ContentRemovalProcessor.process(ast); - // Define Recommendation Scope - RecommendationScopeProcessor.process(ast); - // TODO: Optimize the query by removing unnecessary parts, e.g., optional, unions - // 3. Map to the DGS query - SparqlTranslationProcessor.process(ast); - return meta; - } - - /** - * @return the type - */ - public static RecommendationType getRecommendationType() { - return type; - } - -} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/QueryProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryInterface.java similarity index 56% rename from recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/QueryProcessor.java rename to recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryInterface.java index b94dedd..9667eaa 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/QueryProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryInterface.java @@ -15,45 +15,28 @@ * You should have received a copy of the GNU Affero General Public * License along with this project. If not, see . *******************************************************************************/ -/** - * @project sparql-editor-servlet - * @author Campinas Stephane [ 28 Feb 2012 ] - * @link stephane.campinas@deri.org - */ package org.sindice.analytics.queryProcessor; import java.util.List; import org.openrdf.query.MalformedQueryException; import org.openrdf.sindice.query.parser.sparql.ast.ParseException; -import org.openrdf.sindice.query.parser.sparql.ast.SimpleNode; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; import org.openrdf.sindice.query.parser.sparql.ast.TokenMgrError; import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; /** - * Issue ASE-16 + * @author bibhas [Jul 12, 2012] + * @email bibhas.das@deri.org + * */ -public interface QueryProcessor { - - public static final String POF_RESOURCE = "POFresource"; - public static final String CARDINALITY_VAR = SyntaxTreeBuilder.PointOfFocus + "cardinality"; - public static final String CLASS_ATTRIBUTE_CARD_VAR = "CAcardinality"; +public interface SparqlToDGSQueryInterface { + public static final String POF_RESOURCE = "POFresource"; + public static final String CARDINALITY_VAR = SyntaxTreeBuilder.PointOfFocus + + "cardinality"; + public static final String CLASS_ATTRIBUTE_CARD_VAR = "CAcardinality"; public static final String CLASS_ATTRIBUTE_LABEL_VAR = "CAlabel"; - public static enum RecommendationType { - NONE, PREDICATE, CLASS, GRAPH - } - - public class POFMetadata { - // the POF ast node - public SimpleNode pofNode; - /* - * The class attribute of the POF, in case of CLASS recommendation - */ - public SimpleNode pofClassAttribute; - } - /** * Parse a query, perform the mapping to a Data Graph Summary query and reduce * its scope. @@ -67,69 +50,77 @@ public class POFMetadata { * @throws ParseException * @throws TokenMgrError */ - public void load(String query) - throws DGSException; + public void load(String query) throws Exception; /** * Parse a query, perform the mapping to a Data Graph Summary query and reduce * its scope. * * @param query - * @param varsToProject The variables to project in the DataGraphSummary query (By Default, it is the POF) + * @param varsToProject + * The variables to project in the DataGraphSummary query (By + * Default, it is the POF) * @throws MalformedQueryException * @throws VisitorException * @throws TokenMgrError * @throws ParseException */ - public void load(String query, List varsToProject) - throws DGSException; + public void load(String query, List varsToProject) throws Exception; /** - * Return the Data Graph Summary query from the one passed in {@link AbstractQueryProcessor#load(String)}. - * Only valid after the call to load. + * Return the Data Graph Summary query from the one passed in + * {@link AbstractQueryProcessor#load(String)}. Only valid after the call to + * load. + * * @return - * @throws VisitorException + * @throws VisitorException */ - public String getDGSQuery() - throws DGSException; + public String getDGSQuery() throws DGSException; /** - * returns a list of metadata for the given field, - * associated to the POF while building the AST. + * returns a list of metadata for the given field, associated to the POF while + * building the AST. + * * @return */ public POFMetadata getPofASTMetadata(); /** * Returns a query for getting the set of properties from the specified domain - * @param domain if empty string, returns all the properties available - * @param limit limit the response to the first "limit" solutions + * + * @param domain + * if empty string, returns all the properties available + * @param limit + * limit the response to the first "limit" solutions * @return - * @throws DGSException + * @throws DGSException */ public String getPropertiesQuery(String domain, int limit) - throws DGSException; + throws DGSException; /** * Returns a query for getting the set of classes from the specified domain - * @param domain if empty string, returns all the classes available - * @param limit limit the response to the first "limit" solutions + * + * @param domain + * if empty string, returns all the classes available + * @param limit + * limit the response to the first "limit" solutions * @return * @throws DGSException */ - public String getClassesQuery(String domain, int limit) - throws DGSException; + public String getClassesQuery(String domain, int limit) throws DGSException; /** * Returns a query for getting the set of domains - * @param domain if empty string, returns all the domains available - * @param limit limit the response to the first "limit" solutions + * + * @param domain + * if empty string, returns all the domains available + * @param limit + * limit the response to the first "limit" solutions * @return * @throws DGSException */ - public String getDomainsQuery(String domain, int limit) - throws DGSException; + public String getDomainsQuery(String domain, int limit) throws DGSException; public RecommendationType getRecommendationType(); - } diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryManager.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryManager.java new file mode 100644 index 0000000..2adb980 --- /dev/null +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlToDGSQueryManager.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved. + * + * + * This project is a free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This project is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this project. If not, see . + *******************************************************************************/ +package org.sindice.analytics.queryProcessor; + +import java.util.List; + +import org.apache.commons.lang.NotImplementedException; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.sindice.query.parser.sparql.ast.ParseException; +import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; +import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; +import org.sindice.core.analytics.commons.summary.AnalyticsVocab; +import org.sindice.core.analytics.commons.util.URIUtil; +import org.sindice.core.sesame.backend.SesameBackendException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author bibhas [Jul 12, 2012] + * @email bibhas.das@deri.org + * + */ +public class SparqlToDGSQueryManager implements SparqlToDGSQueryInterface { + private static final Logger logger = LoggerFactory + .getLogger(SparqlToDGSQueryInterface.class); + private PipelineObject pipeObj; + private String dgsQuery; + + public SparqlToDGSQueryManager() { + pipeObj = new PipelineObject(null, null, RecommendationType.NONE, null, 0, null); + } + + @Override + public String getDGSQuery() throws DGSException { + try { + dgsQuery = AST2TextTranslator.translate(pipeObj.getAst()); + } catch (VisitorException e) { + throw new DGSException(e); + } + return dgsQuery; + } + + @Override + public void load(String query) throws Exception { + this.load(query, null); + } + + @Override + public void load(String query, List varsToProject) throws Exception { + try { + dgsQuery = null; + pipeObj.setMeta(null); + pipeObj.setAst(SyntaxTreeBuilder.parseQuery(query)); + pipeObj.setVarsToProject(varsToProject); + process(); + } catch (ParseException e) { + throw new DGSException(e); + } catch (VisitorException e) { + throw new DGSException(e); + } catch (MalformedQueryException e) { + throw new DGSException(e); + } + } + + @Override + public POFMetadata getPofASTMetadata() { + return pipeObj.getMeta(); + } + + @Override + public String getDomainsQuery(String domain, int limit) throws DGSException { + throw new NotImplementedException(); + } + + @Override + public String getPropertiesQuery(String domain, int limit) + throws DGSException { + throw new NotImplementedException(); + } + + @Override + public String getClassesQuery(String domain, int limit) throws DGSException { + if (domain == null) { + throw new DGSException("The given domain is null"); + } + final StringBuilder sb = new StringBuilder(); + final String d = URIUtil.getSndDomainFromUrl(domain); + if (d == null) { + throw new DGSException("Unable to get second-level domain name from " + + domain); + } + domain = d; + sb.append("SELECT DISTINCT ?class FROM <").append( + AnalyticsVocab.GRAPH_SUMMARY_GRAPH).append("> WHERE {\n").append( + " ?node <").append(AnalyticsVocab.DOMAIN_URI).append("> ").append( + domain.isEmpty() ? "?domain .\n" : "<" + + AnalyticsVocab.DOMAIN_URI_PREFIX + domain + "> .\n").append( + " ?node <").append(AnalyticsVocab.LABEL).append("> ?l .\n").append( + " ?l <").append(AnalyticsVocab.LABEL).append( + "> ?class .\n}\nORDER BY (?class)\n"); + if (limit != 0) { + sb.append("LIMIT ").append(limit); + } + return sb.toString(); + } + + @Override + public RecommendationType getRecommendationType() { + return pipeObj.getType(); + } + + public void process() throws MalformedQueryException, VisitorException, + ParseException, SesameBackendException { + if (!pipeObj.getAst().containsQuery()) { + return; + } + + ASTVarGenerator.reset(); + // Retrieve the POF metadata + pipeObj = new PofNodesMetadata().process(pipeObj); + // expand each TP into simple one: denormalize syntax sugar constructions + pipeObj = new DeNormalizeAST().process(pipeObj); + + // Ensure the query is valid for recommendation + pipeObj = new ValidateQ4Recommendations().process(pipeObj); + + ASTVarGenerator.addVars(ASTVarProcessor.process(pipeObj.getAst())); + /* + * Map SPARQL query to a Data Graph Summary query + */ + // 1. Materialize the POF + pipeObj = new PointOfFocusProcessor().process(pipeObj); + // 2. Remove Content Elements + pipeObj = new ContentRemovalProcessor().process(pipeObj); + // Define Recommendation Scope + pipeObj = new RecommendationScopeProcessor().process(pipeObj); + // Shortest path in case of PREDICATE recommendation + pipeObj = new AddOneHopPropertyPath(new SparqlTranslationProcessor()) + .process(pipeObj); + + // TODO: Optimize the query by removing unnecessary parts, e.g., optional, + // unions + // 3. Map to the DGS query + pipeObj = new SparqlTranslationProcessor().process(pipeObj); + } + + // getter of pipeobj + public PipelineObject getPipelineObject() { + return pipeObj; + } + +} diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlTranslationProcessor.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlTranslationProcessor.java index 08c6d56..45ac69a 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlTranslationProcessor.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/SparqlTranslationProcessor.java @@ -58,16 +58,13 @@ /** * */ -public final class SparqlTranslationProcessor { +public final class SparqlTranslationProcessor implements BasicOperation{ public static final String BLANK_NODE_COLLECTION = "dummy class: " + Long.toString(Hash.getLong("dummy class")).replace('-', 'n'); private final static IsLeaf isLeaf = new IsLeaf(); private static ASTQueryContainer astQueryContainer; - private SparqlTranslationProcessor() { - } - /** * Translate the SPARQL query to a Summary query. * @param ast @@ -75,14 +72,13 @@ private SparqlTranslationProcessor() { * @throws MalformedQueryException * @throws VisitorException */ - public static void process(ASTQueryContainer ast) - throws MalformedQueryException, VisitorException { + public PipelineObject process(PipelineObject po) throws MalformedQueryException, VisitorException { // get the default datasets + set the DGS graph in the clause // replace any dataset URI (graph and FROM) by their second-level domain name - final Dataset datasets = DGSDatasetClauseProcessor.process(ast); + final Dataset datasets = DGSDatasetClauseProcessor.process(po.getAst()); final ASTIRI d; - astQueryContainer = ast; + astQueryContainer = po.getAst(); if (datasets != null) { if (!datasets.getDefaultGraphs().isEmpty() || !datasets.getNamedGraphs().isEmpty()) { if (!datasets.getDefaultGraphs().isEmpty() && !datasets.getNamedGraphs().isEmpty()) { @@ -114,12 +110,15 @@ public static void process(ASTQueryContainer ast) final GraphGraphPatternRemoval g = new GraphGraphPatternRemoval(); final SparqlTranslationVisitor v = new SparqlTranslationVisitor(d); - final List pofMetadata = (List) v.visit(ast, new ArrayList()); - g.visit(ast, null); + final List pofMetadata = (List) v.visit(po.getAst(), new ArrayList()); + if(po.getVarsToProject()!=null) + pofMetadata.addAll(po.getVarsToProject()); + g.visit(po.getAst(), null); // Change variable name of the POF ressource - change.visit(ast, v.pofResourceName); + change.visit(po.getAst(), v.pofResourceName); // Add POF metadata to the SELECT clause - addPofMetadata(ast, pofMetadata); + addPofMetadata(po.getAst(), pofMetadata); + return po; } private static class ChangeToPofRessource extends ASTVisitorBase { @@ -130,7 +129,7 @@ public Object visit(ASTVar node, Object data) final String pofResource = (String) data; if (node.getName().equals(pofResource)) { - node.setName(QueryProcessor.POF_RESOURCE); + node.setName(SparqlToDGSQueryInterface.POF_RESOURCE); } return super.visit(node, data); } @@ -215,10 +214,10 @@ public Object visit(ASTGraphGraphPattern node, Object data) final ASTIRI cardinality = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); cardinality.setValue(AnalyticsVocab.CARDINALITY.toString()); final ASTVar pofCardinality = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofCardinality.setName(QueryProcessor.CARDINALITY_VAR); + pofCardinality.setName(SparqlToDGSQueryInterface.CARDINALITY_VAR); final ASTVar pofResource = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofResource.setName(QueryProcessor.POF_RESOURCE); + pofResource.setName(SparqlToDGSQueryInterface.POF_RESOURCE); final ASTTriplesSameSubjectPath t1 = ASTProcessorUtil.createTriple(pofResource, cardinality, pofCardinality); final ASTTriplesSameSubjectPath t3 = ASTProcessorUtil.createTriple(pofResource, origin, graphName); @@ -228,9 +227,9 @@ public Object visit(ASTGraphGraphPattern node, Object data) gpg.jjtAppendChild(bgp); node.jjtAppendChild(gpg); - pofResourceName = QueryProcessor.POF_RESOURCE; // the resource here is a newly created bgp - pofMetadata.add(QueryProcessor.POF_RESOURCE); - pofMetadata.add(QueryProcessor.CARDINALITY_VAR); + pofResourceName = SparqlToDGSQueryInterface.POF_RESOURCE; // the resource here is a newly created bgp + pofMetadata.add(SparqlToDGSQueryInterface.POF_RESOURCE); + pofMetadata.add(SparqlToDGSQueryInterface.CARDINALITY_VAR); return data; } } @@ -335,24 +334,24 @@ private Object triplePatternToDGSedge(Object data, Node dataset, ASTBasicGraphPa // Predicate recommendation if (verb instanceof ASTVar && ((ASTVar) verb).getName().equals(SyntaxTreeBuilder.PointOfFocus)) { // the Subject of the POF - pofMetadata.add(QueryProcessor.POF_RESOURCE); + pofMetadata.add(SparqlToDGSQueryInterface.POF_RESOURCE); pofResourceName = s.getName(); final ASTIRI cardinality = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); cardinality.setValue(AnalyticsVocab.CARDINALITY.toString()); final ASTVar pofCardinality = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofCardinality.setName(QueryProcessor.CARDINALITY_VAR); + pofCardinality.setName(SparqlToDGSQueryInterface.CARDINALITY_VAR); final ASTTriplesSameSubjectPath t5 = ASTProcessorUtil.createTriple(s, cardinality, pofCardinality); bgp.jjtAppendChild(t5); - pofMetadata.add(QueryProcessor.CARDINALITY_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CARDINALITY_VAR); } // edge origin if (dataset != null) { final ASTTriplesSameSubjectPath t4 = ASTProcessorUtil.createTriple(s, origin, dataset); bgp.jjtAppendChild(t4); if (datasetEdgePOF(data, node.jjtGetChild(0), dataset, bgp)) { - pofMetadata.add(QueryProcessor.POF_RESOURCE); + pofMetadata.add(SparqlToDGSQueryInterface.POF_RESOURCE); pofResourceName = ((ASTVar) node.jjtGetChild(0)).getName(); } } @@ -371,7 +370,7 @@ private Object classTriplePatternToDGSedge(Object data, Node dataset, ASTBasicGr final ASTTriplesSameSubjectPath t1 = ASTProcessorUtil.createTriple(node.jjtGetChild(0), origin, dataset); bgp.jjtAppendChild(t1); if (datasetClassPOF(data, node.jjtGetChild(0), dataset, bgp)) { - pofMetadata.add(QueryProcessor.POF_RESOURCE); + pofMetadata.add(SparqlToDGSQueryInterface.POF_RESOURCE); pofResourceName = ((ASTVar) node.jjtGetChild(0)).getName(); } } @@ -382,7 +381,7 @@ private Object classTriplePatternToDGSedge(Object data, Node dataset, ASTBasicGr */ if (subject instanceof ASTVar && ((ASTVar) subject).getName().equals(SyntaxTreeBuilder.PointOfFocus)) { // the Subject of the POF - pofMetadata.add(QueryProcessor.POF_RESOURCE); + pofMetadata.add(SparqlToDGSQueryInterface.POF_RESOURCE); pofResourceName = ((ASTVar) node.jjtGetChild(0)).getName(); final ASTVar varLabel = ASTVarGenerator.getASTVar("dgs"); @@ -395,7 +394,7 @@ private Object classTriplePatternToDGSedge(Object data, Node dataset, ASTBasicGr final ASTIRI cardinality = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); cardinality.setValue(AnalyticsVocab.CARDINALITY.toString()); final ASTVar pofCardinality = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofCardinality.setName(QueryProcessor.CARDINALITY_VAR); + pofCardinality.setName(SparqlToDGSQueryInterface.CARDINALITY_VAR); final ASTTriplesSameSubjectPath t5 = ASTProcessorUtil.createTriple(node.jjtGetChild(0), cardinality, pofCardinality); bgp.jjtAppendChild(t5); @@ -406,9 +405,9 @@ private Object classTriplePatternToDGSedge(Object data, Node dataset, ASTBasicGr type.setValue(AnalyticsVocab.TYPE.toString()); final ASTVar varTypeLabel = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - varTypeLabel.setName(QueryProcessor.CLASS_ATTRIBUTE_LABEL_VAR); + varTypeLabel.setName(SparqlToDGSQueryInterface.CLASS_ATTRIBUTE_LABEL_VAR); final ASTVar varTypeCard = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - varTypeCard.setName(QueryProcessor.CLASS_ATTRIBUTE_CARD_VAR); + varTypeCard.setName(SparqlToDGSQueryInterface.CLASS_ATTRIBUTE_CARD_VAR); final ASTTriplesSameSubjectPath t7 = ASTProcessorUtil.createTriple(varLabel, type, varType); final ASTTriplesSameSubjectPath t8 = ASTProcessorUtil.createTriple(varType, cardinality, varTypeCard); final ASTTriplesSameSubjectPath t9 = ASTProcessorUtil.createTriple(varType, label, varTypeLabel); @@ -416,9 +415,9 @@ private Object classTriplePatternToDGSedge(Object data, Node dataset, ASTBasicGr bgp.jjtAppendChild(t8); bgp.jjtAppendChild(t9); - pofMetadata.add(QueryProcessor.CARDINALITY_VAR); - pofMetadata.add(QueryProcessor.CLASS_ATTRIBUTE_LABEL_VAR); - pofMetadata.add(QueryProcessor.CLASS_ATTRIBUTE_CARD_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CARDINALITY_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CLASS_ATTRIBUTE_LABEL_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CLASS_ATTRIBUTE_CARD_VAR); } else { final ASTVar s = ASTVarGenerator.getASTVar("dgs"); final ASTTriplesSameSubjectPath t1 = ASTProcessorUtil.createTriple(node.jjtGetChild(0), label, s); @@ -439,7 +438,7 @@ private boolean datasetEdgePOF(Object data, Node subject, Node dataset, Node bgp final ASTIRI cardinality = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); cardinality.setValue(AnalyticsVocab.CARDINALITY.toString()); final ASTVar pofCardinality = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofCardinality.setName(QueryProcessor.CARDINALITY_VAR); + pofCardinality.setName(SparqlToDGSQueryInterface.CARDINALITY_VAR); final ASTIRI originClass = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); originClass.setValue(AnalyticsVocab.DOMAIN_URI.toString()); @@ -448,7 +447,7 @@ private boolean datasetEdgePOF(Object data, Node subject, Node dataset, Node bgp final ASTTriplesSameSubjectPath t2 = ASTProcessorUtil.createTriple(subject, cardinality, pofCardinality); bgp.jjtAppendChild(t2); - pofMetadata.add(QueryProcessor.CARDINALITY_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CARDINALITY_VAR); return true; } return false; @@ -464,12 +463,12 @@ private boolean datasetClassPOF(Object data, Node subject, Node dataset, Node bg final ASTIRI cardinality = new ASTIRI(SyntaxTreeBuilderTreeConstants.JJTIRI); cardinality.setValue(AnalyticsVocab.CARDINALITY.toString()); final ASTVar pofCardinality = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); - pofCardinality.setName(QueryProcessor.CARDINALITY_VAR); + pofCardinality.setName(SparqlToDGSQueryInterface.CARDINALITY_VAR); final ASTTriplesSameSubjectPath t2 = ASTProcessorUtil.createTriple(subject, cardinality, pofCardinality); bgp.jjtAppendChild(t2); - pofMetadata.add(QueryProcessor.CARDINALITY_VAR); + pofMetadata.add(SparqlToDGSQueryInterface.CARDINALITY_VAR); return true; } return false; diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ValidateQ4Recommendations.java b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ValidateQ4Recommendations.java index e6578c8..c0dce37 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ValidateQ4Recommendations.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/queryProcessor/ValidateQ4Recommendations.java @@ -22,20 +22,16 @@ import org.openrdf.sindice.query.parser.sparql.ast.ASTPathAlternative; import org.openrdf.sindice.query.parser.sparql.ast.ASTPathElt; import org.openrdf.sindice.query.parser.sparql.ast.ASTPathSequence; -import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer; import org.openrdf.sindice.query.parser.sparql.ast.ASTVar; import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder; import org.openrdf.sindice.query.parser.sparql.ast.VisitorException; -public final class ValidateQ4Recommendations { +public final class ValidateQ4Recommendations implements BasicOperation{ - private ValidateQ4Recommendations() { - } - - public static void process(ASTQueryContainer ast) - throws VisitorException { + public PipelineObject process(PipelineObject obj) throws VisitorException { final ASTValidateAST validate = new ASTValidateAST(); - validate.visit(ast, null); + validate.visit(obj.getAst(), null); + return obj; } private static class ASTValidateAST extends ASTVisitorBase { diff --git a/recommendation-servlet/src/main/java/org/sindice/analytics/ranking/BaseLabelRanking.java b/recommendation-servlet/src/main/java/org/sindice/analytics/ranking/BaseLabelRanking.java index 8c9a7ac..b5d2a6f 100644 --- a/recommendation-servlet/src/main/java/org/sindice/analytics/ranking/BaseLabelRanking.java +++ b/recommendation-servlet/src/main/java/org/sindice/analytics/ranking/BaseLabelRanking.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.Properties; -import org.sindice.analytics.queryProcessor.QueryProcessor; +import org.sindice.analytics.queryProcessor.SparqlToDGSQueryInterface; import org.sindice.analytics.ranking.LabelsRankingFactory.RankingType; /** @@ -88,10 +88,10 @@ protected Collection scoreLabels(final List