| Index: editor/tools/plugins/com.google.dart.tools.search/src/com/google/dart/tools/search/internal/core/text/TextSearchVisitor.java
|
| ===================================================================
|
| --- editor/tools/plugins/com.google.dart.tools.search/src/com/google/dart/tools/search/internal/core/text/TextSearchVisitor.java (revision 7355)
|
| +++ editor/tools/plugins/com.google.dart.tools.search/src/com/google/dart/tools/search/internal/core/text/TextSearchVisitor.java (working copy)
|
| @@ -1,404 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2011, the Dart project authors.
|
| - *
|
| - * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
|
| - * in compliance with the License. You may obtain a copy of the License at
|
| - *
|
| - * http://www.eclipse.org/legal/epl-v10.html
|
| - *
|
| - * Unless required by applicable law or agreed to in writing, software distributed under the License
|
| - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
| - * or implied. See the License for the specific language governing permissions and limitations under
|
| - * the License.
|
| - */
|
| -package com.google.dart.tools.search.internal.core.text;
|
| -
|
| -import com.google.dart.tools.search.core.text.TextSearchMatchAccess;
|
| -import com.google.dart.tools.search.core.text.TextSearchRequestor;
|
| -import com.google.dart.tools.search.core.text.TextSearchScope;
|
| -import com.google.dart.tools.search.internal.core.text.FileCharSequenceProvider.FileCharSequenceException;
|
| -import com.google.dart.tools.search.internal.ui.Messages;
|
| -import com.google.dart.tools.search.internal.ui.SearchMessages;
|
| -import com.google.dart.tools.search.internal.ui.SearchPlugin;
|
| -import com.google.dart.tools.search.ui.NewSearchUI;
|
| -
|
| -import org.eclipse.core.filebuffers.FileBuffers;
|
| -import org.eclipse.core.filebuffers.ITextFileBuffer;
|
| -import org.eclipse.core.filebuffers.ITextFileBufferManager;
|
| -import org.eclipse.core.filebuffers.LocationKind;
|
| -import org.eclipse.core.resources.IFile;
|
| -import org.eclipse.core.runtime.CoreException;
|
| -import org.eclipse.core.runtime.IProgressMonitor;
|
| -import org.eclipse.core.runtime.IStatus;
|
| -import org.eclipse.core.runtime.MultiStatus;
|
| -import org.eclipse.core.runtime.NullProgressMonitor;
|
| -import org.eclipse.core.runtime.OperationCanceledException;
|
| -import org.eclipse.core.runtime.Platform;
|
| -import org.eclipse.core.runtime.Status;
|
| -import org.eclipse.core.runtime.content.IContentDescription;
|
| -import org.eclipse.core.runtime.content.IContentType;
|
| -import org.eclipse.core.runtime.content.IContentTypeManager;
|
| -import org.eclipse.core.runtime.jobs.Job;
|
| -import org.eclipse.jface.text.IDocument;
|
| -import org.eclipse.ui.IEditorInput;
|
| -import org.eclipse.ui.IEditorPart;
|
| -import org.eclipse.ui.IEditorReference;
|
| -import org.eclipse.ui.IFileEditorInput;
|
| -import org.eclipse.ui.IWorkbench;
|
| -import org.eclipse.ui.IWorkbenchPage;
|
| -import org.eclipse.ui.IWorkbenchWindow;
|
| -import org.eclipse.ui.PlatformUI;
|
| -import org.eclipse.ui.texteditor.ITextEditor;
|
| -
|
| -import java.io.CharConversionException;
|
| -import java.io.IOException;
|
| -import java.nio.charset.IllegalCharsetNameException;
|
| -import java.nio.charset.UnsupportedCharsetException;
|
| -import java.util.Collections;
|
| -import java.util.HashMap;
|
| -import java.util.Map;
|
| -import java.util.regex.Matcher;
|
| -import java.util.regex.Pattern;
|
| -
|
| -/**
|
| - * The visitor that does the actual work.
|
| - */
|
| -public class TextSearchVisitor {
|
| -
|
| - public static class ReusableMatchAccess extends TextSearchMatchAccess {
|
| -
|
| - private int fOffset;
|
| - private int fLength;
|
| - private IFile fFile;
|
| - private CharSequence fContent;
|
| -
|
| - @Override
|
| - public IFile getFile() {
|
| - return fFile;
|
| - }
|
| -
|
| - @Override
|
| - public String getFileContent(int offset, int length) {
|
| - return fContent.subSequence(offset, offset + length).toString(); // must pass a copy!
|
| - }
|
| -
|
| - @Override
|
| - public char getFileContentChar(int offset) {
|
| - return fContent.charAt(offset);
|
| - }
|
| -
|
| - @Override
|
| - public int getFileContentLength() {
|
| - return fContent.length();
|
| - }
|
| -
|
| - @Override
|
| - public int getMatchLength() {
|
| - return fLength;
|
| - }
|
| -
|
| - @Override
|
| - public int getMatchOffset() {
|
| - return fOffset;
|
| - }
|
| -
|
| - public void initialize(IFile file, int offset, int length, CharSequence content) {
|
| - fFile = file;
|
| - fOffset = offset;
|
| - fLength = length;
|
| - fContent = content;
|
| - }
|
| - }
|
| -
|
| - private final TextSearchRequestor fCollector;
|
| - private final Matcher fMatcher;
|
| -
|
| - private IProgressMonitor fProgressMonitor;
|
| -
|
| - private int fNumberOfScannedFiles;
|
| - private int fNumberOfFilesToScan;
|
| - private IFile fCurrentFile;
|
| -
|
| - private final MultiStatus fStatus;
|
| -
|
| - private final FileCharSequenceProvider fFileCharSequenceProvider;
|
| -
|
| - private final ReusableMatchAccess fMatchAccess;
|
| -
|
| - public TextSearchVisitor(TextSearchRequestor collector, Pattern searchPattern) {
|
| - fCollector = collector;
|
| - fStatus = new MultiStatus(NewSearchUI.PLUGIN_ID, IStatus.OK,
|
| - SearchMessages.TextSearchEngine_statusMessage, null);
|
| -
|
| - fMatcher = searchPattern.pattern().length() == 0 ? null : searchPattern.matcher(new String());
|
| -
|
| - fFileCharSequenceProvider = new FileCharSequenceProvider();
|
| - fMatchAccess = new ReusableMatchAccess();
|
| - }
|
| -
|
| - public boolean processFile(IFile file, Map<IFile, IDocument> documentsInEditors) {
|
| - try {
|
| - if (!fCollector.acceptFile(file) || fMatcher == null) {
|
| - return true;
|
| - }
|
| -
|
| - IDocument document = getOpenDocument(file, documentsInEditors);
|
| -
|
| - if (document != null) {
|
| - DocumentCharSequence documentCharSequence = new DocumentCharSequence(document);
|
| - // assume all documents are non-binary
|
| - locateMatches(file, documentCharSequence);
|
| - } else {
|
| - CharSequence seq = null;
|
| - try {
|
| - seq = fFileCharSequenceProvider.newCharSequence(file);
|
| - if (hasBinaryContent(seq, file) && !fCollector.reportBinaryFile(file)) {
|
| - return true;
|
| - }
|
| - locateMatches(file, seq);
|
| - } catch (FileCharSequenceProvider.FileCharSequenceException e) {
|
| - e.throwWrappedException();
|
| - } finally {
|
| - if (seq != null) {
|
| - try {
|
| - fFileCharSequenceProvider.releaseCharSequence(seq);
|
| - } catch (IOException e) {
|
| - SearchPlugin.log(e);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - } catch (UnsupportedCharsetException e) {
|
| - String[] args = {getCharSetName(file), file.getFullPath().makeRelative().toString()};
|
| - String message = Messages.format(SearchMessages.TextSearchVisitor_unsupportedcharset, args);
|
| - fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, IStatus.ERROR, message, e));
|
| - } catch (IllegalCharsetNameException e) {
|
| - String[] args = {getCharSetName(file), file.getFullPath().makeRelative().toString()};
|
| - String message = Messages.format(SearchMessages.TextSearchVisitor_illegalcharset, args);
|
| - fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, IStatus.ERROR, message, e));
|
| - } catch (IOException e) {
|
| - String[] args = {getExceptionMessage(e), file.getFullPath().makeRelative().toString()};
|
| - String message = Messages.format(SearchMessages.TextSearchVisitor_error, args);
|
| - fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, IStatus.ERROR, message, e));
|
| - } catch (CoreException e) {
|
| - String[] args = {getExceptionMessage(e), file.getFullPath().makeRelative().toString()};
|
| - String message = Messages.format(SearchMessages.TextSearchVisitor_error, args);
|
| - fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, IStatus.ERROR, message, e));
|
| - } catch (StackOverflowError e) {
|
| - String message = SearchMessages.TextSearchVisitor_patterntoocomplex0;
|
| - fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, IStatus.ERROR, message, e));
|
| - return false;
|
| - } finally {
|
| - fNumberOfScannedFiles++;
|
| - }
|
| - if (fProgressMonitor.isCanceled()) {
|
| - throw new OperationCanceledException(SearchMessages.TextSearchVisitor_canceled);
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - public IStatus search(IFile[] files, IProgressMonitor monitor) {
|
| - fProgressMonitor = monitor == null ? new NullProgressMonitor() : monitor;
|
| - fNumberOfScannedFiles = 0;
|
| - fNumberOfFilesToScan = files.length;
|
| - fCurrentFile = null;
|
| -
|
| - Job monitorUpdateJob = new Job(SearchMessages.TextSearchVisitor_progress_updating_job) {
|
| - private int fLastNumberOfScannedFiles = 0;
|
| -
|
| - @Override
|
| - public IStatus run(IProgressMonitor inner) {
|
| - while (!inner.isCanceled()) {
|
| - IFile file = fCurrentFile;
|
| - if (file != null) {
|
| - String fileName = file.getName();
|
| - Object[] args = {
|
| - fileName, new Integer(fNumberOfScannedFiles), new Integer(fNumberOfFilesToScan)};
|
| - fProgressMonitor.subTask(Messages.format(SearchMessages.TextSearchVisitor_scanning,
|
| - args));
|
| - int steps = fNumberOfScannedFiles - fLastNumberOfScannedFiles;
|
| - fProgressMonitor.worked(steps);
|
| - fLastNumberOfScannedFiles += steps;
|
| - }
|
| - try {
|
| - Thread.sleep(100);
|
| - } catch (InterruptedException e) {
|
| - return Status.OK_STATUS;
|
| - }
|
| - }
|
| - return Status.OK_STATUS;
|
| - }
|
| - };
|
| -
|
| - try {
|
| - String taskName = fMatcher == null ? SearchMessages.TextSearchVisitor_filesearch_task_label
|
| - : Messages.format(SearchMessages.TextSearchVisitor_textsearch_task_label,
|
| - fMatcher.pattern().pattern());
|
| - fProgressMonitor.beginTask(taskName, fNumberOfFilesToScan);
|
| - monitorUpdateJob.setSystem(true);
|
| - monitorUpdateJob.schedule();
|
| - try {
|
| - fCollector.beginReporting();
|
| - processFiles(files);
|
| - return fStatus;
|
| - } finally {
|
| - monitorUpdateJob.cancel();
|
| - }
|
| - } finally {
|
| - fProgressMonitor.done();
|
| - fCollector.endReporting();
|
| - }
|
| - }
|
| -
|
| - public IStatus search(TextSearchScope scope, IProgressMonitor monitor) {
|
| - return search(scope.evaluateFilesInScope(fStatus), monitor);
|
| - }
|
| -
|
| - /**
|
| - * @return returns a map from IFile to IDocument for all open, dirty editors
|
| - */
|
| - private Map<IFile, IDocument> evalNonFileBufferDocuments() {
|
| - Map<IFile, IDocument> result = new HashMap<IFile, IDocument>();
|
| - IWorkbench workbench = SearchPlugin.getDefault().getWorkbench();
|
| - IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
|
| - for (int i = 0; i < windows.length; i++) {
|
| - IWorkbenchPage[] pages = windows[i].getPages();
|
| - for (int x = 0; x < pages.length; x++) {
|
| - IEditorReference[] editorRefs = pages[x].getEditorReferences();
|
| - for (int z = 0; z < editorRefs.length; z++) {
|
| - IEditorPart ep = editorRefs[z].getEditor(false);
|
| - if (ep instanceof ITextEditor && ep.isDirty()) { // only dirty editors
|
| - evaluateTextEditor(result, ep);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - private void evaluateTextEditor(Map<IFile, IDocument> result, IEditorPart ep) {
|
| - IEditorInput input = ep.getEditorInput();
|
| - if (input instanceof IFileEditorInput) {
|
| - IFile file = ((IFileEditorInput) input).getFile();
|
| - if (!result.containsKey(file)) { // take the first editor found
|
| - ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
|
| - ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(file.getFullPath(),
|
| - LocationKind.IFILE);
|
| - if (textFileBuffer != null) {
|
| - // file buffer has precedence
|
| - result.put(file, textFileBuffer.getDocument());
|
| - } else {
|
| - // use document provider
|
| - IDocument document = ((ITextEditor) ep).getDocumentProvider().getDocument(input);
|
| - if (document != null) {
|
| - result.put(file, document);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - private String getCharSetName(IFile file) {
|
| - try {
|
| - return file.getCharset();
|
| - } catch (CoreException e) {
|
| - return "unknown"; //$NON-NLS-1$
|
| - }
|
| - }
|
| -
|
| - private String getExceptionMessage(Exception e) {
|
| - String message = e.getLocalizedMessage();
|
| - if (message == null) {
|
| - return e.getClass().getName();
|
| - }
|
| - return message;
|
| - }
|
| -
|
| - private IDocument getOpenDocument(IFile file, Map<IFile, IDocument> documentsInEditors) {
|
| - IDocument document = documentsInEditors.get(file);
|
| - if (document == null) {
|
| - ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
|
| - ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(file.getFullPath(),
|
| - LocationKind.IFILE);
|
| - if (textFileBuffer != null) {
|
| - document = textFileBuffer.getDocument();
|
| - }
|
| - }
|
| - return document;
|
| - }
|
| -
|
| - private boolean hasBinaryContent(CharSequence seq, IFile file) throws CoreException {
|
| - IContentDescription desc = file.getContentDescription();
|
| - if (desc != null) {
|
| - IContentType contentType = desc.getContentType();
|
| - if (contentType != null
|
| - && contentType.isKindOf(Platform.getContentTypeManager().getContentType(
|
| - IContentTypeManager.CT_TEXT))) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - // avoid calling seq.length() at it runs through the complete file,
|
| - // thus it would do so for all binary files.
|
| - try {
|
| - int limit = FileCharSequenceProvider.BUFFER_SIZE;
|
| - for (int i = 0; i < limit; i++) {
|
| - if (seq.charAt(i) == '\0') {
|
| - return true;
|
| - }
|
| - }
|
| - } catch (IndexOutOfBoundsException e) {
|
| - } catch (FileCharSequenceException ex) {
|
| - if (ex.getCause() instanceof CharConversionException) {
|
| - return true;
|
| - }
|
| - throw ex;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - private void locateMatches(IFile file, CharSequence searchInput) throws CoreException {
|
| - try {
|
| - fMatcher.reset(searchInput);
|
| - int k = 0;
|
| - while (fMatcher.find()) {
|
| - int start = fMatcher.start();
|
| - int end = fMatcher.end();
|
| - if (end != start) { // don't report 0-length matches
|
| - fMatchAccess.initialize(file, start, end - start, searchInput);
|
| - boolean res = fCollector.acceptPatternMatch(fMatchAccess);
|
| - if (!res) {
|
| - return; // no further reporting requested
|
| - }
|
| - }
|
| - if (k++ == 20) {
|
| - if (fProgressMonitor.isCanceled()) {
|
| - throw new OperationCanceledException(SearchMessages.TextSearchVisitor_canceled);
|
| - }
|
| - k = 0;
|
| - }
|
| - }
|
| - } finally {
|
| - fMatchAccess.initialize(null, 0, 0, new String()); // clear references
|
| - }
|
| - }
|
| -
|
| - private void processFiles(IFile[] files) {
|
| - final Map<IFile, IDocument> documentsInEditors;
|
| - if (PlatformUI.isWorkbenchRunning()) {
|
| - documentsInEditors = evalNonFileBufferDocuments();
|
| - } else {
|
| - documentsInEditors = Collections.emptyMap();
|
| - }
|
| -
|
| - for (int i = 0; i < files.length; i++) {
|
| - fCurrentFile = files[i];
|
| - boolean res = processFile(fCurrentFile, documentsInEditors);
|
| - if (!res) {
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| -}
|
|
|