/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
package org.eclipse.search.internal.core.text; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.util.Collection; | |
import java.util.Iterator; | |
import org.eclipse.jface.text.Position; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.resources.IProject; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IPath; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.OperationCanceledException; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.search.internal.core.ISearchScope; | |
import org.eclipse.search.internal.ui.SearchPlugin; | |
import org.eclipse.search.internal.ui.util.StringMatcher; | |
import org.eclipse.search.ui.SearchUI; | |
import org.eclipse.search.internal.ui.SearchMessages; | |
/** | |
* The visitor that does the actual work. | |
*/ | |
public class TextSearchVisitor extends TypedResourceVisitor { | |
protected static final int fgLF= '\n'; | |
protected static final int fgCR= '\r'; | |
private String fPattern; | |
private ISearchScope fScope; | |
private ITextSearchResultCollector fCollector; | |
private String fOptions; | |
private IProgressMonitor fProgressMonitor; | |
private StringMatcher fMatcher; | |
private String fErrorMessage; | |
protected int fPushbackChar; | |
protected boolean fPushback; | |
public TextSearchVisitor(String pattern, String options, ISearchScope scope, ITextSearchResultCollector collector) | |
throws CoreException { | |
fPattern= pattern; | |
fScope= scope; | |
fCollector= collector; | |
fPushback= false; | |
if (options != null) | |
fOptions= options; | |
else | |
fOptions= ""; //$NON-NLS-1$ | |
fProgressMonitor= collector.getProgressMonitor(); | |
fMatcher= new StringMatcher(pattern, options.indexOf('i') != -1, false); | |
} | |
public void process(Collection projects) throws CoreException { | |
Iterator i= projects.iterator(); | |
while(i.hasNext()) { | |
IProject project= (IProject)i.next(); | |
project.accept(this); | |
} | |
} | |
protected boolean visitFile(IFile file) throws CoreException { | |
if (! fScope.encloses(file)) | |
return false; | |
try { | |
InputStream stream= file.getContents(false); | |
BufferedReader reader= new BufferedReader(new InputStreamReader(stream)); | |
StringBuffer sb= new StringBuffer(100); | |
int lineCounter= 1; | |
int charCounter=0; | |
boolean eof= false; | |
try { | |
while (!eof) { | |
int eolStrLength= readLine(reader, sb); | |
int lineLength= sb.length(); | |
int start= 0; | |
eof= eolStrLength == -1; | |
String line= sb.toString(); | |
StringMatcher.Position match; | |
while (start < lineLength) { | |
if ((match= fMatcher.find(line, start, lineLength)) != null) { | |
start= charCounter + match.getStart(); | |
int length= match.getEnd() - match.getStart(); | |
fCollector.accept(file, line.trim(), start, length, lineCounter); | |
start= match.getEnd(); | |
} | |
else // no match in this line | |
start= lineLength; | |
} | |
charCounter+= lineLength + eolStrLength; | |
lineCounter++; | |
} | |
} finally { | |
if (reader != null) | |
reader.close(); | |
} | |
} catch (IOException e) { | |
String message= SearchMessages.getFormattedString("TextSearchVisitor.error", file.getFullPath()); //$NON-NLS-1$ | |
throw new CoreException(new Status(IStatus.ERROR, SearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e)); | |
} | |
finally { | |
fProgressMonitor.worked(1); | |
if (fProgressMonitor.isCanceled()) | |
throw new OperationCanceledException(SearchMessages.getString("TextSearchVisitor.canceled")); //$NON-NLS-1$ | |
} | |
return true; | |
} | |
protected int readLine(BufferedReader reader, StringBuffer sb) throws IOException { | |
int ch= -1; | |
sb.setLength(0); | |
if (fPushback) { | |
ch= fPushbackChar; | |
fPushback= false; | |
} | |
else | |
ch= reader.read(); | |
while (ch >= 0) { | |
if (ch == fgLF) | |
return 1; | |
if (ch == fgCR) { | |
ch= reader.read(); | |
if (ch == fgLF) | |
return 2; | |
else { | |
fPushbackChar= ch; | |
fPushback= true; | |
return 1; | |
} | |
} | |
sb.append((char)ch); | |
ch= reader.read(); | |
} | |
return -1; | |
} | |
} | |