1
/*******************************************************************************
2
* Copyright (c) 2009, 2010 Alena Laskavaia
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
9
* Alena Laskavaia - initial API and implementation
10
*******************************************************************************/
11
package org.eclipse.cdt.codan.internal.core.model;
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Collection;
16
import java.util.Iterator;
18
import org.eclipse.cdt.codan.core.CodanCorePlugin;
19
import org.eclipse.cdt.codan.core.CodanRuntime;
20
import org.eclipse.cdt.codan.core.model.AbstractProblemReporter;
21
import org.eclipse.cdt.codan.core.model.IChecker;
22
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
23
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
24
import org.eclipse.cdt.codan.core.model.IProblem;
25
import org.eclipse.cdt.codan.core.model.IProblemLocation;
26
import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent;
27
import org.eclipse.cdt.codan.core.model.IProblemReporterSessionPersistent;
28
import org.eclipse.core.resources.IMarker;
29
import org.eclipse.core.resources.IResource;
30
import org.eclipse.core.resources.IWorkspace;
31
import org.eclipse.core.resources.IWorkspaceRunnable;
32
import org.eclipse.core.resources.ResourcesPlugin;
33
import org.eclipse.core.runtime.CoreException;
34
import org.eclipse.core.runtime.IProgressMonitor;
37
* Problem reported that created eclipse markers
39
public class CodanMarkerProblemReporter extends AbstractProblemReporter implements
40
IProblemReporterPersistent, IProblemReporterSessionPersistent {
41
private IResource resource;
42
private IChecker checker;
43
private ArrayList<ICodanProblemMarker> toAdd = new ArrayList<ICodanProblemMarker>();
46
* Create instance, which can be use as factory for
47
* IProblemReporterSessionPersistent or
48
* as IProblemReporterPersistent.
50
public CodanMarkerProblemReporter() {
58
public CodanMarkerProblemReporter(IResource resource, IChecker checker) {
59
this.resource = resource;
60
this.checker = checker;
63
public IResource getResource() {
67
public IChecker getChecker() {
72
protected void reportProblem(ICodanProblemMarker codanProblemMarker) {
73
if (checker == null) {
74
createProblem(codanProblemMarker);
76
toAdd.add(codanProblemMarker);
81
* @param codanProblemMarker
83
protected IMarker createProblem(ICodanProblemMarker codanProblemMarker) {
85
return codanProblemMarker.createMarker();
86
} catch (CoreException e) {
87
CodanCorePlugin.log(e);
92
public void deleteProblems(IResource file) {
94
file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_ZERO);
95
} catch (CoreException ce) {
96
CodanCorePlugin.log(ce);
100
public void deleteAllProblems() {
102
ResourcesPlugin.getWorkspace().getRoot().deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE,
103
true, IResource.DEPTH_INFINITE);
104
} catch (CoreException e) {
105
CodanCorePlugin.log(e);
109
public void deleteProblems(final IResource file, final IChecker checker) {
111
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
112
public void run(IProgressMonitor monitor) throws CoreException {
113
Collection<IMarker> markers = findResourceMarkers(file, checker);
114
for (Iterator<IMarker> iterator = markers.iterator(); iterator.hasNext();) {
115
IMarker iMarker = iterator.next();
119
}, null, IWorkspace.AVOID_UPDATE, null);
120
} catch (CoreException e) {
121
CodanCorePlugin.log(e);
125
protected Collection<IMarker> findResourceMarkers(IResource resource, IChecker checker) throws CoreException {
126
Collection<IMarker> res = new ArrayList<IMarker>();
128
if (resource.exists()) {
129
markers = resource.findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true,
130
IResource.DEPTH_INFINITE);
132
if (resource.getProject() == null || !resource.getProject().isAccessible())
134
// non resource markers attached to a project itself
135
markers = resource.getProject().findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true,
136
IResource.DEPTH_ZERO);
138
ICheckersRegistry reg = CodanRuntime.getInstance().getCheckersRegistry();
139
Collection<IProblem> problems = reg.getRefProblems(checker);
140
for (int i = 0; i < markers.length; i++) {
141
IMarker m = markers[i];
142
String id = m.getAttribute(ICodanProblemMarker.ID, ""); //$NON-NLS-1$
143
for (Iterator<IProblem> iterator = problems.iterator(); iterator.hasNext();) {
144
IProblem iProblem = iterator.next();
145
if (iProblem.getId().equals(id)) {
156
* @return session aware problem reporter
159
public IProblemReporterSessionPersistent createReporter(IResource resource, IChecker checker) {
160
return new CodanMarkerProblemReporter(resource, checker);
163
public void start() {
165
deleteProblems(false);
169
if (checker != null) {
170
if (toAdd.size() == 0)
171
deleteProblems(false);
178
protected void reconcileMarkers() {
180
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
181
public void run(IProgressMonitor monitor) throws CoreException {
182
Collection<IMarker> markers = findResourceMarkers(resource, checker);
183
for (Iterator<IMarker> iterator = markers.iterator(); iterator.hasNext();) {
184
IMarker m = iterator.next();
185
ICodanProblemMarker cm = similarMarker(m);
193
for (Iterator<ICodanProblemMarker> iterator = toAdd.iterator(); iterator.hasNext();) {
194
ICodanProblemMarker cm = iterator.next();
198
}, null, IWorkspace.AVOID_UPDATE, null);
199
} catch (CoreException e) {
200
CodanCorePlugin.log(e);
208
protected void updateMarker(IMarker m, ICodanProblemMarker cm) {
209
IProblemLocation loc = cm.getLocation();
211
if (m.getAttribute(IMarker.LINE_NUMBER, 0) != loc.getLineNumber())
212
m.setAttribute(IMarker.LINE_NUMBER, loc.getLineNumber());
213
if (m.getAttribute(IMarker.CHAR_START, 0) != loc.getStartingChar())
214
m.setAttribute(IMarker.CHAR_START, loc.getStartingChar());
215
if (m.getAttribute(IMarker.CHAR_END, 0) != loc.getEndingChar())
216
m.setAttribute(IMarker.CHAR_END, loc.getEndingChar());
217
int severity = cm.getProblem().getSeverity().intValue();
218
if (m.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) != severity)
219
m.setAttribute(IMarker.SEVERITY, severity);
220
} catch (CoreException e) {
224
} catch (CoreException e1) {
225
CodanCorePlugin.log(e1);
234
protected ICodanProblemMarker similarMarker(IMarker m) {
235
ICodanProblemMarker mcm = CodanProblemMarker.createCodanProblemMarkerFromResourceMarker(m);
236
ArrayList<ICodanProblemMarker> cand = new ArrayList<ICodanProblemMarker>();
237
for (Iterator<ICodanProblemMarker> iterator = toAdd.iterator(); iterator.hasNext();) {
238
ICodanProblemMarker cm = iterator.next();
241
if (markersAreSimilar(mcm, cm)) {
245
if (cand.size() == 1)
255
private boolean markersAreSimilar(ICodanProblemMarker marker1, ICodanProblemMarker marker2) {
256
if (!marker1.getProblem().getId().equals(marker2.getProblem().getId()))
258
if (!Arrays.equals(marker1.getArgs(), marker2.getArgs()))
260
IProblemLocation loc1 = marker1.getLocation();
261
IProblemLocation loc2 = marker2.getLocation();
262
if (!loc1.getFile().equals(loc2.getFile()))
264
if (Math.abs(loc1.getLineNumber() - loc2.getLineNumber()) > 2)
272
* @see IProblemReporterSessionPersistent#deleteProblems(boolean)
274
public void deleteProblems(boolean all) {
276
throw new UnsupportedOperationException();
277
deleteProblems(resource, checker);