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: d23011610f28d9f348348b00103cf1f4dbb42a11 (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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
package org.eclipse.wst.html.internal.validation;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

/**
 * This class must be called only by the validation framework.
 * 
 * This singleton interacts with the eclipse workbench's Task list.
 * TaskListUtility adds and removes tasks from the list.
 * 
 * This class must not be called outside of an IWorkspaceRunnable or
 * IRunnableWithProgress. Many resource deltas can be generated by the methods
 * in this class.
 * 
 * This came from com.ibm.etools.validate.internal.util.TaskListUtility
 */
public class TaskListUtility {
	// private static final String PLUGIN_ID = ValidationPlugin.PLUGIN_ID;
	private static final String PLUGIN_ID = "com.ibm.etools.validation";//$NON-NLS-1$
	private static final String VALIDATION_MARKER = PLUGIN_ID + ".problemmarker"; //$NON-NLS-1$ // The extension which is used to add validation markers to the task list
	private static final String VALIDATION_MARKER_OWNER = "owner"; //$NON-NLS-1$ // The IValidator who owns the IMarker on the task list
	private static final String VALIDATION_MARKER_SEVERITY = "validationSeverity"; //$NON-NLS-1$ // one of the IMessage values
	private static final String VALIDATION_MARKER_TARGETOBJECT = "targetObject"; //$NON-NLS-1$ // When more than one target object resolves to the same IResource, this field identifies which targetObject owns a particular message.
	private static final String VALIDATION_MARKER_GROUP = "groupName"; //$NON-NLS-1$ // For incremental validation, this field associates a message with a group, so that a subset of messages may be removed from a file.
	private static final String VALIDATION_MARKER_MESSAGEID = "messageId"; //$NON-NLS-1$ // Persist the message id of the message, not just the translated text.
	private static final int DEPTH_INFINITE = IResource.DEPTH_INFINITE;
	private static final int DEPTH_ZERO = IResource.DEPTH_ZERO;
	private final static IMarker[] NO_MARKERS = new IMarker[0];

	/**
	 * This method adds a message to a resource in the task list.
	 */
	public static IMarker addTask(String pluginId, IResource resource, String location, String messageId, String message, int markerType, String targetObjectName, String groupName, int offset, int length) throws CoreException {
		if ((message == null) || (resource == null)) {
			return null;
		}

		int severity = getSeverity(markerType);

		// Allow duplicate entries in the task list.
		// Prior to a full validation, the validation framework will remove
		// all messages owned
		// by a validator before it is executed.
		// Prior to an incremental validation, the validation framework will
		// remove all messages,
		// on each of the changed resources, owned by a validator before it is
		// invoked.
		// 
		// It is up to the validator to make sure that it is not adding the
		// same message
		// in more than one place, and also to clear out any old messages
		// which are not cleared
		// by the validation framework.
		IMarker item = resource.createMarker(VALIDATION_MARKER); // add a
																	// validation
																	// marker

		// For performance reasons, replace the multiple setAttribute
		// calls above with a single setAttributes call.
		boolean offsetSet = ((offset != IMessage.OFFSET_UNSET) && (length != IMessage.OFFSET_UNSET));
		int size = (offsetSet) ? 10 : 8; // add CHAR_START, CHAR_END only
											// if the offset is set. If the
											// offset is set, it takes
											// precendence over the line
											// number. (eclipse's rule, not
											// mine.)
		String[] attribNames = new String[size];
		Object[] attribValues = new Object[size];

		// Very first thing, add the owner. That way, if the code dies
		// before things are persisted, hopefully this marker will be
		// persisted.
		// Hopefully, eclipse WILL persist this field, as requested.
		attribNames[0] = VALIDATION_MARKER_OWNER;
		attribValues[0] = pluginId;
		attribNames[1] = VALIDATION_MARKER_SEVERITY; // this validation
														// severity is stored,
														// in addition to the
														// marker severity, to
														// enable more than
														// one severity of
														// message to be
														// displayed. e.g.
														// ERROR | WARNING
														// (using binary OR).
														// The IMarker
														// constants are
														// regular decimal
														// constants.
		attribValues[1] = new Integer(markerType);
		attribNames[2] = VALIDATION_MARKER_TARGETOBJECT; // to distinguish
															// between
															// messages which
															// are registered
															// on an
															// IResource, but
															// against
															// different
															// target objects
		attribValues[2] = ((targetObjectName == null) ? "" : targetObjectName); //$NON-NLS-1$
		attribNames[3] = VALIDATION_MARKER_GROUP;
		attribValues[3] = ((groupName == null) ? "" : groupName); //$NON-NLS-1$
		attribNames[4] = IMarker.MESSAGE;
		attribValues[4] = message;
		attribNames[5] = VALIDATION_MARKER_MESSAGEID;
		attribValues[5] = messageId;

		attribNames[6] = IMarker.SEVERITY; // IMarker.SEVERITY_ERROR,
											// IMarker.SEVERITY_WARNING,
											// IMarker.SEVERITY_INFO
		attribValues[6] = new Integer(severity);
		try {
			// If the location is a line number, store it as a line number
			Integer lineNumber = Integer.valueOf(location);
			attribNames[7] = IMarker.LINE_NUMBER;
			attribValues[7] = lineNumber;
		}
		catch (NumberFormatException exc) {
			// Otherwise, store it as a text location
			attribNames[7] = IMarker.LOCATION;
			attribValues[7] = location;
		}

		if (offsetSet) {
			attribNames[8] = IMarker.CHAR_START;
			attribValues[8] = new Integer(offset);
			attribNames[9] = IMarker.CHAR_END;
			attribValues[9] = new Integer(offset + length);
		}

		item.setAttributes(attribNames, attribValues);

		return item;
	}

	/**
	 * Given one of the SeverityEnum severities, return the IMarker severity
	 * int that is its equivalent.
	 */
	private static int getSeverity(int severityEnumValue) {
		switch (severityEnumValue) {
			case (IMessage.HIGH_SEVERITY) : {
				return IMarker.SEVERITY_ERROR;
			}

			case (IMessage.LOW_SEVERITY) : {
				return IMarker.SEVERITY_INFO;
			}

			case (IMessage.NORMAL_SEVERITY) : {
				return IMarker.SEVERITY_WARNING;
			}

			case (IMessage.ALL_MESSAGES) :
			case (IMessage.ERROR_AND_WARNING) :
			default : {
				// assume it's a warning.
				return IMarker.SEVERITY_WARNING;
			}
		}
	}

	private static int getDepth(IResource resource) {
		if (resource instanceof IProject) {
			return DEPTH_INFINITE; // DEPTH_INFINITE means get this project's
									// markers, and the markers belonging to
									// the project's children.
		}
		else if (resource instanceof IWorkspaceRoot) {
			// Needed for the ValidationMigrator when it checks for orphan
			// tasks.
			return DEPTH_INFINITE; // DEPTH_INFINITE means get all of the
									// markers in the workspace
		}

		return DEPTH_ZERO; // DEPTH_ZERO means just this resource, not its
							// children
	}

	private static IMarker[] getValidationTasks(IResource resource, int severity, int depth) {
		IMarker[] tempMarkers = null;
		int validCount = 0;
		try {
			IMarker[] allMarkers = null;
			try {
				allMarkers = resource.findMarkers(VALIDATION_MARKER, false, depth); // false
																					// means
																					// only
																					// consider
																					// PROBLEM_MARKER,
																					// not
																					// variants
																					// of
																					// PROBLEM_MARKER.
																					// Since
																					// addTask
																					// only
																					// adds
																					// PROBLEM_MARKER,
																					// we
																					// don't
																					// need
																					// to
																					// consider
																					// its
																					// subtypes.
			}
			catch (CoreException exc) {
				// Logger logger =
				// ValidationPlugin.getPlugin().getMsgLogger();
				// if (logger.isLoggingLevel(Level.SEVERE)) {
				// LogEntry entry = ValidationPlugin.getLogEntry();
				// entry.setSourceID("TaskListUtility.getValidationTasks(IResource,
				// int)"); //$NON-NLS-1$
				// entry.setTargetException(exc);
				// logger.write(Level.SEVERE, entry);
				// }
				return NO_MARKERS;
			}

			// Now filter in the markers, based on severity type.
			if (allMarkers.length != 0) {
				tempMarkers = new IMarker[allMarkers.length];
				for (int i = 0; i < allMarkers.length; i++) {
					IMarker marker = allMarkers[i];
					Integer filterSeverity = (Integer) marker.getAttribute(VALIDATION_MARKER_SEVERITY);
					if (filterSeverity == null) {
						// odd...marker wasn't created correctly. How could
						// this happen?
						// Default to the current severity and add it to the
						// list.
						try {
							marker.setAttribute(IMarker.SEVERITY, getSeverity(severity));
						}
						catch (CoreException exc) {
							// Logger logger =
							// ValidationPlugin.getPlugin().getMsgLogger();
							// if (logger.isLoggingLevel(Level.SEVERE)) {
							// LogEntry entry =
							// ValidationPlugin.getLogEntry();
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
							// IResource, int)"); //$NON-NLS-1$
							// entry.setTargetException(exc);
							// logger.write(Level.SEVERE, entry);
							// }
							continue;
						}
						catch (Throwable exc) {
							// Logger logger =
							// ValidationPlugin.getPlugin().getMsgLogger();
							// if (logger.isLoggingLevel(Level.SEVERE)) {
							// LogEntry entry =
							// ValidationPlugin.getLogEntry();
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
							// IResource, int)"); //$NON-NLS-1$
							// entry.setTargetException(exc);
							// logger.write(Level.SEVERE, entry);
							// }
							continue;
						}
					}
					else if ((severity & filterSeverity.intValue()) == 0) {
						continue;
					}
					tempMarkers[validCount++] = marker;
				}
			}
		}
		catch (CoreException exc) {
			// Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			// if (logger.isLoggingLevel(Level.SEVERE)) {
			// LogEntry entry = ValidationPlugin.getLogEntry();
			// entry.setSourceID("TaskListUtility.getValidationTasks(int,
			// IResource, int)"); //$NON-NLS-1$
			// entry.setTargetException(exc);
			// logger.write(Level.SEVERE, entry);
			// }
		}

		if (validCount == 0) {
			return NO_MARKERS;
		}

		IMarker[] validMarkers = new IMarker[validCount];
		System.arraycopy(tempMarkers, 0, validMarkers, 0, validCount);
		return validMarkers;
	}

	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwners, int depth) {
		IMarker[] markers = getValidationTasks(resource, IMessage.ALL_MESSAGES, depth);
		if (markers.length == 0) {
			return NO_MARKERS;
		}

		IMarker[] temp = new IMarker[markers.length];
		int validCount = 0;
		for (int i = 0; i < markers.length; i++) {
			IMarker marker = markers[i];

			try {
				Object owner = marker.getAttribute(VALIDATION_MARKER_OWNER);
				if ((owner == null) || !(owner instanceof String)) {
					// The ValidationMigrator will remove any "unowned"
					// validation markers.
					continue;
				}

				for (int j = 0; j < messageOwners.length; j++) {
					String messageOwner = messageOwners[j];
					if (((String) owner).equals(messageOwner)) {
						temp[validCount++] = marker;
						break;
					}
				}
			}
			catch (CoreException exc) {
				// Logger logger =
				// ValidationPlugin.getPlugin().getMsgLogger();
				// if (logger.isLoggingLevel(Level.SEVERE)) {
				// LogEntry entry = ValidationPlugin.getLogEntry();
				// entry.setSourceID("TaskListUtility.getValidationTasks(project,
				// String[])"); //$NON-NLS-1$
				// entry.setTargetException(exc);
				// logger.write(Level.SEVERE, entry);
				// }
				return NO_MARKERS;
			}
		}

		IMarker[] result = new IMarker[validCount];
		System.arraycopy(temp, 0, result, 0, validCount);
		return result;
	}

	/**
	 * This method retrieves all validation tasks from the resource. If depth
	 * is INFINITE, child tasks are returned as well. Only the tasks which are
	 * owned by the specified messageOwner, and apply to the named IMessage's
	 * target object (objectName) will be returned.
	 */
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwner, String objectName, String groupName, int depth) throws CoreException {
		if ((messageOwner == null) || (resource == null)) {
			return NO_MARKERS;
		}

		int validCount = 0;
		IMarker[] validList = null;
		IMarker[] markers = getValidationTasks(resource, messageOwner, depth);
		if (markers != null) {
			validList = new IMarker[markers.length];
			for (int i = 0; i < markers.length; i++) {
				IMarker marker = markers[i];

				// If more than one target object resolves to the same
				// resource, removing one target's
				// messages should not remove the other target object's
				// messages.
				if (objectName != null) {
					Object targetObject = marker.getAttribute(VALIDATION_MARKER_TARGETOBJECT);
					if ((targetObject == null) || !(targetObject instanceof String) || !(((String) targetObject).equals(objectName))) {
						continue;
					}
				}

				if (groupName != null) {
					Object group = marker.getAttribute(VALIDATION_MARKER_GROUP);
					if ((group == null) || !(group instanceof String) || !(((String) group).equals(groupName))) {
						continue;
					}
				}

				validList[validCount++] = marker;
			}
		}

		if (validCount == 0) {
			return NO_MARKERS;
		}

		IMarker[] result = new IMarker[validCount];
		System.arraycopy(validList, 0, result, 0, validCount);
		return result;
	}

	/**
	 * This method removes all messages from a resource in the task list.
	 */
	public static void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
		removeAllTasks(resource, new String[]{owner}, objectName);
	}

	public static void removeAllTasks(IResource resource, String[] owners, String objectName) throws CoreException {
		removeAllTasks(resource, owners, objectName, getDepth(resource));
	}

	protected static void removeAllTasks(IResource resource, String[] owners, String objectName, int depth) throws CoreException {
		removeTaskSubset(resource, owners, objectName, null, depth); // null
																		// means
																		// no
																		// group
																		// name
	}

	/**
	 * This method removes a subset of tasks from the project, including child
	 * tasks. Every task which belongs to the group, identified by groupName,
	 * will be removed.
	 */
	protected static void removeTaskSubset(IResource resource, String[] owners, String objectName, String groupName, int depth) throws CoreException {
		if ((owners == null) || (resource == null)) {
			return;
		}

		IMarker[] allTasks = getValidationTasks(resource, owners, objectName, groupName, depth);
		if (allTasks.length > 0) {
			ResourcesPlugin.getWorkspace().deleteMarkers(allTasks);
		}
	}
}

Back to the top