Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
blob: be29c233abd416a10f53421defbe626a19f1ee8c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.Match;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.wst.sse.ui.internal.Logger;


/**
 * @author pavery
 */
public class BasicSearchQuery implements ISearchQuery {

	/** attribute to identify markers added by find occurrences */
	public static final String ATTR_OCCURRENCES_MARKER = "occurrences_marker"; //$NON-NLS-1$

	private static int LINE_LENGTH_LIMIT = 200;

	/** the file we're searching * */
	private IFile fFile = null;
	/** occurrence search matches * */
	private List fMatches = null;

	public BasicSearchQuery(IFile file) {
		this.fFile = file;
		this.fMatches = new ArrayList();
	}

	public void addMatch(IDocument document, int matchStart, int matchEnd) {

		try {
			int lineNumber = document.getLineOfOffset(matchStart);
			int lineStart = document.getLineOffset(lineNumber);
			int lineLength = document.getLineLength(lineNumber);

			String searchResultString = document.get().substring(lineStart, lineStart + lineLength).trim();

			// create search marker (so annotations show up in editor)
			IMarker marker = createSearchMarker(matchStart, matchEnd, lineNumber, searchResultString);

			addMatch(new Match(marker, Match.UNIT_CHARACTER, matchStart, matchStart + matchEnd));

		} catch (BadLocationException e) {
			Logger.logException(e);
		}
	}

	private void addMatch(Match match) {
		if (match != null)
			this.fMatches.add(match);
	}

	/**
	 * @see org.eclipse.search.ui.ISearchQuery#canRerun()
	 */
	public boolean canRerun() {
		return false;
	}

	/**
	 * @see org.eclipse.search.ui.ISearchQuery#canRunInBackground()
	 */
	public boolean canRunInBackground() {
		return true;
	}

	public void clearMatches() {
		this.fMatches.clear();
	}

	protected IMarker createSearchMarker(int matchStart, int matchEnd, int lineNumber, String searchResultString) {

		IMarker marker = null;
		try {
			if (getFile() != null) {

				marker = getFile().createMarker(NewSearchUI.SEARCH_MARKER);
				HashMap attributes = new HashMap(6);

				MarkerUtilities.setCharStart(attributes, matchStart);
				MarkerUtilities.setCharEnd(attributes, matchEnd);
				MarkerUtilities.setLineNumber(attributes, lineNumber);

				// this might be bad if line of text is VERY long?
				if (searchResultString.length() > LINE_LENGTH_LIMIT)
					searchResultString = searchResultString.substring(0, LINE_LENGTH_LIMIT) + "..."; //$NON-NLS-1$
				MarkerUtilities.setMessage(attributes, searchResultString);

				// so we can remove them later
				attributes.put(ATTR_OCCURRENCES_MARKER, new Boolean(true));

				marker.setAttributes(attributes);
			}
		} catch (CoreException e) {
			Logger.logException(e);
		}
		return marker;
	}

	private void deleteOccurrencesMarkers() {

		final List removals = new ArrayList();
		try {
			// clear all old find occurrences markers
			IMarker[] searchMarkers = fFile.findMarkers(NewSearchUI.SEARCH_MARKER, false, IResource.DEPTH_ZERO);
			for (int i = 0; i < searchMarkers.length; i++) {
				Object o = searchMarkers[i].getAttribute(BasicSearchQuery.ATTR_OCCURRENCES_MARKER);
				if (o != null && ((Boolean) o).booleanValue() == true)
					removals.add(searchMarkers[i]);

			}

			if (removals.size() > 0) {
				IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
					public void run(IProgressMonitor monitor) throws CoreException {
						for (int i = 0; i < removals.size(); i++)
							((IMarker) removals.get(i)).delete();
					}
				};
				// BUG158846 - deadlock if lock up entire workspace, so only lock
				// up the file we are searching on
				ISchedulingRule markerRule = ResourcesPlugin.getWorkspace().getRuleFactory().markerRule(fFile);
				ResourcesPlugin.getWorkspace().run(runnable, markerRule, IWorkspace.AVOID_UPDATE, null); 
			}
		} catch (CoreException e) {
			Logger.logException(e);
		}
	}

	/**
	 * The acutal work of the query. Will be run in a background Job
	 * automatically if canRunInBackground(..) returns true.
	 * 
	 * @return
	 */
	protected IStatus doQuery() {
		return Status.OK_STATUS;
	}

	/*
	 * public to avoid synthetic method access from inner class
	 */
	public IFile getFile() {
		return this.fFile;
	}

	/**
	 * @see org.eclipse.search.ui.ISearchQuery#getLabel()
	 */
	public String getLabel() {
		return ""; //$NON-NLS-1$
	}

	public Match[] getMatches() {
		// get rid of the old markers
		if(fFile.exists()) {
			deleteOccurrencesMarkers();
			doQuery();
		}
		return (Match[]) this.fMatches.toArray(new Match[this.fMatches.size()]);
	}

	/**
	 * @see org.eclipse.search.ui.ISearchQuery#getSearchResult()
	 */
	public ISearchResult getSearchResult() {
		return null;
	}

	/**
	 * used in search result display labels
	 * 
	 * @return
	 */
	protected String getSearchText() {
		return ""; //$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.search.ui.ISearchQuery#run(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus run(IProgressMonitor monitor) {
		// defer to "get(...)"
		return Status.OK_STATUS;
	}
}

Back to the top