KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > FindInFiles


1 /*
2  * FindInFiles.java
3  *
4  * Copyright (C) 1998-2004 Peter Graves
5  * $Id: FindInFiles.java,v 1.16 2004/04/26 19:49:28 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import gnu.regexp.RE;
25 import gnu.regexp.REMatch;
26 import java.io.BufferedReader JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.InputStreamReader JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34 import java.util.Vector JavaDoc;
35 import java.util.regex.Matcher JavaDoc;
36 import java.util.regex.Pattern JavaDoc;
37 import java.util.regex.PatternSyntaxException JavaDoc;
38 import javax.swing.SwingUtilities JavaDoc;
39 import javax.swing.undo.CompoundEdit JavaDoc;
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 JavaDoc 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 JavaDoc results = new Vector JavaDoc();
62
63     private boolean cancelled;
64
65     private int numFilesExamined;
66     private int numFilesModified;
67
68     private List JavaDoc filters;
69
70     private SaveException saveException;
71     private ConfirmReplacementDialog confirmDialog;
72
73     private final String JavaDoc 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                 // Output buffer was closed.
146
outputBuffer.relink();
147             }
148             editor.makeNext(outputBuffer);
149             Editor ed = editor.activateInOtherWindow(outputBuffer);
150             if (buf == null) {
151                 // Need to restore dot pos.
152
ed.setDot(outputBuffer.getLastDotPos());
153                 ed.moveCaretToDotCol();
154                 ed.setUpdateFlag(REFRAME);
155                 ed.updateDisplay();
156             }
157         }
158     }
159
160     public final String JavaDoc getFiles()
161     {
162         return files;
163     }
164
165     public void setFiles(String JavaDoc files) throws Exception JavaDoc
166     {
167         ArrayList JavaDoc list = new ArrayList JavaDoc();
168         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(files, ";");
169         // We start in the editor's current directory.
170
File currentDir = getEditor().getCurrentDirectory();
171         if (currentDir == null || currentDir.isRemote())
172             throw new Exception JavaDoc("Operation not supported for remote files");
173         while (st.hasMoreTokens()) {
174             String JavaDoc token = st.nextToken().trim();
175             File file = File.getInstance(currentDir, token);
176             if (file == null) {
177                 String JavaDoc message = "Invalid path \"" + token + '"';
178                 throw new Exception JavaDoc(message);
179             }
180             File parent = file.getParentFile();
181             // Verify that the parent directory actually exists.
182
if (parent == null || !parent.isDirectory()) {
183                 String JavaDoc message = "Invalid path \"" + token + '"';
184                 throw new Exception JavaDoc(message);
185             }
186             // Parent is our new current directory.
187
currentDir = parent;
188             String JavaDoc canonicalPath = file.canonicalPath();
189             // This will throw an exception if canonicalPath isn't an
190
// acceptable wildcard pattern.
191
try {
192                 list.add(new Filter(canonicalPath));
193             }
194             catch (Exception JavaDoc e) {
195                 String JavaDoc message = "Unsupported wild card pattern";
196                 throw new Exception JavaDoc(message);
197             }
198         }
199         // Success.
200
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 JavaDoc r = new Runnable JavaDoc() {
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 JavaDoc 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             // Did the user cancel?
241
if (cancelled)
242                 break;
243         }
244         if (getReplaceWith() == null) {
245             // Find in files, not replace in files.
246
Runnable JavaDoc runnable = new Runnable JavaDoc() {
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             // Nothing more to do.
283
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 JavaDoc[] 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); // Recurse!
305
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                 // No buffer found, fall through...
323
}
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 JavaDoc reader =
335                 new BufferedReader JavaDoc(new InputStreamReader JavaDoc(file.getInputStream(),
336                                                          encoding));
337             int lineNumber = 0;
338             int matches = 0;
339             final boolean delimited = wholeWordsOnly();
340             String JavaDoc 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 JavaDoc e) {
349                         Log.error(e);
350                         return;
351                     }
352                     try {
353                         if (matches == 0) {
354                             // First match in this file.
355
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             // Update display once per file.
375
if (update)
376                 SwingUtilities.invokeLater(updateDisplayRunnable);
377         }
378         catch (IOException JavaDoc e) {
379             Log.error(e);
380         }
381     }
382
383     // BUG!! Unicode files are treated as binary.
384
private static boolean isBinaryFile(File file)
385     {
386         try {
387             InputStream JavaDoc 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 JavaDoc 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 JavaDoc 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         // Update display once per file.
421
SwingUtilities.invokeLater(updateDisplayRunnable);
422     }
423
424     private final Runnable JavaDoc updateDisplayRunnable = new Runnable JavaDoc() {
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         // Restore state and display completion message.
480
Runnable JavaDoc runnable = new Runnable JavaDoc() {
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 JavaDoc runnable = new Runnable JavaDoc() {
499             public void run()
500             {
501                 String JavaDoc title = "Replace In Files";
502                 String JavaDoc 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 JavaDoc ex) {
517                 Log.error(ex);
518             }
519         }
520     }
521
522     private void handleSaveException(final SaveException e)
523     {
524         Runnable JavaDoc runnable = new Runnable JavaDoc() {
525             public void run()
526             {
527                 String JavaDoc title = "Replace In Files";
528                 String JavaDoc message = e.getMessage();
529
530                 // Tell user exactly what error occurred.
531
if (message != null)
532                     MessageDialog.showMessageDialog(message, title);
533
534                 // Display summary message.
535
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 JavaDoc 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 JavaDoc runnable = new Runnable JavaDoc() {
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 JavaDoc 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             // Found existing buffer. It may or may not be loaded at this
597
// point.
598
if (!buffer.isLoaded()) {
599                 if (!buffer.initialized())
600                     buffer.initialize();
601                 buffer.load();
602                 if (!buffer.isLoaded())
603                     return; // Error handling?
604
}
605             final boolean wasModified = buffer.isModified();
606             int oldReplacementCount = getReplacementCount();
607             try {
608                 buffer.lockWrite();
609             }
610             catch (InterruptedException JavaDoc e) {
611                 Log.error(e);
612                 return;
613             }
614             try {
615                 CompoundEdit JavaDoc compoundEdit = new CompoundEdit JavaDoc();
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             // There was no buffer for the file in question prior to this operation.
645
SystemBuffer buf = new SystemBuffer(file);
646             buf.load();
647             if (!buf.isLoaded())
648                 return; // Error handling?
649
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(); // Throws SaveException if there's an error.
659
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; // Error handling?
674

675             // We created the buffer for this operation, so we should close it
676
// when we're done.
677
close = true;
678         }
679         editor.activate(buffer);
680         int oldReplacementCount = getReplacementCount();
681         Position saved = new Position(editor.getDot());
682         CompoundEdit JavaDoc compoundEdit = buffer.beginCompoundEdit();
683         editor.moveDotTo(buffer.getFirstLine(), 0);
684         Position pos = find(mode, editor.getDot());
685         if (pos == null) {
686             // Not found.
687
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         // This is modal: carry out all replacements in this file.
699
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(); // Throws SaveException if there's an error.
708
buffer.saved();
709                 buffer.setLastModified(buffer.getFile().lastModified());
710             }
711             if (!buffer.isModified())
712                 buffer.kill();
713         } else {
714             // We're keeping the buffer open. Make sure the sidebar shows the
715
// modified status for the file correctly.
716
if (buffer.isModified() != wasModified) {
717                 // The file was just modified for the fist time. The buffer
718
// lists need to be updated.
719
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 JavaDoc 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             // Update display once per file.
749
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 JavaDoc 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     // Completion message for replace in files only.
802
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             // Kill old output buffer.
868
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 JavaDoc(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 JavaDoc originalPattern;
897         private final boolean ignoreCase;
898         private Pattern JavaDoc pattern;
899
900         public Filter(String JavaDoc s) throws Exception JavaDoc
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 JavaDoc("process pattern failed");
907         }
908
909         public String JavaDoc getOriginalPattern()
910         {
911             return originalPattern;
912         }
913
914         private boolean processFilter(String JavaDoc 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 JavaDoc e) {
939                 Log.error(e);
940                 return false;
941             }
942         }
943
944         public boolean accepts(String JavaDoc name)
945         {
946             if (ignoreCase)
947                 name = name.toLowerCase();
948             Matcher JavaDoc matcher = pattern.matcher(name);
949             return matcher.matches();
950         }
951     }
952
953     private static final class CheckFileException extends Exception JavaDoc
954     {
955         CheckFileException(String JavaDoc message)
956         {
957             super(message);
958         }
959     }
960 }
961
Popular Tags