Skip to main content
summaryrefslogtreecommitdiffstats
blob: b58156f38267de98d6f1ab93bef64c61b3705f00 (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
218
219
220
221
222
223
/*******************************************************************************
 * Copyright (c) 2009,2010 Alena Laskavaia 
 * 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:
 *    Alena Laskavaia  - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.codan.core.model;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.cdt.codan.core.param.AbstractProblemPreference;
import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType;
import org.eclipse.cdt.codan.core.param.ListProblemPreference;
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;

/**
 * AbstarctChecker that has extra methods to simplify adding problem
 * preferences.
 * Checker can produce several problems, but preferences are per problem.
 * Sharing preferences between problems is not supported now.
 */
public abstract class AbstractCheckerWithProblemPreferences extends
		AbstractChecker implements ICheckerWithPreferences {
	/**
	 * Checker that actually has parameter must override this
	 */
	public void initPreferences(IProblemWorkingCopy problem) {
		// by default add file scope preference
		addPreference(problem, new FileScopeProblemPreference(), null);
	}

	/**
	 * Scope preference - special preference that all file checkers should have,
	 * it allows user to include/exclude files for this specific problem.
	 * 
	 * @param problem - problem for which scope preference is need
	 * @return scope problem preference, null if not defined
	 */
	public FileScopeProblemPreference getScopePreference(IProblem problem) {
		FileScopeProblemPreference scope = (FileScopeProblemPreference) getTopLevelPreferenceMap(
				problem).getChildDescriptor(FileScopeProblemPreference.KEY);
		return scope;
	}

	/**
	 * User can scope out some resources for this checker. Checker can use this
	 * call to test if it should run on this resource at all or not. Test should
	 * be done within processResource method not in enabledInContext.
	 * This test uses user "scope" preference for the all problems that this
	 * checker can produce.
	 * 
	 * @param res - resource to test on
	 * @return true if checker should report problems, fails otherwise.
	 */
	public boolean shouldProduceProblems(IResource res) {
		Collection<IProblem> refProblems = getRuntime().getChechersRegistry()
				.getRefProblems(this);
		for (Iterator<IProblem> iterator = refProblems.iterator(); iterator
				.hasNext();) {
			IProblem checkerProblem = iterator.next();
			if (shouldProduceProblem(
					getProblemById(checkerProblem.getId(), res),
					res.getLocation()))
				return true;
		}
		return false;
	}

	/**
	 * User can scope out some resources for this checker. Checker can use this
	 * call to test if it should run on this resource at all or produce a
	 * specific problem on this resource. Test should
	 * be done within processResource method not in enabledInContext, or just
	 * before printing of a problem.
	 * This test uses user "scope" preference for the given problem. If scope is
	 * not defined preference it returns true.
	 * 
	 * @param problem - problem to test for
	 * @param resource - resource to test on
	 * 
	 * @return true if problem should be report for given resource, fails
	 *         otherwise.
	 */
	public boolean shouldProduceProblem(IProblem problem, IPath resource) {
		FileScopeProblemPreference scope = getScopePreference(problem);
		if (scope == null)
			return true;
		return scope.isInScope(resource);
	}

	@Override
	public void reportProblem(String problemId, IProblemLocation loc,
			Object... args) {
		if (shouldProduceProblem(getProblemById(problemId, loc.getFile()), loc
				.getFile().getLocation()))
			super.reportProblem(problemId, loc, args);
	}

	/**
	 * Add a parameter
	 * 
	 * @param problem
	 *        - problem that has parameter
	 * @param key
	 *        - parameter key
	 * @param label
	 *        - parameter label - user visible
	 * @param defaultValue
	 *        - parameter default value
	 * @return - parameter info object
	 */
	public IProblemPreference addPreference(IProblemWorkingCopy problem,
			String key, String label, Object defaultValue) {
		MapProblemPreference map = getTopLevelPreferenceMap(problem);
		BasicProblemPreference info = new BasicProblemPreference(key, label,
				PreferenceType.typeOf(defaultValue));
		map.addChildDescriptor(info);
		setDefaultPreferenceValue(problem, key, defaultValue);
		return info;
	}

	/**
	 * Add preference of type list of strings, list is empty by
	 * default
	 * 
	 * @param problem
	 *        - problem
	 * @param key
	 *        - preference key
	 * @param label
	 *        - preference label
	 * @param itemLabel
	 * @return preference instance of of the list, can be used to add default
	 *         values or set different element type
	 * 
	 */
	public ListProblemPreference addListPreference(IProblemWorkingCopy problem,
			String key, String label, String itemLabel) {
		MapProblemPreference map = getTopLevelPreferenceMap(problem);
		ListProblemPreference list = new ListProblemPreference(key, label);
		list.setChildDescriptor(new BasicProblemPreference(
				ListProblemPreference.COMMON_DESCRIPTOR_KEY, itemLabel,
				PreferenceType.TYPE_STRING));
		return (ListProblemPreference) map.addChildDescriptor(list);
	}

	/**
	 * Add preference for the given problem with default value
	 * 
	 * @param problem
	 * @param pref - preference
	 * @param defaultValue - default value of the preference
	 * @return added preference
	 */
	public IProblemPreference addPreference(IProblemWorkingCopy problem,
			IProblemPreference pref, Object defaultValue) {
		MapProblemPreference map = getTopLevelPreferenceMap(problem);
		String key = pref.getKey();
		pref = map.addChildDescriptor(pref);
		setDefaultPreferenceValue(problem, key, defaultValue);
		return pref;
	}

	/**
	 * Convenience method for setting default preference value for checker that
	 * uses "map" as top level problem preference.
	 * 
	 * @param problem - problem for which to set default value for a prefence
	 * @param key - preference key
	 * @param defaultValue - value of preference to be set
	 */
	protected void setDefaultPreferenceValue(IProblemWorkingCopy problem,
			String key, Object defaultValue) {
		MapProblemPreference map = getTopLevelPreferenceMap(problem);
		if (map.getChildValue(key) == null)
			map.setChildValue(key, defaultValue);
	}

	/**
	 * Return "map" problem preference for a give problem, if problem
	 * has preference different than a map, it will throw ClassCastException.
	 * If top level preference does not exist create a map preference with name
	 * "params"
	 * and return it.
	 * 
	 * @param problem
	 * @return top level preference if it is a map
	 */
	protected MapProblemPreference getTopLevelPreferenceMap(IProblem problem) {
		MapProblemPreference map = (MapProblemPreference) problem
				.getPreference();
		if (map == null) {
			map = new MapProblemPreference(AbstractProblemPreference.PARAM, ""); //$NON-NLS-1$
			if (problem instanceof IProblemWorkingCopy) {
				((IProblemWorkingCopy) problem).setPreference(map);
			}
		}
		return map;
	}

	/**
	 * Returns value of the preference for the key in the top level
	 * preference map for the given problem
	 * 
	 * @param problem - problem for which to get the preference
	 * @param key - preference key
	 * @return value of the preference
	 */
	public Object getPreference(IProblem problem, String key) {
		return ((MapProblemPreference) problem.getPreference())
				.getChildValue(key);
	}
}

Back to the top