diff --git a/pom.xml b/pom.xml index e2aeb07..2b2d319 100644 --- a/pom.xml +++ b/pom.xml @@ -1,23 +1,28 @@ 4.0.0 + com.anqit.spanqit spanqit - 1.1-SNAPSHOT + 1.1 + - + org.apache.maven.plugins maven-compiler-plugin 3.1 - 1.8 - 1.8 - + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.0.0-M1 + + private diff --git a/src/main/java/com/anqit/spanqit/constraint/Aggregate.java b/src/main/java/com/anqit/spanqit/constraint/Aggregate.java index 5a178eb..c2b39f2 100644 --- a/src/main/java/com/anqit/spanqit/constraint/Aggregate.java +++ b/src/main/java/com/anqit/spanqit/constraint/Aggregate.java @@ -1,7 +1,13 @@ package com.anqit.spanqit.constraint; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; +/** + * A SPARQL aggregate expression. + * + * @see + * SPARQL Aggregates + */ public class Aggregate extends Expression { private static final String DISTINCT = "DISTINCT"; private static final Object SEPARATOR = "SEPARATOR"; @@ -14,26 +20,61 @@ public class Aggregate extends Expression { super(aggregate); } + /** + * Specify this aggregate expression to be distinct + * + * @return this aggregate instance + */ public Aggregate distinct() { return distinct(true); } + /** + * Specify if this aggregate expression should be distinct or not + * + * @param isDistinct + * if this aggregate should be distinct + * + * @return this aggregate instance + */ public Aggregate distinct(boolean isDistinct) { this.isDistinct = isDistinct; return this; } + /** + * If this is a {@code count} aggregate expressions, specify that it should count all + * + * @return this aggregate instance + */ public Aggregate countAll() { return countAll(true); } + /** + * If this is a {@code count} aggregate expressions, specify if it should count all + * + * @param countAll if this should count all arguments or not + * + * @return this aggregate instance + */ public Aggregate countAll(boolean countAll) { this.countAll = countAll; return this; } + /** + * If this is a {@code group_concat} aggregate expression, specify the separator to use + * + * @param separator the separator to use + * + * @return this aggregate instance + * + * @see + * group_concat() + */ public Aggregate separator(String separator) { this.separator = separator; @@ -64,6 +105,6 @@ public String getQueryString() { .append(" ").append("=").append(" ").append(separator); } - return aggregate.append(SpanqitStringUtils.getParenthesizedString(params.toString())).toString(); + return aggregate.append(SpanqitUtils.getParenthesizedString(params.toString())).toString(); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/constraint/BinaryOperation.java b/src/main/java/com/anqit/spanqit/constraint/BinaryOperation.java index 985fa7a..d24feb7 100644 --- a/src/main/java/com/anqit/spanqit/constraint/BinaryOperation.java +++ b/src/main/java/com/anqit/spanqit/constraint/BinaryOperation.java @@ -3,7 +3,6 @@ /** * Represents a SPARQL operation that takes exactly 2 arguments * - * @author Ankit */ class BinaryOperation extends Operation { BinaryOperation(BinaryOperator operator) { diff --git a/src/main/java/com/anqit/spanqit/constraint/BinaryOperator.java b/src/main/java/com/anqit/spanqit/constraint/BinaryOperator.java index 52b209f..bf4c2bb 100644 --- a/src/main/java/com/anqit/spanqit/constraint/BinaryOperator.java +++ b/src/main/java/com/anqit/spanqit/constraint/BinaryOperator.java @@ -2,9 +2,6 @@ /** * The SPARQL binary operators - * - * @author Ankit - * */ enum BinaryOperator implements SparqlOperator { EQUALS("="), diff --git a/src/main/java/com/anqit/spanqit/constraint/ConnectiveOperator.java b/src/main/java/com/anqit/spanqit/constraint/ConnectiveOperator.java index 3b3d59e..5c9d606 100644 --- a/src/main/java/com/anqit/spanqit/constraint/ConnectiveOperator.java +++ b/src/main/java/com/anqit/spanqit/constraint/ConnectiveOperator.java @@ -2,9 +2,6 @@ /** * The SPARQL connective operators - * - * @author Ankit - * */ enum ConnectiveOperator implements SparqlOperator { // Logical diff --git a/src/main/java/com/anqit/spanqit/constraint/Expression.java b/src/main/java/com/anqit/spanqit/constraint/Expression.java index 4adacab..7aacaef 100644 --- a/src/main/java/com/anqit/spanqit/constraint/Expression.java +++ b/src/main/java/com/anqit/spanqit/constraint/Expression.java @@ -6,7 +6,7 @@ import com.anqit.spanqit.core.Groupable; import com.anqit.spanqit.core.Orderable; import com.anqit.spanqit.core.QueryElementCollection; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; /** * A SPARQL expression. Used by filters, having clauses, order and group by @@ -36,7 +36,7 @@ * SPARQL Assignments */ public abstract class Expression> extends - QueryElementCollection implements ExpressionOperand, + QueryElementCollection implements Operand, Orderable, Groupable, Assignable { protected SparqlOperator operator; private boolean parenthesize; @@ -46,14 +46,14 @@ public abstract class Expression> extends } Expression(SparqlOperator operator, String delimeter) { - super(delimeter, new ArrayList()); + super(delimeter, new ArrayList()); this.operator = operator; parenthesize(false); } @SuppressWarnings("unchecked") - T addOperand(ExpressionOperand... operands) { - for (ExpressionOperand operand : operands) { + T addOperand(Operand... operands) { + for (Operand operand : operands) { elements.add(operand); } @@ -84,14 +84,14 @@ public T parenthesize(boolean parenthesize) { return (T) this; } - ExpressionOperand getOperand(int index) { - return ((ArrayList) elements).get(index); + Operand getOperand(int index) { + return ((ArrayList) elements).get(index); } @Override public String getQueryString() { String queryString = super.getQueryString(); - return parenthesize ? SpanqitStringUtils.getParenthesizedString(queryString) : queryString; + return parenthesize ? SpanqitUtils.getParenthesizedString(queryString) : queryString; } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/constraint/Expressions.java b/src/main/java/com/anqit/spanqit/constraint/Expressions.java index 0d482e9..25af754 100644 --- a/src/main/java/com/anqit/spanqit/constraint/Expressions.java +++ b/src/main/java/com/anqit/spanqit/constraint/Expressions.java @@ -9,6 +9,7 @@ import static com.anqit.spanqit.constraint.SparqlFunction.REGEX; import com.anqit.spanqit.core.Variable; +import com.anqit.spanqit.rdf.Rdf; import com.anqit.spanqit.rdf.RdfLiteral; /** @@ -35,7 +36,7 @@ private Expressions() { } * SPARQL ABS Function */ public static Expression abs(Number operand) { - return abs(RdfLiteral.of(operand)); + return abs(Rdf.literalOf(operand)); } /** @@ -49,7 +50,7 @@ public static Expression abs(Number operand) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-abs"> * SPARQL ABS Function */ - public static Expression abs(ExpressionOperand operand) { + public static Expression abs(Operand operand) { return function(ABS, operand); } @@ -63,7 +64,7 @@ public static Expression abs(ExpressionOperand operand) { * SPARQL BNODE Function */ public static Expression bnode() { - return function(BNODE, (ExpressionOperand) null); + return function(BNODE, (Operand) null); } /** @@ -93,7 +94,7 @@ public static Expression bnode(RdfLiteral literal) { * SPARQL BNODE Function */ public static Expression bnode(String literal) { - return function(BNODE, RdfLiteral.of(literal)); + return function(BNODE, Rdf.literalOf(literal)); } /** @@ -122,7 +123,7 @@ public static Expression bound(Variable var) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-ceil"> * SPARQL CEIL Function */ - public static Expression ceil(ExpressionOperand operand) { + public static Expression ceil(Operand operand) { return function(CEIL, operand); } @@ -137,7 +138,7 @@ public static Expression ceil(ExpressionOperand operand) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-coalesce"> * SPARQL COALESCE Function */ - public static Expression coalesce(ExpressionOperand... operands) { + public static Expression coalesce(Operand... operands) { return function(COALESCE, operands); } @@ -152,7 +153,7 @@ public static Expression coalesce(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-concat"> * SPARQL CONCAT Function */ - public static Expression concat(ExpressionOperand... operands) { + public static Expression concat(Operand... operands) { return function(CONCAT, operands); } @@ -169,8 +170,8 @@ public static Expression concat(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-regex"> * SPARQL REGEX Function */ - public static Expression regex(ExpressionOperand testString, String pattern) { - return regex(testString, RdfLiteral.of(pattern)); + public static Expression regex(Operand testString, String pattern) { + return regex(testString, Rdf.literalOf(pattern)); } /** @@ -188,9 +189,9 @@ public static Expression regex(ExpressionOperand testString, String pattern) * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-regex"> * SPARQL REGEX Function */ - public static Expression regex(ExpressionOperand testString, String pattern, + public static Expression regex(Operand testString, String pattern, String flags) { - return regex(testString, RdfLiteral.of(pattern), RdfLiteral.of(flags)); + return regex(testString, Rdf.literalOf(pattern), Rdf.literalOf(flags)); } /** @@ -206,8 +207,8 @@ public static Expression regex(ExpressionOperand testString, String pattern, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-regex"> * SPARQL REGEX Function */ - public static Expression regex(ExpressionOperand testString, - ExpressionOperand pattern) { + public static Expression regex(Operand testString, + Operand pattern) { return function(REGEX, testString, pattern); } @@ -226,12 +227,22 @@ public static Expression regex(ExpressionOperand testString, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-regex"> * SPARQL REGEX Function */ - public static Expression regex(ExpressionOperand testString, - ExpressionOperand pattern, ExpressionOperand flags) { + public static Expression regex(Operand testString, + Operand pattern, Operand flags) { return function(REGEX, testString, pattern, flags); } - public static Expression str(ExpressionOperand operand) { + /** + * {@code STR(literal)} or {@code STR(iri)} + * + * @param operand the arg to convert to a string + * + * @return a {@code STR()} function + * + * @see + * SPARQL STR Function + */ + public static Expression str(Operand operand) { return function(SparqlFunction.STRING, operand); } @@ -252,7 +263,7 @@ public static Expression str(ExpressionOperand operand) { * operands */ public static Expression function(SparqlFunction function, - ExpressionOperand... operands) { + Operand... operands) { return new Function(function).addOperand(operands); } @@ -267,7 +278,7 @@ public static Expression function(SparqlFunction function, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression not(ExpressionOperand operand) { + public static Expression not(Operand operand) { return unaryExpression(UnaryOperator.NOT, operand); } @@ -282,7 +293,7 @@ public static Expression not(ExpressionOperand operand) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression plus(ExpressionOperand operand) { + public static Expression plus(Operand operand) { return unaryExpression(UnaryOperator.UNARY_PLUS, operand); } @@ -297,12 +308,12 @@ public static Expression plus(ExpressionOperand operand) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression minus(ExpressionOperand operand) { + public static Expression minus(Operand operand) { return unaryExpression(UnaryOperator.UNARY_MINUS, operand); } private static UnaryOperation unaryExpression(UnaryOperator operator, - ExpressionOperand operand) { + Operand operand) { return new UnaryOperation(operator).addOperand(operand); } @@ -318,8 +329,8 @@ private static UnaryOperation unaryExpression(UnaryOperator operator, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression equals(ExpressionOperand left, - ExpressionOperand right) { + public static Expression equals(Operand left, + Operand right) { return binaryExpression(BinaryOperator.EQUALS, left, right); } @@ -335,8 +346,8 @@ public static Expression equals(ExpressionOperand left, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression notEquals(ExpressionOperand left, - ExpressionOperand right) { + public static Expression notEquals(Operand left, + Operand right) { return binaryExpression(BinaryOperator.NOT_EQUALS, left, right); } @@ -353,8 +364,8 @@ public static Expression notEquals(ExpressionOperand left, * Operators */ public static Expression gt(Number left, Number right) { - return binaryExpression(BinaryOperator.GREATER_THAN, RdfLiteral.of(left), - RdfLiteral.of(right)); + return binaryExpression(BinaryOperator.GREATER_THAN, Rdf.literalOf(left), + Rdf.literalOf(right)); } /** @@ -369,8 +380,8 @@ public static Expression gt(Number left, Number right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression gt(Number left, ExpressionOperand right) { - return binaryExpression(BinaryOperator.GREATER_THAN, RdfLiteral.of(left), + public static Expression gt(Number left, Operand right) { + return binaryExpression(BinaryOperator.GREATER_THAN, Rdf.literalOf(left), right); } @@ -386,9 +397,9 @@ public static Expression gt(Number left, ExpressionOperand right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression gt(ExpressionOperand left, Number right) { + public static Expression gt(Operand left, Number right) { return binaryExpression(BinaryOperator.GREATER_THAN, left, - RdfLiteral.of(right)); + Rdf.literalOf(right)); } /** @@ -403,8 +414,8 @@ public static Expression gt(ExpressionOperand left, Number right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression gt(ExpressionOperand left, - ExpressionOperand right) { + public static Expression gt(Operand left, + Operand right) { return binaryExpression(BinaryOperator.GREATER_THAN, left, right); } @@ -420,8 +431,8 @@ public static Expression gt(ExpressionOperand left, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression gte(ExpressionOperand left, - ExpressionOperand right) { + public static Expression gte(Operand left, + Operand right) { return binaryExpression(BinaryOperator.GREATER_THAN_EQUALS, left, right); } @@ -438,8 +449,8 @@ public static Expression gte(ExpressionOperand left, * Operators */ public static Expression lt(Number left, Number right) { - return binaryExpression(BinaryOperator.LESS_THAN, RdfLiteral.of(left), - RdfLiteral.of(right)); + return binaryExpression(BinaryOperator.LESS_THAN, Rdf.literalOf(left), + Rdf.literalOf(right)); } /** @@ -454,8 +465,8 @@ public static Expression lt(Number left, Number right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression lt(Number left, ExpressionOperand right) { - return binaryExpression(BinaryOperator.LESS_THAN, RdfLiteral.of(left), + public static Expression lt(Number left, Operand right) { + return binaryExpression(BinaryOperator.LESS_THAN, Rdf.literalOf(left), right); } @@ -471,9 +482,9 @@ public static Expression lt(Number left, ExpressionOperand right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression lt(ExpressionOperand left, Number right) { + public static Expression lt(Operand left, Number right) { return binaryExpression(BinaryOperator.LESS_THAN, left, - RdfLiteral.of(right)); + Rdf.literalOf(right)); } /** @@ -488,8 +499,8 @@ public static Expression lt(ExpressionOperand left, Number right) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression lt(ExpressionOperand left, - ExpressionOperand right) { + public static Expression lt(Operand left, + Operand right) { return binaryExpression(BinaryOperator.LESS_THAN, left, right); } @@ -506,13 +517,13 @@ public static Expression lt(ExpressionOperand left, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression lte(ExpressionOperand left, - ExpressionOperand right) { + public static Expression lte(Operand left, + Operand right) { return binaryExpression(BinaryOperator.LESS_THAN_EQUALS, left, right); } private static BinaryOperation binaryExpression(BinaryOperator operator, - ExpressionOperand op1, ExpressionOperand op2) { + Operand op1, Operand op2) { BinaryOperation op = new BinaryOperation(operator); op.addOperand(op1).addOperand(op2); @@ -531,7 +542,7 @@ private static BinaryOperation binaryExpression(BinaryOperator operator, * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression and(ExpressionOperand... operands) { + public static Expression and(Operand... operands) { return connectiveExpression(ConnectiveOperator.AND, operands); } @@ -546,7 +557,7 @@ public static Expression and(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression or(ExpressionOperand... operands) { + public static Expression or(Operand... operands) { return connectiveExpression(ConnectiveOperator.OR, operands); } @@ -561,7 +572,7 @@ public static Expression or(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression add(ExpressionOperand... operands) { + public static Expression add(Operand... operands) { return connectiveExpression(ConnectiveOperator.ADD, operands); } @@ -576,7 +587,7 @@ public static Expression add(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression subtract(ExpressionOperand... operands) { + public static Expression subtract(Operand... operands) { return connectiveExpression(ConnectiveOperator.SUBTRACT, operands); } @@ -591,7 +602,7 @@ public static Expression subtract(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression multiply(ExpressionOperand... operands) { + public static Expression multiply(Operand... operands) { return connectiveExpression(ConnectiveOperator.MULTIPLY, operands); } @@ -606,14 +617,14 @@ public static Expression multiply(ExpressionOperand... operands) { * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping">SPARQL * Operators */ - public static Expression divide(ExpressionOperand... operands) { + public static Expression divide(Operand... operands) { return connectiveExpression(ConnectiveOperator.DIVIDE, operands); } - private static ConnectiveOperation connectiveExpression(ConnectiveOperator operator, ExpressionOperand... operands) { + private static ConnectiveOperation connectiveExpression(ConnectiveOperator operator, Operand... operands) { ConnectiveOperation op = new ConnectiveOperation(operator); - for (ExpressionOperand operand : operands) { + for (Operand operand : operands) { op.addOperand(operand); } @@ -629,7 +640,7 @@ private static ConnectiveOperation connectiveExpression(ConnectiveOperator opera * @param operand * @return */ - public static Aggregate avg(ExpressionOperand operand) { + public static Aggregate avg(Operand operand) { return new Aggregate(SparqlAggregate.AVG).addOperand(operand); } @@ -638,7 +649,7 @@ public static Aggregate avg(ExpressionOperand operand) { * @param operand * @return */ - public static Aggregate count(ExpressionOperand operand) { + public static Aggregate count(Operand operand) { return new Aggregate(SparqlAggregate.COUNT).addOperand(operand); } @@ -646,27 +657,27 @@ public static Aggregate countAll() { return new Aggregate(SparqlAggregate.COUNT).countAll(); } - public static Aggregate group_concat(ExpressionOperand... operands) { + public static Aggregate group_concat(Operand... operands) { return new Aggregate(SparqlAggregate.GROUP_CONCAT).addOperand(operands); } - public static Aggregate group_concat(String separator, ExpressionOperand... operands) { + public static Aggregate group_concat(String separator, Operand... operands) { return new Aggregate(SparqlAggregate.GROUP_CONCAT).addOperand(operands).separator(separator); } - public static Aggregate max(ExpressionOperand operand) { + public static Aggregate max(Operand operand) { return new Aggregate(SparqlAggregate.MAX).addOperand(operand); } - public static Aggregate min(ExpressionOperand operand) { + public static Aggregate min(Operand operand) { return new Aggregate(SparqlAggregate.MIN).addOperand(operand); } - public static Aggregate sample(ExpressionOperand operand) { + public static Aggregate sample(Operand operand) { return new Aggregate(SparqlAggregate.SAMPLE).addOperand(operand); } - public static Aggregate sum(ExpressionOperand operand) { + public static Aggregate sum(Operand operand) { return new Aggregate(SparqlAggregate.SUM).addOperand(operand); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/constraint/Function.java b/src/main/java/com/anqit/spanqit/constraint/Function.java index e4aa9eb..fa26b3f 100644 --- a/src/main/java/com/anqit/spanqit/constraint/Function.java +++ b/src/main/java/com/anqit/spanqit/constraint/Function.java @@ -10,8 +10,6 @@ * * SPARQL Function Definitions - * - * @author Ankit */ class Function extends Expression { Function(SparqlFunction function) { diff --git a/src/main/java/com/anqit/spanqit/constraint/ExpressionOperand.java b/src/main/java/com/anqit/spanqit/constraint/Operand.java similarity index 54% rename from src/main/java/com/anqit/spanqit/constraint/ExpressionOperand.java rename to src/main/java/com/anqit/spanqit/constraint/Operand.java index 9702238..d9d5138 100644 --- a/src/main/java/com/anqit/spanqit/constraint/ExpressionOperand.java +++ b/src/main/java/com/anqit/spanqit/constraint/Operand.java @@ -3,7 +3,7 @@ import com.anqit.spanqit.core.QueryElement; /** - * An element that can be used as an operand to an + * Denotes an element that can be used as an operand to an * {@link com.anqit.spanqit.constraint.Expression} */ -public interface ExpressionOperand extends QueryElement { } \ No newline at end of file +public interface Operand extends QueryElement { } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/constraint/Operation.java b/src/main/java/com/anqit/spanqit/constraint/Operation.java index 233e6fb..7ab9183 100644 --- a/src/main/java/com/anqit/spanqit/constraint/Operation.java +++ b/src/main/java/com/anqit/spanqit/constraint/Operation.java @@ -4,8 +4,6 @@ * A SPARQL Operation. Differs from a {@link Function} in the way operators and * arguments are printed. * - * @author Ankit - * * @param The type of operation. Used to support fluency. */ abstract class Operation> extends Expression { @@ -22,8 +20,7 @@ abstract class Operation> extends Expression { } @SuppressWarnings("unchecked") - // ugh, wish the compiler dug just a little deeper... - T addOperand(ExpressionOperand operand) /* throws Exception */{ + T addOperand(Operand operand) /* throws Exception */ { if (isBelowOperatorLimit()) { return super.addOperand(operand); } diff --git a/src/main/java/com/anqit/spanqit/constraint/SparqlAggregate.java b/src/main/java/com/anqit/spanqit/constraint/SparqlAggregate.java index 24b2e33..fa728dc 100644 --- a/src/main/java/com/anqit/spanqit/constraint/SparqlAggregate.java +++ b/src/main/java/com/anqit/spanqit/constraint/SparqlAggregate.java @@ -7,8 +7,6 @@ * @see * SPARQL Function Definitions - * @author Ankit - * */ @SuppressWarnings("javadoc") // acceptable, as this won't be public for long public enum SparqlAggregate implements SparqlOperator { diff --git a/src/main/java/com/anqit/spanqit/constraint/SparqlFunction.java b/src/main/java/com/anqit/spanqit/constraint/SparqlFunction.java index 6abb73e..61acb9a 100644 --- a/src/main/java/com/anqit/spanqit/constraint/SparqlFunction.java +++ b/src/main/java/com/anqit/spanqit/constraint/SparqlFunction.java @@ -7,8 +7,6 @@ * @see * SPARQL Function Definitions - * @author Ankit - * */ @SuppressWarnings("javadoc") // acceptable, as this won't be public for long public enum SparqlFunction implements SparqlOperator { diff --git a/src/main/java/com/anqit/spanqit/constraint/SparqlOperator.java b/src/main/java/com/anqit/spanqit/constraint/SparqlOperator.java index ceac0cc..d81d823 100644 --- a/src/main/java/com/anqit/spanqit/constraint/SparqlOperator.java +++ b/src/main/java/com/anqit/spanqit/constraint/SparqlOperator.java @@ -4,8 +4,5 @@ /** * Interface to denote an Expression operator - * - * @author Ankit - * */ interface SparqlOperator extends QueryElement { } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/constraint/UnaryOperation.java b/src/main/java/com/anqit/spanqit/constraint/UnaryOperation.java index 1cc890c..1b7c6d1 100644 --- a/src/main/java/com/anqit/spanqit/constraint/UnaryOperation.java +++ b/src/main/java/com/anqit/spanqit/constraint/UnaryOperation.java @@ -1,11 +1,9 @@ package com.anqit.spanqit.constraint; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; /** * Represents a SPARQL operation that takes exactly 1 argument - * - * @author Ankit */ class UnaryOperation extends Operation { UnaryOperation(UnaryOperator operator) { @@ -19,7 +17,7 @@ public String getQueryString() { expression.append(operator.getQueryString()); String op = getOperand(0).getQueryString(); - expression.append(SpanqitStringUtils.getParenthesizedString(op)); + expression.append(SpanqitUtils.getParenthesizedString(op)); return expression.toString(); } else { diff --git a/src/main/java/com/anqit/spanqit/constraint/UnaryOperator.java b/src/main/java/com/anqit/spanqit/constraint/UnaryOperator.java index b5ef58e..8e87c59 100644 --- a/src/main/java/com/anqit/spanqit/constraint/UnaryOperator.java +++ b/src/main/java/com/anqit/spanqit/constraint/UnaryOperator.java @@ -2,9 +2,6 @@ /** * The SPARQL unary operators - * - * @author Ankit - * */ enum UnaryOperator implements SparqlOperator { NOT("!"), diff --git a/src/main/java/com/anqit/spanqit/core/Assignment.java b/src/main/java/com/anqit/spanqit/core/Assignment.java index 46558f7..67ffdfd 100644 --- a/src/main/java/com/anqit/spanqit/core/Assignment.java +++ b/src/main/java/com/anqit/spanqit/core/Assignment.java @@ -1,10 +1,8 @@ package com.anqit.spanqit.core; /** - * A SPARQL expression to variable assignment + * A SPARQL expression-to-variable assignment * - * @author Ankit - * * @see * SPARQL Assignments @@ -21,6 +19,6 @@ public class Assignment implements Projectable, Groupable { @Override public String getQueryString() { - return SpanqitStringUtils.getParenthesizedString(expression.getQueryString() + AS + var.getQueryString()); + return SpanqitUtils.getParenthesizedString(expression.getQueryString() + AS + var.getQueryString()); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/Base.java b/src/main/java/com/anqit/spanqit/core/Base.java index dbde375..8ed2e8b 100644 --- a/src/main/java/com/anqit/spanqit/core/Base.java +++ b/src/main/java/com/anqit/spanqit/core/Base.java @@ -5,8 +5,6 @@ /** * A SPARQL Base declaration * - * @author Ankit - * * @see * SPARQL Relative IRIs @@ -22,6 +20,6 @@ public class Base implements QueryElement { @Override public String getQueryString() { - return iri == null ? "" : BASE + iri.getQueryString(); + return BASE + iri.getQueryString(); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/Dataset.java b/src/main/java/com/anqit/spanqit/core/Dataset.java index e8360bb..23b0cde 100644 --- a/src/main/java/com/anqit/spanqit/core/Dataset.java +++ b/src/main/java/com/anqit/spanqit/core/Dataset.java @@ -7,8 +7,6 @@ /** * A SPARQL dataset specification * - * @author Ankit - * * @see * RDF Datasets @@ -32,6 +30,6 @@ public Dataset from(From... graphs) { * @return this */ public Dataset from(Iri... iris) { - return addElements(Arrays.stream(iris).map(Spanqit::from).toArray(From[]::new)); + return from(Arrays.stream(iris).map(Spanqit::from).toArray(From[]::new)); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/From.java b/src/main/java/com/anqit/spanqit/core/From.java index 337937c..4543b24 100644 --- a/src/main/java/com/anqit/spanqit/core/From.java +++ b/src/main/java/com/anqit/spanqit/core/From.java @@ -5,8 +5,6 @@ /** * A SPARQL Dataset specifier. * - * @author Ankit - * * @see * Specifying RDF Datasets diff --git a/src/main/java/com/anqit/spanqit/core/GraphTemplate.java b/src/main/java/com/anqit/spanqit/core/GraphTemplate.java index df7c7ca..b7e9c8d 100644 --- a/src/main/java/com/anqit/spanqit/core/GraphTemplate.java +++ b/src/main/java/com/anqit/spanqit/core/GraphTemplate.java @@ -5,27 +5,47 @@ /** * A SPARQL Graph Template, used in Construct queries * - * @author Ankit - * * @see * SPARQL CONSTRUCT Query */ -public class GraphTemplate extends StandardQueryElementCollection { +public class GraphTemplate implements QueryElement { private static final String CONSTRUCT = "CONSTRUCT"; + private TriplesTemplate triplesTemplate = Spanqit.triplesTemplate(); - GraphTemplate() { - super(CONSTRUCT, SpanqitStringUtils::getBracketedString); - } + GraphTemplate() { } /** * Add triple patterns to this graph template * - * @param patterns + * @param triples * the patterns to add * @return this */ - public GraphTemplate construct(TriplePattern... patterns) { - return addElements(patterns); + public GraphTemplate construct(TriplePattern... triples) { + triplesTemplate.and(triples); + + return this; + } + + /** + * Set, rather than augment, this graph template's triples template + * @param triplesTemplate + * the {@link TriplesTemplate} instance to set + * @return this graph template + */ + public GraphTemplate construct(TriplesTemplate triplesTemplate) { + this.triplesTemplate = triplesTemplate; + + return this; + } + + @Override + public String getQueryString() { + StringBuilder graphTemplate = new StringBuilder(); + + graphTemplate.append(CONSTRUCT).append(" ").append(triplesTemplate.getQueryString()); + + return graphTemplate.toString(); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/GroupBy.java b/src/main/java/com/anqit/spanqit/core/GroupBy.java index 4667acd..c1391eb 100644 --- a/src/main/java/com/anqit/spanqit/core/GroupBy.java +++ b/src/main/java/com/anqit/spanqit/core/GroupBy.java @@ -5,8 +5,6 @@ /** * A SPARQL Group By clause * - * @author Ankit - * * @see * SPARQL Group By Clause diff --git a/src/main/java/com/anqit/spanqit/core/Groupable.java b/src/main/java/com/anqit/spanqit/core/Groupable.java index bbeabc2..a60bb7c 100644 --- a/src/main/java/com/anqit/spanqit/core/Groupable.java +++ b/src/main/java/com/anqit/spanqit/core/Groupable.java @@ -4,8 +4,6 @@ * Denotes a groupable SPARQL query element (can be used in a * GROUP BY clause) * - * @author Ankit - * * @see * SPARQL Group By Clause diff --git a/src/main/java/com/anqit/spanqit/core/Having.java b/src/main/java/com/anqit/spanqit/core/Having.java index 4678f63..feca9df 100644 --- a/src/main/java/com/anqit/spanqit/core/Having.java +++ b/src/main/java/com/anqit/spanqit/core/Having.java @@ -7,8 +7,6 @@ /** * A SPARQL Having clause * - * @author Ankit - * * @see * SPARQL Having Clause */ @@ -17,7 +15,7 @@ public class Having extends StandardQueryElementCollection private static final String DELIMETER = " "; Having() { - super(HAVING, DELIMETER, SpanqitStringUtils::getParenthesizedString, new ArrayList>()); + super(HAVING, DELIMETER, SpanqitUtils::getParenthesizedString, new ArrayList>()); printBodyIfEmpty(true); } diff --git a/src/main/java/com/anqit/spanqit/core/OrderBy.java b/src/main/java/com/anqit/spanqit/core/OrderBy.java index 8127136..fc493cd 100644 --- a/src/main/java/com/anqit/spanqit/core/OrderBy.java +++ b/src/main/java/com/anqit/spanqit/core/OrderBy.java @@ -5,8 +5,6 @@ /** * A SPARQL Order By clause * - * @author Ankit - * * @see * SPARQL Order By Clause diff --git a/src/main/java/com/anqit/spanqit/core/OrderCondition.java b/src/main/java/com/anqit/spanqit/core/OrderCondition.java index 028ec9c..6a079fe 100644 --- a/src/main/java/com/anqit/spanqit/core/OrderCondition.java +++ b/src/main/java/com/anqit/spanqit/core/OrderCondition.java @@ -3,8 +3,6 @@ /** * An ascending or descending order condition * - * @author Ankit - * * @see * SPARQL Order By Clause @@ -61,7 +59,7 @@ public String getQueryString() { condition.append(DESC); } - condition.append("(").append(orderOn.getQueryString()).append(")"); + condition.append(SpanqitUtils.getParenthesizedString(orderOn.getQueryString())); } return condition.toString(); diff --git a/src/main/java/com/anqit/spanqit/core/Orderable.java b/src/main/java/com/anqit/spanqit/core/Orderable.java index 9e39759..0ba1244 100644 --- a/src/main/java/com/anqit/spanqit/core/Orderable.java +++ b/src/main/java/com/anqit/spanqit/core/Orderable.java @@ -4,10 +4,22 @@ * Denotes an orederable SPARQL query element (can be used in a * ORDER BY clause) * - * @author Ankit - * * @see * SPARQL Order By Clause */ -public interface Orderable extends QueryElement { } \ No newline at end of file +public interface Orderable extends QueryElement { + /** + * @return an ascending {@link OrderCondition} instance for this {@link Orderable} object + */ + default public OrderCondition asc() { + return Spanqit.asc(this); + } + + /** + * @return an descending {@link OrderCondition} instance for this {@link Orderable} object + */ + default public OrderCondition desc() { + return Spanqit.desc(this); + } +} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/Projectable.java b/src/main/java/com/anqit/spanqit/core/Projectable.java index 1596d9a..29ec302 100644 --- a/src/main/java/com/anqit/spanqit/core/Projectable.java +++ b/src/main/java/com/anqit/spanqit/core/Projectable.java @@ -3,8 +3,6 @@ /** * Denotes a projectable query element (can be SELECT'ed) * - * @author Ankit - * * @see * SPARQL Projections diff --git a/src/main/java/com/anqit/spanqit/core/Queries.java b/src/main/java/com/anqit/spanqit/core/Queries.java deleted file mode 100644 index 8e3b316..0000000 --- a/src/main/java/com/anqit/spanqit/core/Queries.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.anqit.spanqit.core; - -/** - * A class with static methods to create SPARQL queries - * - * @author Ankit - * - * @see SPARQL - * Query Language - */ -public class Queries { - // prevent instantiation of this class - private Queries() { } - - /** - * Create a SPARQL Select query - * - * @return a new SPARQL Select query - * - * @see SPARQL - * Select Query - */ - public static SelectQuery SELECT() { - return new SelectQuery(); - } - - /** - * Create a SPARQL Construct query - * - * @return a new Construct query - * - * @see SPARQL - * Construct Query - */ - public static ConstructQuery CONSTRUCT() { - return new ConstructQuery(); - } -} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/QueryElement.java b/src/main/java/com/anqit/spanqit/core/QueryElement.java index 7c4223b..3fe3f5e 100644 --- a/src/main/java/com/anqit/spanqit/core/QueryElement.java +++ b/src/main/java/com/anqit/spanqit/core/QueryElement.java @@ -2,9 +2,6 @@ /** * Denotes a SPARQL Query Element - * - * @author Ankit - * */ public interface QueryElement { /** diff --git a/src/main/java/com/anqit/spanqit/core/QueryElementCollection.java b/src/main/java/com/anqit/spanqit/core/QueryElementCollection.java index 7f79709..b104268 100644 --- a/src/main/java/com/anqit/spanqit/core/QueryElementCollection.java +++ b/src/main/java/com/anqit/spanqit/core/QueryElementCollection.java @@ -12,8 +12,7 @@ * @param * the type of elements in the collection */ -public abstract class QueryElementCollection implements - QueryElement { +public abstract class QueryElementCollection implements QueryElement { protected Collection elements; private String delimeter; diff --git a/src/main/java/com/anqit/spanqit/core/QueryPattern.java b/src/main/java/com/anqit/spanqit/core/QueryPattern.java index 67e589c..da807fd 100644 --- a/src/main/java/com/anqit/spanqit/core/QueryPattern.java +++ b/src/main/java/com/anqit/spanqit/core/QueryPattern.java @@ -14,12 +14,9 @@ public class QueryPattern implements QueryElement { private static final String WHERE = "WHERE"; - private GraphPatternNotTriple where; + private GraphPatternNotTriple where = GraphPatterns.and(); - // Package-protect default constructor - QueryPattern() { - where = GraphPatterns.and(); - } + QueryPattern() { } /** * Add graph patterns to this query pattern. Adds the given patterns into @@ -35,6 +32,19 @@ public QueryPattern where(GraphPattern... patterns) { return this; } + /** + * Set this query pattern's where clause + * @param where + * the {@link GraphPatternNotTriple} instance to set the where clause to + * @return + * this QueryPattern instance + */ + public QueryPattern where(GraphPatternNotTriple where) { + this.where = GraphPatterns.and(where); + + return this; + } + @Override public String getQueryString() { StringBuilder whereClause = new StringBuilder(); diff --git a/src/main/java/com/anqit/spanqit/core/Spanqit.java b/src/main/java/com/anqit/spanqit/core/Spanqit.java index d60621f..7b3c95f 100644 --- a/src/main/java/com/anqit/spanqit/core/Spanqit.java +++ b/src/main/java/com/anqit/spanqit/core/Spanqit.java @@ -22,7 +22,7 @@ private Spanqit() { } public static Variable var(String varName) { return new Variable(varName); } - + /** * Create a SPARQL assignment * @@ -213,4 +213,15 @@ public static OrderCondition asc(Orderable orderOn) { public static OrderCondition desc(Orderable orderOn) { return new OrderCondition(orderOn, false); } + + /** + * Create a TriplesTemplate instance, for use with Construct and Update queries + * + * @param triples + * the triples to include in the triples template + * @return a TriplesTemplate of the given triples + */ + public static TriplesTemplate triplesTemplate(TriplePattern... triples) { + return new TriplesTemplate(triples); + } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/SpanqitStringUtils.java b/src/main/java/com/anqit/spanqit/core/SpanqitUtils.java similarity index 56% rename from src/main/java/com/anqit/spanqit/core/SpanqitStringUtils.java rename to src/main/java/com/anqit/spanqit/core/SpanqitUtils.java index a76207c..f780866 100644 --- a/src/main/java/com/anqit/spanqit/core/SpanqitStringUtils.java +++ b/src/main/java/com/anqit/spanqit/core/SpanqitUtils.java @@ -1,13 +1,34 @@ package com.anqit.spanqit.core; import java.util.Optional; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; @SuppressWarnings("javadoc") -public class SpanqitStringUtils { +public class SpanqitUtils { private static final String PAD = " "; - public static void appendAndNewlineIfNonNull(QueryElement element, StringBuilder builder) { - builder.append(Optional.ofNullable(element).map(e -> e.getQueryString() + "\n").orElse("")); + public static Optional getOrCreateAndModifyOptional(Optional optional, Supplier getter, UnaryOperator operator) { + return Optional.of(operator.apply(optional.orElseGet(getter))); + } + + public static void appendAndNewlineIfPresent(Optional elementOptional, StringBuilder builder) { + appendQueryElementIfPresent(elementOptional, builder, null, "\n"); + } + + public static void appendQueryElementIfPresent(Optional queryElementOptional, StringBuilder builder, String prefix, String suffix) { + appendStringIfPresent(queryElementOptional.map(QueryElement::getQueryString), builder, prefix, suffix); + } + + public static void appendStringIfPresent(Optional stringOptional, StringBuilder builder, String prefix, String suffix) { + Optional preOpt = Optional.ofNullable(prefix); + Optional sufOpt = Optional.ofNullable(suffix); + + stringOptional.ifPresent(string -> { + preOpt.ifPresent(p -> builder.append(p)); + builder.append(string); + sufOpt.ifPresent(s -> builder.append(s)); + }); } public static String getBracedString(String contents) { diff --git a/src/main/java/com/anqit/spanqit/core/TriplesTemplate.java b/src/main/java/com/anqit/spanqit/core/TriplesTemplate.java new file mode 100644 index 0000000..fe002cb --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/TriplesTemplate.java @@ -0,0 +1,34 @@ +package com.anqit.spanqit.core; + +import java.util.Collections; + +import com.anqit.spanqit.graphpattern.TriplePattern; + +/** + * Represents a collection of triple patterns + */ +public class TriplesTemplate extends QueryElementCollection { + TriplesTemplate(TriplePattern... triples) { + super(" .\n"); + and(triples); + } + + /** + * add triples to this template + * + * @param triples the triples to add + * + * @return this TriplesTemplate instance + */ + public TriplesTemplate and(TriplePattern... triples) { + Collections.addAll(elements, triples); + + return this; + } + + @Override + public String getQueryString() { + return SpanqitUtils.getBracedString(super.getQueryString()); + } + +} diff --git a/src/main/java/com/anqit/spanqit/core/Variable.java b/src/main/java/com/anqit/spanqit/core/Variable.java index 8ea39ee..d754436 100644 --- a/src/main/java/com/anqit/spanqit/core/Variable.java +++ b/src/main/java/com/anqit/spanqit/core/Variable.java @@ -1,6 +1,6 @@ package com.anqit.spanqit.core; -import com.anqit.spanqit.constraint.ExpressionOperand; +import com.anqit.spanqit.constraint.Operand; import com.anqit.spanqit.graphpattern.GraphName; import com.anqit.spanqit.rdf.RdfObject; import com.anqit.spanqit.rdf.RdfPredicate; @@ -14,7 +14,7 @@ * SPARQL Variable Syntax */ public class Variable implements Projectable, RdfSubject, - RdfPredicate, RdfObject, ExpressionOperand, Orderable, + RdfPredicate, RdfObject, Operand, Orderable, Groupable, GraphName, Assignable { private String alias; diff --git a/src/main/java/com/anqit/spanqit/core/query/AddQuery.java b/src/main/java/com/anqit/spanqit/core/query/AddQuery.java new file mode 100644 index 0000000..c563144 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/AddQuery.java @@ -0,0 +1,18 @@ +package com.anqit.spanqit.core.query; + +/** + * A SPARQL ADD Query + * + * @see + * SPARQL ADD Query + */ +public class AddQuery extends DestinationSourceManagementQuery { + private static final String ADD = "ADD"; + + AddQuery() { } + + @Override + protected String getQueryActionString() { + return ADD; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/ClearQuery.java b/src/main/java/com/anqit/spanqit/core/query/ClearQuery.java new file mode 100644 index 0000000..92b501a --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/ClearQuery.java @@ -0,0 +1,19 @@ +package com.anqit.spanqit.core.query; + +/** + * A SPARQL CLEAR Query + * + * @see + * SPARQL CLEAR Query + * + */ +public class ClearQuery extends TargetedGraphManagementQuery { + private static final String CLEAR = "CLEAR"; + + ClearQuery() { } + + @Override + protected String getQueryActionString() { + return CLEAR; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/ConstructQuery.java b/src/main/java/com/anqit/spanqit/core/query/ConstructQuery.java similarity index 89% rename from src/main/java/com/anqit/spanqit/core/ConstructQuery.java rename to src/main/java/com/anqit/spanqit/core/query/ConstructQuery.java index 46a5997..dc99e05 100644 --- a/src/main/java/com/anqit/spanqit/core/ConstructQuery.java +++ b/src/main/java/com/anqit/spanqit/core/query/ConstructQuery.java @@ -1,12 +1,12 @@ -package com.anqit.spanqit.core; +package com.anqit.spanqit.core.query; +import com.anqit.spanqit.core.GraphTemplate; +import com.anqit.spanqit.core.Spanqit; import com.anqit.spanqit.graphpattern.TriplePattern; /** * The SPARQL CONSTRUCT query * - * @author Ankit - * * @see * SPARQL CONSTRUCT Query diff --git a/src/main/java/com/anqit/spanqit/core/query/CopyQuery.java b/src/main/java/com/anqit/spanqit/core/query/CopyQuery.java new file mode 100644 index 0000000..a3ec5e0 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/CopyQuery.java @@ -0,0 +1,17 @@ +package com.anqit.spanqit.core.query; + +/** + * A SPARQL COPY Query + * + * @see + * SPARQL COPY query + */ +public class CopyQuery extends DestinationSourceManagementQuery { + private static String COPY = "COPY"; + + CopyQuery() { } + + protected String getQueryActionString() { + return COPY; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/CreateQuery.java b/src/main/java/com/anqit/spanqit/core/query/CreateQuery.java new file mode 100644 index 0000000..7c67f22 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/CreateQuery.java @@ -0,0 +1,45 @@ +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.rdf.Iri; + +/** + * A SPARQL CREATE Query + * + * @see + * SPARQL CREATE Query + */ +public class CreateQuery extends GraphManagementQuery { + private static final String CREATE = "CREATE"; + private static final String GRAPH = "GRAPH"; + + private Iri graph; + + CreateQuery() { } + + /** + * Specify the graph to create + * + * @param graph the IRI identifier for the new graph + * + * @return this CreateQuery instance + */ + public CreateQuery graph(Iri graph) { + this.graph = graph; + + return this; + } + + @Override + public String getQueryString() { + StringBuilder create = new StringBuilder(); + + create.append(CREATE).append(" "); + + appendSilent(create); + + create.append(GRAPH).append(" ").append(graph.getQueryString()); + + return create.toString(); + } + +} diff --git a/src/main/java/com/anqit/spanqit/core/query/DeleteDataQuery.java b/src/main/java/com/anqit/spanqit/core/query/DeleteDataQuery.java new file mode 100644 index 0000000..e544546 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/DeleteDataQuery.java @@ -0,0 +1,55 @@ +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.GraphName; +import com.anqit.spanqit.graphpattern.TriplePattern; + +/** + * The SPARQL Delete Data Query + * + * @see SPARQL + * DELETE DATA Query + * + */ +public class DeleteDataQuery extends UpdateDataQuery { + private static final String DELETE_DATA = "DELETE DATA"; + + /** + * Add triples to be deleted + * + * @param triples the triples to add to this delete data query + * + * @return this Delete Data query instance + */ + public DeleteDataQuery deleteData(TriplePattern... triples) { + return addTriples(triples); + } + + /** + * Set this query's triples template + * + * @param triplesTemplate + * the {@link TriplesTemplate} instance to set + * + * @return this instance + */ + public DeleteDataQuery deleteData(TriplesTemplate triplesTemplate) { + return setTriplesTemplate(triplesTemplate); + } + + /** + * Specify a graph to delete the data from + * + * @param graph the identifier of the graph + * + * @return this Delete Data query instance + */ + public DeleteDataQuery from(GraphName graph) { + return graph(graph); + } + + @Override + protected String getPrefix() { + return DELETE_DATA; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/DestinationSourceManagementQuery.java b/src/main/java/com/anqit/spanqit/core/query/DestinationSourceManagementQuery.java new file mode 100644 index 0000000..9ce8b1d --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/DestinationSourceManagementQuery.java @@ -0,0 +1,117 @@ +package com.anqit.spanqit.core.query; + +import java.util.Optional; + +import com.anqit.spanqit.rdf.Iri; + +/** + * A SPARQL Update Query that has a source and a destination + * + * @param the type of the query; used to support fluency + */ +public abstract class DestinationSourceManagementQuery> extends GraphManagementQuery> { + private static String DEFAULT = "DEFAULT"; + private static String TO = "TO"; + + private Optional from = Optional.empty(); + private Optional to = Optional.empty(); + private boolean fromDefault = false, toDefault = false; + + /** + * Specify the query source graph + * + * @param from the Iri identifying the source graph + * + * @return this query instance + */ + public T from(Iri from) { + this.from = Optional.ofNullable(from); + + return fromDefault(false); + } + + /** + * Specify the query destination graph + * + * @param to the Iri identifying the destination graph + * + * @return this query instance + */ + public T to(Iri to) { + this.to = Optional.ofNullable(to); + + return toDefault(false); + } + + /** + * Specify that the source graph of this query should be the default graph + * + * @return this query instance + */ + public T fromDefault() { + return fromDefault(true); + } + + /** + * Specify if this query's source should be the default graph + * + * @param fromDefault if this query's source should be the default graph + * + * @return this query instance + */ + @SuppressWarnings("unchecked") + public T fromDefault(boolean fromDefault) { + this.fromDefault = fromDefault; + + return (T) this; + } + + /** + * Specify that the destination graph of this query should be the default graph + * + * @return this query instance + */ + public T toDefault() { + return toDefault(true); + } + + /** + * Specify if this query's destination should be the default graph + * + * @param toDefault if this query's destination should be the default graph + * + * @return this query instance + */ + @SuppressWarnings("unchecked") + public T toDefault(boolean toDefault) { + this.toDefault = toDefault; + + return (T) this; + } + + protected abstract String getQueryActionString(); + + @Override + public String getQueryString() { + StringBuilder query = new StringBuilder(); + query.append(getQueryActionString()).append(" "); + + appendSilent(query); + + if(fromDefault) { + query.append(DEFAULT); + } else { + query.append(from.map(Iri::getQueryString).orElse(DEFAULT)); + } + + query.append(" ").append(TO).append(" "); + + if(toDefault) { + query.append(DEFAULT); + } else { + query.append(to.map(Iri::getQueryString).orElse(DEFAULT)); + } + + return query.toString(); + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/DropQuery.java b/src/main/java/com/anqit/spanqit/core/query/DropQuery.java new file mode 100644 index 0000000..d92ceed --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/DropQuery.java @@ -0,0 +1,18 @@ +package com.anqit.spanqit.core.query; + +/** + * A SPARQL DROP Query + * + * @see + * SPARQL DROP Query + */ +public class DropQuery extends TargetedGraphManagementQuery { + private static final String DROP = "DROP"; + + DropQuery() { } + + @Override + protected String getQueryActionString() { + return DROP; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/GraphManagementQuery.java b/src/main/java/com/anqit/spanqit/core/query/GraphManagementQuery.java new file mode 100644 index 0000000..ec0c815 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/GraphManagementQuery.java @@ -0,0 +1,40 @@ +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.core.QueryElement; + +abstract class GraphManagementQuery> implements QueryElement { + private static final String SILENT = "SILENT"; + + private boolean silent = false; + + GraphManagementQuery() { } + + /** + * Set the SILENT option to true on this query + * + * @return this query instance + */ + public T silent() { + return silent(true); + } + + /** + * Specify if the SILENT option should be on for this query + * + * @param isSilent if this should be a SILENT operation or not + * + * @return this query instance + */ + @SuppressWarnings("unchecked") + public T silent(boolean isSilent) { + this.silent = isSilent; + + return (T) this; + } + + protected void appendSilent(StringBuilder builder) { + if (silent) { + builder.append(SILENT).append(" "); + } + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/InsertDataQuery.java b/src/main/java/com/anqit/spanqit/core/query/InsertDataQuery.java new file mode 100644 index 0000000..ef976c3 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/InsertDataQuery.java @@ -0,0 +1,54 @@ +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.GraphName; +import com.anqit.spanqit.graphpattern.TriplePattern; + +/** + * The SPARQL Insert Data Query + * + * @see + * SPARQL INSERT DATA Query + * + */ +public class InsertDataQuery extends UpdateDataQuery { + private static final String INSERT_DATA = "INSERT DATA"; + + /** + * Add triples to be inserted + * + * @param triples the triples to add to this insert data query + * + * @return this Insert Data query instance + */ + public InsertDataQuery insertData(TriplePattern... triples) { + return addTriples(triples); + } + + /** + * Set this query's triples template + * + * @param triplesTemplate + * the {@link TriplesTemplate} instance to set + * + * @return this instance + */ + public InsertDataQuery insertData(TriplesTemplate triplesTemplate) { + return setTriplesTemplate(triplesTemplate); + } + /** + * Specify a graph to insert the data into + * + * @param graph the identifier of the graph + * + * @return this Insert Data query instance + */ + public InsertDataQuery into(GraphName graph) { + return graph(graph); + } + + @Override + public String getPrefix() { + return INSERT_DATA; + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/LoadQuery.java b/src/main/java/com/anqit/spanqit/core/query/LoadQuery.java new file mode 100644 index 0000000..f0c6147 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/LoadQuery.java @@ -0,0 +1,63 @@ +package com.anqit.spanqit.core.query; + +import java.util.Optional; + +import com.anqit.spanqit.core.SpanqitUtils; +import com.anqit.spanqit.rdf.Iri; + +/** + * A SPARQL LOAD Query + * + * @see + * SPARQL LOAD Query + */ +public class LoadQuery extends GraphManagementQuery { + private static final String LOAD = "LOAD"; + private static final String INTO_GRAPH = "INTO GRAPH"; + + private Iri from; + private Optional to = Optional.empty(); + + LoadQuery() { } + + /** + * Specify which graph to load form + * + * @param from the IRI identifying the graph to load triples from + * + * @return this LoadQuery instance + */ + public LoadQuery from(Iri from) { + this.from = from; + + return this; + } + + /** + * Specify which graph to load into, if not the default graph + * + * @param to the IRI identifying the graph to load into + * + * @return this LoadQuery instance + */ + public LoadQuery to(Iri to) { + this.to = Optional.ofNullable(to); + + return this; + } + + @Override + public String getQueryString() { + StringBuilder load = new StringBuilder(); + load.append(LOAD).append(" "); + + appendSilent(load); + + load.append(from.getQueryString()); + + SpanqitUtils.appendQueryElementIfPresent(to, load, " " + INTO_GRAPH + " ", null); + + return load.toString(); + } + +} diff --git a/src/main/java/com/anqit/spanqit/core/query/ModifyQuery.java b/src/main/java/com/anqit/spanqit/core/query/ModifyQuery.java new file mode 100644 index 0000000..1bed5e8 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/ModifyQuery.java @@ -0,0 +1,186 @@ +package com.anqit.spanqit.core.query; + +import java.util.Optional; + +import com.anqit.spanqit.core.QueryPattern; +import com.anqit.spanqit.core.Spanqit; +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.GraphName; +import com.anqit.spanqit.graphpattern.GraphPattern; +import com.anqit.spanqit.graphpattern.TriplePattern; +import com.anqit.spanqit.rdf.Iri; + +import static com.anqit.spanqit.core.SpanqitUtils.getOrCreateAndModifyOptional; + +/** + * The SPARQL Modify Queries + * + * @see + * SPARQL DELETE/INSERT Query + */ +public class ModifyQuery extends UpdateQuery { + private static final String INSERT = "INSERT"; + private static final String DELETE = "DELETE"; + private static final String WITH = "WITH"; + private static final String USING = "USING"; + private static final String NAMED = "NAMED"; + + private Optional with = Optional.empty(); + private Optional using = Optional.empty(); + private boolean usingNamed = false; + + private Optional deleteTriples = Optional.empty(); + private Optional insertTriples = Optional.empty(); + private Optional deleteGraph = Optional.empty(); + private Optional insertGraph = Optional.empty(); + + private QueryPattern where = Spanqit.where(); + + ModifyQuery() { } + + /** + * Define the graph that will be modified or matched against in the absence of more explicit graph definitions + * + * @param iri the IRI identifying the desired graph + * + * @return this modify query instance + */ + public ModifyQuery with(Iri iri) { + with = Optional.ofNullable(iri); + + return this; + } + + /** + * Specify triples to delete (or leave empty for DELETE WHERE shortcut) + * + * @param triples the triples to delete + * + * @return this modify query instance + * + * @see + * SPARQL DELETE WHERE shortcut + */ + public ModifyQuery delete(TriplePattern... triples) { + deleteTriples = getOrCreateAndModifyOptional(deleteTriples, Spanqit::triplesTemplate, tt -> tt.and(triples)); + + return this; + } + + /** + * Specify the graph to delete triples from + * + * @param graphName the identifier of the graph + * + * @return this modify query instance + */ + public ModifyQuery from(GraphName graphName) { + this.deleteGraph = Optional.ofNullable(graphName); + + return this; + } + + /** + * Specify triples to insert + * + * @param triples the triples to insert + * + * @return this modify query instance + */ + public ModifyQuery insert(TriplePattern... triples) { + insertTriples = getOrCreateAndModifyOptional(insertTriples, Spanqit::triplesTemplate, tt -> tt.and(triples)); + + return this; + } + + /** + * Specify the graph to insert triples into + * + * @param graphName the identifier of the graph + * + * @return this modify query instance + */ + public ModifyQuery into(GraphName graphName) { + insertGraph = Optional.ofNullable(graphName); + + return this; + } + + /** + * Specify the graph used when evaluating the WHERE clause + * + * @param iri the IRI identifying the desired graph + * + * @return this modify query instance + */ + public ModifyQuery using(Iri iri) { + using = Optional.ofNullable(iri); + + return this; + } + + /** + * Specify a named graph to use to when evaluating the WHERE clause + * + * @param iri the IRI identifying the desired graph + * + * @return this modify query instance + */ + public ModifyQuery usingNamed(Iri iri) { + usingNamed = true; + + return using(iri); + } + + /** + * Add graph patterns to this query's query pattern + * + * @param patterns the patterns to add + * + * @return this modify query instance + */ + public ModifyQuery where(GraphPattern... patterns) { + where.where(patterns); + + return this; + } + + @Override + protected String getQueryActionString() { + StringBuilder modifyQuery = new StringBuilder(); + + with.ifPresent(withIri -> modifyQuery.append(WITH).append(" ").append(withIri.getQueryString()).append("\n")); + + deleteTriples.ifPresent(delTriples -> { + modifyQuery.append(DELETE).append(" "); + + // DELETE WHERE shortcut + // https://www.w3.org/TR/sparql11-update/#deleteWhere + if(!delTriples.isEmpty()) { + appendNamedTriplesTemplates(modifyQuery, deleteGraph, delTriples); + } + modifyQuery.append("\n"); + }); + + insertTriples.ifPresent(insTriples -> { + modifyQuery.append(INSERT).append(" "); + appendNamedTriplesTemplates(modifyQuery, insertGraph, insTriples); + modifyQuery.append("\n"); + }); + + using.ifPresent(usingIri -> { + modifyQuery.append(USING).append(" "); + + if(usingNamed) { + modifyQuery.append(NAMED).append(" "); + } + + modifyQuery.append(usingIri.getQueryString()); + modifyQuery.append("\n"); + }); + + modifyQuery.append(where.getQueryString()); + + return modifyQuery.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/query/MoveQuery.java b/src/main/java/com/anqit/spanqit/core/query/MoveQuery.java new file mode 100644 index 0000000..9d13a42 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/MoveQuery.java @@ -0,0 +1,19 @@ +package com.anqit.spanqit.core.query; + +/** + * A SPARQL MOVE Query + * + * @see + * SPARQL MOVE Query + */ +public class MoveQuery extends DestinationSourceManagementQuery { + private static final String MOVE = "MOVE"; + + MoveQuery() { } + + @Override + protected String getQueryActionString() { + return MOVE; + } + +} diff --git a/src/main/java/com/anqit/spanqit/core/OuterQuery.java b/src/main/java/com/anqit/spanqit/core/query/OuterQuery.java similarity index 55% rename from src/main/java/com/anqit/spanqit/core/OuterQuery.java rename to src/main/java/com/anqit/spanqit/core/query/OuterQuery.java index 53f2c45..6e1ba16 100644 --- a/src/main/java/com/anqit/spanqit/core/OuterQuery.java +++ b/src/main/java/com/anqit/spanqit/core/query/OuterQuery.java @@ -1,24 +1,29 @@ -package com.anqit.spanqit.core; +package com.anqit.spanqit.core.query; -import com.anqit.spanqit.rdf.Iri; +import static com.anqit.spanqit.core.SpanqitUtils.appendAndNewlineIfPresent; +import static com.anqit.spanqit.core.SpanqitUtils.getOrCreateAndModifyOptional; + +import java.util.Optional; -import static com.anqit.spanqit.core.SpanqitStringUtils.appendAndNewlineIfNonNull; +import com.anqit.spanqit.core.Base; +import com.anqit.spanqit.core.Dataset; +import com.anqit.spanqit.core.From; +import com.anqit.spanqit.core.Prefix; +import com.anqit.spanqit.core.PrefixDeclarations; +import com.anqit.spanqit.core.Spanqit; +import com.anqit.spanqit.rdf.Iri; /** * A non-subquery query. * - * @author Ankit - * * @param - * The query type. Used to support fluency. + * The query type. Used to support fluency. */ -// argh, so frustrating @SuppressWarnings("unchecked") -public abstract class OuterQuery> extends - Query> { - protected Base base; // ? - protected PrefixDeclarations prefixes; // * - protected Dataset from; // * +public abstract class OuterQuery> extends Query { + protected Optional base = Optional.empty(); + protected Optional prefixes = Optional.empty(); + protected Optional from = Optional.empty(); /** * Set the base IRI of this query @@ -28,7 +33,7 @@ public abstract class OuterQuery> extends * @return this */ public T base(Iri iri) { - this.base = Spanqit.base(iri); + this.base = Optional.of(Spanqit.base(iri)); return (T) this; } @@ -41,7 +46,7 @@ public T base(Iri iri) { * @return this */ public T base(Base base) { - this.base = base; + this.base = Optional.of(base); return (T) this; } @@ -54,11 +59,7 @@ public T base(Base base) { * @return this */ public T prefix(Prefix... prefixes) { - if (this.prefixes == null) { - this.prefixes = Spanqit.prefixes(); - } - - this.prefixes.addPrefix(prefixes); + this.prefixes = getOrCreateAndModifyOptional(this.prefixes, Spanqit::prefixes, p -> p.addPrefix(prefixes)); return (T) this; } @@ -71,7 +72,7 @@ public T prefix(Prefix... prefixes) { * @return this */ public T prefix(PrefixDeclarations prefixes) { - this.prefixes = prefixes; + this.prefixes = Optional.of(prefixes); return (T) this; } @@ -84,10 +85,7 @@ public T prefix(PrefixDeclarations prefixes) { * @return this */ public T from(From... graphs) { - if (from == null) { - from = Spanqit.dataset(); - } - from.from(graphs); + from = getOrCreateAndModifyOptional(from, Spanqit::dataset, f -> f.from(graphs)); return (T) this; } @@ -100,7 +98,7 @@ public T from(From... graphs) { * @return this */ public T from(Dataset from) { - this.from = from; + this.from = Optional.of(from); return (T) this; } @@ -109,9 +107,9 @@ public T from(Dataset from) { public String getQueryString() { StringBuilder query = new StringBuilder(); - appendAndNewlineIfNonNull(base, query); - appendAndNewlineIfNonNull(prefixes, query); - appendAndNewlineIfNonNull(from, query); + appendAndNewlineIfPresent(base, query); + appendAndNewlineIfPresent(prefixes, query); + appendAndNewlineIfPresent(from, query); query.append(super.getQueryString()); diff --git a/src/main/java/com/anqit/spanqit/core/query/Queries.java b/src/main/java/com/anqit/spanqit/core/query/Queries.java new file mode 100644 index 0000000..d824a63 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/Queries.java @@ -0,0 +1,234 @@ +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.core.GraphTemplate; +import com.anqit.spanqit.core.Projectable; +import com.anqit.spanqit.core.Projection; +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.TriplePattern; + +/** + * A class with static methods to create SPARQL queries + * + * @see + * SPARQL Query Language + */ +public class Queries { + // prevent instantiation of this class + private Queries() { } + + /** + * Create a SPARQL Select query + * + * @param projectables + * the initial set of {@link Projectable}(s), if any, to select + * + * @return a new {@link SelectQuery} + * + * @see SPARQL + * Select Query + */ + public static SelectQuery SELECT(Projectable... projectables) { + return new SelectQuery().select(projectables); + } + + /** + * Create a SPARQL Select query + * + * @param select + * the {@link Projection} to set initially + * @return a new {@link SelectQuery} + * + * @see SPARQL + * Select Query + */ + public static SelectQuery SELECT(Projection select) { + return new SelectQuery().select(select); + } + + /** + * Create a SPARQL Construct query + * + * @param patterns + * the initial set of {@link TriplePattern}(s), if any, to construct + * @return a new {@link ConstructQuery} + * + * @see SPARQL + * Construct Query + */ + public static ConstructQuery CONSTRUCT(TriplePattern... patterns) { + return new ConstructQuery().construct(patterns); + } + + /** + * Create a SPARQL Construct query + * + * @param construct + * the {@link GraphTemplate} to set initially + * @return a new {@link ConstructQuery} + * + * @see SPARQL + * Construct Query + */ + public static ConstructQuery CONSTRUCT(GraphTemplate construct) { + return new ConstructQuery().construct(construct); + } + /** + * Create a SPARQL INSERT DATA query + * + * @param triples + * the initial set of {@link TriplePattern}(s), if any, to use + * + * @return a new {@link InsertDataQuery} + * + * @see + * SPARQL INSERT DATA Query + */ + public static InsertDataQuery INSERT_DATA(TriplePattern... triples) { + return new InsertDataQuery().insertData(triples); + } + + /** + * Create a SPARQL INSERT DATA query + * + * @param triplesTemplate + * the {@link TriplesTemplate} to set initially + * + * @return a new {@link InsertDataQuery} + * + * @see + * SPARQL INSERT DATA Query + */ + public static InsertDataQuery INSERT_DATA(TriplesTemplate triplesTemplate) { + return new InsertDataQuery().insertData(triplesTemplate); + } + + /** + * Create a SPARQL DELETE DATA query + * + * @param triples + * the initial set of {@link TriplePattern}(s), if any, to use + * + * @return a new {@link DeleteDataQuery} + * + * @see + * SPARQL DELETE DATA Query + */ + public static DeleteDataQuery DELETE_DATA(TriplePattern... triples) { + return new DeleteDataQuery().deleteData(triples); + } + + /** + * Create a SPARQL DELETE DATA query + * + * @param triplesTemplate + * the {@link TriplesTemplate} to set initially + * + * @return a new {@link DeleteDataQuery} + * + * @see + * SPARQL DELETE DATA Query + */ + public static DeleteDataQuery DELETE_DATA(TriplesTemplate triplesTemplate) { + return new DeleteDataQuery().deleteData(triplesTemplate); + } + + /** + * Creates a SPARQL Modify query + * + * @return a new {@link ModifyQuery} + * + * @see + * SPARQL Modify Query + */ + public static ModifyQuery MODIFY() { + return new ModifyQuery(); + } + + /** + * Creates a SPARQL LOAD query + * + * @return a new {@link LoadQuery} + * + * @see + * SPARQL LOAD Query + */ + public static LoadQuery LOAD() { + return new LoadQuery(); + } + + /** + * Creates a SPARQL CLEAR Query + * + * @return a new {@link ClearQuery} + * + * @see + * SPARQL CLEAR Query + */ + public static ClearQuery CLEAR() { + return new ClearQuery(); + } + + /** + * Creates a SPARQL CREATE Query + * + * @return a new {@link CreateQuery} + * + * @see + * SPARQL CREATE Query + */ + public static CreateQuery CREATE() { + return new CreateQuery(); + } + + /** + * Creates a SPARQL DROP Query + * + * @return a new {@link DropQuery} + * + * @see + * SPARQL DROP Query + */ + public static DropQuery DROP() { + return new DropQuery(); + } + + /** + * Creates a SPARQL COPY Query + * + * @return a new {@link CopyQuery} + * + * @see + * SPARQL COPY Query + */ + public static CopyQuery COPY() { + return new CopyQuery(); + } + + /** + * Creates a SPARQL MOVE Query + * + * @return a new {@link MoveQuery} + * + * @see + * SPARQL MOVE Query + */ + public static MoveQuery MOVE() { + return new MoveQuery(); + } + + /** + * Creates a new SPARQL ADD Query + * + * @return a new {@link AddQuery} + * + * @see + * SPARQL ADD Query + */ + public static AddQuery ADD() { + return new AddQuery(); + } +} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/Query.java b/src/main/java/com/anqit/spanqit/core/query/Query.java similarity index 71% rename from src/main/java/com/anqit/spanqit/core/Query.java rename to src/main/java/com/anqit/spanqit/core/query/Query.java index a4048a7..1cc2ce7 100644 --- a/src/main/java/com/anqit/spanqit/core/Query.java +++ b/src/main/java/com/anqit/spanqit/core/query/Query.java @@ -1,28 +1,38 @@ -package com.anqit.spanqit.core; +package com.anqit.spanqit.core.query; + +import static com.anqit.spanqit.core.SpanqitUtils.appendAndNewlineIfPresent; +import static com.anqit.spanqit.core.SpanqitUtils.getOrCreateAndModifyOptional; + +import java.util.Optional; import com.anqit.spanqit.constraint.Expression; +import com.anqit.spanqit.core.GroupBy; +import com.anqit.spanqit.core.Groupable; +import com.anqit.spanqit.core.Having; +import com.anqit.spanqit.core.OrderBy; +import com.anqit.spanqit.core.Orderable; +import com.anqit.spanqit.core.QueryElement; +import com.anqit.spanqit.core.QueryPattern; +import com.anqit.spanqit.core.Spanqit; +import com.anqit.spanqit.core.Variable; import com.anqit.spanqit.graphpattern.GraphPattern; -import static com.anqit.spanqit.core.SpanqitStringUtils.appendAndNewlineIfNonNull; - /** * The base class for all SPARQL Queries. Contains elements and methods common * to all queries. * - * @author Ankit - * * @param * They type of query. Used to support fluency. */ -@SuppressWarnings("unchecked") // really wish i didn't have to do this +@SuppressWarnings("unchecked") public abstract class Query> implements QueryElement { protected static final String LIMIT = "LIMIT"; protected static final String OFFSET = "OFFSET"; protected QueryPattern where = Spanqit.where(); - protected GroupBy groupBy; - protected OrderBy orderBy; - protected Having having; + protected Optional groupBy = Optional.empty(); + protected Optional orderBy = Optional.empty(); + protected Optional having = Optional.empty(); protected int limit = -1, offset = -1, varCount = -1; /** @@ -64,10 +74,7 @@ public T where(QueryPattern where) { * @see GroupBy */ public T groupBy(Groupable... groupables) { - if (groupBy == null) { - groupBy = Spanqit.groupBy(); - } - groupBy.by(groupables); + groupBy = getOrCreateAndModifyOptional(groupBy, Spanqit::groupBy, gb -> gb.by(groupables)); return (T) this; } @@ -80,7 +87,7 @@ public T groupBy(Groupable... groupables) { * @return this */ public T groupBy(GroupBy groupBy) { - this.groupBy = groupBy; + this.groupBy = Optional.of(groupBy); return (T) this; } @@ -95,11 +102,8 @@ public T groupBy(GroupBy groupBy) { * @see OrderBy */ public T orderBy(Orderable... conditions) { - if (orderBy == null) { - orderBy = Spanqit.orderBy(); - } - orderBy.by(conditions); - + orderBy = getOrCreateAndModifyOptional(orderBy, Spanqit::orderBy, ob -> ob.by(conditions)); + return (T) this; } @@ -111,7 +115,7 @@ public T orderBy(Orderable... conditions) { * @return this */ public T orderBy(OrderBy orderBy) { - this.orderBy = orderBy; + this.orderBy = Optional.of(orderBy); return (T) this; } @@ -126,10 +130,7 @@ public T orderBy(OrderBy orderBy) { * @see Having */ public T having(Expression... constraints) { - if (having == null) { - having = Spanqit.having(); - } - having.having(constraints); + having = getOrCreateAndModifyOptional(having, Spanqit::having, h -> h.having(constraints)); return (T) this; } @@ -142,7 +143,7 @@ public T having(Expression... constraints) { * @return this */ public T having(Having having) { - this.having = having; + this.having = Optional.of(having); return (T) this; } @@ -198,9 +199,9 @@ public String getQueryString() { query.append(getQueryActionString()).append("\n"); query.append(where.getQueryString()).append("\n"); - appendAndNewlineIfNonNull(groupBy, query); - appendAndNewlineIfNonNull(having, query); - appendAndNewlineIfNonNull(orderBy, query); + appendAndNewlineIfPresent(groupBy, query); + appendAndNewlineIfPresent(having, query); + appendAndNewlineIfPresent(orderBy, query); if (limit >= 0) { query.append(LIMIT + " ").append(limit).append("\n"); @@ -211,5 +212,5 @@ public String getQueryString() { } return query.toString(); - } + } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/SelectQuery.java b/src/main/java/com/anqit/spanqit/core/query/SelectQuery.java similarity index 87% rename from src/main/java/com/anqit/spanqit/core/SelectQuery.java rename to src/main/java/com/anqit/spanqit/core/query/SelectQuery.java index 6c05d1b..80e9f2d 100644 --- a/src/main/java/com/anqit/spanqit/core/SelectQuery.java +++ b/src/main/java/com/anqit/spanqit/core/query/SelectQuery.java @@ -1,16 +1,21 @@ -package com.anqit.spanqit.core; +package com.anqit.spanqit.core.query; + +import com.anqit.spanqit.core.Projectable; +import com.anqit.spanqit.core.Projection; +import com.anqit.spanqit.core.Spanqit; /** * A SPARQL Select query * - * @author Ankit - * * @see * SPARQL Select Query */ public class SelectQuery extends OuterQuery { private Projection select = Spanqit.select(); + // package-protect instantiation of this class + SelectQuery() { } + /** * Specify the query's projection to be distinct * @@ -58,7 +63,8 @@ public SelectQuery all() { *

* NOTE: if called with true, this setting will take precedence * over any expressions added to the projection via - * {@link #select(Projectable...)} or {@link #select(Projection)} when printing + * {@link #select(Projectable...)} or {@link #select(Projection)} when + * converting to string via {@link #getQueryString()} * * @param selectAll * if all in-scope expressions should be selected @@ -77,8 +83,7 @@ public SelectQuery all(boolean selectAll) { *

* NOTE: if SELECT * has been specified (by {@link #all()} or calling * {@link #all(boolean)} with true), that will take precedence - * over specified expressions when converting to string via - * {@link #getQueryString()} + * over specified expressions when converting to string via {@link #getQueryString()} * * @param projectables * expressions to add diff --git a/src/main/java/com/anqit/spanqit/core/query/TargetedGraphManagementQuery.java b/src/main/java/com/anqit/spanqit/core/query/TargetedGraphManagementQuery.java new file mode 100644 index 0000000..8fb635b --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/TargetedGraphManagementQuery.java @@ -0,0 +1,81 @@ +package com.anqit.spanqit.core.query; + +import java.util.Optional; + +import com.anqit.spanqit.rdf.Iri; + +@SuppressWarnings("javadoc") +public abstract class TargetedGraphManagementQuery> extends GraphManagementQuery> { + private static final String GRAPH = "GRAPH"; + private static final String DEFAULT = "DEFAULT"; + private static final String NAMED = "NAMED"; + private static final String ALL = "ALL"; + + private String target = DEFAULT; + private Optional graph = Optional.empty(); + + /** + * Specify which graph to target + * + * @param graph the IRI identifying the graph to target + * + * @return this query instance + */ + @SuppressWarnings("unchecked") + public T graph(Iri graph) { + this.graph = Optional.ofNullable(graph); + + return (T) this; + } + + /** + * Target the default graph + * + * @return this query instance + */ + public T def() { + return target(DEFAULT); + } + + /** + * Target all named graphs + * + * @return this query instance + */ + public T named() { + return target(NAMED); + } + + /** + * Target all graphs + * + * @return this query instance + */ + public T all() { + return target(ALL); + } + + @SuppressWarnings("unchecked") + private T target(String target) { + this.target = target; + graph = Optional.empty(); + + return (T) this; + } + + protected abstract String getQueryActionString(); + + @Override + public String getQueryString() { + StringBuilder query = new StringBuilder(); + + query.append(getQueryActionString()).append(" "); + + appendSilent(query); + + String targetString = graph.map(iri -> GRAPH + " " + iri.getQueryString()).orElse(target); + query.append(targetString); + + return query.toString(); + } +} diff --git a/src/main/java/com/anqit/spanqit/core/query/UpdateDataQuery.java b/src/main/java/com/anqit/spanqit/core/query/UpdateDataQuery.java new file mode 100644 index 0000000..692969d --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/UpdateDataQuery.java @@ -0,0 +1,44 @@ +package com.anqit.spanqit.core.query; + +import java.util.Optional; + +import com.anqit.spanqit.core.Spanqit; +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.GraphName; +import com.anqit.spanqit.graphpattern.TriplePattern; + +@SuppressWarnings("unchecked") +abstract class UpdateDataQuery> extends UpdateQuery { + protected TriplesTemplate triplesTemplate = Spanqit.triplesTemplate(); + protected Optional graphName = Optional.empty(); + + protected T addTriples(TriplePattern... triples) { + triplesTemplate.and(triples); + + return (T) this; + } + + protected T setTriplesTemplate(TriplesTemplate triplesTemplate) { + this.triplesTemplate = triplesTemplate; + + return (T) this; + } + + public T graph(GraphName graph) { + graphName = Optional.ofNullable(graph); + + return (T) this; + } + + protected abstract String getPrefix(); + + @Override + protected String getQueryActionString() { + StringBuilder updateDataQuery = new StringBuilder(); + + updateDataQuery.append(getPrefix()).append(" "); + appendNamedTriplesTemplates(updateDataQuery, graphName, triplesTemplate); + + return updateDataQuery.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/core/query/UpdateQuery.java b/src/main/java/com/anqit/spanqit/core/query/UpdateQuery.java new file mode 100644 index 0000000..2ebc2c0 --- /dev/null +++ b/src/main/java/com/anqit/spanqit/core/query/UpdateQuery.java @@ -0,0 +1,104 @@ +package com.anqit.spanqit.core.query; + +import static com.anqit.spanqit.core.SpanqitUtils.getOrCreateAndModifyOptional; + +import java.util.Optional; + +import com.anqit.spanqit.core.Base; +import com.anqit.spanqit.core.Prefix; +import com.anqit.spanqit.core.PrefixDeclarations; +import com.anqit.spanqit.core.QueryElement; +import com.anqit.spanqit.core.Spanqit; +import com.anqit.spanqit.core.SpanqitUtils; +import com.anqit.spanqit.core.TriplesTemplate; +import com.anqit.spanqit.graphpattern.GraphName; +import com.anqit.spanqit.rdf.Iri; + +/** + * A SPARQL Update query + * + * @param The type of update query. Used to support fluency. + * + * @see + * SPARQL Update Query + */ +@SuppressWarnings("unchecked") +abstract class UpdateQuery> implements QueryElement { + private Optional base = Optional.empty(); + private Optional prefixes = Optional.empty(); + + UpdateQuery() { } + + /** + * Set the base IRI of this query + * + * @param iri + * the base IRI + * @return this + */ + public T base(Iri iri) { + this.base = Optional.of(Spanqit.base(iri)); + + return (T) this; + } + + /** + * Set the Base clause of this query + * + * @param base + * the {@link Base} clause to set + * @return this + */ + public T base(Base base) { + this.base = Optional.of(base); + + return (T) this; + } + + /** + * Add prefix declarations to this query + * + * @param prefixes + * the prefixes to add + * @return this + */ + public T prefix(Prefix... prefixes) { + this.prefixes = getOrCreateAndModifyOptional(this.prefixes, Spanqit::prefixes, p -> p.addPrefix(prefixes)); + + return (T) this; + } + + /** + * Set the Prefix declarations of this query + * + * @param prefixes + * the {@link PrefixDeclarations} to set + * @return this + */ + public T prefix(PrefixDeclarations prefixes) { + this.prefixes = Optional.of(prefixes); + + return (T) this; + } + + protected abstract String getQueryActionString(); + + @Override + public String getQueryString() { + StringBuilder query = new StringBuilder(); + + SpanqitUtils.appendAndNewlineIfPresent(base, query); + SpanqitUtils.appendAndNewlineIfPresent(prefixes, query); + + query.append(getQueryActionString()); + + return query.toString(); + } + + protected void appendNamedTriplesTemplates(StringBuilder queryString, Optional graphName, TriplesTemplate triples) { + queryString.append(graphName.map(graph -> + SpanqitUtils.getBracedString("GRAPH " + graph.getQueryString() + " " + triples.getQueryString())) + .orElseGet(() ->triples.getQueryString())); + } +} diff --git a/src/main/java/com/anqit/spanqit/graphpattern/AlternativeGraphPattern.java b/src/main/java/com/anqit/spanqit/graphpattern/AlternativeGraphPattern.java index e935371..c7253ea 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/AlternativeGraphPattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/AlternativeGraphPattern.java @@ -5,8 +5,6 @@ /** * A SPARQL Alternative Graph Pattern. * - * @author Ankit - * * @see * SPARQL Alternative Graph Patterns diff --git a/src/main/java/com/anqit/spanqit/graphpattern/BNodeTriplePattern.java b/src/main/java/com/anqit/spanqit/graphpattern/BNodeTriplePattern.java index 09f2f4d..90a9855 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/BNodeTriplePattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/BNodeTriplePattern.java @@ -1,8 +1,7 @@ package com.anqit.spanqit.graphpattern; import com.anqit.spanqit.rdf.RdfBlankNode.PropertiesBlankNode; -import com.anqit.spanqit.rdf.RdfObject; -import com.anqit.spanqit.rdf.RdfPredicate; +import com.anqit.spanqit.rdf.RdfPredicateObjectList; /** * A triple pattern formed by a property-list blank node @@ -10,7 +9,7 @@ * @see * blank node syntax */ -class BNodeTriplePattern implements TriplePattern { +class BNodeTriplePattern implements TriplePattern { private PropertiesBlankNode bnode; BNodeTriplePattern(PropertiesBlankNode subject) { @@ -18,17 +17,12 @@ class BNodeTriplePattern implements TriplePattern { } @Override - public BNodeTriplePattern andHas(RdfPredicate predicate, RdfObject... objects) { - bnode.andHas(predicate, objects); + public BNodeTriplePattern andHas(RdfPredicateObjectList... lists) { + bnode.andHas(lists); return this; } - @Override - public boolean isEmpty() { - return false; - } - @Override public String getQueryString() { return bnode.getQueryString() + SUFFIX; diff --git a/src/main/java/com/anqit/spanqit/graphpattern/Filter.java b/src/main/java/com/anqit/spanqit/graphpattern/Filter.java index 38518e4..434e506 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/Filter.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/Filter.java @@ -1,20 +1,20 @@ package com.anqit.spanqit.graphpattern; +import java.util.Optional; + import com.anqit.spanqit.constraint.Expression; import com.anqit.spanqit.core.QueryElement; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; /** * A SPARQL Filter Clause * - * @author Ankit - * * @see SPARQL * Filter */ class Filter implements QueryElement { private static final String FILTER = "FILTER"; - private Expression constraint; + private Optional> constraint = Optional.empty(); Filter() { this(null); @@ -32,7 +32,7 @@ class Filter implements QueryElement { * @return this */ public Filter filter(Expression expression) { - constraint = expression; + constraint = Optional.ofNullable(expression); return this; } @@ -42,11 +42,8 @@ public String getQueryString() { StringBuilder filter = new StringBuilder(); filter.append(FILTER).append(" "); - String exp = ""; - if (constraint != null) { - exp = constraint.getQueryString(); - } - filter.append(SpanqitStringUtils.getParenthesizedString(exp)); + String exp = constraint.map(QueryElement::getQueryString).orElse(""); + filter.append(SpanqitUtils.getParenthesizedString(exp)); return filter.toString(); } diff --git a/src/main/java/com/anqit/spanqit/graphpattern/FilterExistsGraphPattern.java b/src/main/java/com/anqit/spanqit/graphpattern/FilterExistsGraphPattern.java index d023281..0a1fbfc 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/FilterExistsGraphPattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/FilterExistsGraphPattern.java @@ -3,8 +3,6 @@ /** * A SPARQL Graph Pattern Filter * - * @author Ankit - * * @see * Filtering using Graph Pattern diff --git a/src/main/java/com/anqit/spanqit/graphpattern/GraphName.java b/src/main/java/com/anqit/spanqit/graphpattern/GraphName.java index 7f4e7e1..96ce802 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/GraphName.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/GraphName.java @@ -5,8 +5,6 @@ /** * Denotes a query element that can be used as a Graph Name * - * @author Ankit - * * @see Specifying Datasets diff --git a/src/main/java/com/anqit/spanqit/graphpattern/GraphPattern.java b/src/main/java/com/anqit/spanqit/graphpattern/GraphPattern.java index 3a98b0e..1ffe1ab 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/GraphPattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/GraphPattern.java @@ -15,5 +15,5 @@ public interface GraphPattern extends QueryElement { * Alternative patterns), returns if the collection contains any * patterns */ - public boolean isEmpty(); + default public boolean isEmpty() { return true; } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/graphpattern/GraphPatternNotTriple.java b/src/main/java/com/anqit/spanqit/graphpattern/GraphPatternNotTriple.java index cf49e9b..574ac59 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/GraphPatternNotTriple.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/GraphPatternNotTriple.java @@ -1,25 +1,26 @@ package com.anqit.spanqit.graphpattern; +import java.util.Arrays; +import java.util.function.Consumer; + import com.anqit.spanqit.constraint.Expression; /** * A SPARQL Graph Pattern that is not a triple pattern. * - * @author Ankit - * * @see * SPARQL Graph Patterns */ public class GraphPatternNotTriple implements GraphPattern { - protected GraphPattern pattern; + private GraphPattern pattern; GraphPatternNotTriple() { this(new GroupGraphPattern()); } GraphPatternNotTriple(GraphPattern other) { - this.pattern = getPattern(other); + this.pattern = extractPattern(other); } /** @@ -47,10 +48,7 @@ public class GraphPatternNotTriple implements GraphPattern { public GraphPatternNotTriple and(GraphPattern... patterns) { if (patterns != null && patterns.length > 0) { GroupGraphPattern groupPattern = new GroupGraphPattern(pattern); - - for (GraphPattern p : patterns) { - groupPattern.and(getPattern(p)); - } + extractAndAddPatterns(groupPattern::and, patterns); pattern = groupPattern; } @@ -81,12 +79,8 @@ public GraphPatternNotTriple and(GraphPattern... patterns) { * Alternative Graph Pattern */ public GraphPatternNotTriple union(GraphPattern... patterns) { - AlternativeGraphPattern alternativePattern = new AlternativeGraphPattern( - pattern); - - for (GraphPattern p : patterns) { - alternativePattern.union(getPattern(p)); - } + AlternativeGraphPattern alternativePattern = new AlternativeGraphPattern(pattern); + extractAndAddPatterns(alternativePattern::union, patterns); pattern = alternativePattern; @@ -232,11 +226,8 @@ public GraphPatternNotTriple filterNotExists(GraphPattern... patterns) { */ public GraphPatternNotTriple minus(GraphPattern... patterns) { MinusGraphPattern minus = new MinusGraphPattern(); - - for (GraphPattern p : patterns) { - minus.and(getPattern(p)); - } - + extractAndAddPatterns(minus::and, patterns); + pattern = new GroupGraphPattern(pattern).and(minus); return this; @@ -258,7 +249,7 @@ public GraphPatternNotTriple minus(GraphPattern... patterns) { * Specifying Datasets in SPARQL Queries */ public GraphPatternNotTriple from(GraphName name) { - pattern = new NamedGraphPattern(pattern, name); + pattern = new GroupGraphPattern(pattern).from(name); return this; } @@ -269,17 +260,17 @@ public boolean isEmpty() { } private void filterExists(boolean exists, GraphPattern... patterns) { - FilterExistsGraphPattern filterExists = new FilterExistsGraphPattern() - .exists(exists); - - for (GraphPattern p : patterns) { - filterExists.and(getPattern(p)); - } + FilterExistsGraphPattern filterExists = new FilterExistsGraphPattern().exists(exists); + extractAndAddPatterns(filterExists::and, patterns); pattern = new GroupGraphPattern(pattern).and(filterExists); } - private GraphPattern getPattern(GraphPattern pattern) { + private void extractAndAddPatterns(Consumer action, GraphPattern... patterns) { + Arrays.stream(patterns).map(this::extractPattern).forEach(action); + } + + private GraphPattern extractPattern(GraphPattern pattern) { if (pattern instanceof GraphPatternNotTriple) { return ((GraphPatternNotTriple) pattern).pattern; } else { @@ -289,10 +280,6 @@ private GraphPattern getPattern(GraphPattern pattern) { @Override public String getQueryString() { - if (pattern == null) { - pattern = new GroupGraphPattern(); - } - return pattern.getQueryString(); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/graphpattern/GraphPatterns.java b/src/main/java/com/anqit/spanqit/graphpattern/GraphPatterns.java index c24fd5d..92db0c6 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/GraphPatterns.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/GraphPatterns.java @@ -4,6 +4,7 @@ import com.anqit.spanqit.rdf.RdfBlankNode.PropertiesBlankNode; import com.anqit.spanqit.rdf.RdfObject; import com.anqit.spanqit.rdf.RdfPredicate; +import com.anqit.spanqit.rdf.RdfPredicateObjectList; import com.anqit.spanqit.rdf.RdfSubject; /** @@ -24,7 +25,7 @@ private GraphPatterns() { } * @param predicate * @param objects * - * @return a new triple pattern + * @return a new {@link TriplePattern} * * @see @@ -34,6 +35,21 @@ public static TriplePattern tp(RdfSubject subject, RdfPredicate predicate, RdfOb return new TriplesSameSubject(subject, predicate, objects); } + /** + * Create a triple pattern with the given subject and predicate-object list(s) + * + * @param subject + * @param lists + * + * @return a new {@link TriplePattern} + * + * @see + * Triple pattern syntax + */ + public static TriplePattern tp(RdfSubject subject, RdfPredicateObjectList... lists) { + return new TriplesSameSubject(subject, lists); + } /** * Create a triple pattern from a property-list blank node * @param bnode the PropertiesBlankNode instance to convert to a triple pattern diff --git a/src/main/java/com/anqit/spanqit/graphpattern/GroupGraphPattern.java b/src/main/java/com/anqit/spanqit/graphpattern/GroupGraphPattern.java index 9086072..66a9d97 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/GroupGraphPattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/GroupGraphPattern.java @@ -1,14 +1,16 @@ package com.anqit.spanqit.graphpattern; +import java.util.Optional; + import com.anqit.spanqit.constraint.Expression; import com.anqit.spanqit.core.QueryElementCollection; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; + +import static com.anqit.spanqit.core.SpanqitUtils.appendQueryElementIfPresent; /** * A SPARQL Group Graph Pattern * - * @author Ankit - * * @see * SPARQL Group Graph Patterns @@ -16,8 +18,11 @@ class GroupGraphPattern extends QueryElementCollection implements GraphPattern { private static final String OPTIONAL = "OPTIONAL"; - private static final String DELIMITER = " . "; - private Filter filter; +// private static final String DELIMITER = " . "; + private static final String GRAPH = "GRAPH "; + + private Optional from = Optional.empty(); + private Optional filter = Optional.empty(); protected boolean isOptional = false; GroupGraphPattern() { @@ -25,12 +30,12 @@ class GroupGraphPattern extends QueryElementCollection implements } GroupGraphPattern(boolean isOptional) { - super(DELIMITER); +// super(DELIMITER); this.isOptional = isOptional; } GroupGraphPattern(GraphPattern original) { - super(DELIMITER); +// super(DELIMITER); if (original instanceof GroupGraphPattern) { copy((GroupGraphPattern) original); @@ -42,6 +47,7 @@ class GroupGraphPattern extends QueryElementCollection implements protected void copy(GroupGraphPattern original) { this.elements = original.elements; this.isOptional = original.isOptional; + this.from = original.from; this.filter = original.filter; } @@ -58,12 +64,18 @@ GroupGraphPattern optional(boolean isOptional) { return this; } + + GroupGraphPattern from(GraphName name) { + from = Optional.of(name); + + return this; + } GroupGraphPattern filter(Expression constraint) { - if (filter == null) { - filter = new Filter(); + if (!filter.isPresent()) { + filter = Optional.of(new Filter()); } - filter.filter(constraint); + filter.get().filter(constraint); return this; } @@ -85,17 +97,17 @@ public String getQueryString() { boolean bracketize = !(elements.size() == 1 && elements.toArray()[0] instanceof GroupGraphPattern); if (isOptional) { - pattern.append(OPTIONAL + " "); + pattern.append(OPTIONAL).append(" "); } + appendQueryElementIfPresent(from, pattern, GRAPH, " "); + innerPattern.append(super.getQueryString()); - if (filter != null) { - innerPattern.append("\n").append(filter.getQueryString()); - } + appendQueryElementIfPresent(filter, innerPattern, "\n", null); if (bracketize) { - pattern.append(SpanqitStringUtils.getBracedString(innerPattern + pattern.append(SpanqitUtils.getBracedString(innerPattern .toString())); } else { pattern.append(innerPattern.toString()); diff --git a/src/main/java/com/anqit/spanqit/graphpattern/NamedGraphPattern.java b/src/main/java/com/anqit/spanqit/graphpattern/NamedGraphPattern.java deleted file mode 100644 index cfe20c6..0000000 --- a/src/main/java/com/anqit/spanqit/graphpattern/NamedGraphPattern.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.anqit.spanqit.graphpattern; - -/** - * A named graph pattern. - * - * @author Ankit - * - * @see - * Specifying Datasets in SPARQL Queries - */ -class NamedGraphPattern extends GroupGraphPattern { - private static final String GRAPH = "GRAPH"; - private GraphName name; - - NamedGraphPattern(GraphPattern original, GraphName name) { - super(original); - this.name = name; - } - - @Override - protected void copy(GroupGraphPattern original) { - super.copy(original); - if(original instanceof NamedGraphPattern) { - this.name = ((NamedGraphPattern) original).name; - } - } - - @Override - public String getQueryString() { - StringBuilder namedGraphPattern = new StringBuilder(); - namedGraphPattern.append(GRAPH).append(" ") - .append(name.getQueryString()).append(" ") - .append(super.getQueryString()); - - return namedGraphPattern.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/graphpattern/SubSelect.java b/src/main/java/com/anqit/spanqit/graphpattern/SubSelect.java index 79f6c9e..90ca915 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/SubSelect.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/SubSelect.java @@ -2,9 +2,9 @@ import com.anqit.spanqit.core.Projectable; import com.anqit.spanqit.core.Projection; -import com.anqit.spanqit.core.Query; import com.anqit.spanqit.core.Spanqit; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; +import com.anqit.spanqit.core.query.Query; /** * A SPARQL subquery @@ -138,6 +138,6 @@ public String getQueryString() { // TODO: VALUES // subselect.append(values.getQueryString()); - return SpanqitStringUtils.getBracedString(subSelect.toString()); + return SpanqitUtils.getBracedString(subSelect.toString()); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/graphpattern/TriplePattern.java b/src/main/java/com/anqit/spanqit/graphpattern/TriplePattern.java index b85a33d..27a9c2e 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/TriplePattern.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/TriplePattern.java @@ -1,12 +1,14 @@ package com.anqit.spanqit.graphpattern; +import static com.anqit.spanqit.rdf.Rdf.toRdfLiteralArray; + +import com.anqit.spanqit.rdf.Rdf; import com.anqit.spanqit.rdf.RdfObject; import com.anqit.spanqit.rdf.RdfPredicate; +import com.anqit.spanqit.rdf.RdfPredicateObjectList; /** * Denotes a SPARQL Triple Pattern - * - * @param the type of triple pattern; used to support fluency * * @see @@ -14,15 +16,82 @@ * @see * blank node syntax */ -public interface TriplePattern> extends GraphPattern { +public interface TriplePattern extends GraphPattern { + @SuppressWarnings("javadoc") static String SUFFIX = " ."; /** - * add predicate-object lists describing this triple pattern's subject + * Add predicate-object lists describing this triple pattern's subject * * @param predicate the predicate to use to describe this triple pattern's subject * @param objects the corresponding object(s) + * + * @return this triple pattern + */ + default public TriplePattern andHas(RdfPredicate predicate, RdfObject... objects) { + return andHas(Rdf.predicateObjectList(predicate, objects)); + } + + /** + * Add predicate-object lists describing this triple pattern's subject + * + * @param lists + * the {@link RdfPredicateObjectList}(s) to add + * + * @return this triple pattern + */ + public TriplePattern andHas(RdfPredicateObjectList... lists); + + /** + * Convenience version of {@link #andHas(RdfPredicate, RdfObject...)} that takes Strings + * and converts them to StringLiterals + * + * @param predicate the predicate to use to describe this triple pattern's subject + * @param objects the corresponding object(s) + * + * @return this triple pattern + */ + default TriplePattern andHas(RdfPredicate predicate, String... objects) { + return andHas(predicate, toRdfLiteralArray(objects)); + }; + + /** + * Convenience version of {@link #andHas(RdfPredicate, RdfObject...)} that takes Boolean + * and converts them to BooleanLiterals + * + * @param predicate the predicate to use to describe this triple pattern's subject + * @param objects the corresponding object(s) + * + * @return this triple pattern + */ + default TriplePattern andHas(RdfPredicate predicate, Boolean... objects) { + return andHas(predicate, toRdfLiteralArray(objects)); + }; + + /** + * Convenience version of {@link #andHas(RdfPredicate, RdfObject...)} that takes Numbers + * and converts them to NumberLiterals + * + * @param predicate the predicate to use to describe this triple pattern's subject + * @param objects the corresponding object(s) + * * @return this triple pattern */ - public T andHas(RdfPredicate predicate, RdfObject... objects); + default TriplePattern andHas(RdfPredicate predicate, Number... objects) { + return andHas(predicate, toRdfLiteralArray(objects)); + }; + + /** + * Use the built-in RDF shortcut {@code a} for {@code rdf:type} to specify the subject's type + * + * @param object the object describing this triple pattern's subject's {@code rdf:type} + * + * @return this triple pattern + * + * @see + * RDF Type abbreviation + */ + default TriplePattern andIsA(RdfObject object) { + return andHas(RdfPredicate.a, object); + } } diff --git a/src/main/java/com/anqit/spanqit/graphpattern/TriplesSameSubject.java b/src/main/java/com/anqit/spanqit/graphpattern/TriplesSameSubject.java index 6eca59e..0007ad1 100644 --- a/src/main/java/com/anqit/spanqit/graphpattern/TriplesSameSubject.java +++ b/src/main/java/com/anqit/spanqit/graphpattern/TriplesSameSubject.java @@ -3,6 +3,7 @@ import com.anqit.spanqit.rdf.Rdf; import com.anqit.spanqit.rdf.RdfObject; import com.anqit.spanqit.rdf.RdfPredicate; +import com.anqit.spanqit.rdf.RdfPredicateObjectList; import com.anqit.spanqit.rdf.RdfPredicateObjectListCollection; import com.anqit.spanqit.rdf.RdfSubject; @@ -13,7 +14,7 @@ * href="http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#QSynTriples"> * Triple pattern syntax */ -class TriplesSameSubject implements TriplePattern { +class TriplesSameSubject implements TriplePattern { private RdfSubject subject; private RdfPredicateObjectListCollection predicateObjectLists = Rdf.predicateObjectListCollection(); @@ -22,30 +23,16 @@ class TriplesSameSubject implements TriplePattern { andHas(predicate, objects); } - /** - * Using the predicate-object and object list mechanisms, expand this triple pattern to include - * triples consisting of this subject, and the given predicate and object(s) - * - * @param predicate the predicate of the triple to add - * @param objects the object or objects of the triple to add - * - * @return this triple pattern - * - * @see - * Predicate-Object Lists - * @see - * Object Lists - */ - @Override - public TriplesSameSubject andHas(RdfPredicate predicate, RdfObject... objects) { - predicateObjectLists.andHas(predicate, objects); - - return this; + TriplesSameSubject(RdfSubject subject, RdfPredicateObjectList... lists) { + this.subject = subject; + andHas(lists); } @Override - public boolean isEmpty() { - return false; + public TriplesSameSubject andHas(RdfPredicateObjectList... lists) { + predicateObjectLists.andHas(lists); + + return this; } @Override diff --git a/src/main/java/com/anqit/spanqit/rdf/Iri.java b/src/main/java/com/anqit/spanqit/rdf/Iri.java index 5ff9d74..0adf4cd 100644 --- a/src/main/java/com/anqit/spanqit/rdf/Iri.java +++ b/src/main/java/com/anqit/spanqit/rdf/Iri.java @@ -5,8 +5,6 @@ /** * Denotes an RDF IRI * - * @author Ankit - * * @see * RDF IRIs diff --git a/src/main/java/com/anqit/spanqit/rdf/Rdf.java b/src/main/java/com/anqit/spanqit/rdf/Rdf.java index 285b02f..c93346f 100644 --- a/src/main/java/com/anqit/spanqit/rdf/Rdf.java +++ b/src/main/java/com/anqit/spanqit/rdf/Rdf.java @@ -1,13 +1,202 @@ package com.anqit.spanqit.rdf; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.anqit.spanqit.rdf.RdfBlankNode.AnonymousBlankNode; +import com.anqit.spanqit.rdf.RdfBlankNode.LabeledBlankNode; +import com.anqit.spanqit.rdf.RdfBlankNode.PropertiesBlankNode; +import com.anqit.spanqit.rdf.RdfLiteral.BooleanLiteral; +import com.anqit.spanqit.rdf.RdfLiteral.NumericLiteral; +import com.anqit.spanqit.rdf.RdfLiteral.StringLiteral; + /** * A class with static methods to create basic RDF objects */ public class Rdf { + // not sure if other protocols are generally used in RDF iri's? + private static final Set IRI_PROTOCOLS = Stream.of("http://", "https://", "mailto:").collect(Collectors.toSet()); private Rdf() { } + + /** + * Create a Spanqit Iri instance from a String iri + * + * @param iriString the String representing the iri + * @return the {@link Iri} instance + */ + public static Iri iri(String iriString) { + return () -> IRI_PROTOCOLS.stream().anyMatch(iriString.toLowerCase()::startsWith) ? + "<" + iriString + ">" : iriString; + } + + /** + * Create a Spanqit Iri instance from a namespace and local name + * @param namespace + * the namespace of the Iri + * @param localName + * the local name of the Iri + * @return a {@link Iri} instance + */ + public static Iri iri(String namespace, String localName) { + return iri(namespace + localName); + } + + /** + * creates a labeled blank node + * + * @param label the label of the blank node + * + * @return a new {@link LabeledBlankNode} instance + */ + public static LabeledBlankNode bNode(String label) { + return new LabeledBlankNode(label); + } + + /** + * creates a label-less blank node, identified by the supplied predicate-object lists + * + * @param predicate the predicate of the initial predicate-object list to populate this blank node with + * @param objects the objects of the initial predicate-object list to populate this blank node with + * + * @return a new {@link PropertiesBlankNode} instance + * + * @see + * Blank node syntax + */ + public static PropertiesBlankNode bNode(RdfPredicate predicate, RdfObject... objects) { + return new PropertiesBlankNode(predicate, objects); + } + + /** + * create an empty anonymous blank node + * @return an empty {@link AnonymousBlankNode} instance + */ + public static AnonymousBlankNode bNode() { + return new AnonymousBlankNode(); + } + + /** + * create an RDF string literal + * + * @param stringValue the String instance to create a literal from + * @return a StringLiteral instance representing the given String + */ + public static StringLiteral literalOf(String stringValue) { + return new StringLiteral(stringValue); + } + + /** + * create a literal with a datatype + * + * @param stringValue the literal string + * @param dataType the datatype tag + * + * @return a StringLiteral instance representing the given String and datatype + */ + public static StringLiteral literalOfType(String stringValue, Iri dataType) { + return new StringLiteral(stringValue, dataType); + } + + /** + * create a literal with a language tag + * + * @param stringValue the literal string + * @param language the language tag + * + * @return a StringLiteral instance representing the given String and language + */ + public static StringLiteral literalOfLanguage(String stringValue, String language) { + return new StringLiteral(stringValue, language); + } + + /** + * create an RDF numeric literal + * + * @param numberValue the Number instance to create a literal from + * @return a NumberLiteral instance representing the given Number + */ + public static NumericLiteral literalOf(Number numberValue) { + return new NumericLiteral(numberValue); + } + + /** + * create an RDF boolean literal + * + * @param boolValue the boolean to create a literal from + * @return a BooleanLiteral instance representing the given boolean + */ + public static BooleanLiteral literalOf(Boolean boolValue) { + return new BooleanLiteral(boolValue); + } + + /** + * Create a {@link RdfPredicateObjectList} + * + * @param predicate the {@link RdfPredicate} of the predicate-object list + * @param objects the {@link RdfObject}(s) of the list + * + * @return a new {@link RdfPredicateObjectList} + */ + public static RdfPredicateObjectList predicateObjectList(RdfPredicate predicate, RdfObject... objects) { + return new RdfPredicateObjectList(predicate, objects); + } + + /** + * Create a {@link RdfPredicateObjectListCollection} with an initial {@link RdfPredicateObjectList} + * + * @param predicate the {@link RdfPredicate} of the initial {@link RdfPredicateObjectList} + * @param objects the {@link RdfObject}(s) of the initial {@link RdfPredicateObjectList} + * + * @return a new {@link RdfPredicateObjectListCollection} + */ + public static RdfPredicateObjectListCollection predicateObjectListCollection(RdfPredicate predicate, RdfObject... objects) { + return new RdfPredicateObjectListCollection().andHas(predicate, objects); + } + + /** + * Create a {@link RdfPredicateObjectListCollection} with the given {@link RdfPredicateObjectList}(s) + * + * @param predicateObjectLists the {@link RdfPredicateObjectList}(s) to add to the collection + * + * @return a new {@link RdfPredicateObjectListCollection} + */ + public static RdfPredicateObjectListCollection predicateObjectListCollection(RdfPredicateObjectList... predicateObjectLists) { + return new RdfPredicateObjectListCollection().andHas(predicateObjectLists); + } + + /** + * Convert an array of {@link String}s to an array of {@link StringLiteral}s + * + * @param literals the {@link String}s to convert + * + * @return an array of the corresponding {@link StringLiteral}s + */ + public static StringLiteral[] toRdfLiteralArray(String... literals) { + return Arrays.stream(literals).map(Rdf::literalOf).toArray(StringLiteral[]::new); + } + + /** + * Convert an array of {@link Boolean}s to an array of {@link BooleanLiteral}s + * + * @param literals the {@link Boolean}s to convert + * + * @return an array of the corresponding {@link BooleanLiteral}s + */ + public static BooleanLiteral[] toRdfLiteralArray(Boolean... literals) { + return Arrays.stream(literals).map(Rdf::literalOf).toArray(BooleanLiteral[]::new); + } - public static RdfPredicateObjectListCollection predicateObjectListCollection() { - return new RdfPredicateObjectListCollection(); + /** + * Convert an array of {@link Number}s to an array of {@link NumericLiteral}s + * + * @param literals the {@link Number}s to convert + * + * @return an array of the corresponding {@link NumericLiteral}s + */ + public static NumericLiteral[] toRdfLiteralArray(Number... literals) { + return Arrays.stream(literals).map(Rdf::literalOf).toArray(NumericLiteral[]::new); } } diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfBlankNode.java b/src/main/java/com/anqit/spanqit/rdf/RdfBlankNode.java index 07c3ece..e7caf9e 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfBlankNode.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfBlankNode.java @@ -1,54 +1,20 @@ package com.anqit.spanqit.rdf; -import com.anqit.spanqit.core.SpanqitStringUtils; +import com.anqit.spanqit.core.SpanqitUtils; import com.anqit.spanqit.graphpattern.GraphPatterns; import com.anqit.spanqit.graphpattern.TriplePattern; /** * Denotes an RDF Blank Node */ -public interface RdfBlankNode extends RdfResource { - /** - * creates a labeled blank node - * - * @param label the label of the blank node - * - * @return a new {@link LabeledBlankNode} instance - */ - public static LabeledBlankNode bNode(String label) { - return new LabeledBlankNode(label); - } - - /** - * creates a label-less blank node, identified by the supplied predicate-object lists - * - * @param predicate the predicate of the initial predicate-object list to populate this blank node with - * @param objects the objects of the initial predicate-object list to populate this blank node with - * - * @return a new {@link AnonymousBlankNode} instance - * - * @see - * Blank node syntax - */ - public static PropertiesBlankNode bNode(RdfPredicate predicate, RdfObject... objects) { - return new PropertiesBlankNode(predicate, objects); - } - - /** - * create an empty anonymous blank node - * @return an empty {@link AnonymousBlankNode} instance - */ - public static AnonymousBlankNode bNode() { - return new AnonymousBlankNode(); - } - +public interface RdfBlankNode extends RdfResource { /** * a labeled blank node, of the form "_:label" */ public static class LabeledBlankNode implements RdfBlankNode { private String label; - private LabeledBlankNode(String label) { + LabeledBlankNode(String label) { this.label = label; } @@ -59,33 +25,33 @@ public String getQueryString() { } /** - * an anonymous blank node, identifying a resource matching all of the containing predicate-object lists + * an anonymous blank node * @see * Blank node syntax */ public static class AnonymousBlankNode implements RdfBlankNode { @Override public String getQueryString() { - return SpanqitStringUtils.getBracketedString(" "); + return SpanqitUtils.getBracketedString(" "); } } /** - * A blank node representing a resource that matches a set of predicate-object lists + * A blank node representing a resource that matches the contained set of predicate-object lists * * @see - * blank node syntax + * Blank node syntax */ public static class PropertiesBlankNode implements RdfBlankNode { private RdfPredicateObjectListCollection predicateObjectLists = Rdf.predicateObjectListCollection(); - private PropertiesBlankNode(RdfPredicate predicate, RdfObject... objects) { + PropertiesBlankNode(RdfPredicate predicate, RdfObject... objects) { andHas(predicate, objects); } /** - * Using the predicate-object and object list mechanisms, expand this triple pattern to include - * triples consisting of this subject, and the given predicate and object(s) + * Using the predicate-object and object list mechanisms, expand this blank node's pattern to include + * triples consisting of this blank node as the subject, and the given predicate and object(s) * * @param predicate the predicate of the triple to add * @param objects the object or objects of the triple to add @@ -103,6 +69,23 @@ public PropertiesBlankNode andHas(RdfPredicate predicate, RdfObject... objects) return this; } + /** + * Add predicate-object lists to this blank node's pattern + * + * @param lists + * the {@link RdfPredicateObjectList}(s) to add + * @return this blank node + * + * @see + * Predicate-Object Lists + * @see + * Object Lists + */ + public PropertiesBlankNode andHas(RdfPredicateObjectList... lists) { + predicateObjectLists.andHas(lists); + + return this; + } /** * convert this blank node to a triple pattern * @@ -117,7 +100,7 @@ public TriplePattern toTp() { @Override public String getQueryString() { - return SpanqitStringUtils.getBracketedString(predicateObjectLists.getQueryString()); + return SpanqitUtils.getBracketedString(predicateObjectLists.getQueryString()); } } } diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfLiteral.java b/src/main/java/com/anqit/spanqit/rdf/RdfLiteral.java index fac2178..1bd6ee6 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfLiteral.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfLiteral.java @@ -1,6 +1,11 @@ package com.anqit.spanqit.rdf; -import com.anqit.spanqit.core.SpanqitStringUtils; +import java.util.Optional; + +import com.anqit.spanqit.core.SpanqitUtils; + +import static com.anqit.spanqit.core.SpanqitUtils.appendQueryElementIfPresent; +import static com.anqit.spanqit.core.SpanqitUtils.appendStringIfPresent; /** * Denotes an RDF literal @@ -17,7 +22,7 @@ public abstract class RdfLiteral implements RdfValue { protected T value; - protected RdfLiteral(T value) { + private RdfLiteral(T value) { this.value = value; } @@ -54,58 +59,60 @@ public int hashCode() { } /** - * create an RDF string literal - * - * @param stringValue the String instance to create a literal from - * @return a StringLiteral instance representing the given String - */ - public static StringLiteral of(String stringValue) { - return new StringLiteral(stringValue); - } - - /** - * create an RDF numeric literal - * - * @param numberValue the Number instance to create a literal from - * @return a NumberLiteral instance representing the given Number + * Represents an RDF string literal */ - public static NumericLiteral of(Number numberValue) { - return new NumericLiteral(numberValue); - } - - /** - * create am RDF boolean literal - * - * @param boolValue the boolean to create a literal from - * @return a BooleanLiteral instance representing the given boolean - */ - public static BooleanLiteral of(Boolean boolValue) { - return new BooleanLiteral(boolValue); - } - public static class StringLiteral extends RdfLiteral { - private StringLiteral(String stringValue) { + private static final String DATATYPE_SPECIFIER = "^^"; + private static final String LANG_TAG_SPECIFIER = "@"; + + private Optional dataType = Optional.empty(); + private Optional languageTag = Optional.empty(); + + StringLiteral(String stringValue) { + super(stringValue); + } + + StringLiteral(String stringValue, Iri dataType) { super(stringValue); + this.dataType = Optional.ofNullable(dataType); } + StringLiteral(String stringValue, String languageTag) { + super(stringValue); + this.languageTag = Optional.ofNullable(languageTag); + } + @Override public String getQueryString() { + StringBuilder literal = new StringBuilder(); + if(value.contains("'") || value.contains("\"")) { - return SpanqitStringUtils.getLongQuotedString(value); + literal.append(SpanqitUtils.getLongQuotedString(value)); } else { - return SpanqitStringUtils.getQuotedString(value); + literal.append(SpanqitUtils.getQuotedString(value)); } + + appendQueryElementIfPresent(dataType, literal, DATATYPE_SPECIFIER, null); + appendStringIfPresent(languageTag, literal, LANG_TAG_SPECIFIER, null); + + return literal.toString(); } } + /** + * Represents an RDF number literal + */ public static class NumericLiteral extends RdfLiteral { - private NumericLiteral(Number numbervalue) { + NumericLiteral(Number numbervalue) { super(numbervalue); } } + /** + * Represents an RDF boolean literal + */ public static class BooleanLiteral extends RdfLiteral { - private BooleanLiteral(Boolean boolValue) { + BooleanLiteral(Boolean boolValue) { super(boolValue); } } diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfPredicate.java b/src/main/java/com/anqit/spanqit/rdf/RdfPredicate.java index 92d576c..e8f526f 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfPredicate.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfPredicate.java @@ -13,5 +13,5 @@ public interface RdfPredicate extends QueryElement { * @see * RDF Type abbreviation */ - public static RdfPredicate isA = () -> "a"; + public static RdfPredicate a = () -> "a"; } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectList.java b/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectList.java index 8a53c68..880688e 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectList.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectList.java @@ -4,7 +4,13 @@ import com.anqit.spanqit.core.QueryElementCollection; -class RdfPredicateObjectList extends QueryElementCollection { +/** + * A Predicate-Object List + * + * @see + * SPARQL Predicate-Object List + */ +public class RdfPredicateObjectList extends QueryElementCollection { private RdfPredicate predicate; RdfPredicateObjectList(RdfPredicate predicate, RdfObject... objects) { @@ -13,6 +19,13 @@ class RdfPredicateObjectList extends QueryElementCollection { and(objects); } + /** + * Add {@link RdfObject} instances to this predicate-object list + * + * @param objects the objects to add to this list + * + * @return this {@link RdfPredicateObjectList} instance + */ public RdfPredicateObjectList and(RdfObject... objects) { Collections.addAll(elements, objects); diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectListCollection.java b/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectListCollection.java index 9fd11d5..8c7c34c 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectListCollection.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfPredicateObjectListCollection.java @@ -1,5 +1,7 @@ package com.anqit.spanqit.rdf; +import java.util.Collections; + import com.anqit.spanqit.core.QueryElementCollection; /** @@ -11,13 +13,8 @@ * Object Lists */ public class RdfPredicateObjectListCollection extends QueryElementCollection { - private static String DELIMITER = " ;\n "; + private static final String DELIMITER = " ;\n "; - RdfPredicateObjectListCollection(RdfPredicate predicate, RdfObject... objects) { - this(); - andHas(predicate, objects); - } - RdfPredicateObjectListCollection() { super(DELIMITER); }; @@ -31,8 +28,20 @@ public class RdfPredicateObjectListCollection extends QueryElementCollection 1; here or in triplessamesubject } diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfSubject.java b/src/main/java/com/anqit/spanqit/rdf/RdfSubject.java index f9a500e..6779100 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfSubject.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfSubject.java @@ -1,5 +1,7 @@ package com.anqit.spanqit.rdf; +import static com.anqit.spanqit.rdf.Rdf.toRdfLiteralArray; + import com.anqit.spanqit.core.QueryElement; import com.anqit.spanqit.graphpattern.GraphPatterns; import com.anqit.spanqit.graphpattern.TriplePattern; @@ -17,8 +19,7 @@ public interface RdfSubject extends QueryElement { * the predicate of the triple pattern * @param objects * the object(s) of the triple pattern - * @return a new triple pattern with this subject, and the given predicate - * and object(s) + * @return a new {@link TriplePattern} with this subject, and the given predicate and object(s) * * @see @@ -28,6 +29,55 @@ default public TriplePattern has(RdfPredicate predicate, RdfObject... objects) { return GraphPatterns.tp(this, predicate, objects); } + /** + * Create a triple pattern from this subject and the given predicate-object list(s) + * @param lists + * the {@link RdfPredicateObjectList}(s) to describing this subject + * @return a new {@link TriplePattern} with this subject, and the given predicate-object list(s) + */ + default public TriplePattern has(RdfPredicateObjectList... lists) { + return GraphPatterns.tp(this, lists); + } + + /** + * Wrapper for {@link #has(RdfPredicate, RdfObject...)} that converts String objects into RdfLiteral instances + * + * @param predicate + * the predicate of the triple pattern + * @param objects + * the String object(s) of the triple pattern + * @return a new {@link TriplePattern} with this subject, and the given predicate and object(s) + */ + default public TriplePattern has(RdfPredicate predicate, String... objects) { + return GraphPatterns.tp(this, predicate, toRdfLiteralArray(objects)); + } + + /** + * Wrapper for {@link #has(RdfPredicate, RdfObject...)} that converts Number objects into RdfLiteral instances + * + * @param predicate + * the predicate of the triple pattern + * @param objects + * the Number object(s) of the triple pattern + * @return a new {@link TriplePattern} with this subject, and the given predicate and object(s) + */ + default public TriplePattern has(RdfPredicate predicate, Number... objects) { + return GraphPatterns.tp(this, predicate, toRdfLiteralArray(objects)); + } + + /** + * Wrapper for {@link #has(RdfPredicate, RdfObject...)} that converts Boolean objects into RdfLiteral instances + * + * @param predicate + * the predicate of the triple pattern + * @param objects + * the Boolean object(s) of the triple pattern + * @return a new {@link TriplePattern} with this subject, and the given predicate and object(s) + */ + default public TriplePattern has(RdfPredicate predicate, Boolean... objects) { + return GraphPatterns.tp(this, predicate, toRdfLiteralArray(objects)); + } + /** * Use the built-in shortcut "a" for rdf:type to build a triple with this subject and the given objects * @param objects the objects to use to describe the rdf:type of this subject @@ -38,6 +88,6 @@ default public TriplePattern has(RdfPredicate predicate, RdfObject... objects) { * RDF Type abbreviation */ default public TriplePattern isA(RdfObject... objects) { - return has(RdfPredicate.isA, objects); + return has(RdfPredicate.a, objects); } } \ No newline at end of file diff --git a/src/main/java/com/anqit/spanqit/rdf/RdfValue.java b/src/main/java/com/anqit/spanqit/rdf/RdfValue.java index 7c6990a..202f1ae 100644 --- a/src/main/java/com/anqit/spanqit/rdf/RdfValue.java +++ b/src/main/java/com/anqit/spanqit/rdf/RdfValue.java @@ -1,8 +1,8 @@ package com.anqit.spanqit.rdf; -import com.anqit.spanqit.constraint.ExpressionOperand; +import com.anqit.spanqit.constraint.Operand; /** * Denotes an RDF Value. */ -public interface RdfValue extends RdfObject, ExpressionOperand { } \ No newline at end of file +public interface RdfValue extends RdfObject, Operand { } \ No newline at end of file