RSyntaxSQLParser extends AbstractParser { @Override public ParseResult parse(RSyntaxDocument doc, String style) { DefaultParseResult res = new DefaultParseResult(this); int docLength = doc.getLength(); if (docLength==0) { return res; } DocumentSQLReader documentReader = new DocumentSQLReader(doc); long start = System.currentTimeMillis(); try { try (Connection connection = dataSource.getConnection()) { while (documentReader.hasNext()) { String statement = documentReader.next(); if (!documentReader.isInsideRemark()) { try { connection.prepareStatement(statement); } catch (SQLException ex) { int syntaxErrorPosition = ex.getLocalizedMessage().indexOf("[*]"); int syntaxErrorLength; if (syntaxErrorPosition == -1) { syntaxErrorPosition = statement.indexOf(statement.trim()); syntaxErrorLength = statement.length() - syntaxErrorPosition; } else { int[] syntaxWord = getLastWordPositionAndLength(ex.getLocalizedMessage(), syntaxErrorPosition); String word = ex.getLocalizedMessage().substring(syntaxWord[WORD_POSITION], syntaxWord[WORD_POSITION] + syntaxWord[WORD_LENGTH]); syntaxErrorPosition = statement.toLowerCase().indexOf(word.toLowerCase()); syntaxErrorLength = syntaxWord[WORD_LENGTH]; } int syntaxErrorPositionOffset = Math.min(docLength, documentReader.getPosition() + syntaxErrorPosition); DefaultParserNotice notice = new DefaultParserNotice(this, ex.getLocalizedMessage(), documentReader.getLineIndex(syntaxErrorPositionOffset), syntaxErrorPositionOffset, syntaxErrorLength); notice.setLevel(ParserNotice.Level.ERROR); res.addNotice(notice); } } } } } catch (SQLException ex) { log.trace(ex.getLocalizedMessage(), ex); } long time = System.currentTimeMillis() - start; res.setParseTime(time); return res; } RSyntaxSQLParser(DataSource dataSource); static int[] getLastWordPositionAndLength(String statement, int end); void setDataSource(DataSource dataSource); @Override ParseResult parse(RSyntaxDocument doc, String style); static int WORD_POSITION; static int WORD_LENGTH; }
@Test public void testBounds() throws Exception { assumeTrue(!GraphicsEnvironment.isHeadless()); org.h2.Driver driver = org.h2.Driver.load(); OsgiDataSourceFactory dataSourceFactory = new OsgiDataSourceFactory(driver); Properties properties = new Properties(); properties.setProperty(OsgiDataSourceFactory.JDBC_URL, DATABASE_PATH); RSyntaxDocument document = new RSyntaxDocument("sql"); RSyntaxTextArea rSyntaxTextArea = new RSyntaxTextArea(document); rSyntaxTextArea.setText("alter"); RSyntaxSQLParser parser = new RSyntaxSQLParser(dataSourceFactory.createDataSource(properties)); ParseResult res = parser.parse((RSyntaxDocument)rSyntaxTextArea.getDocument(), ""); List noticeList = res.getNotices(); assertEquals(1, noticeList.size()); ParserNotice notice = (ParserNotice) noticeList.get(0); assertEquals(0, notice.getLine()); assertEquals(0, notice.getOffset()); assertEquals(5, notice.getLength()); }