diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangEngine.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangEngine.java
index bf698fda349..25a2d3903e2 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangEngine.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangEngine.java
@@ -20,9 +20,9 @@
import static org.apache.jena.riot.tokens.TokenType.EOF ;
import static org.apache.jena.riot.tokens.TokenType.NODE ;
+
import org.apache.jena.atlas.AtlasException ;
import org.apache.jena.atlas.iterator.PeekIterator ;
-import org.apache.jena.graph.Node ;
import org.apache.jena.riot.RiotParseException ;
import org.apache.jena.riot.system.ErrorHandler ;
import org.apache.jena.riot.system.ParserProfile ;
@@ -117,11 +117,11 @@ protected final Token nextToken()
}
}
- protected final Node scopedBNode(Node scopeNode, String label)
- {
- return profile.getLabelToNode().get(scopeNode, label) ;
- }
-
+// protected final Node scopedBNode(Node scopeNode, String label)
+// {
+// return profile.getLabelToNode().get(scopeNode, label) ;
+// }
+//
protected final void expectOrEOF(String msg, TokenType tokenType)
{
// DOT or EOF
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDF.java b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDF.java
new file mode 100644
index 00000000000..d2ba8f8848b
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDF.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import org.apache.jena.datatypes.RDFDatatype ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+
+/**
+ * Create core RDF objects: {@link Node}s, {@link Triple}s, {@link Quad}s,
+ * {@link Graph}, {@link DatasetGraph}s.
+ *
+ */
+public interface FactoryRDF {
+ // ?? Are these too varied?
+ public Graph createGraph() ;
+ // ?? Are these too varied?
+ public DatasetGraph createDatasetGraph() ;
+ public Triple createTriple(Node subject, Node predicate, Node object) ;
+ public Quad createQuad(Node graph, Node subject, Node predicate, Node object) ;
+ public Node createURI(String uriStr) ;
+ public Node createTypedLiteral(String lexical, RDFDatatype datatype) ;
+ public Node createLangLiteral(String lexical, String langTag) ;
+ public Node createStringLiteral(String lexical) ;
+ /** Create a blank node */
+ public Node createBlankNode() ;
+ /** Create a blank node with the given string as internal system id */
+ public Node createBlankNode(String label) ;
+ /** Create a blank with the internal system id taken from 128 bit number provided.
+ */
+ public Node createBlankNode(long mostSigBits, long leastSigBits) ;
+
+// // Object for scope better?
+// public Node createBlankNode(Node scope, String label) ;
+// // Object for scope better?
+// public Node createBlankNode(Node scope) ;
+}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFCaching.java b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFCaching.java
new file mode 100644
index 00000000000..03982b63fc2
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFCaching.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import java.util.concurrent.ExecutionException ;
+
+import org.apache.jena.ext.com.google.common.cache.Cache ;
+import org.apache.jena.atlas.lib.cache.CacheInfo ;
+import org.apache.jena.datatypes.RDFDatatype ;
+import org.apache.jena.datatypes.xsd.XSDDatatype ;
+import org.apache.jena.ext.com.google.common.cache.CacheBuilder ;
+import org.apache.jena.ext.com.google.common.cache.CacheStats ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.lang.LabelToNode ;
+import org.apache.jena.sparql.graph.NodeConst ;
+
+/** Adds some caching of created nodes - the caching is tuned to RIOT parser usage */
+public class FactoryRDFCaching extends FactoryRDFStd {
+ public static final int DftNodeCacheSize = 5000 ;
+
+ // Control the setup - for one thread; start size = 50% of full size, no stats
+ private final Cache cache ;
+
+ public FactoryRDFCaching() {
+ this(DftNodeCacheSize) ;
+ }
+
+ public FactoryRDFCaching(int cacheSize) {
+ super() ;
+ cache = setCache(cacheSize) ;
+ }
+
+ private Cache setCache(int cacheSize) {
+ return CacheBuilder.newBuilder()
+ .maximumSize(cacheSize)
+ .initialCapacity(cacheSize/2)
+ //.recordStats()
+ .concurrencyLevel(1)
+ .build() ;
+ }
+
+ public FactoryRDFCaching(int cacheSize, LabelToNode labelMapping) {
+ super(labelMapping) ;
+ cache = setCache(cacheSize) ;
+ }
+
+ @Override
+ public Node createURI(String uriStr) {
+ try {
+ return cache.get(uriStr, ()->RiotLib.createIRIorBNode(uriStr)) ;
+ }
+ catch (ExecutionException e) {
+ throw new RiotException("Execution exception filling cache <"+uriStr+">", e) ;
+ }
+ }
+
+ // A few constants
+
+ @Override
+ public Node createTypedLiteral(String lexical, RDFDatatype datatype) {
+ if ( XSDDatatype.XSDinteger.equals(datatype) ) {
+ switch(lexical) {
+ case "0" : return NodeConst.nodeZero ;
+ case "1" : return NodeConst.nodeOne ;
+ case "2" : return NodeConst.nodeTwo ;
+ case "-1" : return NodeConst.nodeMinusOne ;
+ }
+ // fallthrough.
+ } else if ( XSDDatatype.XSDboolean.equals(datatype) ) {
+ switch(lexical) {
+ case "true" : return NodeConst.nodeTrue ;
+ case "false" : return NodeConst.nodeFalse ;
+ }
+ // fallthrough.
+ }
+ return super.createTypedLiteral(lexical, datatype) ;
+ }
+
+ @Override
+ public Node createStringLiteral(String lexical) {
+ if ( lexical.isEmpty() )
+ return NodeConst.emptyString ;
+ return super.createStringLiteral(lexical) ;
+ }
+
+ public CacheInfo stats() {
+ CacheStats stats = cache.stats() ;
+ if ( stats.missCount() == 0 && stats.hitCount() == 0 )
+ // Stats not enabled - all counts zero.
+ return null ;
+ return new CacheInfo(DftNodeCacheSize, stats) ;
+ }
+}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
new file mode 100644
index 00000000000..4d0ca873e19
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import org.apache.jena.datatypes.RDFDatatype ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.NodeFactory ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.lang.LabelToNode ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.DatasetGraphFactory ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.graph.GraphFactory ;
+
+public class FactoryRDFStd implements FactoryRDF {
+ // Needs reset?
+ private final LabelToNode labelMapping ;
+
+ public FactoryRDFStd() {
+ this(SyntaxLabels.createLabelToNode()) ;
+ }
+
+ public FactoryRDFStd(LabelToNode labelMapping) {
+ this.labelMapping = labelMapping ;
+ }
+
+ @Override
+ public Graph createGraph() {
+ return GraphFactory.createDefaultGraph() ;
+ }
+
+ @Override
+ public DatasetGraph createDatasetGraph() {
+ return DatasetGraphFactory.create(); // createTxnMem() ;
+ }
+
+ @Override
+ public Triple createTriple(Node subject, Node predicate, Node object) {
+ return Triple.create(subject, predicate, object);
+ }
+
+ @Override
+ public Quad createQuad(Node graph, Node subject, Node predicate, Node object) {
+ return Quad.create(graph, subject, predicate, object) ;
+ }
+
+ @Override
+ public Node createURI(String uriStr) {
+ return RiotLib.createIRIorBNode(uriStr) ;
+ //return NodeFactory.createURI(uriStr) ;
+ }
+
+ @Override
+ public Node createTypedLiteral(String lexical, RDFDatatype datatype) {
+ return NodeFactory.createLiteral(lexical, datatype) ;
+ }
+
+ @Override
+ public Node createLangLiteral(String lexical, String langTag) {
+ return NodeFactory.createLiteral(lexical, langTag) ;
+ }
+
+ @Override
+ public Node createStringLiteral(String lexical) {
+ return NodeFactory.createLiteral(lexical) ;
+ }
+
+ @Override
+ public Node createBlankNode(long mostSigBits, long leastSigBits) {
+ // XXX Style: Do this fast. Guava? Apache commons? Special case for char[32]
+ // (Eventually, blank node Nodes will have two longs normally.)
+ return createBlankNode(String.format("%08X%08X", mostSigBits, leastSigBits)) ;
+ }
+
+ // Fixed scope.
+ private static Node scope = NodeFactory.createURI("urn:jena:global_scope") ;
+ // Scope
+ @Override
+ public Node createBlankNode(String label) {
+ //return NodeFactory.createBlankNode(label) ;
+ return labelMapping.get(scope, label) ;
+ }
+
+ // Scope
+ @Override
+ public Node createBlankNode() {
+ //return NodeFactory.createBlankNode() ;
+ return labelMapping.create() ;
+ }
+
+}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfile.java b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfile.java
index 670f691571f..6969991cd2b 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfile.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfile.java
@@ -18,12 +18,10 @@
package org.apache.jena.riot.system;
-
import org.apache.jena.datatypes.RDFDatatype ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.iri.IRI ;
-import org.apache.jena.riot.lang.LabelToNode ;
import org.apache.jena.riot.tokens.Token ;
import org.apache.jena.sparql.core.Quad ;
@@ -55,21 +53,23 @@ public interface ParserProfile
/** Create a fresh blank node */
public Node createBlankNode(Node scope, long line, long col) ;
- /** Make a node from a token - called after all else has been tried - return null for no such node */
+ /** Make a node from a token - called after all else has been tried to handle special cases
+ * Return null for "no special node recoginzed"
+ */
public Node createNodeFromToken(Node scope, Token token, long line, long col) ;
/** Make any node from a token as appropriate */
public Node create(Node currentGraph, Token token) ;
-
- public LabelToNode getLabelToNode() ;
- public void setLabelToNode(LabelToNode labelToNode) ;
-
+
public ErrorHandler getHandler() ;
public void setHandler(ErrorHandler handler) ;
public Prologue getPrologue() ;
public void setPrologue(Prologue prologue) ;
+ public FactoryRDF getFactoryRDF() ;
+ public void setFactoryRDF(FactoryRDF factory) ;
+
public boolean isStrictMode() ;
public void setStrictMode(boolean mode) ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileBase.java b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileBase.java
index 3299c46a293..e743cdc9c02 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileBase.java
@@ -18,6 +18,8 @@
package org.apache.jena.riot.system ;
+import java.util.Objects ;
+
import org.apache.jena.datatypes.RDFDatatype ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.graph.Node ;
@@ -26,7 +28,6 @@
import org.apache.jena.iri.IRI ;
import org.apache.jena.riot.RiotException ;
import org.apache.jena.riot.SysRIOT ;
-import org.apache.jena.riot.lang.LabelToNode ;
import org.apache.jena.riot.tokens.Token ;
import org.apache.jena.riot.tokens.TokenType ;
import org.apache.jena.sparql.core.Quad ;
@@ -38,17 +39,20 @@
public class ParserProfileBase implements ParserProfile {
protected ErrorHandler errorHandler ;
protected Prologue prologue ;
- protected LabelToNode labelMapping ;
protected boolean strictMode = SysRIOT.isStrictMode() ;
+ protected FactoryRDF factory ;
public ParserProfileBase(Prologue prologue, ErrorHandler errorHandler) {
- this(prologue, errorHandler, SyntaxLabels.createLabelToNode()) ;
+ this(prologue, errorHandler, RiotLib.factoryRDF()) ;
}
- public ParserProfileBase(Prologue prologue, ErrorHandler errorHandler, LabelToNode labelMapping) {
+ public ParserProfileBase(Prologue prologue, ErrorHandler errorHandler, FactoryRDF factory) {
+ Objects.requireNonNull(prologue) ;
+ Objects.requireNonNull(errorHandler) ;
+ Objects.requireNonNull(factory) ;
this.prologue = prologue ;
this.errorHandler = errorHandler ;
- this.labelMapping = labelMapping ;
+ this.factory = factory ;
}
@Override
@@ -72,15 +76,15 @@ public void setPrologue(Prologue p) {
}
@Override
- public LabelToNode getLabelToNode() {
- return labelMapping ;
+ public FactoryRDF getFactoryRDF() {
+ return factory;
}
@Override
- public void setLabelToNode(LabelToNode mapper) {
- labelMapping = mapper ;
+ public void setFactoryRDF(FactoryRDF factory) {
+ this.factory = factory;
}
-
+
@Override
public String resolveIRI(String uriStr, long line, long col) {
return prologue.getResolver().resolveToString(uriStr) ;
@@ -93,44 +97,44 @@ public IRI makeIRI(String uriStr, long line, long col) {
@Override
public Quad createQuad(Node g, Node s, Node p, Node o, long line, long col) {
- return new Quad(g, s, p, o) ;
+ return factory.createQuad(g, s, p, o);
}
@Override
public Triple createTriple(Node s, Node p, Node o, long line, long col) {
- return new Triple(s, p, o) ;
+ return factory.createTriple(s, p, o);
}
@Override
public Node createURI(String uriStr, long line, long col) {
- return RiotLib.createIRIorBNode(uriStr) ;
+ return factory.createURI(uriStr);
}
@Override
public Node createBlankNode(Node scope, String label, long line, long col) {
- return labelMapping.get(scope, label) ;
+ return factory.createBlankNode(label);
}
@Override
public Node createBlankNode(Node scope, long line, long col) {
- return labelMapping.create() ;
+ return factory.createBlankNode();
}
@Override
public Node createTypedLiteral(String lexical, RDFDatatype dt, long line, long col) {
- return NodeFactory.createLiteral(lexical, dt) ;
+ return factory.createTypedLiteral(lexical, dt);
}
@Override
public Node createLangLiteral(String lexical, String langTag, long line, long col) {
- return NodeFactory.createLiteral(lexical, langTag) ;
+ return factory.createLangLiteral(lexical, langTag);
}
@Override
public Node createStringLiteral(String lexical, long line, long col) {
- return NodeFactory.createLiteral(lexical) ;
+ return factory.createStringLiteral(lexical);
}
-
+
/** Special token forms */
@Override
public Node createNodeFromToken(Node scope, Token token, long line, long col) {
@@ -144,27 +148,31 @@ public Node createNodeFromToken(Node scope, Token token, long line, long col) {
@Override
public Node create(Node currentGraph, Token token) {
- // Dispatches to the underlying operation
+ return create(this, currentGraph, token) ;
+ }
+
+ private static Node create(ParserProfile pp, Node currentGraph, Token token) {
+ // Dispatches to the underlying ParserProfile operation
long line = token.getLine() ;
long col = token.getColumn() ;
String str = token.getImage() ;
switch (token.getType()) {
case BNODE :
- return createBlankNode(currentGraph, str, line, col) ;
+ return pp.createBlankNode(currentGraph, str, line, col) ;
case IRI :
- return createURI(str, line, col) ;
+ return pp.createURI(str, line, col) ;
case PREFIXED_NAME : {
String prefix = str ;
String suffix = token.getImage2() ;
- String expansion = expandPrefixedName(prefix, suffix, token) ;
- return createURI(expansion, line, col) ;
+ String expansion = expandPrefixedName(pp, prefix, suffix, token) ;
+ return pp.createURI(expansion, line, col) ;
}
case DECIMAL :
- return createTypedLiteral(str, XSDDatatype.XSDdecimal, line, col) ;
+ return pp.createTypedLiteral(str, XSDDatatype.XSDdecimal, line, col) ;
case DOUBLE :
- return createTypedLiteral(str, XSDDatatype.XSDdouble, line, col) ;
+ return pp.createTypedLiteral(str, XSDDatatype.XSDdouble, line, col) ;
case INTEGER :
- return createTypedLiteral(str, XSDDatatype.XSDinteger, line, col) ;
+ return pp.createTypedLiteral(str, XSDDatatype.XSDinteger, line, col) ;
case LITERAL_DT : {
Token tokenDT = token.getSubToken2() ;
String uriStr ;
@@ -176,41 +184,41 @@ public Node create(Node currentGraph, Token token) {
case PREFIXED_NAME : {
String prefix = tokenDT.getImage() ;
String suffix = tokenDT.getImage2() ;
- uriStr = expandPrefixedName(prefix, suffix, tokenDT) ;
+ uriStr = expandPrefixedName(pp, prefix, suffix, tokenDT) ;
break ;
}
default :
throw new RiotException("Expected IRI for datatype: " + token) ;
}
- uriStr = resolveIRI(uriStr, tokenDT.getLine(), tokenDT.getColumn()) ;
+ uriStr = pp.resolveIRI(uriStr, tokenDT.getLine(), tokenDT.getColumn()) ;
RDFDatatype dt = NodeFactory.getType(uriStr) ;
- return createTypedLiteral(str, dt, line, col) ;
+ return pp.createTypedLiteral(str, dt, line, col) ;
}
case LITERAL_LANG :
- return createLangLiteral(str, token.getImage2(), line, col) ;
+ return pp.createLangLiteral(str, token.getImage2(), line, col) ;
case STRING :
case STRING1 :
case STRING2 :
case LONG_STRING1 :
case LONG_STRING2 :
- return createStringLiteral(str, line, col) ;
+ return pp.createStringLiteral(str, line, col) ;
default : {
- Node x = createNodeFromToken(currentGraph, token, line, col) ;
+ Node x = pp.createNodeFromToken(currentGraph, token, line, col) ;
if (x != null)
return x ;
- errorHandler.fatal("Not a valid token for an RDF term: " + token, line, col) ;
+ pp.getHandler().fatal("Not a valid token for an RDF term: " + token, line, col) ;
return null ;
}
}
}
- private String expandPrefixedName(String prefix, String localPart, Token token) {
- String expansion = prologue.getPrefixMap().expand(prefix, localPart) ;
+ private static String expandPrefixedName(ParserProfile pp, String prefix, String localPart, Token token) {
+ String expansion = pp.getPrologue().getPrefixMap().expand(prefix, localPart) ;
if (expansion == null)
- errorHandler.fatal("Undefined prefix: " + prefix, token.getLine(), token.getColumn()) ;
+ pp.getHandler().fatal("Undefined prefix: " + prefix, token.getLine(), token.getColumn()) ;
return expansion ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileChecker.java b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileChecker.java
index 30809a6b8d4..920ce558cbe 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileChecker.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/ParserProfileChecker.java
@@ -26,7 +26,6 @@
import org.apache.jena.riot.RiotException ;
import org.apache.jena.riot.checker.CheckerIRI ;
import org.apache.jena.riot.checker.CheckerLiterals ;
-import org.apache.jena.riot.lang.LabelToNode ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.util.FmtUtils ;
@@ -40,8 +39,7 @@
*
*/
-public class ParserProfileChecker extends ParserProfileBase // implements
- // ParserProfile
+public class ParserProfileChecker extends ParserProfileBase // implements ParserProfile
{
private boolean checkLiterals = true ;
@@ -49,8 +47,8 @@ public ParserProfileChecker(Prologue prologue, ErrorHandler errorHandler) {
super(prologue, errorHandler) ;
}
- public ParserProfileChecker(Prologue prologue, ErrorHandler errorHandler, LabelToNode labelMapping) {
- super(prologue, errorHandler, labelMapping) ;
+ public ParserProfileChecker(Prologue prologue, ErrorHandler errorHandler, FactoryRDF factory) {
+ super(prologue, errorHandler, factory) ;
}
@Override
@@ -105,19 +103,9 @@ private void checkQuad(Node graph, Node subject, Node predicate, Node object, lo
@Override
public Node createURI(String x, long line, long col) {
- try {
- if ( RiotLib.isBNodeIRI(x) )
- return RiotLib.createIRIorBNode(x) ;
- else {
- String resolvedIRI = resolveIRI(x, line, col) ;
- return NodeFactory.createURI(resolvedIRI) ;
- }
- }
- catch (RiotException ex) {
- // Error was handled.
- // errorHandler.error(ex.getMessage(), line, col) ;
- throw ex ;
- }
+ if ( ! RiotLib.isBNodeIRI(x) )
+ x = resolveIRI(x, line, col) ;
+ return super.createURI(x, line, col) ;
}
@Override
@@ -134,14 +122,14 @@ public Node createLangLiteral(String lexical, String langTag, long line, long co
return n ;
}
- @Override
- public Node createStringLiteral(String lexical, long line, long col) {
- return NodeFactory.createLiteral(lexical) ;
- }
-
- @Override
- public Node createBlankNode(Node scope, String label, long line, long col) {
- return labelMapping.get(scope, label) ;
- }
-
+ // No checks
+// @Override
+// public Node createStringLiteral(String lexical, long line, long col) {
+// return super.createStringLiteral(lexical, line, col) ;
+// }
+//
+// @Override
+// public Node createBlankNode(Node scope, String label, long line, long col) {
+// return super.createBlankNode(scope, label, line, col) ;
+// }
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/ProgressStreamRDF.java b/jena-arq/src/main/java/org/apache/jena/riot/system/ProgressStreamRDF.java
new file mode 100644
index 00000000000..f57d41e322a
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/ProgressStreamRDF.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import org.apache.jena.atlas.lib.ProgressMonitor ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.sparql.core.Quad ;
+
+/** Send ticks to a {@link ProgressMonitor} as triples and quads
+ * are sent along the {@link StreamRDF}.
+ */
+
+public class ProgressStreamRDF extends StreamRDFWrapper {
+
+ private final ProgressMonitor monitor ;
+
+ public ProgressStreamRDF(StreamRDF other, ProgressMonitor monitor) {
+ super(other);
+ this.monitor = monitor ;
+ }
+
+ // Better that the app call start/finish on the monitor so that a number of
+ // inputs on the stream can call start/finish. i.e the monitor can be used
+ // for a batch of oeprations.
+
+// @Override
+// public void start() {
+// monitor.start();
+// super.start();
+// }
+//
+// @Override
+// public void finish() {
+// super.finish();
+// monitor.finish();
+// }
+
+ @Override
+ public void triple(Triple triple) {
+ super.triple(triple);
+ monitor.tick();
+ }
+
+ @Override
+ public void quad(Quad quad) {
+ super.quad(quad);
+ monitor.tick();
+ }
+}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
index 0455295ece0..76ec07f1935 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
@@ -38,10 +38,7 @@
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.query.ARQ ;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFLanguages ;
-import org.apache.jena.riot.SysRIOT ;
-import org.apache.jena.riot.WriterDatasetRIOT ;
+import org.apache.jena.riot.* ;
import org.apache.jena.riot.lang.LabelToNode ;
import org.apache.jena.riot.tokens.Token ;
import org.apache.jena.riot.tokens.Tokenizer ;
@@ -82,7 +79,7 @@ public static boolean isBNodeIRI(String iri)
return skolomizedBNodes && iri.startsWith(bNodeLabelStart) ;
}
- private static ParserProfile profile = profile(RDFLanguages.TURTLE, null, null) ;
+ private static ParserProfile profile = profile(RDFLanguages.TURTLE, null, ErrorHandlerFactory.errorHandlerStd) ;
static {
PrefixMap pmap = profile.getPrologue().getPrefixMap() ;
pmap.add("rdf", ARQConstants.rdfPrefix) ;
@@ -147,9 +144,23 @@ public static ParserProfile profile(String baseIRI, boolean resolveIRIs, boolean
prologue = new Prologue(PrefixMapFactory.createForInput(), IRIResolver.createNoResolve()) ;
if ( checking )
- return new ParserProfileChecker(prologue, handler, labelToNode) ;
+ return new ParserProfileChecker(prologue, handler, factoryRDF(labelToNode)) ;
else
- return new ParserProfileBase(prologue, handler, labelToNode) ;
+ return new ParserProfileBase(prologue, handler, factoryRDF(labelToNode)) ;
+ }
+
+ /** Create a new (notinfluenced by anything else) FactoryRDF
+ * using the label to blank node scheme provided.
+ */
+ public static FactoryRDF factoryRDF(LabelToNode labelMapping) {
+ return new FactoryRDFStd(labelMapping);
+ }
+
+ /** Create a new (not influenced by anything else) FactoryRDF
+ * using the label to blank node scheme scope by this FactoryRDF.
+ */
+ public static FactoryRDF factoryRDF() {
+ return factoryRDF(SyntaxLabels.createLabelToNode());
}
/** Get triples with the same subject */
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/SerializationFactoryFinder.java b/jena-arq/src/main/java/org/apache/jena/riot/system/SerializationFactoryFinder.java
index 281defe2f93..33341225034 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/SerializationFactoryFinder.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/SerializationFactoryFinder.java
@@ -81,9 +81,11 @@ public Sink createSerializer(OutputStream out)
@Override
public Iterator createDeserializer(InputStream in)
{
- Tokenizer tokenizer = TokenizerFactory.makeTokenizerASCII(in) ;
- ParserProfileBase profile = new ParserProfileBase(new Prologue(null, IRIResolver.createNoResolve()), null, LabelToNode.createUseLabelEncoded()) ;
- LangNTriples parser = new LangNTriples(tokenizer, profile, null) ;
+ Tokenizer tokenizer = TokenizerFactory.makeTokenizerASCII(in);
+ ParserProfileBase profile = new ParserProfileBase(new Prologue(null, IRIResolver.createNoResolve()),
+ ErrorHandlerFactory.errorHandlerNoWarnings,
+ RiotLib.factoryRDF(LabelToNode.createUseLabelEncoded()));
+ LangNTriples parser = new LangNTriples(tokenizer, profile, null);
return parser ;
}
@@ -110,7 +112,9 @@ public Sink createSerializer(OutputStream out)
public Iterator createDeserializer(InputStream in)
{
Tokenizer tokenizer = TokenizerFactory.makeTokenizerASCII(in) ;
- ParserProfileBase profile = new ParserProfileBase(new Prologue(null, IRIResolver.createNoResolve()), null, LabelToNode.createUseLabelEncoded()) ;
+ ParserProfileBase profile = new ParserProfileBase(new Prologue(null, IRIResolver.createNoResolve()),
+ ErrorHandlerFactory.errorHandlerNoWarnings,
+ RiotLib.factoryRDF(LabelToNode.createUseLabelEncoded())) ;
LangNQuads parser = new LangNQuads(tokenizer, profile, null) ;
return parser ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/binding/BindingInputStream.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/binding/BindingInputStream.java
index 786f6f70316..e54c919d85a 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/binding/BindingInputStream.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/binding/BindingInputStream.java
@@ -82,8 +82,8 @@ static ParserProfile profile()
// Don't do anything with IRIs.
Prologue prologue = new Prologue(PrefixMapFactory.createForInput(), IRIResolver.createNoResolve()) ;
ErrorHandler handler = ErrorHandlerFactory.getDefaultErrorHandler() ;
- ParserProfile profile = new ParserProfileBase(prologue, handler) ;
- profile.setLabelToNode(LabelToNode.createUseLabelAsGiven()) ;
+ FactoryRDF factory = RiotLib.factoryRDF(LabelToNode.createUseLabelAsGiven()) ;
+ ParserProfile profile = new ParserProfileBase(prologue, handler, factory) ;
// Include safe bNode labels.
return profile ;
}
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java b/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
index 4229e78b3c2..7b4f08d53a0 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
@@ -30,6 +30,9 @@
@SuiteClasses({
TestChecker.class
, TestStreamRDF.class
+ , TestFactoryRDF.class
+ , TestFactoryRDFCaching.class
+
// Prefix Map implementations
, TestPrefixMap.class
, TestPrefixMapWrapper.class
@@ -37,11 +40,13 @@
, TestFastAbbreviatingPrefixMap.class
, TestPrefixMapExtended1.class
, TestPrefixMapExtended2.class
+
, TestIO_JenaReaders.class
, TestIO_JenaWriters.class
, TestLangRegistration.class
, TestFormatRegistration.class
, TestJsonLDReadWrite.class // Some simple testing of the jsonld-java engine.
+
// May be subject to performance vagaries, with the improvements made
// to the fast implementation this should be fairly safe
//, TestAbbreviationPerformance.class
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDF.java b/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDF.java
new file mode 100644
index 00000000000..75ae5f47228
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDF.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import static org.junit.Assert.assertEquals ;
+import static org.junit.Assert.assertNotEquals ;
+import static org.junit.Assert.assertNotNull ;
+import static org.junit.Assert.assertTrue ;
+
+import org.apache.jena.datatypes.xsd.XSDDatatype ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.lang.LabelToNode ;
+import org.apache.jena.riot.system.FactoryRDF ;
+import org.apache.jena.riot.system.FactoryRDFStd ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.vocabulary.RDF ;
+import org.junit.Test ;
+
+public class TestFactoryRDF {
+ protected FactoryRDF factory = new FactoryRDFStd(LabelToNode.createUseLabelAsGiven()) ;
+
+ @Test public void factoryRDF_blanknode_01() {
+ Node n1 = factory.createBlankNode() ;
+ assertTrue(n1.isBlank()) ;
+ Node n2 = factory.createBlankNode() ;
+ assertNotEquals(n1, n2);
+ }
+
+ @Test public void factoryRDF_blanknode_02() {
+ Node n1 = factory.createBlankNode("ABCDE") ;
+ assertTrue(n1.isBlank()) ;
+ Node n2 = factory.createBlankNode("ABCDE") ;
+ assertEquals(n1, n2);
+ assertEquals("ABCDE", n1.getBlankNodeLabel()) ;
+ }
+
+ @Test public void factoryRDF_blanknode_03() {
+ Node n1 = factory.createBlankNode(0x1234L, 0x5678L) ;
+ assertTrue(n1.isBlank()) ;
+ Node n2 = factory.createBlankNode(0x1234L, 0x5678L) ;
+ assertEquals(n1, n2);
+ assertEquals("0000123400005678", n1.getBlankNodeLabel()) ;
+ }
+
+ @Test public void factoryRDF_uri_02() {
+ Node n = factory.createURI("http://example/") ;
+ assertTrue(n.isURI()) ;
+ assertEquals("http://example/", n.getURI()) ;
+ }
+
+ @Test public void factoryRDF_uri_03() {
+ Node n = factory.createURI("_:abc") ; // Blank node!
+ assertTrue(n.isBlank()) ;
+ assertEquals("abc", n.getBlankNodeLabel()) ;
+ }
+
+ @Test public void factoryRDF_literal_01() {
+ Node n = factory.createStringLiteral("hello") ;
+ assertTrue(n.isLiteral()) ;
+ assertEquals("hello", n.getLiteralLexicalForm()) ;
+ assertEquals(XSDDatatype.XSDstring, n.getLiteralDatatype()) ;
+ assertEquals("", n.getLiteralLanguage()) ;
+ }
+
+ @Test public void factoryRDF_literal_02() {
+ Node n = factory.createLangLiteral("xyz", "en") ;
+ assertTrue(n.isLiteral()) ;
+ assertEquals("xyz", n.getLiteralLexicalForm()) ;
+ assertEquals(RDF.dtLangString, n.getLiteralDatatype()) ;
+ assertEquals("en", n.getLiteralLanguage()) ;
+ }
+
+ @Test public void factoryRDF_literal_03() {
+ Node n = factory.createTypedLiteral("1", XSDDatatype.XSDinteger) ;
+ assertTrue(n.isLiteral()) ;
+ assertEquals("1", n.getLiteralLexicalForm()) ;
+ assertEquals(XSDDatatype.XSDinteger, n.getLiteralDatatype()) ;
+ assertEquals("", n.getLiteralLanguage()) ;
+ }
+
+ @Test public void factoryRDF_triple_01() {
+ Node s = factory.createURI("http://test/s") ;
+ Node p = factory.createURI("http://test/p") ;
+ Node o = factory.createURI("http://test/o") ;
+ Triple triple = factory.createTriple(s, p, o) ;
+ assertEquals(s, triple.getSubject()) ;
+ assertEquals(p, triple.getPredicate()) ;
+ assertEquals(o, triple.getObject()) ;
+ }
+
+ @Test public void factoryRDF_quad_01() {
+ Node g = factory.createURI("http://test/g") ;
+ Node s = factory.createURI("http://test/s") ;
+ Node p = factory.createURI("http://test/p") ;
+ Node o = factory.createURI("http://test/o") ;
+ Quad quad = factory.createQuad(g, s, p, o) ;
+ assertEquals(g, quad.getGraph()) ;
+ assertEquals(s, quad.getSubject()) ;
+ assertEquals(p, quad.getPredicate()) ;
+ assertEquals(o, quad.getObject()) ;
+ }
+
+ @Test public void factoryRDF_graph_01() {
+ Graph graph = factory.createGraph() ;
+ assertNotNull(graph) ;
+ }
+
+ @Test public void factoryRDF_dataset_01() {
+ DatasetGraph dsg = factory.createDatasetGraph() ;
+ assertNotNull(dsg) ;
+ }
+}
+
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDFCaching.java b/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDFCaching.java
new file mode 100644
index 00000000000..b51c3913550
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/riot/system/TestFactoryRDFCaching.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.system;
+
+import static org.junit.Assert. * ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.riot.lang.LabelToNode ;
+import org.apache.jena.riot.system.FactoryRDFCaching ;
+import org.junit.Test ;
+
+public class TestFactoryRDFCaching extends TestFactoryRDF {
+
+ public TestFactoryRDFCaching() {
+ super.factory = new FactoryRDFCaching(100, LabelToNode.createUseLabelAsGiven()) ;
+ }
+
+ @Test public void factory_cache_01() {
+ Node n1 = factory.createStringLiteral("") ;
+ Node n2 = factory.createStringLiteral("") ;
+ assertSame(n1, n2);
+ }
+
+ @Test public void factory_cache_02() {
+ Node n1 = factory.createURI("http://test/n1") ;
+ Node n2 = factory.createURI("http://test/n2") ;
+ Node n3 = factory.createURI("http://test/n1") ;
+ assertSame(n1, n3);
+ }
+}
+
+
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheInfo.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheInfo.java
index 11fafc544fa..9a4fae1c4c9 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheInfo.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheInfo.java
@@ -21,42 +21,28 @@
import org.apache.jena.ext.com.google.common.cache.CacheStats ;
/** Simplified version of Guava's CacheStats (and abstractign away from Guava cache implementation) */
- public class CacheInfo {
- public final long requests;
- public final long hits;
- public final long misses;
- public final double hitRate;
- public final int cacheSize;
+public class CacheInfo {
+ public final long requests;
+ public final long hits;
+ public final long misses;
+ public final double hitRate;
+ public final int cacheSize;
- public CacheInfo(int cacheSize, CacheStats stats) {
- this(cacheSize, stats.requestCount(), stats.hitCount(), stats.missCount(), stats.hitRate() ) ;
- }
-
- public CacheInfo(int cacheSize, long requests, long hits, long misses, double hitRate) {
- this.cacheSize = cacheSize ;
- this.requests = requests ;
- this.hits = hits ;
- this.misses = misses ;
- this.hitRate = hitRate ;
- }
+ public CacheInfo(int cacheSize, CacheStats stats) {
+ this(cacheSize, stats.requestCount(), stats.hitCount(), stats.missCount(), stats.hitRate() ) ;
+ }
- @Override
- public String toString() {
- return String.format("size=%,d count=%,d hits=%,d misses=%,d rate=%.1f",
- cacheSize, requests, hits, misses, hitRate) ;
- }
-
-// private void details(String label, CacheGuava, ?> cache, int cacheSize) {
-// System.out.printf("%s [%,d]\n", label, cacheSize) ;
-// CacheStats stats = ((CacheGuava, ?>)cache).stats() ;
-//// System.out.printf(" Cache usage: %,d\n", cache.size()) ;
-// System.out.printf(" Requests: %,d\n", stats.requestCount()) ;
-// System.out.printf(" Hit rate: %.1f%%\n", 100*stats.hitRate()) ;
-//// System.out.printf(" Hits: %,d\n", stats.hitCount()) ;
-//// System.out.printf(" Misses: %,d\n", stats.missCount()) ;
-//// if ( stats.loadSuccessCount() != stats.missCount() ) {
-//// System.out.printf(" Load success: %,d\n", stats.loadSuccessCount()) ;
-//// System.out.printf(" Load ex: %,d\n", stats.loadExceptionCount()) ;
-//// }
+ public CacheInfo(int cacheSize, long requests, long hits, long misses, double hitRate) {
+ this.cacheSize = cacheSize ;
+ this.requests = requests ;
+ this.hits = hits ;
+ this.misses = misses ;
+ this.hitRate = hitRate ;
+ }
- }
\ No newline at end of file
+ @Override
+ public String toString() {
+ return String.format("size=%,d count=%,d hits=%,d misses=%,d rate=%.1f",
+ cacheSize, requests, hits, misses, hitRate) ;
+ }
+}
\ No newline at end of file
diff --git a/jena-cmds/src/main/java/riotcmd/CmdLangParse.java b/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
index 61f3b968205..080edd79664 100644
--- a/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
+++ b/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
@@ -276,8 +276,11 @@ else if ( RDFLanguages.isTriples(lang) )
} else
reader.setParserProfile(RiotLib.profile(baseURI, false, false, errHandler)) ;
- if ( labelsAsGiven )
- reader.getParserProfile().setLabelToNode(LabelToNode.createUseLabelAsGiven()) ;
+ if ( labelsAsGiven ) {
+ FactoryRDF f = RiotLib.factoryRDF(LabelToNode.createUseLabelAsGiven()) ;
+ reader.getParserProfile().setFactoryRDF(f);
+ }
+
modTime.startTimer() ;
sink.start() ;
reader.read(in, baseURI, ct, sink, null) ;
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
index b05fc4ebeb6..0da573f3732 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
@@ -19,21 +19,9 @@
import java.util.HashMap;
import java.util.Map;
-import java.util.Stack;
-
-import org.apache.jena.arq.querybuilder.clauses.ConstructClause;
-import org.apache.jena.arq.querybuilder.clauses.DatasetClause;
import org.apache.jena.arq.querybuilder.clauses.PrologClause;
-import org.apache.jena.arq.querybuilder.clauses.SelectClause;
-import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause;
-import org.apache.jena.arq.querybuilder.clauses.WhereClause;
-import org.apache.jena.arq.querybuilder.handlers.ConstructHandler;
-import org.apache.jena.arq.querybuilder.handlers.DatasetHandler;
-import org.apache.jena.arq.querybuilder.handlers.Handler;
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
import org.apache.jena.arq.querybuilder.handlers.PrologHandler;
-import org.apache.jena.arq.querybuilder.handlers.SelectHandler;
-import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler;
-import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
import org.apache.jena.graph.FrontsNode ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
@@ -58,8 +46,6 @@
public abstract class AbstractQueryBuilder>
implements Cloneable, PrologClause {
- // all queries have prologs
- protected PrologHandler prologHandler;
// the query this builder is building
protected Query query;
// a map of vars to nodes for replacement during build.
@@ -175,9 +161,20 @@ public Var makeVar(Object o) throws ARQInternalErrorException {
*/
protected AbstractQueryBuilder() {
query = new Query();
- prologHandler = new PrologHandler(query);
values = new HashMap();
}
+
+ /**
+ * Get the HandlerBlock for this query builder.
+ * @return The associated handler block.
+ */
+ public abstract HandlerBlock getHandlerBlock();
+
+ @Override
+ public final PrologHandler getPrologHandler() {
+ return getHandlerBlock().getPrologHandler();
+ }
+
/**
* Set a variable replacement. During build all instances of var in the
@@ -220,11 +217,6 @@ public void setVar(Object var, Object value) {
}
}
- @Override
- public PrologHandler getPrologHandler() {
- return prologHandler;
- }
-
@Override
public T addPrefix(String pfx, Resource uri) {
return addPrefix(pfx, uri.getURI());
@@ -238,21 +230,21 @@ public T addPrefix(String pfx, Node uri) {
@SuppressWarnings("unchecked")
@Override
public T addPrefix(String pfx, String uri) {
- prologHandler.addPrefix(pfx, uri);
+ getPrologHandler().addPrefix(pfx, uri);
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public T addPrefixes(Map prefixes) {
- prologHandler.addPrefixes(prefixes);
+ getPrologHandler().addPrefixes(prefixes);
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public T setBase(String base) {
- prologHandler.setBase(base);
+ getPrologHandler().setBase(base);
return (T) this;
}
@@ -285,6 +277,8 @@ public final String buildString() {
*/
public final Query build() {
Query q = new Query();
+
+ // set the query type
switch (query.getQueryType())
{
case Query.QueryTypeAsk:
@@ -303,51 +297,20 @@ public final Query build() {
throw new IllegalStateException( "Internal query is not a known type: "+q.getQueryType());
}
- Stack handlerStack = new Stack();
- PrologHandler ph = new PrologHandler(q);
- handlerStack.push(ph);
- ph.addAll(prologHandler);
- ph.setVars(values);
- if (this instanceof SelectClause) {
- SelectHandler sh = new SelectHandler(q);
- sh.addAll(((SelectClause>) this).getSelectHandler());
- sh.setVars(values);
- handlerStack.push(sh);
- }
- if (this instanceof ConstructClause) {
- ConstructHandler ch = new ConstructHandler(q);
- ch.addAll(((ConstructClause>) this).getConstructHandler());
- ch.setVars(values);
- handlerStack.push(ch);
- }
- if (this instanceof DatasetClause) {
- DatasetHandler dh = new DatasetHandler(q);
- dh.addAll(((DatasetClause>) this).getDatasetHandler());
- dh.setVars(values);
- handlerStack.push(dh);
- }
- if (this instanceof SolutionModifierClause) {
- SolutionModifierHandler smh = new SolutionModifierHandler(q);
- smh.addAll(((SolutionModifierClause>) this)
- .getSolutionModifierHandler());
- smh.setVars(values);
- handlerStack.push(smh);
- }
- if (this instanceof WhereClause) {
- WhereHandler wh = new WhereHandler(q);
- wh.addAll(((WhereClause>) this).getWhereHandler());
- wh.setVars(values);
- handlerStack.push(wh);
- }
-
+ // use the HandlerBlock implementation to copy the data.
+ HandlerBlock handlerBlock = new HandlerBlock(q);
+ handlerBlock.addAll( getHandlerBlock() );
+
+ // set the vars
+ handlerBlock.setVars(values);
+
// make sure we have a query pattern before we start building.
if (q.getQueryPattern() == null)
{
q.setQueryPattern( new ElementGroup() );
}
- while (!handlerStack.isEmpty()) {
- handlerStack.pop().build();
- }
+
+ handlerBlock.build();
return q;
}
@@ -365,6 +328,7 @@ public final Query build() {
public static Query clone(Query q2) {
Query retval = new Query();
+ // set the query type
if (q2.isSelectType())
{
retval.setQuerySelectType();
@@ -378,13 +342,11 @@ public static Query clone(Query q2) {
retval.setQueryConstructType();
}
- new PrologHandler(retval).addAll(new PrologHandler(q2));
- new ConstructHandler(retval).addAll(new ConstructHandler(q2));
- new DatasetHandler(retval).addAll(new DatasetHandler(q2));
- new SolutionModifierHandler(retval).addAll(new SolutionModifierHandler(
- q2));
- new WhereHandler(retval).addAll(new WhereHandler(q2));
- new SelectHandler(retval).addAll(new SelectHandler(q2));
+ // use the handler block to clone the data
+ HandlerBlock hb = new HandlerBlock( retval );
+ HandlerBlock hb2 = new HandlerBlock( q2 );
+ hb.addAll(hb2);
+
return retval;
}
@@ -398,12 +360,8 @@ public static Query clone(Query q2) {
* @return The new query with the specified vars replaced.
*/
public static Query rewrite(Query q2, Map values) {
- new PrologHandler(q2).setVars(values);
- new ConstructHandler(q2).setVars(values);
- new DatasetHandler(q2).setVars(values);
- new SolutionModifierHandler(q2).setVars(values);
- new WhereHandler(q2).setVars(values);
- new SelectHandler(q2).setVars(values);
+ HandlerBlock hb = new HandlerBlock(q2);
+ hb.setVars(values);
return q2;
}
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
index 1e2c437ac75..9ae7fa22ae4 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
@@ -23,6 +23,7 @@
import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause;
import org.apache.jena.arq.querybuilder.clauses.WhereClause;
import org.apache.jena.arq.querybuilder.handlers.DatasetHandler;
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler;
import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
import org.apache.jena.graph.FrontsTriple ;
@@ -38,12 +39,8 @@
public class AskBuilder extends AbstractQueryBuilder implements
DatasetClause, WhereClause,
SolutionModifierClause {
- // the dataset handler
- private final DatasetHandler datasetHandler;
- // the where handler.
- private final WhereHandler whereHandler;
- // the solution modifier handler.
- private final SolutionModifierHandler solutionModifier;
+
+ private final HandlerBlock handlerBlock;
/**
* The constructor
@@ -51,63 +48,65 @@ public class AskBuilder extends AbstractQueryBuilder implements
public AskBuilder() {
super();
query.setQueryAskType();
- datasetHandler = new DatasetHandler(query);
- whereHandler = new WhereHandler(query);
- solutionModifier = new SolutionModifierHandler(query);
+ handlerBlock = new HandlerBlock( query );
}
-
+
+ @Override
+ public HandlerBlock getHandlerBlock()
+ {
+ return handlerBlock;
+ }
+
@Override
public DatasetHandler getDatasetHandler() {
- return datasetHandler;
+ return handlerBlock.getDatasetHandler();
}
@Override
public WhereHandler getWhereHandler() {
- return whereHandler;
+ return handlerBlock.getWhereHandler();
}
@Override
public AskBuilder clone() {
AskBuilder qb = new AskBuilder();
- qb.prologHandler.addAll(prologHandler);
- qb.datasetHandler.addAll(datasetHandler);
- qb.solutionModifier.addAll(solutionModifier);
+ qb.handlerBlock.addAll( handlerBlock );
return qb;
}
@Override
public AskBuilder fromNamed(String graphName) {
- datasetHandler.fromNamed(graphName);
+ getDatasetHandler().fromNamed(graphName);
return this;
}
@Override
public AskBuilder fromNamed(Collection graphNames) {
- datasetHandler.fromNamed(graphNames);
+ getDatasetHandler().fromNamed(graphNames);
return this;
}
@Override
public AskBuilder from(String graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public AskBuilder from(Collection graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public AskBuilder addWhere(Triple t) {
- whereHandler.addWhere(t);
+ getWhereHandler().addWhere(t);
return this;
}
@Override
public AskBuilder addWhere(FrontsTriple t) {
- whereHandler.addWhere(t.asTriple());
+ getWhereHandler().addWhere(t.asTriple());
return this;
}
@@ -119,20 +118,20 @@ public AskBuilder addWhere(Object s, Object p, Object o) {
@Override
public AskBuilder addOptional(Triple t) {
- whereHandler.addOptional(t);
+ getWhereHandler().addOptional(t);
return this;
}
@Override
public AskBuilder addOptional(SelectBuilder t)
{
- whereHandler.addOptional(t.getWhereHandler());
+ getWhereHandler().addOptional(t.getWhereHandler());
return this;
}
@Override
public AskBuilder addOptional(FrontsTriple t) {
- whereHandler.addOptional(t.asTriple());
+ getWhereHandler().addOptional(t.asTriple());
return this;
}
@@ -144,78 +143,77 @@ public AskBuilder addOptional(Object s, Object p, Object o) {
@Override
public AskBuilder addFilter(String s) throws ParseException {
- whereHandler.addFilter(s);
+ getWhereHandler().addFilter(s);
return this;
}
@Override
public AskBuilder addSubQuery(SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.getPrologHandler());
- whereHandler.addSubQuery(subQuery);
+ getWhereHandler().addSubQuery(subQuery);
return this;
}
@Override
public AskBuilder addUnion(SelectBuilder subQuery) {
- whereHandler.addUnion(subQuery);
+ getWhereHandler().addUnion(subQuery);
return this;
}
@Override
public AskBuilder addGraph(Object graph, SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.getPrologHandler());
- whereHandler.addGraph(makeNode(graph), subQuery.getWhereHandler());
+ getPrologHandler().addAll(subQuery.getPrologHandler());
+ getWhereHandler().addGraph(makeNode(graph), subQuery.getWhereHandler());
return this;
}
@Override
public AskBuilder addBind(Expr expression, Object var) {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public AskBuilder addBind(String expression, Object var) throws ParseException {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public AskBuilder addOrderBy(String orderBy) {
- solutionModifier.addOrderBy(orderBy);
+ getSolutionModifierHandler().addOrderBy(orderBy);
return this;
}
@Override
public AskBuilder addGroupBy(String groupBy) {
- solutionModifier.addGroupBy(groupBy);
+ getSolutionModifierHandler().addGroupBy(groupBy);
return this;
}
@Override
public AskBuilder addHaving(String having) throws ParseException {
- solutionModifier.addHaving(having);
+ getSolutionModifierHandler().addHaving(having);
return this;
}
@Override
public AskBuilder setLimit(int limit) {
- solutionModifier.setLimit(limit);
+ getSolutionModifierHandler().setLimit(limit);
return this;
}
@Override
public AskBuilder setOffset(int offset) {
- solutionModifier.setOffset(offset);
+ getSolutionModifierHandler().setOffset(offset);
return this;
}
@Override
public SolutionModifierHandler getSolutionModifierHandler() {
- return solutionModifier;
+ return handlerBlock.getModifierHandler();
}
@Override
public Node list(Object... objs) {
- return whereHandler.list(objs);
+ return getWhereHandler().list(objs);
}
}
\ No newline at end of file
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
index 034fdefcd97..64324a4623c 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
@@ -25,6 +25,7 @@
import org.apache.jena.arq.querybuilder.clauses.WhereClause;
import org.apache.jena.arq.querybuilder.handlers.ConstructHandler;
import org.apache.jena.arq.querybuilder.handlers.DatasetHandler;
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler;
import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
import org.apache.jena.graph.FrontsTriple ;
@@ -43,118 +44,113 @@ public class ConstructBuilder extends AbstractQueryBuilder
SolutionModifierClause,
ConstructClause {
- // the handlers used by this builder
- private final DatasetHandler datasetHandler;
- private final WhereHandler whereHandler;
- private final SolutionModifierHandler solutionModifier;
- private final ConstructHandler constructHandler;
-
+ private final HandlerBlock handlerBlock;
+
/**
* Constructor
*/
public ConstructBuilder() {
super();
query.setQueryConstructType();
- datasetHandler = new DatasetHandler(query);
- whereHandler = new WhereHandler(query);
- solutionModifier = new SolutionModifierHandler(query);
- constructHandler = new ConstructHandler(query);
+ handlerBlock = new HandlerBlock(query);
}
@Override
public DatasetHandler getDatasetHandler() {
- return datasetHandler;
+ return handlerBlock.getDatasetHandler();
}
@Override
public WhereHandler getWhereHandler() {
- return whereHandler;
+ return handlerBlock.getWhereHandler();
}
@Override
public ConstructHandler getConstructHandler() {
- return constructHandler;
+ return handlerBlock.getConstructHandler();
}
@Override
public SolutionModifierHandler getSolutionModifierHandler() {
- return solutionModifier;
+ return handlerBlock.getModifierHandler();
}
+ @Override
+ public HandlerBlock getHandlerBlock()
+ {
+ return handlerBlock;
+ }
+
@Override
public ConstructBuilder clone() {
ConstructBuilder qb = new ConstructBuilder();
- qb.prologHandler.addAll(prologHandler);
- qb.datasetHandler.addAll(datasetHandler);
- qb.whereHandler.addAll(whereHandler);
- qb.solutionModifier.addAll(solutionModifier);
- qb.constructHandler.addAll(constructHandler);
+ qb.handlerBlock.addAll( handlerBlock );
return qb;
}
@Override
public ConstructBuilder fromNamed(String graphName) {
- datasetHandler.fromNamed(graphName);
+ getDatasetHandler().fromNamed(graphName);
return this;
}
@Override
public ConstructBuilder fromNamed(Collection graphNames) {
- datasetHandler.fromNamed(graphNames);
+ getDatasetHandler().fromNamed(graphNames);
return this;
}
@Override
public ConstructBuilder from(String graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public ConstructBuilder from(Collection graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public ConstructBuilder addOrderBy(String orderBy) {
- solutionModifier.addOrderBy(orderBy);
+ getSolutionModifierHandler().addOrderBy(orderBy);
return this;
}
@Override
public ConstructBuilder addGroupBy(String groupBy) {
- solutionModifier.addGroupBy(groupBy);
+ getSolutionModifierHandler().addGroupBy(groupBy);
return this;
}
@Override
public ConstructBuilder addHaving(String having) throws ParseException {
- solutionModifier.addHaving(having);
+ getSolutionModifierHandler().addHaving(having);
return this;
}
@Override
public ConstructBuilder setLimit(int limit) {
- solutionModifier.setLimit(limit);
+ getSolutionModifierHandler().setLimit(limit);
return this;
}
@Override
public ConstructBuilder setOffset(int offset) {
- solutionModifier.setOffset(offset);
+ getSolutionModifierHandler().setOffset(offset);
return this;
}
@Override
public ConstructBuilder addWhere(Triple t) {
- whereHandler.addWhere(t);
+ getWhereHandler().addWhere(t);
return this;
}
@Override
public ConstructBuilder addWhere(FrontsTriple t) {
- whereHandler.addWhere(t.asTriple());
+ getWhereHandler().addWhere(t.asTriple());
return this;
}
@@ -166,20 +162,20 @@ public ConstructBuilder addWhere(Object s, Object p, Object o) {
@Override
public ConstructBuilder addOptional(Triple t) {
- whereHandler.addOptional(t);
+ getWhereHandler().addOptional(t);
return this;
}
@Override
public ConstructBuilder addOptional(SelectBuilder t)
{
- whereHandler.addOptional(t.getWhereHandler());
+ getWhereHandler().addOptional(t.getWhereHandler());
return this;
}
@Override
public ConstructBuilder addOptional(FrontsTriple t) {
- whereHandler.addOptional(t.asTriple());
+ getWhereHandler().addOptional(t.asTriple());
return this;
}
@@ -191,45 +187,44 @@ public ConstructBuilder addOptional(Object s, Object p, Object o) {
@Override
public ConstructBuilder addFilter(String s) throws ParseException {
- whereHandler.addFilter(s);
+ getWhereHandler().addFilter(s);
return this;
}
@Override
public ConstructBuilder addSubQuery(SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.prologHandler);
- whereHandler.addSubQuery(subQuery);
+ getWhereHandler().addSubQuery(subQuery);
return this;
}
@Override
public ConstructBuilder addUnion(SelectBuilder subQuery) {
- whereHandler.addUnion(subQuery);
+ getWhereHandler().addUnion(subQuery);
return this;
}
@Override
public ConstructBuilder addGraph(Object graph, SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.prologHandler);
- whereHandler.addGraph(makeNode(graph), subQuery.getWhereHandler());
+ getPrologHandler().addAll(subQuery.getPrologHandler());
+ getWhereHandler().addGraph(makeNode(graph), subQuery.getWhereHandler());
return this;
}
@Override
public ConstructBuilder addBind(Expr expression, Object var) {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public ConstructBuilder addBind(String expression, Object var) throws ParseException {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public ConstructBuilder addConstruct(Triple t) {
- constructHandler.addConstruct(t);
+ getConstructHandler().addConstruct(t);
return this;
}
@@ -245,6 +240,6 @@ public ConstructBuilder addConstruct(Object s, Object p, Object o) {
@Override
public Node list(Object... objs) {
- return whereHandler.list(objs);
+ return getWhereHandler().list(objs);
}
}
\ No newline at end of file
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
index 12a909eefd1..03796e93664 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
@@ -25,6 +25,7 @@
import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause;
import org.apache.jena.arq.querybuilder.clauses.WhereClause;
import org.apache.jena.arq.querybuilder.handlers.DatasetHandler;
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
import org.apache.jena.arq.querybuilder.handlers.SelectHandler;
import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler;
import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
@@ -44,61 +45,55 @@ public class SelectBuilder extends AbstractQueryBuilder
implements DatasetClause, WhereClause,
SolutionModifierClause, SelectClause {
- // the handlers.
- private DatasetHandler datasetHandler;
- private WhereHandler whereHandler;
- private SolutionModifierHandler solutionModifier;
- private SelectHandler selectHandler;
-
+ private final HandlerBlock handlerBlock;
+
/**
* Constructor.
*/
public SelectBuilder() {
super();
query.setQuerySelectType();
- datasetHandler = new DatasetHandler(query);
- whereHandler = new WhereHandler(query);
- solutionModifier = new SolutionModifierHandler(query);
- selectHandler = new SelectHandler(query);
+ handlerBlock = new HandlerBlock( query );
}
@Override
public DatasetHandler getDatasetHandler() {
- return datasetHandler;
+ return handlerBlock.getDatasetHandler();
}
+ @Override
+ public HandlerBlock getHandlerBlock()
+ {
+ return handlerBlock;
+ }
+
@Override
public WhereHandler getWhereHandler() {
- return whereHandler;
+ return handlerBlock.getWhereHandler();
}
@Override
public SelectBuilder clone() {
SelectBuilder qb = new SelectBuilder();
- qb.prologHandler.addAll(prologHandler);
- qb.datasetHandler.addAll(datasetHandler);
- qb.whereHandler.addAll(whereHandler);
- qb.solutionModifier.addAll(solutionModifier);
- qb.selectHandler.addAll(selectHandler);
-
+ qb.handlerBlock.addAll(handlerBlock);
return qb;
}
@Override
public SelectBuilder setDistinct(boolean state) {
- selectHandler.setDistinct(state);
+ getSelectHandler().setDistinct(state);
return this;
}
@Override
public SelectBuilder setReduced(boolean state) {
- selectHandler.setReduced(state);
+ getSelectHandler().setReduced(state);
return this;
}
@Override
public SelectBuilder addVar(Object var) {
- selectHandler.addVar(makeVar(var));
+ getSelectHandler().addVar(makeVar(var));
return this;
}
@@ -109,77 +104,77 @@ public SelectBuilder addVar(Object var) {
*/
@Override
public SelectBuilder addVar(String expression, Object var) throws ParseException {
- selectHandler.addVar( expression, makeVar(var) );
+ getSelectHandler().addVar( expression, makeVar(var) );
return this;
}
@Override
public SelectBuilder addVar(Expr expr, Object var) {
- selectHandler.addVar(expr, makeVar(var));
+ getSelectHandler().addVar(expr, makeVar(var));
return this;
}
@Override
public List getVars() {
- return selectHandler.getVars();
+ return getSelectHandler().getVars();
}
@Override
public SelectBuilder fromNamed(String graphName) {
- datasetHandler.fromNamed(graphName);
+ getDatasetHandler().fromNamed(graphName);
return this;
}
@Override
public SelectBuilder fromNamed(Collection graphNames) {
- datasetHandler.fromNamed(graphNames);
+ getDatasetHandler().fromNamed(graphNames);
return this;
}
@Override
public SelectBuilder from(String graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public SelectBuilder from(Collection graphName) {
- datasetHandler.from(graphName);
+ getDatasetHandler().from(graphName);
return this;
}
@Override
public SelectBuilder addOrderBy(String orderBy) {
- solutionModifier.addOrderBy(orderBy);
+ getSolutionModifierHandler().addOrderBy(orderBy);
return this;
}
@Override
public SelectBuilder addGroupBy(String groupBy) {
- solutionModifier.addGroupBy(groupBy);
+ getSolutionModifierHandler().addGroupBy(groupBy);
return this;
}
@Override
public SolutionModifierHandler getSolutionModifierHandler() {
- return solutionModifier;
+ return handlerBlock.getModifierHandler();
}
@Override
public SelectBuilder addHaving(String having) throws ParseException {
- solutionModifier.addHaving(having);
+ getSolutionModifierHandler().addHaving(having);
return this;
}
@Override
public SelectBuilder setLimit(int limit) {
- solutionModifier.setLimit(limit);
+ getSolutionModifierHandler().setLimit(limit);
return this;
}
@Override
public SelectBuilder setOffset(int offset) {
- solutionModifier.setOffset(offset);
+ getSolutionModifierHandler().setOffset(offset);
return this;
}
@@ -231,13 +226,13 @@ public static String makeString(Object o) {
@Override
public SelectBuilder addWhere(Triple t) {
- whereHandler.addWhere(t);
+ getWhereHandler().addWhere(t);
return this;
}
@Override
public SelectBuilder addWhere(FrontsTriple t) {
- whereHandler.addWhere(t.asTriple());
+ getWhereHandler().addWhere(t.asTriple());
return this;
}
@@ -249,13 +244,13 @@ public SelectBuilder addWhere(Object s, Object p, Object o) {
@Override
public SelectBuilder addOptional(Triple t) {
- whereHandler.addOptional(t);
+ getWhereHandler().addOptional(t);
return this;
}
@Override
public SelectBuilder addOptional(FrontsTriple t) {
- whereHandler.addOptional(t.asTriple());
+ getWhereHandler().addOptional(t.asTriple());
return this;
}
@@ -268,55 +263,54 @@ public SelectBuilder addOptional(Object s, Object p, Object o) {
@Override
public SelectBuilder addOptional(SelectBuilder t)
{
- whereHandler.addOptional(t.getWhereHandler());
+ getWhereHandler().addOptional(t.getWhereHandler());
return this;
}
@Override
public SelectBuilder addFilter(String s) throws ParseException {
- whereHandler.addFilter(s);
+ getWhereHandler().addFilter(s);
return this;
}
@Override
public SelectBuilder addSubQuery(SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.prologHandler);
- whereHandler.addSubQuery(subQuery);
+ getWhereHandler().addSubQuery(subQuery);
return this;
}
@Override
public SelectBuilder addUnion(SelectBuilder subQuery) {
- whereHandler.addUnion(subQuery);
+ getWhereHandler().addUnion(subQuery);
return this;
}
@Override
public SelectBuilder addGraph(Object graph, SelectBuilder subQuery) {
- prologHandler.addAll(subQuery.prologHandler);
- whereHandler.addGraph(makeNode(graph), subQuery.whereHandler);
+ getPrologHandler().addAll(subQuery.getPrologHandler());
+ getWhereHandler().addGraph(makeNode(graph), subQuery.getWhereHandler());
return this;
}
@Override
public SelectBuilder addBind(Expr expression, Object var) {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public SelectBuilder addBind(String expression, Object var) throws ParseException {
- whereHandler.addBind( expression, makeVar(var) );
+ getWhereHandler().addBind( expression, makeVar(var) );
return this;
}
@Override
public SelectHandler getSelectHandler() {
- return selectHandler;
+ return handlerBlock.getSelectHandler();
}
@Override
public Node list(Object... objs) {
- return whereHandler.list(objs);
+ return getWhereHandler().list(objs);
}
}
\ No newline at end of file
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java
index 261db7bdc42..dc83218b2b6 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java
@@ -22,7 +22,6 @@
import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
import org.apache.jena.arq.querybuilder.handlers.SelectHandler;
import org.apache.jena.sparql.core.Var;
-import org.apache.jena.sparql.core.VarExprList;
import org.apache.jena.sparql.expr.Expr;
import org.apache.jena.sparql.lang.sparql_11.ParseException;
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/AggregationHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/AggregationHandler.java
new file mode 100644
index 00000000000..f999ca8237d
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/AggregationHandler.java
@@ -0,0 +1,110 @@
+package org.apache.jena.arq.querybuilder.handlers;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.Query;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.expr.Expr;
+import org.apache.jena.sparql.expr.ExprAggregator;
+
+/**
+ * Class to handle manipulation the aggregation variables in the query.
+ *
+ */
+public class AggregationHandler implements Handler {
+ // the query
+ private final Query query;
+
+ // a map of variables to aggregators
+ private final Map aggMap;
+
+ /**
+ * Constructor.
+ * @param query the query to handle.
+ */
+ public AggregationHandler( Query query )
+ {
+ this.query = query;
+ aggMap = new HashMap();
+ }
+
+ /**
+ * Add all the aggregations from the other handler.
+ * @param handler The other handler.
+ * @return This handler for chaining.
+ */
+ public AggregationHandler addAll(AggregationHandler handler)
+ {
+ for (ExprAggregator agg : handler.query.getAggregators())
+ {
+ query.allocAggregate(agg.getAggregator());
+ }
+ for (Map.Entry entry : handler.aggMap.entrySet())
+ {
+ aggMap.put( entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+
+ /**
+ * Get the query we are executing against.
+ * @return the query.
+ */
+ public Query getQuery()
+ {
+ return query;
+ }
+
+ @Override
+ public void setVars(Map values) {
+ // nothing to do
+
+ }
+
+ @Override
+ public void build() {
+ for (Map.Entry entry : query.getProject().getExprs().entrySet())
+ {
+ if (aggMap.containsKey(entry.getKey()))
+ {
+ entry.setValue( aggMap.get(entry.getKey()));
+ }
+ }
+ }
+
+ /**
+ * Add and expression aggregator and variable to the mapping.
+ *
+ * if the expr parameter is not an instance of ExprAggregator then no action is taken.
+ *
+ * @param expr The expression to add.
+ * @param var The variable that it is bound to.
+ */
+ public void add(Expr expr, Var var) {
+ if (expr instanceof ExprAggregator)
+ {
+ ExprAggregator eAgg = (ExprAggregator)expr;
+ Expr expr2 = query.allocAggregate( eAgg.getAggregator() );
+ aggMap.put(var, (ExprAggregator)expr2);
+ }
+ }
+
+}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/HandlerBlock.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/HandlerBlock.java
new file mode 100644
index 00000000000..41c7e42fb92
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/HandlerBlock.java
@@ -0,0 +1,268 @@
+package org.apache.jena.arq.querybuilder.handlers;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.Map;
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.Query;
+import org.apache.jena.sparql.core.Var;
+
+/**
+ * A class to handle all the handlers of a query builder and keep them in sync
+ * as needed.
+ *
+ */
+public class HandlerBlock {
+ private final AggregationHandler aggHandler;
+ private final ConstructHandler constructHandler;
+ private final DatasetHandler datasetHandler;
+ private final PrologHandler prologHandler;
+ private final SelectHandler selectHandler;
+ private final SolutionModifierHandler modifierHandler;
+ private final WhereHandler whereHandler;
+
+ /**
+ * Constructor.
+ *
+ * @param query
+ * The query we are working with.
+ */
+ public HandlerBlock(Query query) {
+ prologHandler = new PrologHandler(query);
+ aggHandler = new AggregationHandler(query);
+ whereHandler = new WhereHandler(query);
+ datasetHandler = new DatasetHandler(query);
+ modifierHandler = new SolutionModifierHandler(query);
+ /*
+ * selecthandler and constructhandler may be null so processthem
+ * accordingly
+ */
+ SelectHandler sTemp = null;
+ ConstructHandler cTemp = null;
+ if (query.isSelectType()) {
+ sTemp = new SelectHandler(aggHandler);
+ } else if (query.isAskType()) {
+ // nochange
+ } else if (query.isDescribeType()) {
+ // no change
+ } else if (query.isConstructType()) {
+ cTemp = new ConstructHandler(query);
+ }
+ selectHandler = sTemp;
+ constructHandler = cTemp;
+ }
+
+ /**
+ * Get the aggregation handler.
+ *
+ * @return the aggregation handler.
+ */
+ public AggregationHandler getAggregationHandler() {
+ return aggHandler;
+ }
+
+ /**
+ * Get the construct handler.
+ *
+ * @return the construct handler or null.
+ */
+ public ConstructHandler getConstructHandler() {
+ return constructHandler;
+ }
+
+ /**
+ * Get the dataset handler.
+ *
+ * @return the dataset handler.
+ */
+ public DatasetHandler getDatasetHandler() {
+ return datasetHandler;
+ }
+
+ /**
+ * Get the prolog handler.
+ *
+ * @return the prolog handler.
+ */
+ public PrologHandler getPrologHandler() {
+ return prologHandler;
+ }
+
+ /**
+ * Get the select handler.
+ *
+ * @return the select handler or null.
+ */
+ public SelectHandler getSelectHandler() {
+ return selectHandler;
+ }
+
+ /**
+ * Get the solution modifier handler.
+ *
+ * @return the solution modifier handler.
+ */
+ public SolutionModifierHandler getModifierHandler() {
+ return modifierHandler;
+ }
+
+ /**
+ * Get the where handler.
+ *
+ * @return the where handler.
+ */
+ public WhereHandler getWhereHandler() {
+ return whereHandler;
+ }
+
+ /**
+ * Add the prolog handler contents to this prolog handler.
+ *
+ * @param handler
+ * The prolog handler to add to this one.
+ */
+ public void addAll(PrologHandler handler) {
+ prologHandler.addAll(handler);
+ }
+
+ /**
+ * Add the aggregation handler contents to this prolog handler.
+ *
+ * @param handler
+ * The aggregation handler to add to this one.
+ */
+ public void addAll(AggregationHandler handler) {
+ aggHandler.addAll(handler);
+ }
+
+ /**
+ * Add the construct handler contents to this prolog handler. If this
+ * construct handler is null or the handler argument is null this method
+ * does nothing.
+ *
+ * @param handler
+ * The construct handler to add to this one.
+ */
+ public void addAll(ConstructHandler handler) {
+ if (constructHandler != null && handler != null) {
+ constructHandler.addAll(handler);
+ }
+ }
+
+ /**
+ * Add the dataset handler contents to this prolog handler.
+ *
+ * @param handler
+ * The dataset handler to add to this one.
+ */
+ public void addAll(DatasetHandler handler) {
+ datasetHandler.addAll(handler);
+ }
+
+ /**
+ * Add the solution modifier handler contents to this prolog handler.
+ *
+ * @param handler
+ * The solution modifier handler to add to this one.
+ */
+ public void addAll(SolutionModifierHandler handler) {
+ modifierHandler.addAll(handler);
+ }
+
+ /**
+ * Add the select handler contents to this prolog handler. If this select
+ * handler is null or the handler argument is null this method does nothing.
+ *
+ * @param handler
+ * The construct handler to add to this one.
+ */
+ public void addAll(SelectHandler handler) {
+ if (selectHandler != null && handler != null) {
+ selectHandler.addAll(handler);
+ }
+ }
+
+ /**
+ * Add the where handler contents to this prolog handler.
+ *
+ * @param handler
+ * The where handler to add to this one.
+ */
+ public void addAll(WhereHandler handler) {
+ whereHandler.addAll(handler);
+ }
+
+ /**
+ * Add all of the handlers in the handler block to this one. Any handler
+ * that is null or is null in the handler argument are properly skipped.
+ *
+ * @param handler
+ * The handler block to add to this one.
+ */
+ public void addAll(HandlerBlock handler) {
+ addAll(handler.aggHandler);
+ addAll(handler.constructHandler);
+ addAll(handler.selectHandler);
+ addAll(handler.datasetHandler);
+ addAll(handler.modifierHandler);
+ addAll(handler.prologHandler);
+ addAll(handler.whereHandler);
+ }
+
+ /**
+ * Set the variables in all the enclosed handlers in the proper order.
+ *
+ * @param values
+ * The map of values to set.
+ */
+ public void setVars(Map values) {
+ aggHandler.setVars(values);
+
+ if (constructHandler != null) {
+ constructHandler.setVars(values);
+ }
+
+ datasetHandler.setVars(values);
+ prologHandler.setVars(values);
+
+ if (selectHandler != null) {
+ selectHandler.setVars(values);
+ }
+
+ modifierHandler.setVars(values);
+ whereHandler.setVars(values);
+ }
+
+ /**
+ * Build all the the enclosed handlers in the proper order.
+ */
+ public void build() {
+ prologHandler.build();
+
+ if (selectHandler != null) {
+ selectHandler.build();
+ }
+ if (constructHandler != null) {
+ constructHandler.build();
+ }
+ datasetHandler.build();
+ modifierHandler.build();
+ whereHandler.build();
+ aggHandler.build();
+ }
+}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java
index 37629d7c1bf..0a5b1b94637 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java
@@ -24,6 +24,7 @@
import org.apache.jena.query.Query ;
import org.apache.jena.riot.system.IRIResolver;
import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.shared.impl.PrefixMappingImpl;
import org.apache.jena.sparql.core.Var ;
/**
@@ -82,6 +83,13 @@ public void setBase(String base) {
public void addPrefix(String pfx, String uri) {
query.setPrefix(canonicalPfx(pfx), uri);
}
+
+ /**
+ * Clear the prefix mapping.
+ */
+ public void clearPrefixes() {
+ query.setPrefixMapping( new PrefixMappingImpl() );
+ }
/**
* Add the map of prefixes to the query prefixes.
@@ -92,6 +100,10 @@ public void addPrefixes(Map prefixes) {
addPrefix(e.getKey(), e.getValue());
}
}
+
+ public PrefixMapping getPrefixes() {
+ return query.getPrefixMapping();
+ }
/**
* Add prefixes from a prefix mapping.
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java
index 2d0904bc01a..8875cd3e070 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java
@@ -20,7 +20,6 @@
import java.io.StringReader;
import java.util.List;
import java.util.Map;
-
import org.apache.jena.graph.Node;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryParseException;
@@ -39,15 +38,16 @@ public class SelectHandler implements Handler {
// the query to handle
private final Query query;
+ private final AggregationHandler aggHandler;
/**
* Constructor.
*
- * @param query
- * The query to manage.
+ * @param aggHandler The aggregate handler that wraps the query we want to handle.
*/
- public SelectHandler(Query query) {
- this.query = query;
+ public SelectHandler(AggregationHandler aggHandler) {
+ this.query = aggHandler.getQuery();
+ this.aggHandler = aggHandler;
setDistinct(query.isDistinct());
setReduced(query.isReduced());
}
@@ -113,9 +113,12 @@ public void addVar(String expression, Var var) {
* Parse an expression string into an expression.
*
* This must be able to be parsed as though it were written "SELECT "+s
- * @param s the select string to parse.
+ *
+ * @param s
+ * the select string to parse.
* @return the epxression
- * @throws QueryParseException on error
+ * @throws QueryParseException
+ * on error
*/
private Expr parseExpr(String s) throws QueryParseException {
try {
@@ -142,7 +145,7 @@ private Expr parseExpr(String s) throws QueryParseException {
* Add an Expression as variable to the select.
*
* @param expr
- * The expresson to add.
+ * The expression to add.
* @param var
* The variable to add.
*/
@@ -155,6 +158,7 @@ public void addVar(Expr expr, Var var) {
}
query.setQueryResultStar(false);
query.addResultVar(var, expr);
+ aggHandler.add( expr, var );
}
/**
@@ -169,7 +173,7 @@ public List getVars() {
/**
* Return the projected var expression list.
*
- * @return The proejct var expression list.
+ * @return The projected var expression list.
*/
public VarExprList getProject() {
return query.getProject();
@@ -182,7 +186,6 @@ public VarExprList getProject() {
* The select handler to copy the variables from.
*/
public void addAll(SelectHandler selectHandler) {
-
setReduced(selectHandler.query.isReduced());
setDistinct(selectHandler.query.isDistinct());
query.setQueryResultStar(selectHandler.query.isQueryResultStar());
@@ -194,6 +197,7 @@ public void addAll(SelectHandler selectHandler) {
qProjectVars.add(var, shProjectVars.getExpr(var));
}
}
+ aggHandler.addAll( selectHandler.aggHandler );
}
@Override
@@ -206,6 +210,9 @@ public void build() {
if (query.getProject().getVars().isEmpty()) {
query.setQueryResultStar(true);
}
+
+ aggHandler.build();
+
// handle the SELECT * case
query.getProjectVars();
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
index 0a4d4c9c626..83cd469d4dc 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
@@ -20,17 +20,14 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-
import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
import org.apache.jena.arq.querybuilder.SelectBuilder;
-import org.apache.jena.arq.querybuilder.clauses.ConstructClause;
import org.apache.jena.arq.querybuilder.rewriters.ElementRewriter;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.Query;
import org.apache.jena.sparql.core.Var;
-import org.apache.jena.sparql.core.VarExprList;
import org.apache.jena.sparql.expr.Expr;
import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.apache.jena.sparql.syntax.*;
@@ -220,6 +217,10 @@ public void addOptional(Triple t) throws IllegalArgumentException {
getClause().addElement(opt);
}
+ /**
+ * Add the contents of a where handler as an optional statement.
+ * @param whereHandler The where handler to use as the optional statement.
+ */
public void addOptional(WhereHandler whereHandler) {
getClause().addElement(new ElementOptional(whereHandler.getClause()));
}
@@ -263,28 +264,29 @@ public void addSubQuery(SelectBuilder subQuery) {
* The sub query to convert
* @return THe converted element.
*/
- private ElementSubQuery makeSubQuery(SelectBuilder subQuery) {
+ private ElementSubQuery makeSubQuery(AbstractQueryBuilder> subQuery) {
Query q = new Query();
- PrologHandler ph = new PrologHandler(query);
- ph.addAll(subQuery.getPrologHandler());
-
- VarExprList vars = subQuery.getSelectHandler().getProject();
- for (Var v : vars.getVars()) {
- q.addResultVar(v, vars.getExpr(v));
- q.setQuerySelectType();
+ SelectHandler sh = subQuery.getHandlerBlock().getSelectHandler();
+ if (sh != null)
+ {
+ if (! sh.getProject().isEmpty()) {
+ q.setQuerySelectType();
+ }
}
-
- if (subQuery instanceof ConstructClause) {
- ConstructHandler ch = new ConstructHandler(q);
- ch.addAll(((ConstructClause>) subQuery).getConstructHandler());
-
+ PrologHandler ph = new PrologHandler(query);
+ ph.addPrefixes( subQuery.getPrologHandler().getPrefixes() );
+ HandlerBlock handlerBlock = new HandlerBlock(q);
+ handlerBlock.addAll( subQuery.getHandlerBlock() );
+ // remove the prefix mappings from the sub query.
+ handlerBlock.getPrologHandler().clearPrefixes();
+
+
+ // make sure we have a query pattern before we start building.
+ if (q.getQueryPattern() == null)
+ {
+ q.setQueryPattern( new ElementGroup() );
}
- DatasetHandler dh = new DatasetHandler(q);
- dh.addAll(subQuery.getDatasetHandler());
- SolutionModifierHandler smh = new SolutionModifierHandler(q);
- smh.addAll(subQuery.getSolutionModifierHandler());
- WhereHandler wh = new WhereHandler(q);
- wh.addAll(subQuery.getWhereHandler());
+ handlerBlock.build();
return new ElementSubQuery(q);
}
@@ -320,7 +322,7 @@ public void addUnion(SelectBuilder subQuery) {
union.addElement(makeSubQuery(subQuery));
} else {
PrologHandler ph = new PrologHandler(query);
- ph.addAll(subQuery.getPrologHandler());
+ ph.addPrefixes(subQuery.getPrologHandler().getPrefixes());
union.addElement(subQuery.getWhereHandler().getClause());
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/ElementRewriter.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/ElementRewriter.java
index 91acce25c8e..4a9a56ac3d9 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/ElementRewriter.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/ElementRewriter.java
@@ -23,6 +23,7 @@
import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
+import org.apache.jena.query.Query;
import org.apache.jena.sparql.core.TriplePath ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.binding.Binding ;
@@ -190,8 +191,9 @@ public void visit(ElementService el) {
@Override
public void visit(ElementSubQuery el) {
+ Query q = AbstractQueryBuilder.clone(el.getQuery());
push(new ElementSubQuery(AbstractQueryBuilder.rewrite(
- AbstractQueryBuilder.clone(el.getQuery()), values)));
+ q, values)));
}
}
\ No newline at end of file
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
index 4293a6f5a2f..89108a9e46e 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
@@ -19,11 +19,15 @@
package org.apache.jena.arq.querybuilder;
import static org.junit.Assert.*;
+
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
+import org.apache.jena.arq.querybuilder.handlers.PrologHandler;
import org.apache.jena.graph.FrontsNode ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.graph.impl.LiteralLabel ;
import org.apache.jena.graph.impl.LiteralLabelFactory ;
+import org.apache.jena.query.Query;
import org.apache.jena.reasoner.rulesys.Node_RuleVariable ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.expr.ExprVar ;
@@ -41,10 +45,23 @@ public void setup() {
}
private class TestBuilder extends AbstractQueryBuilder {
+ private HandlerBlock handlerBlock;
+
+ public TestBuilder()
+ {
+ super();
+ handlerBlock = new HandlerBlock( query );
+
+ }
@Override
public String toString() {
return "TestBuilder";
}
+
+ @Override
+ public HandlerBlock getHandlerBlock() {
+ return handlerBlock;
+ }
}
private class NodeFront implements FrontsNode {
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
index 535be17acd9..3eb209f3187 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
@@ -18,20 +18,32 @@
package org.apache.jena.arq.querybuilder;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.apache.jena.arq.AbstractRegexpBasedTest;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.vocabulary.RDF ;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.QuerySolution;
+import org.apache.jena.query.ResultSet;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.lang.sparql_11.ParseException;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.XSD;
import org.junit.Before;
import org.junit.Test;
public class SelectBuilderTest extends AbstractRegexpBasedTest {
private SelectBuilder builder;
-
- @Before
+
+ @Before
public void setup() {
builder = new SelectBuilder();
}
@@ -40,23 +52,18 @@ public void setup() {
public void testSelectAsterisk() {
builder.addVar("*").addWhere("?s", "?p", "?o");
- assertContainsRegex(SELECT + "\\*" + SPACE + WHERE + OPEN_CURLY
- + var("s") + SPACE + var("p") + SPACE + var("o") + OPT_SPACE
- + CLOSE_CURLY, builder.buildString());
+ assertContainsRegex(SELECT + "\\*" + SPACE + WHERE + OPEN_CURLY + var("s") + SPACE + var("p") + SPACE + var("o")
+ + OPT_SPACE + CLOSE_CURLY, builder.buildString());
builder.setVar(Var.alloc("p"), RDF.type);
- assertContainsRegex(SELECT + "\\*" + SPACE + WHERE + OPEN_CURLY
- + var("s") + SPACE
- + regexRDFtype
- + SPACE + var("o") + OPT_SPACE + CLOSE_CURLY,
- builder.buildString());
+ assertContainsRegex(SELECT + "\\*" + SPACE + WHERE + OPEN_CURLY + var("s") + SPACE + regexRDFtype + SPACE
+ + var("o") + OPT_SPACE + CLOSE_CURLY, builder.buildString());
}
@Test
public void testAll() {
- builder.addVar("s").addPrefix("foaf", "http://xmlns.com/foaf/0.1/")
- .addWhere("?s", RDF.type, "foaf:Person")
+ builder.addVar("s").addPrefix("foaf", "http://xmlns.com/foaf/0.1/").addWhere("?s", RDF.type, "foaf:Person")
.addOptional("?s", "foaf:name", "?name").addOrderBy("?s");
String query = builder.buildString();
@@ -67,60 +74,49 @@ public void testAll() {
* foaf:Person .
* OPTIONAL { ?s foaf:name ?name .} } ORDER BY ?s
*/
- assertContainsRegex(PREFIX + "foaf:" + SPACE
- + uri("http://xmlns.com/foaf/0.1/"), query);
+ assertContainsRegex(PREFIX + "foaf:" + SPACE + uri("http://xmlns.com/foaf/0.1/"), query);
assertContainsRegex(SELECT + var("s"), query);
- assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE
- + regexRDFtype
- + SPACE + "foaf:Person" + SPACE + OPTIONAL
- + OPEN_CURLY + var("s") + SPACE + "foaf:name" + SPACE
- + var("name") + OPT_SPACE + CLOSE_CURLY
+ assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE + regexRDFtype + SPACE + "foaf:Person" + SPACE
+ + OPTIONAL + OPEN_CURLY + var("s") + SPACE + "foaf:name" + SPACE + var("name") + OPT_SPACE + CLOSE_CURLY
+ CLOSE_CURLY, query);
assertContainsRegex(ORDER_BY + var("s"), query);
builder.setVar("name", "Smith");
query = builder.buildString();
- assertContainsRegex(PREFIX + "foaf:" + SPACE
- + uri("http://xmlns.com/foaf/0.1/"), query);
+ assertContainsRegex(PREFIX + "foaf:" + SPACE + uri("http://xmlns.com/foaf/0.1/"), query);
assertContainsRegex(SELECT + var("s"), query);
- assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE
- + regexRDFtype
- + SPACE + "foaf:Person" + SPACE + OPTIONAL
- + OPEN_CURLY + var("s") + SPACE + "foaf:name" + SPACE
- + quote("Smith") + presentStringType()
+ assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE + regexRDFtype + SPACE + "foaf:Person" + SPACE
+ + OPTIONAL + OPEN_CURLY + var("s") + SPACE + "foaf:name" + SPACE + quote("Smith") + presentStringType()
+ OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query);
assertContainsRegex(ORDER_BY + var("s"), query);
}
@Test
public void testPredicateVar() {
- builder.addVar("*").addPrefix("", "http://example/")
- .addWhere(":S", "?p", ":O");
+ builder.addVar("*").addPrefix("", "http://example/").addWhere(":S", "?p", ":O");
String query = builder.buildString();
- assertContainsRegex(WHERE + OPEN_CURLY + ":S" + SPACE + var("p")
- + SPACE + ":O" + OPT_SPACE + CLOSE_CURLY, query);
+ assertContainsRegex(WHERE + OPEN_CURLY + ":S" + SPACE + var("p") + SPACE + ":O" + OPT_SPACE + CLOSE_CURLY,
+ query);
}
@Test
public void testSubjectVar() {
- builder.addVar("*").addPrefix("", "http://example/")
- .addWhere("?s", ":P", ":O");
+ builder.addVar("*").addPrefix("", "http://example/").addWhere("?s", ":P", ":O");
String query = builder.buildString();
- assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE + ":P"
- + SPACE + ":O" + OPT_SPACE + CLOSE_CURLY, query);
+ assertContainsRegex(WHERE + OPEN_CURLY + var("s") + SPACE + ":P" + SPACE + ":O" + OPT_SPACE + CLOSE_CURLY,
+ query);
}
@Test
public void testObjectVar() {
- builder.addVar("*").addPrefix("", "http://example/")
- .addWhere(":S", ":P", "?o");
+ builder.addVar("*").addPrefix("", "http://example/").addWhere(":S", ":P", "?o");
String query = builder.buildString();
- assertContainsRegex(WHERE + OPEN_CURLY + ":S" + SPACE + ":P" + SPACE
- + var("o") + OPT_SPACE + CLOSE_CURLY, query);
+ assertContainsRegex(WHERE + OPEN_CURLY + ":S" + SPACE + ":P" + SPACE + var("o") + OPT_SPACE + CLOSE_CURLY,
+ query);
}
@Test
@@ -130,37 +126,149 @@ public void testNoVars() {
assertContainsRegex(SELECT + "\\*" + SPACE, query);
}
-
+
@Test
public void testList() {
- builder.addVar( "*" )
- .addWhere( builder.list( "", "?two", "'three'"), "", "");
+ builder.addVar("*").addWhere(builder.list("", "?two", "'three'"), "", "");
String query = builder.buildString();
-
- assertContainsRegex(
- "_:b0"+SPACE+ uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + uri("one") + SEMI
- + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE+"_:b1"+ DOT
- + SPACE + "_:b1"+SPACE+ uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + var("two") + SEMI
- + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE+"_:b2"+ DOT
- + SPACE + "_:b2"+SPACE+ uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + quote("three") + SEMI
- + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE +uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")
- , query);
-
- assertContainsRegex(
- "_:b0"+SPACE+ uri("foo") + SPACE + uri("bar"), query);
+
+ assertContainsRegex("_:b0" + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE
+ + uri("one") + SEMI + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE + "_:b1"
+ + DOT + SPACE + "_:b1" + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE
+ + var("two") + SEMI + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE + "_:b2"
+ + DOT + SPACE + "_:b2" + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE
+ + quote("three") + SEMI + SPACE + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE
+ + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"), query);
+
+ assertContainsRegex("_:b0" + SPACE + uri("foo") + SPACE + uri("bar"), query);
}
-
+
@Test
public void testClone() {
- builder.addVar( "*" )
- .addWhere( "?two", "", "");
+ builder.addVar("*").addWhere("?two", "", "");
SelectBuilder builder2 = builder.clone();
- builder2.addOrderBy( "?two");
-
+ builder2.addOrderBy("?two");
+
String q1 = builder.buildString();
String q2 = builder2.buildString();
+
+ assertTrue(q2.contains("ORDER BY"));
+ assertFalse(q1.contains("ORDER BY"));
+ }
+
+ @Test
+ public void testAggregatorsInSelect() throws ParseException {
+ builder.addVar("?x").addVar("count(*)", "?c").addWhere("?x", "?p", "?o").addGroupBy("?x");
+
+ Model m = ModelFactory.createDefaultModel();
+ Resource r = m.createResource("urn:one");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(1));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(3));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(5));
+ r = m.createResource("urn:two");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(1));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(3));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(5));
+
+ QueryExecution qexec = QueryExecutionFactory.create(builder.build(), m);
+
+ ResultSet results = qexec.execSelect();
+ assertTrue(results.hasNext());
+ for (; results.hasNext();) {
+ QuerySolution soln = results.nextSolution();
+ assertTrue(soln.contains("c"));
+ assertTrue(soln.contains("x"));
+ assertEquals(3, soln.get("c").asLiteral().getInt());
+ }
+
+ builder.addVar("min(?o)", "?min").addVar("max(?o)", "?max");
+
+ qexec = QueryExecutionFactory.create(builder.build(), m);
+
+ results = qexec.execSelect();
+ assertTrue(results.hasNext());
+ for (; results.hasNext();) {
+ QuerySolution soln = results.nextSolution();
+ assertTrue(soln.contains("c"));
+ assertTrue(soln.contains("x"));
+ assertTrue(soln.contains("?min"));
+ assertEquals(3, soln.get("c").asLiteral().getInt());
+ assertEquals(1, soln.get("min").asLiteral().getInt());
+ assertEquals(5, soln.get("max").asLiteral().getInt());
+ }
+
+ }
+
+ @Test
+ public void testAggregatorsInSubQuery() throws ParseException {
+
+ Model m = ModelFactory.createDefaultModel();
+ Resource r = m.createResource("urn:one");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(1));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(3));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(5));
+ r = m.createResource("urn:two");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(2));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(4));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(6));
+
+ SelectBuilder sb = new SelectBuilder().addVar("?x").addVar("max(?o)", "?max").addWhere("?x", "?p", "?o")
+ .addGroupBy("?x");
+
+ builder.addPrefix("xsd", XSD.getURI()).addVar("?x").addVar("min(?o2)", "?min").addWhere("?x", "?p2", "?o2")
+ .addSubQuery(sb).addFilter("?max = '6'^^xsd:int").addGroupBy("?x");
+
+ QueryExecution qexec = QueryExecutionFactory.create(builder.build(), m);
+
+ ResultSet results = qexec.execSelect();
+ assertTrue(results.hasNext());
+ for (; results.hasNext();) {
+ QuerySolution soln = results.nextSolution();
+ assertTrue(soln.contains("x"));
+ assertTrue(soln.contains("min"));
+ assertEquals("urn:two", soln.get("?x").asResource().getURI());
+ assertEquals(2, soln.get("?min").asLiteral().getInt());
+ }
+ }
+
+ @Test
+ public void testVarReplacementInSubQuery() throws ParseException {
+
+ Model m = ModelFactory.createDefaultModel();
+ Resource r = m.createResource("urn:one");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(1));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(3));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(5));
+ r = m.createResource("urn:two");
+ m.add(r, m.getProperty("urn:p:one"), m.createTypedLiteral(2));
+ m.add(r, m.getProperty("urn:p:two"), m.createTypedLiteral(4));
+ m.add(r, m.getProperty("urn:p:three"), m.createTypedLiteral(6));
+
+ SelectBuilder sb = new SelectBuilder().addVar("?x").addVar("?p").addWhere("?x", "?p", "?o")
+ .addFilter( "?o < ?limit");
+
+ builder.addPrefix("xsd", XSD.getURI()).addVar("?x").addVar("count(?p)", "?c").addWhere("?x", "?p", "?o2")
+ .addSubQuery(sb).addGroupBy("?x");
+
- assertTrue( q2.contains("ORDER BY"));
- assertFalse( q1.contains("ORDER BY"));
+ builder.setVar( "?limit", 4 );
+
+ QueryExecution qexec = QueryExecutionFactory.create(builder.build(), m);
+
+ ResultSet results = qexec.execSelect();
+ assertTrue(results.hasNext());
+ for (; results.hasNext();) {
+ QuerySolution soln = results.nextSolution();
+ assertTrue(soln.contains("x"));
+ assertTrue(soln.contains("c"));
+ if ("urn:one".equals( soln.get("?x").asResource().getURI()))
+ {
+ assertEquals( 2, soln.get("?c").asLiteral().getInt());
+ }
+ else
+ {
+ assertEquals( 1, soln.get("?c").asLiteral().getInt());
+ }
+ }
}
}
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
index 570a91ef341..23b522bd1d5 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
@@ -144,7 +144,7 @@ public void testAddFilter() throws ParseException {
}
@ContractTest
- public void addSubQuery() {
+ public void testAddSubQuery() {
SelectBuilder sb = new SelectBuilder();
sb.addPrefix("pfx", "urn:uri").addVar("?x")
.addWhere("pfx:one", "pfx:two", "pfx:three");
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SelectHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SelectHandlerTest.java
index 4e514784a6d..6e131deffa5 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SelectHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SelectHandlerTest.java
@@ -38,7 +38,8 @@ public class SelectHandlerTest extends AbstractHandlerTest {
@Before
public void setup() {
query = new Query();
- handler = new SelectHandler(query);
+ AggregationHandler aggHandler = new AggregationHandler(query);
+ handler = new SelectHandler(aggHandler);
}
@Test
@@ -166,7 +167,8 @@ public void testSetReduced() {
@Test
public void testAddAllResultStartReduced() {
- SelectHandler sh = new SelectHandler(new Query());
+ AggregationHandler aggHandler = new AggregationHandler(new Query());
+ SelectHandler sh = new SelectHandler(aggHandler);
sh.addVar(null);
sh.setReduced(true);
@@ -177,7 +179,8 @@ public void testAddAllResultStartReduced() {
@Test
public void testAddAllVarsDistinct() {
- SelectHandler sh = new SelectHandler(new Query());
+ AggregationHandler aggHandler = new AggregationHandler(new Query());
+ SelectHandler sh = new SelectHandler(aggHandler);
sh.addVar(Var.alloc("foo"));
sh.setDistinct(true);