]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMarkerResolutionGenerator.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / text / correction / CorrectionMarkerResolutionGenerator.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.text.correction;
12
13import java.util.ArrayList;
14import java.util.Collections;
15import java.util.Hashtable;
16import java.util.Iterator;
17import java.util.List;
18import java.util.Map;
19import java.util.Map.Entry;
20
21import org.eclipse.swt.graphics.Image;
22
23import org.eclipse.core.runtime.CoreException;
24import org.eclipse.core.runtime.IProgressMonitor;
25import org.eclipse.core.runtime.NullProgressMonitor;
26
27import org.eclipse.core.resources.IFile;
28import org.eclipse.core.resources.IMarker;
29import org.eclipse.core.resources.IResource;
30
31import org.eclipse.jface.text.IDocument;
32import org.eclipse.jface.text.Position;
33import org.eclipse.jface.text.source.Annotation;
34import org.eclipse.jface.text.source.IAnnotationModel;
35
36import org.eclipse.ui.IEditorInput;
37import org.eclipse.ui.IEditorPart;
38import org.eclipse.ui.IMarkerResolution;
39import org.eclipse.ui.IMarkerResolutionGenerator2;
40import org.eclipse.ui.views.markers.WorkbenchMarkerResolution;
41
42import org.eclipse.ui.texteditor.ITextEditor;
43import org.eclipse.ui.texteditor.MarkerUtilities;
44
45import org.eclipse.jdt.core.CorrectionEngine;
46import org.eclipse.jdt.core.ICompilationUnit;
47import org.eclipse.jdt.core.IJavaElement;
48import org.eclipse.jdt.core.IJavaModelMarker;
49import org.eclipse.jdt.core.JavaCore;
50import org.eclipse.jdt.core.compiler.IProblem;
51
52import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.MultiFixTarget;
53
54import org.eclipse.jdt.ui.JavaUI;
55import org.eclipse.jdt.ui.cleanup.ICleanUp;
56import org.eclipse.jdt.ui.text.java.CompletionProposalComparator;
57import org.eclipse.jdt.ui.text.java.IInvocationContext;
58import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
59import org.eclipse.jdt.ui.text.java.IProblemLocation;
60
61import org.eclipse.jdt.internal.ui.JavaPlugin;
62import org.eclipse.jdt.internal.ui.fix.IMultiFix;
63import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
64import org.eclipse.jdt.internal.ui.javaeditor.JavaMarkerAnnotation;
65import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal;
66
67
68public class CorrectionMarkerResolutionGenerator implements IMarkerResolutionGenerator2 {
69
70 public static class CorrectionMarkerResolution extends WorkbenchMarkerResolution {
71
72 private static final IMarker[] NO_MARKERS= new IMarker[0];
73
74 private ICompilationUnit fCompilationUnit;
75 private int fOffset;
76 private int fLength;
77 private IJavaCompletionProposal fProposal;
78 private final IMarker fMarker;
79
80 /**
81 * Constructor for CorrectionMarkerResolution.
82 * @param cu the compilation unit
83 * @param offset the offset
84 * @param length the length
85 * @param proposal the proposal for the given marker
86 * @param marker the marker to fix
87 */
88 public CorrectionMarkerResolution(ICompilationUnit cu, int offset, int length, IJavaCompletionProposal proposal, IMarker marker) {
89 fCompilationUnit= cu;
90 fOffset= offset;
91 fLength= length;
92 fProposal= proposal;
93 fMarker= marker;
94 }
95
96 /* (non-Javadoc)
97 * @see IMarkerResolution#getLabel()
98 */
99 public String getLabel() {
100 return fProposal.getDisplayString();
101 }
102
103 /* (non-Javadoc)
104 * @see IMarkerResolution#run(IMarker)
105 */
106 public void run(IMarker marker) {
107 try {
108 IEditorPart part= EditorUtility.isOpenInEditor(fCompilationUnit);
109 if (part == null) {
110 part= JavaUI.openInEditor(fCompilationUnit, true, false);
111 if (part instanceof ITextEditor) {
112 ((ITextEditor) part).selectAndReveal(fOffset, fLength);
113 }
114 }
115 if (part != null) {
116 IEditorInput input= part.getEditorInput();
117 IDocument doc= JavaPlugin.getDefault().getCompilationUnitDocumentProvider().getDocument(input);
118 fProposal.apply(doc);
119 }
120 } catch (CoreException e) {
121 JavaPlugin.log(e);
122 }
123 }
124
125
126 /**
127 * {@inheritDoc}
128 */
129 @Override
130 public void run(IMarker[] markers, IProgressMonitor monitor) {
131 if (markers.length == 1) {
132 run(markers[0]);
133 return;
134 }
135
136 if (!(fProposal instanceof FixCorrectionProposal))
137 return;
138
139 if (monitor == null)
140 monitor= new NullProgressMonitor();
141
142 try {
143 MultiFixTarget[] problems= getCleanUpTargets(markers);
144
145 ((FixCorrectionProposal)fProposal).resolve(problems, monitor);
146
147 IEditorPart part= EditorUtility.isOpenInEditor(fCompilationUnit);
148 if (part instanceof ITextEditor) {
149 ((ITextEditor) part).selectAndReveal(fOffset, fLength);
150 part.setFocus();
151 }
152 } catch (CoreException e) {
153 JavaPlugin.log(e);
154 } finally {
155 monitor.done();
156 }
157 }
158
159 private MultiFixTarget[] getCleanUpTargets(IMarker[] markers) {
160 Hashtable<ICompilationUnit, List<IProblemLocation>> problemLocations= new Hashtable<ICompilationUnit, List<IProblemLocation>>();
161 for (int i= 0; i < markers.length; i++) {
162 IMarker marker= markers[i];
163 ICompilationUnit cu= getCompilationUnit(marker);
164
165 if (cu != null) {
166 IEditorInput input= EditorUtility.getEditorInput(cu);
167 IProblemLocation location= findProblemLocation(input, marker);
168 if (location != null) {
169 List<IProblemLocation> l= problemLocations.get(cu.getPrimary());
170 if (l == null) {
171 l= new ArrayList<IProblemLocation>();
172 problemLocations.put(cu.getPrimary(), l);
173 }
174 l.add(location);
175 }
176 }
177 }
178
179 MultiFixTarget[] result= new MultiFixTarget[problemLocations.size()];
180 int i= 0;
181 for (Iterator<Map.Entry<ICompilationUnit, List<IProblemLocation>>> iterator= problemLocations.entrySet().iterator(); iterator.hasNext();) {
182 Map.Entry<ICompilationUnit, List<IProblemLocation>> entry= iterator.next();
183 ICompilationUnit cu= entry.getKey();
184 List<IProblemLocation> locations= entry.getValue();
185 result[i]= new MultiFixTarget(cu, locations.toArray(new IProblemLocation[locations.size()]));
186 i++;
187 }
188
189 return result;
190 }
191
192 /* (non-Javadoc)
193 * @see org.eclipse.ui.IMarkerResolution2#getDescription()
194 */
195 public String getDescription() {
196 return fProposal.getAdditionalProposalInfo();
197 }
198
199 /* (non-Javadoc)
200 * @see org.eclipse.ui.IMarkerResolution2#getImage()
201 */
202 public Image getImage() {
203 return fProposal.getImage();
204 }
205
206 /**
207 * {@inheritDoc}
208 */
209 @Override
210 public IMarker[] findOtherMarkers(IMarker[] markers) {
211 if (!(fProposal instanceof FixCorrectionProposal))
212 return NO_MARKERS;
213
214 FixCorrectionProposal fix= (FixCorrectionProposal)fProposal;
215 final ICleanUp cleanUp= fix.getCleanUp();
216 if (!(cleanUp instanceof IMultiFix))
217 return NO_MARKERS;
218
219 IMultiFix multiFix= (IMultiFix) cleanUp;
220
221 final Hashtable<IFile, List<IMarker>> fileMarkerTable= getMarkersForFiles(markers);
222 if (fileMarkerTable.isEmpty())
223 return NO_MARKERS;
224
225 final List<IMarker> result= new ArrayList<IMarker>();
226
227 for (Iterator<Entry<IFile, List<IMarker>>> iterator= fileMarkerTable.entrySet().iterator(); iterator.hasNext();) {
228 Map.Entry<IFile, List<IMarker>> entry= iterator.next();
229 IFile file= entry.getKey();
230 List<IMarker> fileMarkers= entry.getValue();
231
232 IJavaElement element= JavaCore.create(file);
233 if (element instanceof ICompilationUnit) {
234 ICompilationUnit unit= (ICompilationUnit) element;
235
236 for (int i= 0, size= fileMarkers.size(); i < size; i++) {
237 IMarker marker= fileMarkers.get(i);
238 IProblemLocation problem= createFromMarker(marker, unit);
239 if (problem != null && multiFix.canFix(unit, problem)) {
240 result.add(marker);
241 }
242 }
243 }
244 }
245
246 if (result.size() == 0)
247 return NO_MARKERS;
248
249 return result.toArray(new IMarker[result.size()]);
250 }
251
252 /**
253 * Returns the markers with the same type as fMarker.getType for each IFile.
254 * @param markers the markers
255 * @return mapping files to markers
256 */
257 private Hashtable<IFile, List<IMarker>> getMarkersForFiles(IMarker[] markers) {
258 final Hashtable<IFile, List<IMarker>> result= new Hashtable<IFile, List<IMarker>>();
259
260 String markerType;
261 try {
262 markerType= fMarker.getType();
263 } catch (CoreException e1) {
264 JavaPlugin.log(e1);
265 return result;
266 }
267
268 for (int i= 0; i < markers.length; i++) {
269 IMarker marker= markers[i];
270 if (!marker.equals(fMarker)) {
271 String currMarkerType= null;
272 try {
273 currMarkerType= marker.getType();
274 } catch (CoreException e1) {
275 JavaPlugin.log(e1);
276 }
277
278 if (currMarkerType != null && currMarkerType.equals(markerType)) {
279 IResource res= marker.getResource();
280 if (res instanceof IFile && res.isAccessible()) {
281 List<IMarker> markerList= result.get(res);
282 if (markerList == null) {
283 markerList= new ArrayList<IMarker>();
284 result.put((IFile) res, markerList);
285 }
286 markerList.add(marker);
287 }
288 }
289 }
290 }
291 return result;
292 }
293 }
294
295 private static final IMarkerResolution[] NO_RESOLUTIONS= new IMarkerResolution[0];
296
297
298 /**
299 * Constructor for CorrectionMarkerResolutionGenerator.
300 */
301 public CorrectionMarkerResolutionGenerator() {
302 super();
303 }
304
305 /* (non-Javadoc)
306 * @see org.eclipse.ui.IMarkerResolutionGenerator2#hasResolutions(org.eclipse.core.resources.IMarker)
307 */
308 public boolean hasResolutions(IMarker marker) {
309 return internalHasResolutions(marker);
310 }
311
312 /* (non-Javadoc)
313 * @see IMarkerResolutionGenerator#getResolutions(IMarker)
314 */
315 public IMarkerResolution[] getResolutions(IMarker marker) {
316 return internalGetResolutions(marker);
317 }
318
319 private static boolean internalHasResolutions(IMarker marker) {
320 int id= marker.getAttribute(IJavaModelMarker.ID, -1);
321 ICompilationUnit cu= getCompilationUnit(marker);
322 return cu != null && JavaCorrectionProcessor.hasCorrections(cu, id, MarkerUtilities.getMarkerType(marker));
323 }
324
325 private static IMarkerResolution[] internalGetResolutions(IMarker marker) {
326 if (!internalHasResolutions(marker)) {
327 return NO_RESOLUTIONS;
328 }
329
330 ICompilationUnit cu= getCompilationUnit(marker);
331 if (cu != null) {
332 IEditorInput input= EditorUtility.getEditorInput(cu);
333 if (input != null) {
334 IProblemLocation location= findProblemLocation(input, marker);
335 if (location != null) {
336
337 IInvocationContext context= new AssistContext(cu, location.getOffset(), location.getLength());
338 if (!hasProblem (context.getASTRoot().getProblems(), location))
339 return NO_RESOLUTIONS;
340
341 ArrayList<IJavaCompletionProposal> proposals= new ArrayList<IJavaCompletionProposal>();
342 JavaCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
343 Collections.sort(proposals, new CompletionProposalComparator());
344
345 int nProposals= proposals.size();
346 IMarkerResolution[] resolutions= new IMarkerResolution[nProposals];
347 for (int i= 0; i < nProposals; i++) {
348 resolutions[i]= new CorrectionMarkerResolution(context.getCompilationUnit(), location.getOffset(), location.getLength(), proposals.get(i), marker);
349 }
350 return resolutions;
351 }
352 }
353 }
354 return NO_RESOLUTIONS;
355 }
356
357 private static boolean hasProblem(IProblem[] problems, IProblemLocation location) {
358 for (int i= 0; i < problems.length; i++) {
359 IProblem problem= problems[i];
360 if (problem.getID() == location.getProblemId() && problem.getSourceStart() == location.getOffset())
361 return true;
362 }
363 return false;
364 }
365
366 private static ICompilationUnit getCompilationUnit(IMarker marker) {
367 IResource res= marker.getResource();
368 if (res instanceof IFile && res.isAccessible()) {
369 IJavaElement element= JavaCore.create((IFile) res);
370 if (element instanceof ICompilationUnit)
371 return (ICompilationUnit) element;
372 }
373 return null;
374 }
375
376 private static IProblemLocation findProblemLocation(IEditorInput input, IMarker marker) {
377 IAnnotationModel model= JavaPlugin.getDefault().getCompilationUnitDocumentProvider().getAnnotationModel(input);
378 if (model != null) { // open in editor
379 Iterator<Annotation> iter= model.getAnnotationIterator();
380 while (iter.hasNext()) {
381 Annotation curr= iter.next();
382 if (curr instanceof JavaMarkerAnnotation) {
383 JavaMarkerAnnotation annot= (JavaMarkerAnnotation) curr;
384 if (marker.equals(annot.getMarker())) {
385 Position pos= model.getPosition(annot);
386 if (pos != null) {
387 return new ProblemLocation(pos.getOffset(), pos.getLength(), annot);
388 }
389 }
390 }
391 }
392 } else { // not open in editor
393 ICompilationUnit cu= getCompilationUnit(marker);
394 return createFromMarker(marker, cu);
395 }
396 return null;
397 }
398
399 private static IProblemLocation createFromMarker(IMarker marker, ICompilationUnit cu) {
400 try {
401 int id= marker.getAttribute(IJavaModelMarker.ID, -1);
402 int start= marker.getAttribute(IMarker.CHAR_START, -1);
403 int end= marker.getAttribute(IMarker.CHAR_END, -1);
404 int severity= marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
405 String[] arguments= CorrectionEngine.getProblemArguments(marker);
406 String markerType= marker.getType();
407 if (cu != null && id != -1 && start != -1 && end != -1 && arguments != null) {
408 boolean isError= (severity == IMarker.SEVERITY_ERROR);
409 return new ProblemLocation(start, end - start, id, arguments, isError, markerType);
410 }
411 } catch (CoreException e) {
412 JavaPlugin.log(e);
413 }
414 return null;
415 }
416
417
418}