1 21 22 package org.armedbear.j; 23 24 import gnu.regexp.RE; 25 import gnu.regexp.REMatch; 26 import java.io.BufferedReader ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.InputStreamReader ; 30 import java.util.ArrayList ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.StringTokenizer ; 34 import java.util.Vector ; 35 import java.util.regex.Matcher ; 36 import java.util.regex.Pattern ; 37 import java.util.regex.PatternSyntaxException ; 38 import javax.swing.SwingUtilities ; 39 import javax.swing.undo.CompoundEdit ; 40 41 public final class FindInFiles extends Replacement implements Constants, 42 BackgroundProcess 43 { 44 private static FindInFiles findInFiles; 45 46 public static final FindInFiles getFindInFiles() 47 { 48 return findInFiles; 49 } 50 51 private final Frame frame; 52 private String files; 53 54 private boolean includeSubdirs; 55 private boolean searchFilesInMemory = true; 56 private ListOccurrencesInFiles outputBuffer; 57 private boolean listEachOccurrence; 58 59 private Mode mode; 60 61 private Vector results = new Vector (); 62 63 private boolean cancelled; 64 65 private int numFilesExamined; 66 private int numFilesModified; 67 68 private List filters; 69 70 private SaveException saveException; 71 private ConfirmReplacementDialog confirmDialog; 72 73 private final String encoding; 74 75 public FindInFiles(Editor editor) 76 { 77 super(editor); 78 this.frame = editor.getFrame(); 79 encoding = 80 Editor.preferences().getStringProperty(Property.DEFAULT_ENCODING); 81 } 82 83 public final boolean getIncludeSubdirs() 84 { 85 return includeSubdirs; 86 } 87 88 public final void setIncludeSubdirs(boolean b) 89 { 90 includeSubdirs = b; 91 } 92 93 public final boolean getSearchFilesInMemory() 94 { 95 return searchFilesInMemory; 96 } 97 98 public final void setSearchFilesInMemory(boolean b) 99 { 100 searchFilesInMemory = b; 101 } 102 103 public final Mode getMode() 104 { 105 return mode; 106 } 107 108 public final void setMode(Mode mode) 109 { 110 this.mode = mode; 111 } 112 113 public final ListOccurrencesInFiles getOutputBuffer() 114 { 115 return outputBuffer; 116 } 117 118 public final void setOutputBuffer(ListOccurrencesInFiles buf) 119 { 120 outputBuffer = buf; 121 } 122 123 public final boolean getListEachOccurrence() 124 { 125 return listEachOccurrence; 126 } 127 128 public final void setListEachOccurrence(boolean b) 129 { 130 listEachOccurrence = b; 131 } 132 133 public void listFiles(Editor editor) 134 { 135 if (outputBuffer != null && editor.getBuffer() != outputBuffer) { 136 Buffer buf = null; 137 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 138 Buffer b = it.nextBuffer(); 139 if (b == outputBuffer) { 140 buf = b; 141 break; 142 } 143 } 144 if (buf == null) { 145 outputBuffer.relink(); 147 } 148 editor.makeNext(outputBuffer); 149 Editor ed = editor.activateInOtherWindow(outputBuffer); 150 if (buf == null) { 151 ed.setDot(outputBuffer.getLastDotPos()); 153 ed.moveCaretToDotCol(); 154 ed.setUpdateFlag(REFRAME); 155 ed.updateDisplay(); 156 } 157 } 158 } 159 160 public final String getFiles() 161 { 162 return files; 163 } 164 165 public void setFiles(String files) throws Exception 166 { 167 ArrayList list = new ArrayList (); 168 StringTokenizer st = new StringTokenizer (files, ";"); 169 File currentDir = getEditor().getCurrentDirectory(); 171 if (currentDir == null || currentDir.isRemote()) 172 throw new Exception ("Operation not supported for remote files"); 173 while (st.hasMoreTokens()) { 174 String token = st.nextToken().trim(); 175 File file = File.getInstance(currentDir, token); 176 if (file == null) { 177 String message = "Invalid path \"" + token + '"'; 178 throw new Exception (message); 179 } 180 File parent = file.getParentFile(); 181 if (parent == null || !parent.isDirectory()) { 183 String message = "Invalid path \"" + token + '"'; 184 throw new Exception (message); 185 } 186 currentDir = parent; 188 String canonicalPath = file.canonicalPath(); 189 try { 192 list.add(new Filter(canonicalPath)); 193 } 194 catch (Exception e) { 195 String message = "Unsupported wild card pattern"; 196 throw new Exception (message); 197 } 198 } 199 this.files = files; 201 filters = list; 202 } 203 204 public final void run() 205 { 206 Debug.assertTrue(outputBuffer != null); 207 outputBuffer.setBusy(true); 208 outputBuffer.setBackgroundProcess(this); 209 runInternal(); 210 outputBuffer.setBackgroundProcess(null); 211 outputBuffer.setBusy(false); 212 if (!cancelled && getReplaceWith() != null) { 213 Runnable r = new Runnable () { 214 public void run() 215 { 216 Editor.getTagFileManager().setEnabled(false); 217 replaceInAllFiles(); 218 Editor.getTagFileManager().setEnabled(true); 219 } 220 }; 221 SwingUtilities.invokeLater(r); 222 } 223 } 224 225 private void runInternal() 226 { 227 frame.setWaitCursor(); 228 for (Iterator it = filters.iterator(); it.hasNext();) { 229 Filter filter = (Filter) it.next(); 230 File dir = null; 231 File spec = File.getInstance(filter.getOriginalPattern()); 232 if (spec != null) { 233 File parent = spec.getParentFile(); 234 if (parent != null) 235 dir = parent; 236 } 237 if (dir == null) 238 dir = getEditor().getCurrentDirectory(); 239 searchDirectory(dir, filter); 240 if (cancelled) 242 break; 243 } 244 if (getReplaceWith() == null) { 245 Runnable runnable = new Runnable () { 247 public void run() 248 { 249 frame.setDefaultCursor(); 250 if (outputBuffer != null) { 251 if (cancelled) 252 getEditor().status("Search cancelled"); 253 else 254 getEditor().status("Search completed"); 255 FastStringBuffer sb = 256 new FastStringBuffer("Pattern found in "); 257 sb.append(results.size()); 258 sb.append(" of "); 259 sb.append(numFilesExamined); 260 sb.append(" files examined"); 261 if (cancelled) 262 sb.append(" (search cancelled by user)"); 263 outputBuffer.appendStatusLine(sb.toString()); 264 outputBuffer.invalidate(); 265 outputBuffer.renumber(); 266 outputBuffer.setBusy(false); 267 EditorIterator iter = new EditorIterator(); 268 while (iter.hasNext()) { 269 Editor ed = iter.nextEditor(); 270 if (ed.getBuffer() == outputBuffer) { 271 ed.setTopLine(outputBuffer.getFirstLine()); 272 ed.setDot(outputBuffer.getInitialDotPos()); 273 ed.moveCaretToDotCol(); 274 ed.setUpdateFlag(REPAINT); 275 ed.updateDisplay(); 276 } 277 } 278 } 279 } 280 }; 281 SwingUtilities.invokeLater(runnable); 282 return; 284 } 285 SwingUtilities.invokeLater(updateDisplayRunnable); 286 } 287 288 public final void cancel() 289 { 290 cancelled = true; 291 } 292 293 private void searchDirectory(File dir, Filter filter) 294 { 295 String [] files = dir.list(); 296 if (files == null) 297 return; 298 for (int i = 0; i < files.length; i++) { 299 if (cancelled) 300 return; 301 File file = File.getInstance(dir, files[i]); 302 if (file.isDirectory()) { 303 if (includeSubdirs) 304 searchDirectory(file, filter); continue; 306 } 307 if (!filter.accepts(files[i])) 308 continue; 309 if (isBinaryFile(file)) 310 continue; 311 if (searchFilesInMemory) { 312 Buffer buf = Editor.getBufferList().findBuffer(file); 313 if (buf != null && buf.isLoaded()) { 314 Position pos = findInBuffer(buf); 315 if (pos != null) { 316 results.add(file); 317 processFile(file, buf.getMode(), pos); 318 } 319 ++numFilesExamined; 320 continue; 321 } 322 } 324 Debug.assertTrue(outputBuffer != null); 325 processFile(file); 326 ++numFilesExamined; 327 } 328 } 329 330 private void processFile(File file) 331 { 332 try { 333 boolean update = false; 334 BufferedReader reader = 335 new BufferedReader (new InputStreamReader (file.getInputStream(), 336 encoding)); 337 int lineNumber = 0; 338 int matches = 0; 339 final boolean delimited = wholeWordsOnly(); 340 String s; 341 while ((s = reader.readLine()) != null) { 342 ++lineNumber; 343 boolean found = delimited ? findDelimited(s, mode) : find(s); 344 if (found) { 345 try { 346 outputBuffer.lockWrite(); 347 } 348 catch (InterruptedException e) { 349 Log.error(e); 350 return; 351 } 352 try { 353 if (matches == 0) { 354 if (!listEachOccurrence && results.size() == 0) 356 outputBuffer.appendLine("Found in:"); 357 outputBuffer.appendFileLine(file, 358 listEachOccurrence); 359 results.add(file); 360 update = true; 361 } 362 ++matches; 363 if (listEachOccurrence) 364 outputBuffer.appendOccurrenceLine(s, lineNumber); 365 else 366 break; 367 } 368 finally { 369 outputBuffer.renumber(); 370 outputBuffer.unlockWrite(); 371 } 372 } 373 } 374 if (update) 376 SwingUtilities.invokeLater(updateDisplayRunnable); 377 } 378 catch (IOException e) { 379 Log.error(e); 380 } 381 } 382 383 private static boolean isBinaryFile(File file) 385 { 386 try { 387 InputStream in = file.getInputStream(); 388 byte[] bytes = new byte[4096]; 389 int bytesRead = in.read(bytes); 390 in.close(); 391 for (int i = 0; i < bytesRead; i++) { 392 if (bytes[i] == 0) 393 return true; 394 } 395 return false; 396 } 397 catch (IOException e) { 398 Log.error(e); 399 return true; 400 } 401 } 402 403 private void processFile(File file, Mode mode, Position pos) 404 { 405 Debug.assertTrue(outputBuffer != null); 406 try { 407 outputBuffer.lockWrite(); 408 } 409 catch (InterruptedException e) { 410 Log.error(e); 411 return; 412 } 413 try { 414 processFileInternal(file, mode, pos); 415 outputBuffer.renumber(); 416 } 417 finally { 418 outputBuffer.unlockWrite(); 419 } 420 SwingUtilities.invokeLater(updateDisplayRunnable); 422 } 423 424 private final Runnable updateDisplayRunnable = new Runnable () { 425 public void run() 426 { 427 Position end = null; 428 for (EditorIterator iter = new EditorIterator(); iter.hasNext();) { 429 Editor ed = iter.nextEditor(); 430 if (ed.getBuffer() == outputBuffer) { 431 if (end == null) { 432 end = outputBuffer.getEnd(); 433 end.setOffset(0); 434 } 435 ed.moveDotTo(end); 436 ed.setUpdateFlag(REPAINT); 437 ed.updateDisplay(); 438 } 439 } 440 } 441 }; 442 443 private void processFileInternal(File file, Mode mode, Position pos) 444 { 445 if (!listEachOccurrence && results.size() == 1) 446 outputBuffer.appendLine("Found in:"); 447 outputBuffer.appendFileLine(file, listEachOccurrence); 448 if (listEachOccurrence) { 449 outputBuffer.appendOccurrenceLine(pos.getLine()); 450 while (pos.getLine().next() != null) { 451 pos.moveTo(pos.getLine().next(), 0); 452 if ((pos = find(mode, pos)) != null) 453 outputBuffer.appendOccurrenceLine(pos.getLine()); 454 else 455 break; 456 } 457 } 458 } 459 460 private void replaceInAllFiles() 461 { 462 final Editor editor = getEditor(); 463 final Buffer oldBuffer = editor.getBuffer(); 464 for (int i = 0; i < results.size(); i++) { 465 File file = (File) results.get(i); 466 try { 467 replaceInFile(file); 468 } 469 catch (CheckFileException e) { 470 handleCheckFileException(e); 471 } 472 catch (SaveException e) { 473 handleSaveException(e); 474 } 475 if (cancelled) 476 break; 477 } 478 479 Runnable runnable = new Runnable () { 481 public void run() 482 { 483 editor.activate(oldBuffer); 484 editor.setUpdateFlag(REPAINT); 485 frame.setDefaultCursor(); 486 editor.updateDisplay(); 487 completed(); 488 } 489 }; 490 if (SwingUtilities.isEventDispatchThread()) 491 runnable.run(); 492 else 493 SwingUtilities.invokeLater(runnable); 494 } 495 496 private void handleCheckFileException(final CheckFileException e) 497 { 498 Runnable runnable = new Runnable () { 499 public void run() 500 { 501 String title = "Replace In Files"; 502 String message = e.getMessage(); 503 if (message == null) 504 message = "Error."; 505 message += " Continue?"; 506 cancelled = !getEditor().confirm(title, message); 507 } 508 }; 509 510 if (SwingUtilities.isEventDispatchThread()) { 511 runnable.run(); 512 } else { 513 try { 514 SwingUtilities.invokeAndWait(runnable); 515 } 516 catch (Exception ex) { 517 Log.error(ex); 518 } 519 } 520 } 521 522 private void handleSaveException(final SaveException e) 523 { 524 Runnable runnable = new Runnable () { 525 public void run() 526 { 527 String title = "Replace In Files"; 528 String message = e.getMessage(); 529 530 if (message != null) 532 MessageDialog.showMessageDialog(message, title); 533 534 message = "Unable to save " + e.getFile().canonicalPath(); 536 MessageDialog.showMessageDialog(message, title); 537 538 message = "Continue anyway?"; 539 cancelled = !getEditor().confirm(title, message); 540 } 541 }; 542 543 if (SwingUtilities.isEventDispatchThread()) { 544 runnable.run(); 545 } else { 546 try { 547 SwingUtilities.invokeAndWait(runnable); 548 } 549 catch (Exception ex) { 550 Log.error(ex); 551 } 552 } 553 } 554 555 private void replaceInFile(final File file) throws CheckFileException, 556 SaveException 557 { 558 checkFile(file); 559 560 if (confirmChanges()) { 561 if (SwingUtilities.isEventDispatchThread()) { 562 frame.setDefaultCursor(); 563 replaceInFileConfirm(file); 564 frame.setWaitCursor(); 565 } else { 566 Runnable runnable = new Runnable () { 567 public void run() 568 { 569 frame.setDefaultCursor(); 570 try { 571 replaceInFileConfirm(file); 572 } 573 catch (SaveException e) { 574 FindInFiles.this.saveException = e; 575 } 576 frame.setWaitCursor(); 577 } 578 }; 579 try { 580 SwingUtilities.invokeAndWait(runnable); 581 } 582 catch (Exception e) { 583 Log.error(e); 584 } 585 if (FindInFiles.this.saveException != null) 586 throw FindInFiles.this.saveException; 587 } 588 } else 589 replaceInFileNoConfirm(file); 590 } 591 592 private void replaceInFileNoConfirm(File file) throws SaveException 593 { 594 Buffer buffer = Editor.getBufferList().findBuffer(file); 595 if (buffer != null) { 596 if (!buffer.isLoaded()) { 599 if (!buffer.initialized()) 600 buffer.initialize(); 601 buffer.load(); 602 if (!buffer.isLoaded()) 603 return; } 605 final boolean wasModified = buffer.isModified(); 606 int oldReplacementCount = getReplacementCount(); 607 try { 608 buffer.lockWrite(); 609 } 610 catch (InterruptedException e) { 611 Log.error(e); 612 return; 613 } 614 try { 615 CompoundEdit compoundEdit = new CompoundEdit (); 616 Position pos = new Position(buffer.getFirstLine(), 0); 617 while ((pos = find(mode, pos)) != null) { 618 compoundEdit.addEdit(new UndoLineEdit(buffer, pos.getLine())); 619 replaceOccurrence(pos); 620 buffer.incrementModCount(); 621 } 622 compoundEdit.end(); 623 buffer.addEdit(compoundEdit); 624 } 625 finally { 626 buffer.unlockWrite(); 627 } 628 if (buffer.isModified() != wasModified) 629 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_REPAINT_BUFFER_LIST); 630 if (getReplacementCount() > oldReplacementCount) 631 ++numFilesModified; 632 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 633 Editor ed = it.nextEditor(); 634 if (ed.getBuffer() == buffer) { 635 if (ed.getDotOffset() > ed.getDotLine().length()) { 636 ed.getDot().setOffset(ed.getDotLine().length()); 637 ed.moveCaretToDotCol(); 638 ed.updateDotLine(); 639 ed.updateDisplay(); 640 } 641 } 642 } 643 } else { 644 SystemBuffer buf = new SystemBuffer(file); 646 buf.load(); 647 if (!buf.isLoaded()) 648 return; boolean modified = false; 650 Position pos = new Position(buf.getFirstLine(), 0); 651 while ((pos = find((Mode)null, pos)) != null) { 652 if (cancelled) 653 break; 654 replaceOccurrence(pos); 655 modified = true; 656 } 657 if (modified) 658 buf.writeBuffer(); if (modified) 660 ++numFilesModified; 661 } 662 replacedInFile(file); 663 } 664 665 private void replaceInFileConfirm(File file) throws SaveException 666 { 667 final Editor editor = getEditor(); 668 boolean close = false; 669 Buffer buffer = Editor.getBufferList().findBuffer(file); 670 if (buffer == null) { 671 buffer = Buffer.createBuffer(file); 672 if (buffer == null) 673 return; 675 close = true; 678 } 679 editor.activate(buffer); 680 int oldReplacementCount = getReplacementCount(); 681 Position saved = new Position(editor.getDot()); 682 CompoundEdit compoundEdit = buffer.beginCompoundEdit(); 683 editor.moveDotTo(buffer.getFirstLine(), 0); 684 Position pos = find(mode, editor.getDot()); 685 if (pos == null) { 686 buffer.endCompoundEdit(compoundEdit); 688 editor.undo(); 689 return; 690 } 691 final boolean wasModified = buffer.isModified(); 692 editor.moveDotTo(pos); 693 editor.markFoundPattern(this); 694 editor.updateDisplay(); 695 confirmDialog = new ConfirmReplacementDialog(this, true); 696 confirmDialog.setTitle(file.netPath()); 697 698 confirmDialog.show(); 700 701 if (confirmDialog.cancelled()) 702 cancelled = true; 703 editor.moveDotTo(saved); 704 buffer.endCompoundEdit(compoundEdit); 705 if (close) { 706 if (buffer.isModified()) { 707 buffer.writeBuffer(); buffer.saved(); 709 buffer.setLastModified(buffer.getFile().lastModified()); 710 } 711 if (!buffer.isModified()) 712 buffer.kill(); 713 } else { 714 if (buffer.isModified() != wasModified) { 717 Sidebar.setUpdateFlagInAllFrames(SIDEBAR_REPAINT_BUFFER_LIST); 720 } 721 } 722 723 if (getReplacementCount() > oldReplacementCount) { 724 ++numFilesModified; 725 replacedInFile(file); 726 } 727 } 728 729 private void replacedInFile(File file) 730 { 731 if (outputBuffer != null) { 732 try { 733 outputBuffer.lockWrite(); 734 } 735 catch (InterruptedException e) { 736 Log.error(e); 737 return; 738 } 739 try { 740 if (numFilesModified == 1) 741 outputBuffer.appendLine("Replaced in:"); 742 outputBuffer.appendFileLine(file, false); 743 } 744 finally { 745 outputBuffer.renumber(); 746 outputBuffer.unlockWrite(); 747 } 748 if (SwingUtilities.isEventDispatchThread()) { 750 Position end = null; 751 for (EditorIterator iter = new EditorIterator(); iter.hasNext();) { 752 Editor ed = iter.nextEditor(); 753 if (ed.getBuffer() == outputBuffer) { 754 if (end == null) 755 end = outputBuffer.getEnd(); 756 ed.moveDotTo(end); 757 ed.setUpdateFlag(REPAINT); 758 ed.updateDisplay(); 759 ed.repaintNow(); 760 } 761 } 762 } else { 763 Debug.bug(); 764 SwingUtilities.invokeLater(updateDisplayRunnable); 765 } 766 } 767 } 768 769 private void checkFile(File file) throws CheckFileException 770 { 771 if (file.isRemote()) 772 checkFileError(file, "file is not local"); 773 if (file.isDirectory()) 774 checkFileError(file, "file is a directory"); 775 if (!file.isFile()) 776 checkFileError(file, "file not found"); 777 if (!file.canRead()) 778 checkFileError(file, "file is not readable"); 779 boolean writable = file.canWrite(); 780 if (!writable) { 781 if (Editor.preferences().getBooleanProperty(Property.P4_AUTO_EDIT)) { 782 if (P4.autoEdit(file)) 783 writable = file.canWrite(); 784 } 785 if (!writable) 786 checkFileError(file, "file is read only"); 787 } 788 } 789 790 private void checkFileError(File file, String reason) throws CheckFileException 791 { 792 FastStringBuffer sb = new FastStringBuffer("Can't process "); 793 sb.append(file.netPath()); 794 sb.append(" ("); 795 sb.append(reason); 796 sb.append(')'); 797 throw new CheckFileException(sb.toString()); 798 799 } 800 801 private void completed() 803 { 804 FastStringBuffer sb = new FastStringBuffer(); 805 int replacementCount = getReplacementCount(); 806 if (replacementCount == 0) { 807 sb.append("No occurrences replaced"); 808 } else { 809 sb.append("Replaced "); 810 sb.append(replacementCount); 811 sb.append(" occurrence"); 812 if (replacementCount > 1) 813 sb.append('s'); 814 sb.append(" in "); 815 sb.append(numFilesModified); 816 sb.append(" file"); 817 if (numFilesModified > 1) 818 sb.append('s'); 819 } 820 if (cancelled) 821 sb.append(" (operation cancelled)"); 822 else 823 sb.append(" (" + numFilesExamined + " files examined)"); 824 if (outputBuffer != null) { 825 outputBuffer.appendStatusLine(sb.toString()); 826 outputBuffer.renumber(); 827 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 828 Editor ed = it.nextEditor(); 829 if (ed.getBuffer() == outputBuffer) { 830 ed.setTopLine(outputBuffer.getFirstLine()); 831 ed.setDot(outputBuffer.getEnd()); 832 ed.moveCaretToDotCol(); 833 ed.setUpdateFlag(REPAINT); 834 ed.updateDisplay(); 835 } 836 } 837 } else 838 MessageDialog.showMessageDialog(getEditor(), sb.toString(), 839 "ReplaceInFiles"); 840 } 841 842 public static void findInFiles() 843 { 844 final Editor editor = Editor.currentEditor(); 845 final File dir = editor.getCurrentDirectory(); 846 if (dir != null && !dir.isRemote()) 847 findOrReplaceInFiles(editor, false); 848 } 849 850 public static void replaceInFiles() 851 { 852 final Editor editor = Editor.currentEditor(); 853 final File dir = editor.getCurrentDirectory(); 854 if (dir != null && !dir.isRemote()) 855 findOrReplaceInFiles(editor, true); 856 } 857 858 private static void findOrReplaceInFiles(Editor editor, boolean replace) 859 { 860 FindInFilesDialog d = new FindInFilesDialog(editor, replace); 861 editor.centerDialog(d); 862 d.show(); 863 editor.repaintNow(); 864 if (d.getFindInFiles() == null) 865 return; 866 if (findInFiles != null) { 867 Buffer buf = findInFiles.getOutputBuffer(); 869 if (Editor.getBufferList().contains(buf)) 870 buf.kill(); 871 } 872 findInFiles = d.getFindInFiles(); 873 findInFiles.setOutputBuffer(new ListOccurrencesInFiles(findInFiles)); 874 new Thread (findInFiles).start(); 875 Buffer outputBuffer = findInFiles.getOutputBuffer(); 876 if (outputBuffer != null) { 877 Editor otherEditor = editor.getOtherEditor(); 878 if (otherEditor != null) { 879 outputBuffer.setUnsplitOnClose(otherEditor.getBuffer().unsplitOnClose()); 880 otherEditor.makeNext(outputBuffer); 881 } else 882 outputBuffer.setUnsplitOnClose(true); 883 editor.activateInOtherWindow(outputBuffer); 884 } 885 editor.status("Press Escape to cancel search"); 886 } 887 888 public static void listFiles() 889 { 890 if (findInFiles != null) 891 findInFiles.listFiles(Editor.currentEditor()); 892 } 893 894 private static final class Filter 895 { 896 private final String originalPattern; 897 private final boolean ignoreCase; 898 private Pattern pattern; 899 900 public Filter(String s) throws Exception 901 { 902 this.originalPattern = s; 903 ignoreCase = Platform.isPlatformWindows(); 904 File file = File.getInstance(ignoreCase ? s.toLowerCase() : s); 905 if (!processFilter(file.getName())) 906 throw new Exception ("process pattern failed"); 907 } 908 909 public String getOriginalPattern() 910 { 911 return originalPattern; 912 } 913 914 private boolean processFilter(String s) 915 { 916 FastStringBuffer sb = new FastStringBuffer(); 917 for (int i = 0; i < s.length(); i++) { 918 char c = s.charAt(i); 919 switch (c) { 920 case '.': 921 sb.append("\\."); 922 break; 923 case '*': 924 sb.append(".*"); 925 break; 926 case '?': 927 sb.append(".?"); 928 break; 929 default: 930 sb.append(c); 931 break; 932 } 933 } 934 try { 935 pattern = Pattern.compile(sb.toString()); 936 return true; 937 } 938 catch (PatternSyntaxException e) { 939 Log.error(e); 940 return false; 941 } 942 } 943 944 public boolean accepts(String name) 945 { 946 if (ignoreCase) 947 name = name.toLowerCase(); 948 Matcher matcher = pattern.matcher(name); 949 return matcher.matches(); 950 } 951 } 952 953 private static final class CheckFileException extends Exception 954 { 955 CheckFileException(String message) 956 { 957 super(message); 958 } 959 } 960 } 961 | Popular Tags |