1 19 20 24 25 package org.netbeans.modules.db.sql.visualeditor.querybuilder; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 30 import java.awt.event.ActionEvent ; 31 import java.util.ArrayList ; 32 import javax.swing.text.*; 33 34 import javax.swing.JTextPane ; 35 36 import javax.swing.JPopupMenu ; 37 import javax.swing.JMenu ; 38 import javax.swing.JMenuItem ; 39 40 import org.openide.util.NbBundle; 41 42 public class QueryBuilderSqlTextArea extends JTextPane 43 implements ActionListener, KeyListener { 44 45 private boolean DEBUG = false; 46 private boolean stringIsParsed = false; 47 private QueryBuilder _queryBuilder; 48 private JPopupMenu _sqlTextPopup; 49 String _lastGoodQuery = null; 50 private JMenuItem runQueryMenuItem; 51 private JMenuItem parseQueryMenuItem; 52 private boolean _queryChanged = false; 53 private String keysTyped; 54 65 private boolean _maybeShowPopup = false; 68 69 71 73 private String keywordString = ""; 74 private int currentPosition = 0; 75 private SimpleAttributeSet keyword = new SimpleAttributeSet(); 76 private SimpleAttributeSet schema = new SimpleAttributeSet(); 77 private SimpleAttributeSet table = new SimpleAttributeSet(); 78 private SimpleAttributeSet column = new SimpleAttributeSet(); 79 private SimpleAttributeSet normal = new SimpleAttributeSet(); 80 81 private DefaultStyledDocument dsDocument = (DefaultStyledDocument) 82 getStyledDocument(); 83 private static ArrayList keywords = null; 84 private static final String [] sqlReservedWords = new String [] { 87 "ABSOLUTE", "ACTION", "ADD", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "AS", "ASC", "ASSERTION", "AT", "AUTHORIZATION", "AVG", "BEGIN", "BETWEEN", "BIT", "BIT_LENGTH", "BOTH", "BY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR", "CHARACTER", "CHAR_LENGTH", "CHARACTER_LENGTH", "CHECK", "CLOSE", "COALESCE", "COLLATE", "COLLATION", "COLUMN", "COMMIT", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTINUE", "CONVERT", "CORRESPONDING", "COUNT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DISTINCT", "DOMAIN", "DOUBLE", "DROP", "ELSE", "END", "END-EXEC", "ESCAPE", "EXCEPT", "EXCEPTION", "EXEC", "EXECUTE", "EXISTS", "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FIRST", "FLOAT", "FOR", "FOREIGN", "FOUND", "FROM", "FULL", "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GROUP", "HAVING", "HOUR", "IDENTITY", "IMMEDIATE", "IN", "INDICATOR", "INITIALLY", "INNER", "INPUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT", "INTERVAL", "INTO", "IS", "ISOLATION", "JOIN", "KEY", "LANGUAGE", "LAST", "LEADING", "LEFT", "LEVEL", "LIKE", "LOCAL", "LOWER", "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NEXT", "NO", "NOT", "NULL", "NULLIF", "NUMERIC", "OCTET_LENGTH", "OF", "ON", "ONLY", "OPEN", "OPTION", "OR", "ORDER", "OUTER", "OUTPUT", "OVERLAPS", "PAD", "PARTIAL", "POSITION", "PRECISION", "PREPARE", "PRESERVE", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE", "PUBLIC", "READ", "REAL", "REFERENCES", "RELATIVE", "RESTRICT", "REVOKE", "RIGHT", "ROLLBACK", "ROWS", "SCHEMA", "SCROLL", "SECOND", "SECTION", "SELECT", "SESSION", "SESSION_USER", "SET", "SIZE", "SMALLINT", "SOME", "SPACE", "SQL", "SQLCODE", "SQLERROR", "SQLSTATE", "SUBSTRING", "SUM", "SYSTEM_USER", "TABLE", "TEMPORARY", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSACTION", "TRANSLATE", "TRANSLATION", "TRIM", "TRUE", "UNION", "UNIQUE", "UNKNOWN", "UPDATE", "UPPER", "USAGE", "USER", "USING", "VALUE", "VALUES", "VARCHAR", "VARYING", "VIEW", "WHEN", "WHENEVER", "WHERE", "WITH", "WORK", "WRITE", "YEAR", "ZONE" }; 128 static { 129 keywords = new ArrayList (); 130 for (int i=0; i<sqlReservedWords.length; i++) { 131 keywords.add(sqlReservedWords[i]); 132 } 133 } 134 135 public static final boolean SYNTAX_HIGHLIGHT = true ; 137 139 public QueryBuilderSqlTextArea(QueryBuilder queryBuilder) { 140 super(); 141 _queryBuilder = queryBuilder; 142 _sqlTextPopup = createSqlTextPopup(); 143 144 145 146 if ( SYNTAX_HIGHLIGHT ) { 147 addKeyListener(this); 148 } 149 150 StyleConstants.setForeground(keyword,new Color(0,0,153)); 155 156 StyleConstants.setForeground(schema, new Color(0,111,0)); 158 159 161 StyleConstants.setForeground(column,new Color(120,0,0)); 163 164 } 168 169 170 171 public void keyTyped(KeyEvent e) { 172 if ( SYNTAX_HIGHLIGHT 173 && (_queryBuilder.getParseErrorMessage() == null ) ) { 175 this.currentPosition = this.getCaretPosition(); 176 processChar(e.getKeyChar()); 177 } 178 179 180 } 181 182 183 public void keyReleased(KeyEvent e) { 184 185 } 186 187 189 public void keyPressed(KeyEvent e) { 190 if( e.isShiftDown() ) { 191 int code = e.getKeyCode(); 192 switch(code) { 193 case KeyEvent.VK_F10: 195 if ( ((JTextPane )(e.getComponent())).getText().trim().length() != 0 ) { 200 parseQueryMenuItem.setEnabled(true); 201 runQueryMenuItem.setEnabled(true); 202 } else { 203 parseQueryMenuItem.setEnabled(false); 208 runQueryMenuItem.setEnabled(false); 209 } 210 _maybeShowPopup = true; 211 _sqlTextPopup.show(e.getComponent(), 0, 0); 212 break; 213 } 214 } 215 _queryBuilder.handleKeyPress(e); 216 } 217 218 220 private void replaceString( String str, int pos, 223 SimpleAttributeSet attr ) { 224 try { 225 dsDocument.remove( pos - str.length(), str.length() ); 226 dsDocument.insertString(pos - str.length(), str, attr); 227 } catch (Exception ex){ 228 } 231 } 232 233 private void checkKeyword() { 236 int offset = this.currentPosition; 237 Element element = dsDocument.getParagraphElement( offset ); 238 String elementText = ""; 239 try { 240 elementText = dsDocument.getText( element.getStartOffset(), 241 element.getEndOffset() - element.getStartOffset() ); 242 } catch ( Exception ex ) { 243 } 246 int elementTextLength = elementText.length(); 247 if ( elementTextLength == 0 ) return; 248 249 int i = 0; 250 251 if ( element.getStartOffset() > 0 ) { 252 offset = offset - element.getStartOffset(); 253 } 254 if ( ( offset >= 0 ) && ( offset <= elementTextLength-1 ) ) { 255 i = offset; 256 while ( i > 0 ){ 257 i--; 259 char charAt = elementText.charAt( i ); 260 if ( (charAt == ' ') || (i == 0) || (charAt == '.') || (charAt == '"') || (charAt == '\'') || (charAt == '\t') || (charAt == ',') ) { if (i != 0) { 266 i++; 267 } 268 keywordString = 269 elementText.substring(i, offset); 271 String s = keywordString.trim().toUpperCase(); 272 String db_element = keywordString.trim(); 273 if (keywords.contains(s)){ 275 replaceString(s, currentPosition, keyword); 276 } 277 else if ( _queryBuilder.isSchemaName( db_element ) ) { 279 replaceString(db_element, currentPosition, schema); 280 } 281 else if ( _queryBuilder.isTableName( db_element ) ) { 283 replaceString(db_element, currentPosition, table); 284 } 285 else if ( _queryBuilder.isColumnName( db_element ) ) { 287 replaceString(db_element, currentPosition, column); 288 } 289 else { 292 replaceString( keywordString, currentPosition, normal); 293 } 294 break; 295 } 296 } 297 } 298 } 299 300 301 private void checkString() { 304 int offset = this.currentPosition; 305 Element element = dsDocument.getParagraphElement( offset ); 306 String elementText = ""; 307 try { 308 elementText = dsDocument.getText( element.getStartOffset(), 309 element.getEndOffset() - element.getStartOffset() ); 310 } catch ( Exception ex ) { 311 } 314 int elementTextLength = elementText.length(); 315 if ( elementTextLength == 0 ) return; 316 317 int i = 0; 318 319 if ( element.getStartOffset() > 0 ) { 320 offset = offset - element.getStartOffset(); 321 } 322 if ( ( offset >= 0 ) && ( offset <= elementTextLength ) ) { 323 i = offset; 324 while ( i > 0 ){ 325 i--; 327 char charAt = elementText.charAt( i ); 328 if ( (charAt == '"') || (charAt == '\'' ) ) { keywordString = 330 elementText.substring(i, offset); 332 String s = keywordString.toUpperCase(); 333 String db_element = keywordString; 334 String db_element_wo_quotes; 335 if ( keywordString.length() > 2 && 336 ( (keywordString.startsWith("\"") && keywordString.endsWith("\"") ) || 337 (keywordString.startsWith("\'") && keywordString.endsWith("\'") ) ) ) { 338 db_element_wo_quotes = 339 keywordString.substring(1, keywordString.length()-1); 340 } else if (keywordString.length() > 2 && ( keywordString.startsWith("\"") || keywordString.startsWith("\'") ) ) { 341 db_element_wo_quotes = 342 keywordString.substring(1, keywordString.length()); 343 } else 344 db_element_wo_quotes = keywordString; 345 if ( _queryBuilder.isSchemaName( db_element_wo_quotes ) ) { 347 replaceString(db_element, currentPosition, schema); 348 } 349 else if ( _queryBuilder.isTableName( db_element_wo_quotes ) ) { 351 replaceString(db_element, currentPosition, table); 352 } 353 else if ( _queryBuilder.isColumnName( db_element_wo_quotes ) ) { 355 replaceString(db_element, currentPosition, column); 356 } 357 else { 360 replaceString( keywordString, currentPosition, normal); 361 } 362 break; 363 } 364 } 365 } 366 } 367 368 369 private void processString( String str ) { 370 char strChar = str.charAt(0); 371 if ( strChar == '"' || strChar == '\'') { if ( stringIsParsed ) { 374 checkString(); 375 stringIsParsed = false; 376 } else 377 stringIsParsed = true; 378 } 379 if ( ! stringIsParsed ) { 380 if ( strChar == ' ' || strChar == '\n' || strChar == '\t' || strChar == '.' || strChar == ',' ) { checkKeyword(); 386 } 387 } else { 388 checkString(); 389 } 390 } 391 392 private void processChar(char strChar) { 393 char[] chrstr = new char[1]; 394 chrstr[0] = strChar; 395 String str = new String (chrstr); 396 processString(str); 398 } 399 400 private void processWords(String str){ 401 StringBuffer wordBuffer = new StringBuffer ();; 402 stringIsParsed = false; 403 for ( int i =0; i < str.length(); i++ ) { 404 char strChar = str.charAt(i); 405 if ( strChar == '"' || strChar == '\'') { if ( stringIsParsed ) { 407 stringIsParsed = false; 408 wordBuffer.append(strChar); 409 processWord( i, wordBuffer.toString()); 410 wordBuffer = null; 411 wordBuffer = new StringBuffer (); 412 } else { 413 stringIsParsed = true; 414 } 415 } 416 if (!stringIsParsed) { 417 if ( strChar == ' ' || strChar == '\n' || strChar == '\t' || strChar == '.' || strChar == ',' ) { processWord( i, wordBuffer.toString()); 421 wordBuffer = null; 422 wordBuffer = new StringBuffer (); 423 } else 424 wordBuffer.append(strChar); 425 } else { 426 wordBuffer.append(strChar); 427 } 428 } 429 } 430 431 private void processWord(int position, String str) { 432 String s = str.toUpperCase(); 433 String db_element = str; 434 String db_element_wo_quotes; 435 if (str.length() > 2 && 436 ( (str.startsWith("\"") && str.endsWith("\"") ) || 437 (str.startsWith("\'") && str.endsWith("\'") ) ) ) { 438 db_element_wo_quotes = str.substring(1, str.length()-1); 439 position = position+1; 440 } else if ( str.length() > 2 && 441 ( str.startsWith("\"") || 442 str.startsWith("\'") ) ) { 443 db_element_wo_quotes = str.substring(1, str.length()); 444 position = position+1; 445 } else { 446 db_element_wo_quotes = str; 447 } 448 449 boolean checkMore = true ; 450 if (keywords.contains(s)){ 452 replaceString(s, position, keyword); 453 checkMore = false ; 454 } 455 457 while ( checkMore ) { 458 if ( _queryBuilder.isSchemaName( db_element_wo_quotes ) ) { 459 replaceString(db_element, position, schema); 460 break ; 461 } 462 if ( _queryBuilder.isTableName( db_element_wo_quotes ) ) { 463 replaceString(db_element, position, table); 464 break ; 465 } 466 467 if ( _queryBuilder.isColumnName( db_element_wo_quotes ) ) { 469 replaceString(db_element, position, column); 470 break ; 471 } 472 473 474 replaceString( str, position, normal); 475 476 break ; 477 } 478 } 479 480 482 JPopupMenu createSqlTextPopup() { 483 JPopupMenu sqlTextPopup; 484 JMenu menu; 485 JMenuItem menuItem; 486 487 sqlTextPopup = new JPopupMenu (); 489 490 parseQueryMenuItem = new JMenuItem (NbBundle.getMessage(QueryBuilderSqlTextArea.class, "PARSE_QUERY")); parseQueryMenuItem.addActionListener(this); 492 sqlTextPopup.add(parseQueryMenuItem); 493 494 runQueryMenuItem = new JMenuItem (NbBundle.getMessage(QueryBuilderSqlTextArea.class, "RUN_QUERY")); runQueryMenuItem.addActionListener(this); 496 sqlTextPopup.add(runQueryMenuItem); 497 498 MouseListener popupListener = new sqlTextListener(sqlTextPopup); 500 super.addMouseListener(popupListener); 501 502 return ( sqlTextPopup ); 503 } 504 505 public void setParseQueryMenuEnabled( boolean onOff ) { 506 parseQueryMenuItem.setEnabled(onOff); 507 } 508 509 public void setRunQueryMenuEnabled( boolean onOff ) { 510 runQueryMenuItem.setEnabled(onOff); 511 } 512 513 514 516 class sqlTextListener extends MouseAdapter { 517 518 JPopupMenu popup; 519 520 sqlTextListener(JPopupMenu popupMenu) { 521 popup = popupMenu; 522 } 523 524 public void mousePressed(MouseEvent e) { 525 maybeShowPopup(e); 526 } 527 528 public void mouseReleased(MouseEvent e) { 529 mousePressed(e); 530 } 531 532 private void maybeShowPopup(MouseEvent e) { 533 if (e.isPopupTrigger()) { 534 if ( ((JTextPane )(e.getComponent())).getText().trim().length() != 0 ) { 539 parseQueryMenuItem.setEnabled(true); 540 runQueryMenuItem.setEnabled(true); 541 } else { 542 parseQueryMenuItem.setEnabled(false); 547 runQueryMenuItem.setEnabled(false); 548 } 549 _maybeShowPopup = true; 550 popup.show(e.getComponent(), e.getX(), e.getY()); 551 } 552 } 553 } 554 555 public boolean queryChanged() { 556 return ( ! this.getText().equals( _lastGoodQuery ) ); 557 } 558 559 560 562 public void actionPerformed(ActionEvent e) { 563 564 JMenuItem source = (JMenuItem )(e.getSource()); 565 566 if (source.getText().equals(NbBundle.getMessage(QueryBuilder.class, "PARSE_QUERY"))) { 568 _maybeShowPopup = false; 569 String currentQuery = this.getText(); 570 if ( (currentQuery != null) && 571 (currentQuery.trim().length() != 0 ) ) { 572 580 _queryChanged = true ; 581 QueryBuilder.showBusyCursor( true ); 582 _queryBuilder.populate(currentQuery, true); 583 QueryBuilder.showBusyCursor( false ); 584 } 585 } else if (source.getText().equals(NbBundle.getMessage(QueryBuilder.class, "RUN_QUERY"))) { _maybeShowPopup = false; 587 588 String currentQuery = this.getText(); 589 if ( (currentQuery != null) && 592 (currentQuery.trim().length() != 0 ) ) { 593 if ( currentQuery.trim().equals( _lastGoodQuery ) ) { 594 _queryChanged = false; 595 } else { 596 _queryChanged = true ; 597 QueryBuilder.showBusyCursor( true ); 598 _queryBuilder.populate(this.getText(), true) ; 603 QueryBuilder.showBusyCursor( false ); 604 } 605 } else { 606 return; 607 } 608 609 _queryBuilder.executeQuery(this.getText()); 611 612 } 613 } 614 615 619 public void setQueryText(String str) { 620 621 624 String text = new String ( str + " " ); 625 626 super.setText(text); 627 628 if (DEBUG) 629 System.out.println("setQueryText called with " + str + "\n" ); 631 632 638 639 if ( SYNTAX_HIGHLIGHT 640 && (_queryBuilder.getParseErrorMessage() == null ) ) { 642 processWords(text); 643 } 644 645 649 650 if ( ! text.trim().equals( _lastGoodQuery ) ) { 651 _lastGoodQuery = text; 652 _queryChanged = true; 653 } else { 654 _queryChanged = false; 655 } 656 _maybeShowPopup = false; 657 } 658 659 684 685 688 689 public void restoreLastGoodQuery() { 690 super.setText( _lastGoodQuery ); 691 } 692 693 696 697 public void saveLastGoodQuery(String query) { 698 _lastGoodQuery = query ; 699 } 700 701 704 void clear() { 705 this.setQueryText(""); } 707 708 711 void reset() { 712 this.setQueryText(_lastGoodQuery); 713 } 714 } 715 | Popular Tags |