blob: 4f9fab5f0eb04d6c87981355e7a3478cde56290b [file] [log] [blame]
/*
* (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;
}
}