package com.hundsun.ares.studio.ui.editor.text.sql;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWhitespaceDetector;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
/**
* This class implements a RuleBaseScanner for SQL source code text.
*/
public class SQLCodeScanner extends RuleBasedScanner {
private IToken commentToken;
private IToken stringToken;
private IToken keywordToken;
private IToken datatypeToken;
private IToken functionToken;
private IToken delimitedIdentifierToken;
private IToken otherToken;
private IToken multilineCommentToken;
private List rules;
/**
* This class determines if a character is a whitespace character.
*/
public class SQLWhiteSpaceDetector implements IWhitespaceDetector {
/**
* Determines if the given character is a whitespace character.
* @see org.eclipse.jface.text.rules.IWhitespaceDetector#isWhitespace(char)
*/
public boolean isWhitespace( char c ) {
return Character.isWhitespace( c );
}
} // end inner class
/**
* Constructs an instance of this class using the given color provider.
*/
public SQLCodeScanner( SQLColorProvider colorProvider ) {
/* On "high contrast" displays the default text color (black) is a problem,
* since the normal high contrast background is black. ("High contrast" is
* a Windows feature that helps vision-impaired people.) When high contrast mode is enabled,
* use different colors that show up better against a black background.
*/
if (Display.getDefault().getHighContrast() == true) {
commentToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_COMMENT_COLOR )));
multilineCommentToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_MULTILINE_COMMENT_COLOR )));
stringToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_QUOTED_LITERAL_COLOR )));
keywordToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_KEYWORD_COLOR), null, SWT.BOLD));
datatypeToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_TYPE_COLOR), null, SWT.BOLD ));
functionToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_IDENTIFIER_COLOR )));
// identifierToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_IDENTIFIER_COLOR )));
delimitedIdentifierToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_DELIMITED_IDENTIFIER_COLOR )));
otherToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_HC_DEFAULT_COLOR )));
}
else {
commentToken = colorProvider.createToken(SQLColorProvider.SQL_COMMENT);
multilineCommentToken = colorProvider.createToken(SQLColorProvider.SQL_MULTILINE_COMMENT);
stringToken = colorProvider.createToken(SQLColorProvider.SQL_QUOTED_LITERAL);
keywordToken = colorProvider.createToken(SQLColorProvider.SQL_KEYWORD);
datatypeToken = colorProvider.createToken(SQLColorProvider.SQL_TYPE);
functionToken = colorProvider.createToken(SQLColorProvider.SQL_IDENTIFIER);
// identifierToken = new Token( new TextAttribute( colorProvider.getColor( SQLColorProvider.SQL_IDENTIFIER_COLOR )));
delimitedIdentifierToken = colorProvider.createToken(SQLColorProvider.SQL_DELIMITED_IDENTIFIER);
otherToken = colorProvider.createToken(SQLColorProvider.SQL_DEFAULT);
}
setDefaultReturnToken( otherToken );
rules = new ArrayList();
// Add rule for single-line comments.
rules.add( new EndOfLineRule( "--", commentToken )); //$NON-NLS-1$
// Add rules for delimited identifiers and string literals.
rules.add( new SingleLineRule( "'", "'", stringToken, (char) 0 )); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
rules.add( new SingleLineRule( "\"", "\"", delimitedIdentifierToken, (char) 0 )); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// Add rules for multi-line comments
//rules.add(new NestedMultiLineRule("/*", "*/", multilineCommentToken, (char) 0, true));
// Add generic whitespace rule.
rules.add( new WhitespaceRule( new SQLWhiteSpaceDetector() ));
// Convert the list of rules to an array and return it.
IRule[] result = new IRule[ rules.size() ];
rules.toArray( result );
setRules( result );
}
public void setSQLSyntax(ISQLSyntax sqlSyntax)
{
if (sqlSyntax == null)
{
return; //do nothing
}
ArrayList sqlRules = new ArrayList();
// Define a word rule and add SQL keywords to it.
WordRule wordRule = new WordRule( new SQLWordDetector(), otherToken );
String[] reservedWords = sqlSyntax.getReservedwords();
for (int i = 0; i < reservedWords.length; i++) {
wordRule.addWord( reservedWords[i].toLowerCase(), keywordToken );
wordRule.addWord( reservedWords[i].toUpperCase(), keywordToken );
}
//TODO render unreserved keywords in the same way with reserved keywords, should let user decide via preference
String[] unreservedWords = sqlSyntax.getUnreservedwords();
for (int i = 0; i < unreservedWords.length; i++)
{
wordRule.addWord(unreservedWords[i].toLowerCase(), keywordToken);
wordRule.addWord(unreservedWords[i].toUpperCase(), keywordToken);
}
// Add the SQL datatype names to the word rule.
String[] datatypes = sqlSyntax.getTypes();
for (int i = 0; i < datatypes.length; i++) {
wordRule.addWord( datatypes[i].toLowerCase(), datatypeToken );
wordRule.addWord( datatypes[i].toUpperCase(), datatypeToken );
}
// Add the SQL function names to the word rule.
String[] functions = sqlSyntax.getFunctions();
for (int i = 0; i< functions.length; i++) {
wordRule.addWord( functions[i].toLowerCase(), functionToken );
wordRule.addWord( functions[i].toUpperCase(), functionToken );
}
// Add the SQL constants to the word rule.
String[] constants = sqlSyntax.getConstants();
for (int i = 0; i < constants.length; i++)
{
wordRule.addWord(constants[i].toLowerCase(), datatypeToken);
wordRule.addWord( constants[i].toUpperCase(), datatypeToken );
}
// Add the word rule to the list of rules.
sqlRules.addAll(rules);
sqlRules.add(wordRule);
IRule[] result = new IRule[sqlRules.size()];
sqlRules.toArray(result);
setRules(result);
}
} // end class