use of org.eclipse.rdf4j.query.parser.sparql.ast.ASTInsertData in project rdf4j by eclipse.
the class BaseDeclProcessor method process.
/**
* Resolves relative URIs in the supplied query model using either the specified <tt>externalBaseURI</tt>
* or, if this parameter is <tt>null</tt>, the base URI specified in the query model itself.
*
* @param qc
* The query model to resolve relative URIs in.
* @param externalBaseURI
* The external base URI to use for resolving relative URIs, or <tt>null</tt> if the base URI that
* is specified in the query model should be used.
* @throws IllegalArgumentException
* If an external base URI is specified that is not an absolute URI.
* @throws MalformedQueryException
* If the base URI specified in the query model is not an absolute URI.
*/
public static void process(ASTOperationContainer qc, String externalBaseURI) throws MalformedQueryException {
ParsedIRI parsedBaseURI = null;
// Use the query model's own base URI, if available
ASTBaseDecl baseDecl = qc.getBaseDecl();
if (baseDecl != null) {
try {
parsedBaseURI = new ParsedIRI(baseDecl.getIRI());
} catch (URISyntaxException e) {
throw new MalformedQueryException(e);
}
if (!parsedBaseURI.isAbsolute()) {
throw new MalformedQueryException("BASE IRI is not an absolute IRI: " + externalBaseURI);
}
} else if (externalBaseURI != null) {
// Use external base URI if the query doesn't contain one itself
try {
parsedBaseURI = new ParsedIRI(externalBaseURI);
} catch (URISyntaxException e) {
throw new MalformedQueryException(e);
}
if (!parsedBaseURI.isAbsolute()) {
throw new IllegalArgumentException("Supplied base URI is not an absolute IRI: " + externalBaseURI);
}
} else {
// FIXME: use the "Default Base URI"?
}
if (parsedBaseURI != null) {
ASTUnparsedQuadDataBlock dataBlock = null;
if (qc.getOperation() instanceof ASTInsertData) {
ASTInsertData insertData = (ASTInsertData) qc.getOperation();
dataBlock = insertData.jjtGetChild(ASTUnparsedQuadDataBlock.class);
} else if (qc.getOperation() instanceof ASTDeleteData) {
ASTDeleteData deleteData = (ASTDeleteData) qc.getOperation();
dataBlock = deleteData.jjtGetChild(ASTUnparsedQuadDataBlock.class);
}
if (dataBlock != null) {
final String baseURIDeclaration = "BASE <" + parsedBaseURI + "> \n";
dataBlock.setDataBlock(baseURIDeclaration + dataBlock.getDataBlock());
} else {
RelativeIRIResolver visitor = new RelativeIRIResolver(parsedBaseURI);
try {
qc.jjtAccept(visitor, null);
} catch (VisitorException e) {
throw new MalformedQueryException(e);
}
}
}
}
use of org.eclipse.rdf4j.query.parser.sparql.ast.ASTInsertData in project rdf4j by eclipse.
the class PrefixDeclProcessor 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(ASTOperationContainer qc) throws MalformedQueryException {
List<ASTPrefixDecl> prefixDeclList = qc.getPrefixDeclList();
// Build a prefix --> IRI map
Map<String, String> prefixMap = new LinkedHashMap<String, String>();
for (ASTPrefixDecl prefixDecl : prefixDeclList) {
String prefix = prefixDecl.getPrefix();
String iri = prefixDecl.getIRI().getValue();
if (prefixMap.containsKey(prefix)) {
throw new MalformedQueryException("Multiple prefix declarations for prefix '" + prefix + "'");
}
prefixMap.put(prefix, iri);
}
// insert some default prefixes (if not explicitly defined in the query)
final int defaultPrefixesAdded = insertDefaultPrefix(prefixMap, "rdf", RDF.NAMESPACE) + insertDefaultPrefix(prefixMap, "rdfs", RDFS.NAMESPACE) + insertDefaultPrefix(prefixMap, "sesame", SESAME.NAMESPACE) + insertDefaultPrefix(prefixMap, "owl", OWL.NAMESPACE) + insertDefaultPrefix(prefixMap, "xsd", XMLSchema.NAMESPACE) + insertDefaultPrefix(prefixMap, "fn", FN.NAMESPACE);
ASTUnparsedQuadDataBlock dataBlock = null;
if (qc.getOperation() instanceof ASTInsertData) {
ASTInsertData insertData = (ASTInsertData) qc.getOperation();
dataBlock = insertData.jjtGetChild(ASTUnparsedQuadDataBlock.class);
} else if (qc.getOperation() instanceof ASTDeleteData) {
ASTDeleteData deleteData = (ASTDeleteData) qc.getOperation();
dataBlock = deleteData.jjtGetChild(ASTUnparsedQuadDataBlock.class);
}
if (dataBlock != null) {
String prefixes = createPrefixesInSPARQLFormat(prefixMap);
dataBlock.setAddedDefaultPrefixes(defaultPrefixesAdded);
// TODO optimize string concat?
dataBlock.setDataBlock(prefixes + dataBlock.getDataBlock());
} else {
QNameProcessor visitor = new QNameProcessor(prefixMap);
try {
qc.jjtAccept(visitor, null);
} catch (VisitorException e) {
throw new MalformedQueryException(e);
}
}
return prefixMap;
}
use of org.eclipse.rdf4j.query.parser.sparql.ast.ASTInsertData in project rdf4j by eclipse.
the class SPARQLParser method parseUpdate.
@Override
public ParsedUpdate parseUpdate(String updateStr, String baseURI) throws MalformedQueryException {
try {
ParsedUpdate update = new ParsedUpdate(updateStr);
ASTUpdateSequence updateSequence = SyntaxTreeBuilder.parseUpdateSequence(updateStr);
List<ASTUpdateContainer> updateOperations = updateSequence.getUpdateContainers();
List<ASTPrefixDecl> sharedPrefixDeclarations = null;
Node node = updateSequence.jjtGetChild(0);
Set<String> globalUsedBNodeIds = new HashSet<String>();
for (int i = 0; i < updateOperations.size(); i++) {
ASTUpdateContainer uc = updateOperations.get(i);
if (uc.jjtGetNumChildren() == 0 && i > 0 && i < updateOperations.size() - 1) {
// empty update in the middle of the sequence
throw new MalformedQueryException("empty update in sequence not allowed");
}
StringEscapesProcessor.process(uc);
BaseDeclProcessor.process(uc, baseURI);
WildcardProjectionProcessor.process(uc);
if (uc.getBaseDecl() != null) {
baseURI = uc.getBaseDecl().getIRI();
}
// do a special dance to handle prefix declarations in sequences: if
// the current
// operation has its own prefix declarations, use those. Otherwise,
// try and use
// prefix declarations from a previous operation in this sequence.
List<ASTPrefixDecl> prefixDeclList = uc.getPrefixDeclList();
if (prefixDeclList == null || prefixDeclList.size() == 0) {
if (sharedPrefixDeclarations != null) {
for (ASTPrefixDecl prefixDecl : sharedPrefixDeclarations) {
uc.jjtAppendChild(prefixDecl);
}
}
} else {
sharedPrefixDeclarations = prefixDeclList;
}
PrefixDeclProcessor.process(uc);
Set<String> usedBNodeIds = BlankNodeVarProcessor.process(uc);
if (uc.getUpdate() instanceof ASTInsertData || uc.getUpdate() instanceof ASTInsertData) {
if (Collections.disjoint(usedBNodeIds, globalUsedBNodeIds)) {
globalUsedBNodeIds.addAll(usedBNodeIds);
} else {
throw new MalformedQueryException("blank node identifier may not be shared across INSERT/DELETE DATA operations");
}
}
UpdateExprBuilder updateExprBuilder = new UpdateExprBuilder(SimpleValueFactory.getInstance());
ASTUpdate updateNode = uc.getUpdate();
if (updateNode != null) {
UpdateExpr updateExpr = (UpdateExpr) updateNode.jjtAccept(updateExprBuilder, null);
// add individual update expression to ParsedUpdate sequence
// container
update.addUpdateExpr(updateExpr);
// associate updateExpr with the correct dataset (if any)
Dataset dataset = DatasetDeclProcessor.process(uc);
update.map(updateExpr, dataset);
}
}
return update;
} 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);
}
}
use of org.eclipse.rdf4j.query.parser.sparql.ast.ASTInsertData in project rdf4j by eclipse.
the class UpdateExprBuilder method visit.
@Override
public InsertData visit(ASTInsertData node, Object data) throws VisitorException {
ASTUnparsedQuadDataBlock dataBlock = node.jjtGetChild(ASTUnparsedQuadDataBlock.class);
InsertData insertData = new InsertData(dataBlock.getDataBlock());
insertData.setLineNumberOffset(dataBlock.getAddedDefaultPrefixes());
return insertData;
}
Aggregations