SPARQLParser implements QueryParser { @Override public ParsedUpdate parseUpdate(String updateStr, String baseURI) throws MalformedQueryException { try { ParsedUpdate update = new ParsedUpdate(updateStr); SPARQLUpdateDataBlockParser parser = new SPARQLUpdateDataBlockParser(); ASTUpdateSequence updateSequence = SyntaxTreeBuilder.parseUpdateSequence(updateStr); List<ASTUpdateContainer> updateOperations = updateSequence.getUpdateContainers(); List<ASTPrefixDecl> sharedPrefixDeclarations = null; Node node = updateSequence.jjtGetChild(0); Set<String> globalUsedBNodeIds = new HashSet<>(); for (int i = 0; i < updateOperations.size(); i++) { ASTUpdateContainer uc = updateOperations.get(i); if (uc.jjtGetNumChildren() == 0 && i > 0 && i < updateOperations.size() - 1) { 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(); } List<ASTPrefixDecl> prefixDeclList = uc.getPrefixDeclList(); if (prefixDeclList == null || prefixDeclList.isEmpty()) { 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); String datablock = ""; if (updateExpr instanceof InsertData) { InsertData insertDataExpr = (InsertData) updateExpr; parser.getParserConfig().set(BasicParserSettings.SKOLEMIZE_ORIGIN, null); parser.setLineNumberOffset(insertDataExpr.getLineNumberOffset()); datablock = insertDataExpr.getDataBlock(); } else if (updateExpr instanceof DeleteData) { DeleteData deleteDataExpr = (DeleteData) updateExpr; parser.setLineNumberOffset(deleteDataExpr.getLineNumberOffset()); parser.setAllowBlankNodes(false); datablock = deleteDataExpr.getDataBlock(); } if (!datablock.equals("")) { parser.parse(new StringReader(datablock), ""); } update.addUpdateExpr(updateExpr); Dataset dataset = DatasetDeclProcessor.process(uc); update.map(updateExpr, dataset); } } return update; } catch (RDFParseException | ParseException | TokenMgrError | VisitorException | IOException e) { throw new MalformedQueryException(e.getMessage(), e); } }  @Override ParsedUpdate parseUpdate(String updateStr, String baseURI); @Override ParsedQuery parseQuery(String queryStr, String baseURI); static void main(String[] args);  }
@Test public void testInsertDataLineNumberReporting() throws Exception { String insertDataString = "INSERT DATA {\n incorrect reference }"; try { ParsedUpdate u = parser.parseUpdate(insertDataString, null); fail("should have resulted in parse exception"); } catch (MalformedQueryException e) { assertTrue(e.getMessage().contains("line 2,")); } }
@Test public void testDeleteDataLineNumberReporting() throws Exception { String deleteDataString = "DELETE DATA {\n incorrect reference }"; try { ParsedUpdate u = parser.parseUpdate(deleteDataString, null); fail("should have resulted in parse exception"); } catch (MalformedQueryException e) { assertTrue(e.getMessage().contains("line 2,")); } }
@Test public void testParseWildcardSubselectInUpdate() throws Exception { StringBuilder update = new StringBuilder(); update.append("INSERT { <urn:a> <urn:b> <urn:c> . } WHERE { SELECT * {?s ?p ?o } }"); ParsedUpdate parsedUpdate = parser.parseUpdate(update.toString(), null); List<UpdateExpr> exprs = parsedUpdate.getUpdateExprs(); assertEquals(1, exprs.size()); UpdateExpr expr = exprs.get(0); assertTrue(expr instanceof Modify); Modify m = (Modify) expr; TupleExpr whereClause = m.getWhereExpr(); assertTrue(whereClause instanceof Projection); ProjectionElemList projectionElemList = ((Projection) whereClause).getProjectionElemList(); assertNotNull(projectionElemList); List<ProjectionElem> elements = projectionElemList.getElements(); assertNotNull(elements); assertEquals("projection should contain all three variables", 3, elements.size()); }
@Test public void testLongUnicode() throws Exception { ParsedUpdate ru = parser.parseUpdate("insert data {<urn:test:foo> <urn:test:bar> \"\\U0001F61F\" .}", "urn:test"); InsertData insertData = (InsertData) ru.getUpdateExprs().get(0); String[] lines = insertData.getDataBlock().split("\n"); assertEquals("\uD83D\uDE1F", lines[lines.length - 1].replaceAll(".*\"(.*)\".*", "$1")); }