use of org.eclipse.rdf4j.query.parser.serql.ast.VisitorException in project rdf4j by eclipse.
the class ProjectionProcessor method visit.
@Override
public Object visit(ASTSelect selectNode, Object data) throws VisitorException {
// Collect all variables used in the body of the select query
Set<String> bodyVars = VariableCollector.process(selectNode.jjtGetParent());
if (selectNode.isWildcard()) {
// Make wildcard projection explicit
for (String varName : bodyVars) {
ASTProjectionElem projElemNode = new ASTProjectionElem(SyntaxTreeBuilderTreeConstants.JJTPROJECTIONELEM);
selectNode.jjtAppendChild(projElemNode);
projElemNode.jjtSetParent(selectNode);
ASTVar varNode = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR);
varNode.setName(varName);
projElemNode.jjtAppendChild(varNode);
varNode.jjtSetParent(projElemNode);
}
selectNode.setWildcard(false);
} else {
// Verify that all projection vars are bound
Set<String> projVars = new LinkedHashSet<String>();
for (ASTProjectionElem projElem : selectNode.getProjectionElemList()) {
projVars.addAll(VariableCollector.process(projElem.getValueExpr()));
}
projVars.removeAll(bodyVars);
if (!projVars.isEmpty()) {
StringBuilder errMsg = new StringBuilder(64);
errMsg.append("Unbound variable(s) in projection: ");
Iterator<String> iter = projVars.iterator();
while (iter.hasNext()) {
errMsg.append(iter.next());
if (iter.hasNext()) {
errMsg.append(", ");
}
}
throw new VisitorException(errMsg.toString());
}
}
return data;
}
use of org.eclipse.rdf4j.query.parser.serql.ast.VisitorException in project rdf4j by eclipse.
the class ProjectionAliasProcessor method visit.
@Override
public Object visit(ASTSelect node, Object data) throws VisitorException {
// Iterate over all projection elements to retrieve the defined aliases
Set<String> aliases = new HashSet<String>();
List<Node> unaliasedNodes = new ArrayList<Node>();
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
ASTProjectionElem projElem = (ASTProjectionElem) node.jjtGetChild(i);
String alias = projElem.getAlias();
if (alias == null && projElem.getValueExpr() instanceof ASTVar) {
alias = ((ASTVar) projElem.getValueExpr()).getName();
}
if (alias != null) {
boolean isUnique = aliases.add(alias);
if (!isUnique) {
throw new VisitorException("Duplicate projection element names: '" + alias + "'");
}
} else {
unaliasedNodes.add(projElem);
}
}
// Iterate over the unaliased nodes and generate aliases for them
int aliasNo = 1;
for (Node projElem : unaliasedNodes) {
// Generate unique alias for projection element
String alias;
while (aliases.contains(alias = "_" + aliasNo++)) {
// try again
}
aliases.add(alias);
ASTString aliasNode = new ASTString(SyntaxTreeBuilderTreeConstants.JJTSTRING);
aliasNode.setValue(alias);
aliasNode.jjtSetParent(projElem);
projElem.jjtAppendChild(aliasNode);
}
return data;
}
use of org.eclipse.rdf4j.query.parser.serql.ast.VisitorException in project rdf4j by eclipse.
the class NamespaceDeclProcessor method process.
/**
* Processes prefix declarations in queries. This method collects all prefixes that are declared in the
* supplied query, verifies that prefixes are not redefined and replaces any {@link ASTQName} nodes in the
* query with equivalent {@link ASTIRI} nodes.
*
* @param qc
* The query that needs to be processed.
* @return A map containing the prefixes that are declared in the query (key) and the namespace they map
* to (value).
* @throws MalformedQueryException
* If the query contains redefined prefixes or qnames that use undefined prefixes.
*/
public static Map<String, String> process(ASTQueryContainer qc) throws MalformedQueryException {
List<ASTNamespaceDecl> nsDeclList = qc.getNamespaceDeclList();
// Build a prefix --> URI map
Map<String, String> nsMap = new LinkedHashMap<String, String>();
for (ASTNamespaceDecl nsDecl : nsDeclList) {
String prefix = nsDecl.getPrefix();
String uri = nsDecl.getURI().getValue();
if (nsMap.containsKey(prefix)) {
// Prefix already defined
if (nsMap.get(prefix).equals(uri)) {
// duplicate, ignore
} else {
throw new MalformedQueryException("Multiple namespace declarations for prefix '" + prefix + "'");
}
} else {
nsMap.put(prefix, uri);
}
}
// Use default namespace prefixes when not defined explicitly
if (!nsMap.containsKey("rdf")) {
nsMap.put("rdf", RDF.NAMESPACE);
}
if (!nsMap.containsKey("rdfs")) {
nsMap.put("rdfs", RDFS.NAMESPACE);
}
if (!nsMap.containsKey("xsd")) {
nsMap.put("xsd", XMLSchema.NAMESPACE);
}
if (!nsMap.containsKey("owl")) {
nsMap.put("owl", OWL.NAMESPACE);
}
if (!nsMap.containsKey("sesame")) {
nsMap.put("sesame", SESAME.NAMESPACE);
}
// For backwards compatibility:
Map<String, String> extendedNsMap = new HashMap<String, String>(nsMap);
if (!extendedNsMap.containsKey("serql")) {
extendedNsMap.put("serql", SESAME.NAMESPACE);
}
// Replace all qnames with URIs
QNameProcessor visitor = new QNameProcessor(extendedNsMap);
try {
qc.jjtAccept(visitor, null);
} catch (VisitorException e) {
throw new MalformedQueryException(e.getMessage(), e);
}
return nsMap;
}
use of org.eclipse.rdf4j.query.parser.serql.ast.VisitorException in project rdf4j by eclipse.
the class SeRQLParser method parseQuery.
public ParsedQuery parseQuery(String queryStr, String baseURI) throws MalformedQueryException {
try {
ASTQueryContainer qc = SyntaxTreeBuilder.parseQuery(queryStr);
// Replace deprecated NULL nodes with semantically equivalent
// alternatives
NullProcessor.process(qc);
StringEscapesProcessor.process(qc);
Map<String, String> namespaces = NamespaceDeclProcessor.process(qc);
ProjectionProcessor.process(qc);
qc.jjtAccept(new ProjectionAliasProcessor(), null);
qc.jjtAccept(new AnonymousVarGenerator(), null);
// TODO: check use of unbound variables?
TupleExpr tupleExpr = QueryModelBuilder.buildQueryModel(qc, SimpleValueFactory.getInstance());
ASTQuery queryNode = qc.getQuery();
ParsedQuery query;
if (queryNode instanceof ASTTupleQuery) {
query = new ParsedTupleQuery(tupleExpr);
} else if (queryNode instanceof ASTGraphQuery) {
query = new ParsedGraphQuery(tupleExpr, namespaces);
} else {
throw new RuntimeException("Unexpected query type: " + queryNode.getClass());
}
return query;
} catch (ParseException e) {
throw new MalformedQueryException(e.getMessage(), e);
} catch (TokenMgrError e) {
throw new MalformedQueryException(e.getMessage(), e);
} catch (VisitorException e) {
throw new MalformedQueryException(e.getMessage(), e);
}
}
Aggregations