Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 338111
Collapse All | Expand All

(-).classpath (+1 lines)
Lines 1-6 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
1
<?xml version="1.0" encoding="UTF-8"?>
2
<classpath>
2
<classpath>
3
	<classpathentry kind="src" path="src"/>
3
	<classpathentry kind="src" path="src"/>
4
	<classpathentry kind="src" path="src-html-validation"/>
4
	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
5
	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
5
		<accessrules>
6
		<accessrules>
6
			<accessrule kind="accessible" pattern="org/w3c/dom/css/**/*"/>
7
			<accessrule kind="accessible" pattern="org/w3c/dom/css/**/*"/>
(-)plugin.properties (+1 lines)
Lines 14-16 Link Here
14
HTML_Content_Type_Extension_Element.name=HTML
14
HTML_Content_Type_Extension_Element.name=HTML
15
_taskMarker.name=HTML Task
15
_taskMarker.name=HTML Task
16
_validationMarker.name=HTML Problem
16
_validationMarker.name=HTML Problem
17
HTML_Syntax_Validator.name=HTML Syntax Validator
(-)plugin.xml (+24 lines)
Lines 210-213 Link Here
210
			class="org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceInitializer" />
210
			class="org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceInitializer" />
211
	</extension>
211
	</extension>
212
212
213
	<!--======================================================================================-->
214
	<!-- Workbench validation                                       						  -->
215
	<!--======================================================================================-->
216
   <extension id="HTMLValidator" name="%HTML_Syntax_Validator.name" point="org.eclipse.wst.validation.validatorV2">
217
      <validator
218
            build="true"
219
            class="org.eclipse.wst.html.internal.validation.HTMLValidator"
220
            manual="true"
221
            sourceid="org.eclipse.wst.html.ui.internal.validation.htmlsyntaxvalidator"
222
            version="1"
223
            markerId="org.eclipse.wst.html.core.validationMarker">
224
         <include>
225
            <rules>
226
               <contentType id="org.eclipse.wst.html.core.htmlsource"></contentType>
227
               <fileext caseSensitive="false" ext="html"/>
228
               <fileext caseSensitive="false" ext="xhtml"/>
229
               <fileext caseSensitive="false" ext="htm"/>
230
               <fileext caseSensitive="false" ext="htpl"/>
231
               <fileext caseSensitive="false" ext="wml"/>
232
            </rules>
233
         </include>
234
         <group id="org.eclipse.wst.sse.core.structuredModelGroup"/>
235
      </validator>
236
   </extension>
213
</plugin>
237
</plugin>
(-)META-INF/MANIFEST.MF (-3 / +5 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %pluginName
3
Bundle-Name: %pluginName
4
Bundle-SymbolicName: org.eclipse.wst.html.core; singleton:=true
4
Bundle-SymbolicName: org.eclipse.wst.html.core; singleton:=true
5
Bundle-Version: 1.1.404.qualifier
5
Bundle-Version: 1.1.405.qualifier
6
Bundle-Activator: org.eclipse.wst.html.core.internal.HTMLCorePlugin
6
Bundle-Activator: org.eclipse.wst.html.core.internal.HTMLCorePlugin
7
Bundle-Vendor: %providerName
7
Bundle-Vendor: %providerName
8
Bundle-Localization: plugin
8
Bundle-Localization: plugin
Lines 26-32 Link Here
26
 org.eclipse.wst.html.core.internal.provisional.text;x-internal:=true,
26
 org.eclipse.wst.html.core.internal.provisional.text;x-internal:=true,
27
 org.eclipse.wst.html.core.internal.text;x-internal:=true,
27
 org.eclipse.wst.html.core.internal.text;x-internal:=true,
28
 org.eclipse.wst.html.core.internal.validate;x-internal:=true,
28
 org.eclipse.wst.html.core.internal.validate;x-internal:=true,
29
 org.eclipse.wst.html.core.text
29
 org.eclipse.wst.html.core.text,
30
 org.eclipse.wst.html.internal.validation;x-friends:="org.eclipse.wst.html.ui"
30
Import-Package: com.ibm.icu.util; version="3.8"
31
Import-Package: com.ibm.icu.util; version="3.8"
31
Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
32
Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
32
 org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
33
 org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
Lines 35-40 Link Here
35
 org.eclipse.wst.xml.core;bundle-version="[1.1.500,1.2.0)",
36
 org.eclipse.wst.xml.core;bundle-version="[1.1.500,1.2.0)",
36
 org.eclipse.wst.css.core;bundle-version="[1.1.400,1.2.0)",
37
 org.eclipse.wst.css.core;bundle-version="[1.1.400,1.2.0)",
37
 org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)",
38
 org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)",
38
 org.eclipse.wst.common.modulecore;bundle-version="[1.2.0,2.0.0)";resolution:=optional
39
 org.eclipse.wst.common.modulecore;bundle-version="[1.2.0,2.0.0)";resolution:=optional,
40
 org.eclipse.wst.validation;bundle-version="1.2.201"
39
Bundle-ActivationPolicy: lazy;exclude:="org.eclipse.wst.html.core.internal.contenttype,org.eclipse.wst.html.core.internal.provisional.contenttype"
41
Bundle-ActivationPolicy: lazy;exclude:="org.eclipse.wst.html.core.internal.contenttype,org.eclipse.wst.html.core.internal.provisional.contenttype"
40
Bundle-RequiredExecutionEnvironment: J2SE-1.4
42
Bundle-RequiredExecutionEnvironment: J2SE-1.4
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidationReporter.java (+150 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IPath;
16
import org.eclipse.wst.html.core.internal.validate.MessageFactory;
17
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
18
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
19
import org.eclipse.wst.sse.core.internal.validate.ErrorInfo;
20
import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
21
import org.eclipse.wst.sse.core.internal.validate.ValidationReporter;
22
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
23
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
24
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
25
26
public class HTMLValidationReporter implements ValidationReporter {
27
28
	private IValidator owner = null;
29
	private IReporter reporter = null;
30
	private IFile file = null;
31
	private IStructuredModel model = null;
32
	private HTMLValidationResult result = null;
33
	private MessageFactory fFactory = null;
34
	
35
	/**
36
	 */
37
	public HTMLValidationReporter(IValidator owner, IReporter reporter, IFile file, IStructuredModel model) {
38
		super();
39
		this.owner = owner;
40
		this.reporter = reporter;
41
		this.file = file;
42
		this.model = model;
43
		fFactory = new MessageFactory(file != null ? file.getProject() : null);
44
	}
45
46
	/**
47
	 */
48
	public void clear() {
49
		if (this.file == null)
50
			return;
51
52
		this.result = null;
53
54
		if (this.reporter != null) {
55
			this.reporter.removeAllMessages(this.owner, this.file);
56
		}
57
		else {
58
			// remove by myself?
59
			String id = HTMLValidator.class.getName();
60
			try {
61
				// TaskListHelper API changed
62
				// TaskListHelper.getTaskList().removeAllTasks(id, this.file,
63
				// null);
64
				TaskListHelper.getTaskList().removeAllTasks(this.file, id, null);
65
			}
66
			catch (CoreException ex) {
67
			}
68
		}
69
	}
70
71
72
	/**
73
	 */
74
	public HTMLValidationResult getResult() {
75
		if (this.result == null)
76
			this.result = new HTMLValidationResult();
77
		return this.result;
78
	}
79
80
	/**
81
	 */
82
	public void report(ValidationMessage message) {
83
		if (message == null || message.getSeverity() == ValidationMessage.IGNORE)
84
			return;
85
		IMessage mes = translateMessage(message);
86
87
		if (this.reporter != null) {
88
			this.reporter.addMessage(this.owner, mes);
89
		}
90
		else {
91
			if (this.file == null)
92
				return;
93
94
			// add by myself?
95
			String id = HTMLValidator.class.getName();
96
			String location = Integer.toString(mes.getLineNumber());
97
			String name = ""; //$NON-NLS-1$
98
			IPath filePath = this.file.getFullPath();
99
			if (filePath != null) {
100
				name = filePath.toString();
101
			}
102
			try {
103
				TaskListHelper.getTaskList().addTask(id, this.file, location, mes.getId(), mes.getText(), mes.getSeverity(), name, mes.getGroupName(), mes.getOffset(), mes.getLength());
104
			}
105
			catch (CoreException ex) {
106
			}
107
		}
108
	}
109
110
	/**
111
	 * Translate ValidationMessage to IMessage and generate result log
112
	 */
113
	private IMessage translateMessage(ValidationMessage message) {
114
		int severity = IMessage.LOW_SEVERITY;
115
		HTMLValidationResult result = getResult();
116
		switch (message.getSeverity()) {
117
			case ValidationMessage.ERROR :
118
				severity = IMessage.HIGH_SEVERITY;
119
				result.addError();
120
				break;
121
			case ValidationMessage.WARNING :
122
				severity = IMessage.NORMAL_SEVERITY;
123
				result.addWarning();
124
				break;
125
			case ValidationMessage.INFORMATION :
126
				result.addInformation();
127
				break;
128
			default :
129
//				result.addInformation();
130
				break;
131
		}
132
133
		IMessage mes = new LocalizedMessage(severity, message.getMessage(), this.file);
134
		mes.setOffset(message.getOffset());
135
		mes.setLength(message.getLength());
136
		if (this.model != null) {
137
			IStructuredDocument flatModel = this.model.getStructuredDocument();
138
			if (flatModel != null) {
139
				int line = flatModel.getLineOfOffset(message.getOffset());
140
				mes.setLineNo(line + 1);
141
			}
142
		}
143
144
		return mes;
145
	}
146
147
	public void report(ErrorInfo info) {
148
		report(fFactory.createMessage(info));
149
	}
150
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidationResult.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
public class HTMLValidationResult {
14
	private int errors = 0;
15
	private int warnings = 0;
16
	private int informations = 0;
17
18
	/**
19
	 */
20
	public HTMLValidationResult() {
21
	}
22
23
	/**
24
	 */
25
	public void addError() {
26
		this.errors++;
27
	}
28
29
	/**
30
	 */
31
	public void addInformation() {
32
		this.informations++;
33
	}
34
35
	/**
36
	 */
37
	public void addWarning() {
38
		this.warnings++;
39
	}
40
41
	/**
42
	 */
43
	public int getErrors() {
44
		return this.errors;
45
	}
46
47
	/**
48
	 */
49
	public int getInformations() {
50
		return this.informations;
51
	}
52
53
	/**
54
	 */
55
	public int getWarnings() {
56
		return this.warnings;
57
	}
58
59
	/**
60
	 */
61
	public boolean isValid() {
62
		return (this.errors == 0 && this.warnings == 0 && this.informations == 0);
63
	}
64
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java (+380 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import java.io.IOException;
14
import java.io.UnsupportedEncodingException;
15
import java.util.ArrayList;
16
import java.util.List;
17
18
import org.eclipse.core.resources.IContainer;
19
import org.eclipse.core.resources.IFile;
20
import org.eclipse.core.resources.IProject;
21
import org.eclipse.core.resources.IResource;
22
import org.eclipse.core.resources.ResourcesPlugin;
23
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.IConfigurationElement;
25
import org.eclipse.core.runtime.IExecutableExtension;
26
import org.eclipse.core.runtime.IProgressMonitor;
27
import org.eclipse.core.runtime.IStatus;
28
import org.eclipse.core.runtime.NullProgressMonitor;
29
import org.eclipse.core.runtime.OperationCanceledException;
30
import org.eclipse.core.runtime.Path;
31
import org.eclipse.core.runtime.Platform;
32
import org.eclipse.core.runtime.Status;
33
import org.eclipse.core.runtime.content.IContentDescription;
34
import org.eclipse.core.runtime.content.IContentType;
35
import org.eclipse.core.runtime.content.IContentTypeManager;
36
import org.eclipse.core.runtime.jobs.ISchedulingRule;
37
import org.eclipse.wst.html.core.internal.Logger;
38
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeConstants;
39
import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
40
import org.eclipse.wst.sse.core.StructuredModelManager;
41
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
42
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
43
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
44
import org.eclipse.wst.sse.core.internal.validate.ValidationAdapter;
45
import org.eclipse.wst.sse.core.utils.StringUtils;
46
import org.eclipse.wst.validation.AbstractValidator;
47
import org.eclipse.wst.validation.ValidationResult;
48
import org.eclipse.wst.validation.ValidationState;
49
import org.eclipse.wst.validation.internal.core.Message;
50
import org.eclipse.wst.validation.internal.core.ValidationException;
51
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
52
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
53
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
54
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
55
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
56
import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
57
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
58
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
59
60
public class HTMLValidator extends AbstractValidator implements IValidatorJob, IExecutableExtension {
61
	private static final String ORG_ECLIPSE_WST_HTML_CORE_HTMLSOURCE = "org.eclipse.wst.html.core.htmlsource"; //$NON-NLS-1$
62
63
	static boolean shouldValidate(IFile file) {
64
		IResource resource = file;
65
		do {
66
			if (resource.isDerived() || resource.isTeamPrivateMember() || !resource.isAccessible()
67
					|| (resource.getName().charAt(0) == '.' && resource.getType() == IResource.FOLDER)) {
68
				return false;
69
			}
70
			resource = resource.getParent();
71
		}
72
		while ((resource.getType() & IResource.PROJECT) == 0);
73
		return true;
74
	}
75
76
	private IContentTypeManager fContentTypeManager;
77
	private IContentType[] fOtherSupportedContentTypes = null;
78
	private String[] fAdditionalContentTypesIDs = null;
79
	private IContentType fHTMLContentType;
80
81
	public HTMLValidator() {
82
		super();
83
		fContentTypeManager = Platform.getContentTypeManager();
84
		fHTMLContentType = fContentTypeManager.getContentType(ORG_ECLIPSE_WST_HTML_CORE_HTMLSOURCE);
85
	}
86
87
	/**
88
	 */
89
	public void cleanup(IReporter reporter) {
90
		// nothing to do
91
	}
92
93
	/**
94
	 * Gets list of content types this validator is interested in
95
	 * 
96
	 * @return All HTML-related content types
97
	 */
98
	private IContentType[] getOtherSupportedContentTypes() {
99
		if (fOtherSupportedContentTypes == null) {
100
			List contentTypes = new ArrayList(3);
101
			if (fAdditionalContentTypesIDs != null) {
102
				for (int i = 0; i < fAdditionalContentTypesIDs.length; i++) {
103
					IContentType type = Platform.getContentTypeManager().getContentType(fAdditionalContentTypesIDs[i]);
104
					if (type != null) {
105
						contentTypes.add(type);
106
					}
107
				}
108
			}
109
			fOtherSupportedContentTypes = (IContentType[]) contentTypes.toArray(new IContentType[contentTypes.size()]);
110
		}
111
		return fOtherSupportedContentTypes;
112
	}
113
114
	/**
115
	 */
116
	protected IDOMModel getModel(IProject project, IFile file) {
117
		if (project == null || file == null)
118
			return null;
119
		if (!file.exists())
120
			return null;
121
		if (!canHandle(file))
122
			return null;
123
124
		IStructuredModel model = null;
125
		IModelManager manager = StructuredModelManager.getModelManager();
126
		try {
127
			file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
128
		}
129
		catch (CoreException e) {
130
			Logger.logException(e);
131
		}
132
		try {
133
			try {
134
				model = manager.getModelForRead(file);
135
			}
136
			catch (UnsupportedEncodingException ex) {
137
				// retry ignoring META charset for invalid META charset
138
				// specification
139
				// recreate input stream, because it is already partially read
140
				model = manager.getModelForRead(file, new String(), null);
141
			}
142
		}
143
		catch (UnsupportedEncodingException ex) {
144
		}
145
		catch (IOException ex) {
146
		}
147
		catch (CoreException e) {
148
			Logger.logException(e);
149
		}
150
151
		if (model == null)
152
			return null;
153
		if (!(model instanceof IDOMModel)) {
154
			releaseModel(model);
155
			return null;
156
		}
157
		return (IDOMModel) model;
158
	}
159
160
	/**
161
	 */
162
	protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
163
		return new HTMLValidationReporter(this, reporter, file, model);
164
	}
165
166
	/**
167
	 * Check file extension to validate
168
	 */
169
	private boolean canHandle(IFile file) {
170
		boolean result = false;
171
		if (file != null) {
172
			try {
173
				IContentDescription contentDescription = file.getContentDescription();
174
				if (contentDescription != null) {
175
					IContentType fileContentType = contentDescription.getContentType();
176
					if (fileContentType.isKindOf(fHTMLContentType)) {
177
						result = true;
178
					}
179
					else {
180
						IContentType[] otherTypes = getOtherSupportedContentTypes();
181
						for (int i = 0; i < otherTypes.length; i++) {
182
							result = result || fileContentType.isKindOf(otherTypes[i]);
183
						}
184
					}
185
				}
186
				else if (fHTMLContentType != null) {
187
					result = fHTMLContentType.isAssociatedWith(file.getName());
188
				}
189
			}
190
			catch (CoreException e) {
191
				// should be rare, but will ignore to avoid logging "encoding
192
				// exceptions" and the like here.
193
				// Logger.logException(e);
194
			}
195
		}
196
		return result;
197
	}
198
199
	/**
200
	 */
201
	private boolean hasHTMLFeature(IDOMDocument document) {
202
		DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
203
		if (adapter == null)
204
			return false;
205
		return adapter.hasFeature(HTMLDocumentTypeConstants.HTML);
206
	}
207
208
	/**
209
	 */
210
	protected void releaseModel(IStructuredModel model) {
211
		if (model != null)
212
			model.releaseFromRead();
213
	}
214
215
	/**
216
	 */
217
	public void validate(IValidationContext helper, IReporter reporter) {
218
		if (helper == null)
219
			return;
220
		if ((reporter != null) && (reporter.isCancelled() == true)) {
221
			throw new OperationCanceledException();
222
		}
223
		String[] deltaArray = helper.getURIs();
224
		if (deltaArray != null && deltaArray.length > 0) {
225
			validateDelta(helper, reporter);
226
		}
227
		else {
228
			validateFull(helper, reporter);
229
		}
230
	}
231
232
	/**
233
	 */
234
	private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) {
235
		if (file == null || model == null)
236
			return null; // error
237
		IDOMDocument document = model.getDocument();
238
		if (document == null)
239
			return null; // error
240
		if (!hasHTMLFeature(document))
241
			return null; // ignore
242
243
		INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
244
		ValidationAdapter adapter = (ValidationAdapter) factory.adapt(document);
245
		if (adapter == null)
246
			return null; // error
247
248
		HTMLValidationReporter rep = getReporter(reporter, file, model);
249
		rep.clear();
250
		adapter.setReporter(rep);
251
		adapter.validate(document);
252
		return rep.getResult();
253
	}
254
255
	/**
256
	 */
257
	private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) {
258
		try {
259
			IResource[] resourceArray = container.members(false);
260
			for (int i = 0; i < resourceArray.length; i++) {
261
				IResource resource = resourceArray[i];
262
				if (resource == null || reporter.isCancelled())
263
					continue;
264
				if (resource instanceof IFile) {
265
					Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, resource.getFullPath().toString()
266
							.substring(1));
267
					reporter.displaySubtask(this, message);
268
					validateFile(helper, reporter, (IFile) resource);
269
				}
270
				else if (resource instanceof IContainer) {
271
					validateContainer(helper, reporter, (IContainer) resource);
272
				}
273
			}
274
		}
275
		catch (CoreException ex) {
276
		}
277
	}
278
279
	/**
280
	 */
281
	private void validateDelta(IValidationContext helper, IReporter reporter) {
282
		String[] deltaArray = helper.getURIs();
283
		for (int i = 0; i < deltaArray.length; i++) {
284
			String delta = deltaArray[i];
285
			if (delta == null)
286
				continue;
287
288
			if (reporter != null) {
289
				Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, delta.substring(1));
290
				reporter.displaySubtask(this, message);
291
			}
292
293
			IResource resource = getResource(delta);
294
			if (resource == null || !(resource instanceof IFile))
295
				continue;
296
			validateFile(helper, reporter, (IFile) resource);
297
		}
298
	}
299
300
	/**
301
	 */
302
	private void validateFile(IValidationContext helper, IReporter reporter, IFile file) {
303
		if ((reporter != null) && (reporter.isCancelled() == true)) {
304
			throw new OperationCanceledException();
305
		}
306
		if (!shouldValidate(file)) {
307
			return;
308
		}
309
		IDOMModel model = getModel(file.getProject(), file);
310
		if (model == null)
311
			return;
312
313
		try {
314
			validate(reporter, file, model);
315
		}
316
		finally {
317
			releaseModel(model);
318
		}
319
	}
320
321
	/**
322
	 */
323
	private void validateFull(IValidationContext helper, IReporter reporter) {
324
		IProject project = null;
325
		String[] fileDelta = helper.getURIs();
326
		if (helper instanceof IWorkbenchContext) {
327
			IWorkbenchContext wbHelper = (IWorkbenchContext) helper;
328
			project = wbHelper.getProject();
329
		}
330
		else if (fileDelta.length > 0) {
331
			// won't work for project validation (b/c nothing in file delta)
332
			project = getResource(fileDelta[0]).getProject();
333
		}
334
		if (project == null)
335
			return;
336
		validateContainer(helper, reporter, project);
337
	}
338
339
	/*
340
	 * added to get rid or dependency on IWorkbenchHelper
341
	 */
342
	public IResource getResource(String delta) {
343
		return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta));
344
	}
345
346
	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
347
		return null;
348
	}
349
350
	public IStatus validateInJob(IValidationContext helper, IReporter reporter) throws ValidationException {
351
		// Exception catching was removed, see
352
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=123600
353
		IStatus status = Status.OK_STATUS;
354
		validate(helper, reporter);
355
		return status;
356
	}
357
358
	/**
359
	 * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
360
	 *      java.lang.String, java.lang.Object)
361
	 */
362
	public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
363
			throws CoreException {
364
		fAdditionalContentTypesIDs = new String[0];
365
		if (data != null) {
366
			if (data instanceof String && data.toString().length() > 0) {
367
				fAdditionalContentTypesIDs = StringUtils.unpack(data.toString());
368
			}
369
		}
370
	}
371
372
	public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
373
		if (resource.getType() != IResource.FILE)
374
			return null;
375
		ValidationResult result = new ValidationResult();
376
		IReporter reporter = result.getReporter(monitor);
377
		validateFile(null, reporter, (IFile) resource);
378
		return result;
379
	}
380
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/LocalizedMessage.java (+65 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import java.util.Locale;
14
15
import org.eclipse.core.resources.IResource;
16
import org.eclipse.wst.validation.internal.core.Message;
17
18
/**
19
 * copied from org.eclipse.wst.validation.internal.operations.LocalizedMessage
20
 * 
21
 * This class is provided for validators which run only in Eclipse and whose messages, because they
22
 * come from another tool, are already localized. LocalizedMessage cannot be used by any validator
23
 * which needs to run in both WebSphere and Eclipse.
24
 */
25
public class LocalizedMessage extends Message {
26
	private String _message = null;
27
28
	public LocalizedMessage(int severity, String messageText) {
29
		this(severity, messageText, null);
30
	}
31
32
	public LocalizedMessage(int severity, String messageText, IResource targetObject) {
33
		this(severity, messageText, (Object) targetObject);
34
	}
35
36
	public LocalizedMessage(int severity, String messageText, Object targetObject) {
37
		super(null, severity, null);
38
		setLocalizedMessage(messageText);
39
		setTargetObject(targetObject);
40
	}
41
42
	public void setLocalizedMessage(String message) {
43
		_message = message;
44
	}
45
46
	public String getLocalizedMessage() {
47
		return _message;
48
	}
49
50
	public String getText() {
51
		return getLocalizedMessage();
52
	}
53
54
	public String getText(ClassLoader cl) {
55
		return getLocalizedMessage();
56
	}
57
58
	public String getText(Locale l) {
59
		return getLocalizedMessage();
60
	}
61
62
	public String getText(Locale l, ClassLoader cl) {
63
		return getLocalizedMessage();
64
	}
65
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/TaskListHelper.java (+44 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IResource;
14
import org.eclipse.core.runtime.CoreException;
15
16
/**
17
 * 
18
 * Class to help this Problem's list.
19
 * 
20
 */
21
class TaskListHelper {
22
	private static TaskListHelper _taskListHelper = null;
23
24
	public static TaskListHelper getTaskList() {
25
		if (_taskListHelper == null) {
26
			_taskListHelper = new TaskListHelper();
27
		}
28
		return _taskListHelper;
29
	}
30
31
	/**
32
	 * This method adds a message to a resource in the task list.
33
	 */
34
	public void addTask(String pluginId, IResource resource, String location, String messageId, String message, int markerType, String targetObjectName, String groupName, int offset, int length) throws CoreException {
35
		TaskListUtility.addTask(pluginId, resource, location, messageId, message, markerType, targetObjectName, groupName, offset, length);
36
	}
37
38
	/**
39
	 * This method removes all messages from a resource in the task list.
40
	 */
41
	public void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
42
		TaskListUtility.removeAllTasks(resource, owner, objectName);
43
	}
44
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/TaskListUtility.java (+436 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IMarker;
14
import org.eclipse.core.resources.IProject;
15
import org.eclipse.core.resources.IResource;
16
import org.eclipse.core.resources.IWorkspaceRoot;
17
import org.eclipse.core.resources.ResourcesPlugin;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.wst.html.core.internal.HTMLCorePlugin;
20
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
21
22
/**
23
 * This class must be called only by the validation framework.
24
 * 
25
 * This singleton interacts with the eclipse workbench's Task list.
26
 * TaskListUtility adds and removes tasks from the list.
27
 * 
28
 * This class must not be called outside of an IWorkspaceRunnable or
29
 * IRunnableWithProgress. Many resource deltas can be generated by the methods
30
 * in this class.
31
 * 
32
 * This came from TaskListUtility
33
 */
34
public class TaskListUtility {
35
	// private static final String PLUGIN_ID = ValidationPlugin.PLUGIN_ID;
36
	private static final String PLUGIN_ID = HTMLCorePlugin.ID;
37
	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
38
	private static final String VALIDATION_MARKER_OWNER = "owner"; //$NON-NLS-1$ // The IValidator who owns the IMarker on the task list
39
	private static final String VALIDATION_MARKER_SEVERITY = "validationSeverity"; //$NON-NLS-1$ // one of the IMessage values
40
	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.
41
	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.
42
	private static final String VALIDATION_MARKER_MESSAGEID = "messageId"; //$NON-NLS-1$ // Persist the message id of the message, not just the translated text.
43
	private static final int DEPTH_INFINITE = IResource.DEPTH_INFINITE;
44
	private static final int DEPTH_ZERO = IResource.DEPTH_ZERO;
45
	private final static IMarker[] NO_MARKERS = new IMarker[0];
46
47
	/**
48
	 * This method adds a message to a resource in the task list.
49
	 */
50
	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 {
51
		if ((message == null) || (resource == null)) {
52
			return null;
53
		}
54
55
		int severity = getSeverity(markerType);
56
57
		// Allow duplicate entries in the task list.
58
		// Prior to a full validation, the validation framework will remove
59
		// all messages owned
60
		// by a validator before it is executed.
61
		// Prior to an incremental validation, the validation framework will
62
		// remove all messages,
63
		// on each of the changed resources, owned by a validator before it is
64
		// invoked.
65
		// 
66
		// It is up to the validator to make sure that it is not adding the
67
		// same message
68
		// in more than one place, and also to clear out any old messages
69
		// which are not cleared
70
		// by the validation framework.
71
		IMarker item = resource.createMarker(VALIDATION_MARKER); // add a
72
																	// validation
73
																	// marker
74
75
		// For performance reasons, replace the multiple setAttribute
76
		// calls above with a single setAttributes call.
77
		boolean offsetSet = ((offset != IMessage.OFFSET_UNSET) && (length != IMessage.OFFSET_UNSET));
78
		int size = (offsetSet) ? 10 : 8; // add CHAR_START, CHAR_END only
79
											// if the offset is set. If the
80
											// offset is set, it takes
81
											// precendence over the line
82
											// number. (eclipse's rule, not
83
											// mine.)
84
		String[] attribNames = new String[size];
85
		Object[] attribValues = new Object[size];
86
87
		// Very first thing, add the owner. That way, if the code dies
88
		// before things are persisted, hopefully this marker will be
89
		// persisted.
90
		// Hopefully, eclipse WILL persist this field, as requested.
91
		attribNames[0] = VALIDATION_MARKER_OWNER;
92
		attribValues[0] = pluginId;
93
		attribNames[1] = VALIDATION_MARKER_SEVERITY; // this validation
94
														// severity is stored,
95
														// in addition to the
96
														// marker severity, to
97
														// enable more than
98
														// one severity of
99
														// message to be
100
														// displayed. e.g.
101
														// ERROR | WARNING
102
														// (using binary OR).
103
														// The IMarker
104
														// constants are
105
														// regular decimal
106
														// constants.
107
		attribValues[1] = new Integer(markerType);
108
		attribNames[2] = VALIDATION_MARKER_TARGETOBJECT; // to distinguish
109
															// between
110
															// messages which
111
															// are registered
112
															// on an
113
															// IResource, but
114
															// against
115
															// different
116
															// target objects
117
		attribValues[2] = ((targetObjectName == null) ? "" : targetObjectName); //$NON-NLS-1$
118
		attribNames[3] = VALIDATION_MARKER_GROUP;
119
		attribValues[3] = ((groupName == null) ? "" : groupName); //$NON-NLS-1$
120
		attribNames[4] = IMarker.MESSAGE;
121
		attribValues[4] = message;
122
		attribNames[5] = VALIDATION_MARKER_MESSAGEID;
123
		attribValues[5] = messageId;
124
125
		attribNames[6] = IMarker.SEVERITY; // IMarker.SEVERITY_ERROR,
126
											// IMarker.SEVERITY_WARNING,
127
											// IMarker.SEVERITY_INFO
128
		attribValues[6] = new Integer(severity);
129
		try {
130
			// If the location is a line number, store it as a line number
131
			Integer lineNumber = Integer.valueOf(location);
132
			attribNames[7] = IMarker.LINE_NUMBER;
133
			attribValues[7] = lineNumber;
134
		}
135
		catch (NumberFormatException exc) {
136
			// Otherwise, store it as a text location
137
			attribNames[7] = IMarker.LOCATION;
138
			attribValues[7] = location;
139
		}
140
141
		if (offsetSet) {
142
			attribNames[8] = IMarker.CHAR_START;
143
			attribValues[8] = new Integer(offset);
144
			attribNames[9] = IMarker.CHAR_END;
145
			attribValues[9] = new Integer(offset + length);
146
		}
147
148
		item.setAttributes(attribNames, attribValues);
149
150
		return item;
151
	}
152
153
	/**
154
	 * Given one of the SeverityEnum severities, return the IMarker severity
155
	 * int that is its equivalent.
156
	 */
157
	private static int getSeverity(int severityEnumValue) {
158
		switch (severityEnumValue) {
159
			case (IMessage.HIGH_SEVERITY) : {
160
				return IMarker.SEVERITY_ERROR;
161
			}
162
163
			case (IMessage.LOW_SEVERITY) : {
164
				return IMarker.SEVERITY_INFO;
165
			}
166
167
			case (IMessage.NORMAL_SEVERITY) : {
168
				return IMarker.SEVERITY_WARNING;
169
			}
170
171
			case (IMessage.ALL_MESSAGES) :
172
			case (IMessage.ERROR_AND_WARNING) :
173
			default : {
174
				// assume it's a warning.
175
				return IMarker.SEVERITY_WARNING;
176
			}
177
		}
178
	}
179
180
	private static int getDepth(IResource resource) {
181
		if (resource instanceof IProject) {
182
			return DEPTH_INFINITE; // DEPTH_INFINITE means get this project's
183
									// markers, and the markers belonging to
184
									// the project's children.
185
		}
186
		else if (resource instanceof IWorkspaceRoot) {
187
			// Needed for the ValidationMigrator when it checks for orphan
188
			// tasks.
189
			return DEPTH_INFINITE; // DEPTH_INFINITE means get all of the
190
									// markers in the workspace
191
		}
192
193
		return DEPTH_ZERO; // DEPTH_ZERO means just this resource, not its
194
							// children
195
	}
196
197
	private static IMarker[] getValidationTasks(IResource resource, int severity, int depth) {
198
		IMarker[] tempMarkers = null;
199
		int validCount = 0;
200
		try {
201
			IMarker[] allMarkers = null;
202
			try {
203
				allMarkers = resource.findMarkers(VALIDATION_MARKER, false, depth); // false
204
																					// means
205
																					// only
206
																					// consider
207
																					// PROBLEM_MARKER,
208
																					// not
209
																					// variants
210
																					// of
211
																					// PROBLEM_MARKER.
212
																					// Since
213
																					// addTask
214
																					// only
215
																					// adds
216
																					// PROBLEM_MARKER,
217
																					// we
218
																					// don't
219
																					// need
220
																					// to
221
																					// consider
222
																					// its
223
																					// subtypes.
224
			}
225
			catch (CoreException exc) {
226
				// Logger logger =
227
				// ValidationPlugin.getPlugin().getMsgLogger();
228
				// if (logger.isLoggingLevel(Level.SEVERE)) {
229
				// LogEntry entry = ValidationPlugin.getLogEntry();
230
				// entry.setSourceID("TaskListUtility.getValidationTasks(IResource,
231
				// int)"); //$NON-NLS-1$
232
				// entry.setTargetException(exc);
233
				// logger.write(Level.SEVERE, entry);
234
				// }
235
				return NO_MARKERS;
236
			}
237
238
			// Now filter in the markers, based on severity type.
239
			if (allMarkers.length != 0) {
240
				tempMarkers = new IMarker[allMarkers.length];
241
				for (int i = 0; i < allMarkers.length; i++) {
242
					IMarker marker = allMarkers[i];
243
					Integer filterSeverity = (Integer) marker.getAttribute(VALIDATION_MARKER_SEVERITY);
244
					if (filterSeverity == null) {
245
						// odd...marker wasn't created correctly. How could
246
						// this happen?
247
						// Default to the current severity and add it to the
248
						// list.
249
						try {
250
							marker.setAttribute(IMarker.SEVERITY, getSeverity(severity));
251
						}
252
						catch (CoreException exc) {
253
							// Logger logger =
254
							// ValidationPlugin.getPlugin().getMsgLogger();
255
							// if (logger.isLoggingLevel(Level.SEVERE)) {
256
							// LogEntry entry =
257
							// ValidationPlugin.getLogEntry();
258
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
259
							// IResource, int)"); //$NON-NLS-1$
260
							// entry.setTargetException(exc);
261
							// logger.write(Level.SEVERE, entry);
262
							// }
263
							continue;
264
						}
265
						catch (Exception exc) {
266
							// Logger logger =
267
							// ValidationPlugin.getPlugin().getMsgLogger();
268
							// if (logger.isLoggingLevel(Level.SEVERE)) {
269
							// LogEntry entry =
270
							// ValidationPlugin.getLogEntry();
271
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
272
							// IResource, int)"); //$NON-NLS-1$
273
							// entry.setTargetException(exc);
274
							// logger.write(Level.SEVERE, entry);
275
							// }
276
							continue;
277
						}
278
					}
279
					else if ((severity & filterSeverity.intValue()) == 0) {
280
						continue;
281
					}
282
					tempMarkers[validCount++] = marker;
283
				}
284
			}
285
		}
286
		catch (CoreException exc) {
287
			// Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
288
			// if (logger.isLoggingLevel(Level.SEVERE)) {
289
			// LogEntry entry = ValidationPlugin.getLogEntry();
290
			// entry.setSourceID("TaskListUtility.getValidationTasks(int,
291
			// IResource, int)"); //$NON-NLS-1$
292
			// entry.setTargetException(exc);
293
			// logger.write(Level.SEVERE, entry);
294
			// }
295
		}
296
297
		if (validCount == 0) {
298
			return NO_MARKERS;
299
		}
300
301
		IMarker[] validMarkers = new IMarker[validCount];
302
		System.arraycopy(tempMarkers, 0, validMarkers, 0, validCount);
303
		return validMarkers;
304
	}
305
306
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwners, int depth) {
307
		IMarker[] markers = getValidationTasks(resource, IMessage.ALL_MESSAGES, depth);
308
		if (markers.length == 0) {
309
			return NO_MARKERS;
310
		}
311
312
		IMarker[] temp = new IMarker[markers.length];
313
		int validCount = 0;
314
		for (int i = 0; i < markers.length; i++) {
315
			IMarker marker = markers[i];
316
317
			try {
318
				Object owner = marker.getAttribute(VALIDATION_MARKER_OWNER);
319
				if ((owner == null) || !(owner instanceof String)) {
320
					// The ValidationMigrator will remove any "unowned"
321
					// validation markers.
322
					continue;
323
				}
324
325
				for (int j = 0; j < messageOwners.length; j++) {
326
					String messageOwner = messageOwners[j];
327
					if (((String) owner).equals(messageOwner)) {
328
						temp[validCount++] = marker;
329
						break;
330
					}
331
				}
332
			}
333
			catch (CoreException exc) {
334
				// Logger logger =
335
				// ValidationPlugin.getPlugin().getMsgLogger();
336
				// if (logger.isLoggingLevel(Level.SEVERE)) {
337
				// LogEntry entry = ValidationPlugin.getLogEntry();
338
				// entry.setSourceID("TaskListUtility.getValidationTasks(project,
339
				// String[])"); //$NON-NLS-1$
340
				// entry.setTargetException(exc);
341
				// logger.write(Level.SEVERE, entry);
342
				// }
343
				return NO_MARKERS;
344
			}
345
		}
346
347
		IMarker[] result = new IMarker[validCount];
348
		System.arraycopy(temp, 0, result, 0, validCount);
349
		return result;
350
	}
351
352
	/**
353
	 * This method retrieves all validation tasks from the resource. If depth
354
	 * is INFINITE, child tasks are returned as well. Only the tasks which are
355
	 * owned by the specified messageOwner, and apply to the named IMessage's
356
	 * target object (objectName) will be returned.
357
	 */
358
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwner, String objectName, String groupName, int depth) throws CoreException {
359
		if ((messageOwner == null) || (resource == null)) {
360
			return NO_MARKERS;
361
		}
362
363
		int validCount = 0;
364
		IMarker[] validList = null;
365
		IMarker[] markers = getValidationTasks(resource, messageOwner, depth);
366
		if (markers != null) {
367
			validList = new IMarker[markers.length];
368
			for (int i = 0; i < markers.length; i++) {
369
				IMarker marker = markers[i];
370
371
				// If more than one target object resolves to the same
372
				// resource, removing one target's
373
				// messages should not remove the other target object's
374
				// messages.
375
				if (objectName != null) {
376
					Object targetObject = marker.getAttribute(VALIDATION_MARKER_TARGETOBJECT);
377
					if ((targetObject == null) || !(targetObject instanceof String) || !(((String) targetObject).equals(objectName))) {
378
						continue;
379
					}
380
				}
381
382
				if (groupName != null) {
383
					Object group = marker.getAttribute(VALIDATION_MARKER_GROUP);
384
					if ((group == null) || !(group instanceof String) || !(((String) group).equals(groupName))) {
385
						continue;
386
					}
387
				}
388
389
				validList[validCount++] = marker;
390
			}
391
		}
392
393
		if (validCount == 0) {
394
			return NO_MARKERS;
395
		}
396
397
		IMarker[] result = new IMarker[validCount];
398
		System.arraycopy(validList, 0, result, 0, validCount);
399
		return result;
400
	}
401
402
	/**
403
	 * This method removes all messages from a resource in the task list.
404
	 */
405
	public static void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
406
		removeAllTasks(resource, new String[]{owner}, objectName);
407
	}
408
409
	public static void removeAllTasks(IResource resource, String[] owners, String objectName) throws CoreException {
410
		removeAllTasks(resource, owners, objectName, getDepth(resource));
411
	}
412
413
	protected static void removeAllTasks(IResource resource, String[] owners, String objectName, int depth) throws CoreException {
414
		removeTaskSubset(resource, owners, objectName, null, depth); // null
415
																		// means
416
																		// no
417
																		// group
418
																		// name
419
	}
420
421
	/**
422
	 * This method removes a subset of tasks from the project, including child
423
	 * tasks. Every task which belongs to the group, identified by groupName,
424
	 * will be removed.
425
	 */
426
	protected static void removeTaskSubset(IResource resource, String[] owners, String objectName, String groupName, int depth) throws CoreException {
427
		if ((owners == null) || (resource == null)) {
428
			return;
429
		}
430
431
		IMarker[] allTasks = getValidationTasks(resource, owners, objectName, groupName, depth);
432
		if (allTasks.length > 0) {
433
			ResourcesPlugin.getWorkspace().deleteMarkers(allTasks);
434
		}
435
	}
436
}
(-)src/org/eclipse/wst/html/core/internal/HTMLCorePlugin.java (+3 lines)
Lines 20-25 Link Here
20
 * The main plugin class to be used in the desktop.
20
 * The main plugin class to be used in the desktop.
21
 */
21
 */
22
public class HTMLCorePlugin extends Plugin {
22
public class HTMLCorePlugin extends Plugin {
23
24
	public final static String ID = "org.eclipse.wst.html.core"; //$NON-NLS-1$
25
23
	// The shared instance.
26
	// The shared instance.
24
	private static HTMLCorePlugin plugin;
27
	private static HTMLCorePlugin plugin;
25
28
(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %pluginName
3
Bundle-Name: %pluginName
4
Bundle-SymbolicName: org.eclipse.wst.html.ui; singleton:=true
4
Bundle-SymbolicName: org.eclipse.wst.html.ui; singleton:=true
5
Bundle-Version: 1.0.504.qualifier
5
Bundle-Version: 1.0.505.qualifier
6
Bundle-Activator: org.eclipse.wst.html.ui.internal.HTMLUIPlugin
6
Bundle-Activator: org.eclipse.wst.html.ui.internal.HTMLUIPlugin
7
Bundle-Vendor: %providerName
7
Bundle-Vendor: %providerName
8
Bundle-Localization: plugin
8
Bundle-Localization: plugin
(-)plugin.properties (-1 lines)
Lines 28-34 Link Here
28
HTML_Tag_context_type_Extension_Element.name=HTML Tag
28
HTML_Tag_context_type_Extension_Element.name=HTML Tag
29
HTML_Attribute_context_type_Extension_Element.name=HTML Attribute
29
HTML_Attribute_context_type_Extension_Element.name=HTML Attribute
30
HTML_Attribute_value_context_type_Extension_Element.name=HTML Attribute value
30
HTML_Attribute_value_context_type_Extension_Element.name=HTML Attribute value
31
HTML_Syntax_Validator.name=HTML Syntax Validator
32
###############################################################################
31
###############################################################################
33
#org.eclipse.ui.newWizards extension point
32
#org.eclipse.ui.newWizards extension point
34
_UI_WIZARD_NAME = HTML File
33
_UI_WIZARD_NAME = HTML File
(-)plugin.xml (-26 / +1 lines)
Lines 310-347 Link Here
310
	</extension>
310
	</extension>
311
311
312
	<!--======================================================================================-->
312
	<!--======================================================================================-->
313
	<!-- Workbench validation                                       						  -->
314
	<!--======================================================================================-->
315
   <extension id="HTMLValidator" name="%HTML_Syntax_Validator.name" point="org.eclipse.wst.validation.validatorV2">
316
      <validator
317
            build="true"
318
            class="org.eclipse.wst.html.internal.validation.HTMLValidator"
319
            manual="true"
320
            sourceid="org.eclipse.wst.html.ui.internal.validation.htmlsyntaxvalidator"
321
            version="1"
322
            markerId="org.eclipse.wst.html.core.validationMarker">
323
         <include>
324
            <rules>
325
               <contentType id="org.eclipse.wst.html.core.htmlsource"></contentType>
326
               <fileext caseSensitive="false" ext="html"/>
327
               <fileext caseSensitive="false" ext="xhtml"/>
328
               <fileext caseSensitive="false" ext="htm"/>
329
               <fileext caseSensitive="false" ext="htpl"/>
330
               <fileext caseSensitive="false" ext="wml"/>
331
            </rules>
332
         </include>
333
         <group id="org.eclipse.wst.sse.core.structuredModelGroup"/>
334
      </validator>
335
   </extension>
336
337
	<!--======================================================================================-->
338
	<!-- As you type validation                                      						  -->
313
	<!-- As you type validation                                      						  -->
339
	<!--======================================================================================-->
314
	<!--======================================================================================-->
340
315
341
	<extension point="org.eclipse.wst.sse.ui.sourcevalidation">
316
	<extension point="org.eclipse.wst.sse.ui.sourcevalidation">
342
		<validator
317
		<validator
343
			scope="total"
318
			scope="total"
344
			class="org.eclipse.wst.html.internal.validation.HTMLValidator"
319
			class="org.eclipse.wst.html.internal.validation.HTMLSourceValidator"
345
			id="org.eclipse.wst.html.ui.internal.validation.htmlsyntaxvalidator">
320
			id="org.eclipse.wst.html.ui.internal.validation.htmlsyntaxvalidator">
346
			<contentTypeIdentifier
321
			<contentTypeIdentifier
347
				id="org.eclipse.wst.html.core.htmlsource">
322
				id="org.eclipse.wst.html.core.htmlsource">
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLSourceValidator.java (+210 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.filebuffers.ITextFileBuffer;
14
import org.eclipse.core.resources.IFile;
15
import org.eclipse.core.resources.ResourcesPlugin;
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.core.runtime.OperationCanceledException;
18
import org.eclipse.core.runtime.Path;
19
import org.eclipse.jface.text.IDocument;
20
import org.eclipse.jface.text.IRegion;
21
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeConstants;
22
import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
23
import org.eclipse.wst.sse.core.StructuredModelManager;
24
import org.eclipse.wst.sse.core.internal.FileBufferModelManager;
25
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
26
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
27
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
28
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
29
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
30
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
31
import org.eclipse.wst.sse.core.internal.validate.ValidationAdapter;
32
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
33
import org.eclipse.wst.validation.internal.core.Message;
34
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
35
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
36
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
37
import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
38
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
39
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
40
import org.w3c.dom.Text;
41
42
public class HTMLSourceValidator extends HTMLValidator implements ISourceValidator {
43
44
	private IDocument fDocument;
45
46
	public HTMLSourceValidator() {
47
48
		super();
49
	}
50
51
	/**
52
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
53
	 */
54
	public void connect(IDocument document) {
55
		fDocument = document;
56
	}
57
58
	/**
59
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
60
	 */
61
	public void disconnect(IDocument document) {
62
		fDocument = null;
63
	}
64
65
	/**
66
	 * This validate call is for the ISourceValidator partial document validation approach
67
	 * 
68
	 * @param dirtyRegion
69
	 * @param helper
70
	 * @param reporter
71
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
72
	 */
73
	public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
74
75
		if (helper == null || fDocument == null)
76
			return;
77
78
		if ((reporter != null) && (reporter.isCancelled() == true)) {
79
			throw new OperationCanceledException();
80
		}
81
82
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
83
		if (model == null)
84
			return; // error
85
86
		try {
87
88
			IDOMDocument document = null;
89
			if (model instanceof IDOMModel) {
90
				document = ((IDOMModel) model).getDocument();
91
			}
92
93
			if (document == null || !hasHTMLFeature(document)) {
94
				// handled in finally clause
95
				// model.releaseFromRead();
96
				return; // ignore
97
			}
98
99
			IPath filePath = null;
100
			IFile file = null;
101
102
			ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument);
103
			if (fb != null) {
104
				filePath = fb.getLocation();
105
106
				if (filePath.segmentCount() > 1) {
107
					file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
108
					if (!file.isAccessible()) {
109
						file = null;
110
					}
111
				}
112
			}
113
			else {
114
				filePath = new Path(model.getId());
115
			}
116
117
			// this will be the wrong region if it's Text (instead of Element)
118
			// we don't know how to validate Text
119
			IndexedRegion ir = getCoveringNode(dirtyRegion); // model.getIndexedRegion(dirtyRegion.getOffset());
120
			if (ir instanceof Text) {
121
				while (ir != null && ir instanceof Text) {
122
					// it's assumed that this gets the IndexedRegion to
123
					// the right of the end offset
124
					ir = model.getIndexedRegion(ir.getEndOffset());
125
				}
126
			}
127
128
			if (ir instanceof INodeNotifier) {
129
				INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
130
				ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir);
131
				if (adapter == null)
132
					return; // error
133
134
				if (reporter != null) {
135
					HTMLValidationReporter rep = null;
136
					rep = getReporter(reporter, file, (IDOMModel) model);
137
					rep.clear();
138
					adapter.setReporter(rep);
139
140
					Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, filePath.toString().substring(1));
141
					reporter.displaySubtask(this, mess);
142
				}
143
				adapter.validate(ir);
144
			}
145
		}
146
		finally {
147
			releaseModel(model);
148
		}
149
	}
150
151
	private IndexedRegion getCoveringNode(IRegion dirtyRegion) {
152
153
		IndexedRegion largestRegion = null;
154
		if (fDocument instanceof IStructuredDocument) {
155
			IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument).getStructuredDocumentRegions(
156
					dirtyRegion.getOffset(), dirtyRegion.getLength());
157
			largestRegion = getLargest(regions);
158
		}
159
		return largestRegion;
160
	}
161
162
	/**
163
	 */
164
	private boolean hasHTMLFeature(IDOMDocument document) {
165
		DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
166
		if (adapter == null)
167
			return false;
168
		return adapter.hasFeature(HTMLDocumentTypeConstants.HTML);
169
	}
170
171
	protected IndexedRegion getLargest(IStructuredDocumentRegion[] sdRegions) {
172
173
		if (sdRegions == null || sdRegions.length == 0)
174
			return null;
175
176
		IndexedRegion currentLargest = getCorrespondingNode(sdRegions[0]);
177
		for (int i = 0; i < sdRegions.length; i++) {
178
			if (!sdRegions[i].isDeleted()) {
179
				IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);
180
181
				if (currentLargest instanceof Text)
182
					currentLargest = corresponding;
183
184
				if (corresponding != null) {
185
					if (!(corresponding instanceof Text)) {
186
						if (corresponding.getStartOffset() <= currentLargest.getStartOffset()
187
								&& corresponding.getEndOffset() >= currentLargest.getEndOffset())
188
							currentLargest = corresponding;
189
					}
190
				}
191
192
			}
193
		}
194
		return currentLargest;
195
	}
196
197
	protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
198
		IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
199
		IndexedRegion indexedRegion = null;
200
		try {
201
			if (sModel != null)
202
				indexedRegion = sModel.getIndexedRegion(sdRegion.getStart());
203
		}
204
		finally {
205
			if (sModel != null)
206
				sModel.releaseFromRead();
207
		}
208
		return indexedRegion;
209
	}
210
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidationReporter.java (-150 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2008 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IPath;
16
import org.eclipse.wst.html.core.internal.validate.MessageFactory;
17
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
18
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
19
import org.eclipse.wst.sse.core.internal.validate.ErrorInfo;
20
import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
21
import org.eclipse.wst.sse.core.internal.validate.ValidationReporter;
22
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
23
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
24
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
25
26
public class HTMLValidationReporter implements ValidationReporter {
27
28
	private IValidator owner = null;
29
	private IReporter reporter = null;
30
	private IFile file = null;
31
	private IStructuredModel model = null;
32
	private HTMLValidationResult result = null;
33
	private MessageFactory fFactory = null;
34
	
35
	/**
36
	 */
37
	public HTMLValidationReporter(IValidator owner, IReporter reporter, IFile file, IStructuredModel model) {
38
		super();
39
		this.owner = owner;
40
		this.reporter = reporter;
41
		this.file = file;
42
		this.model = model;
43
		fFactory = new MessageFactory(file != null ? file.getProject() : null);
44
	}
45
46
	/**
47
	 */
48
	public void clear() {
49
		if (this.file == null)
50
			return;
51
52
		this.result = null;
53
54
		if (this.reporter != null) {
55
			this.reporter.removeAllMessages(this.owner, this.file);
56
		}
57
		else {
58
			// remove by myself?
59
			String id = HTMLValidator.class.getName();
60
			try {
61
				// TaskListHelper API changed
62
				// TaskListHelper.getTaskList().removeAllTasks(id, this.file,
63
				// null);
64
				TaskListHelper.getTaskList().removeAllTasks(this.file, id, null);
65
			}
66
			catch (CoreException ex) {
67
			}
68
		}
69
	}
70
71
72
	/**
73
	 */
74
	public HTMLValidationResult getResult() {
75
		if (this.result == null)
76
			this.result = new HTMLValidationResult();
77
		return this.result;
78
	}
79
80
	/**
81
	 */
82
	public void report(ValidationMessage message) {
83
		if (message == null || message.getSeverity() == ValidationMessage.IGNORE)
84
			return;
85
		IMessage mes = translateMessage(message);
86
87
		if (this.reporter != null) {
88
			this.reporter.addMessage(this.owner, mes);
89
		}
90
		else {
91
			if (this.file == null)
92
				return;
93
94
			// add by myself?
95
			String id = HTMLValidator.class.getName();
96
			String location = Integer.toString(mes.getLineNumber());
97
			String name = ""; //$NON-NLS-1$
98
			IPath filePath = this.file.getFullPath();
99
			if (filePath != null) {
100
				name = filePath.toString();
101
			}
102
			try {
103
				TaskListHelper.getTaskList().addTask(id, this.file, location, mes.getId(), mes.getText(), mes.getSeverity(), name, mes.getGroupName(), mes.getOffset(), mes.getLength());
104
			}
105
			catch (CoreException ex) {
106
			}
107
		}
108
	}
109
110
	/**
111
	 * Translate ValidationMessage to IMessage and generate result log
112
	 */
113
	private IMessage translateMessage(ValidationMessage message) {
114
		int severity = IMessage.LOW_SEVERITY;
115
		HTMLValidationResult result = getResult();
116
		switch (message.getSeverity()) {
117
			case ValidationMessage.ERROR :
118
				severity = IMessage.HIGH_SEVERITY;
119
				result.addError();
120
				break;
121
			case ValidationMessage.WARNING :
122
				severity = IMessage.NORMAL_SEVERITY;
123
				result.addWarning();
124
				break;
125
			case ValidationMessage.INFORMATION :
126
				result.addInformation();
127
				break;
128
			default :
129
//				result.addInformation();
130
				break;
131
		}
132
133
		IMessage mes = new LocalizedMessage(severity, message.getMessage(), this.file);
134
		mes.setOffset(message.getOffset());
135
		mes.setLength(message.getLength());
136
		if (this.model != null) {
137
			IStructuredDocument flatModel = this.model.getStructuredDocument();
138
			if (flatModel != null) {
139
				int line = flatModel.getLineOfOffset(message.getOffset());
140
				mes.setLineNo(line + 1);
141
			}
142
		}
143
144
		return mes;
145
	}
146
147
	public void report(ErrorInfo info) {
148
		report(fFactory.createMessage(info));
149
	}
150
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidationResult.java (-64 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
public class HTMLValidationResult {
14
	private int errors = 0;
15
	private int warnings = 0;
16
	private int informations = 0;
17
18
	/**
19
	 */
20
	public HTMLValidationResult() {
21
	}
22
23
	/**
24
	 */
25
	public void addError() {
26
		this.errors++;
27
	}
28
29
	/**
30
	 */
31
	public void addInformation() {
32
		this.informations++;
33
	}
34
35
	/**
36
	 */
37
	public void addWarning() {
38
		this.warnings++;
39
	}
40
41
	/**
42
	 */
43
	public int getErrors() {
44
		return this.errors;
45
	}
46
47
	/**
48
	 */
49
	public int getInformations() {
50
		return this.informations;
51
	}
52
53
	/**
54
	 */
55
	public int getWarnings() {
56
		return this.warnings;
57
	}
58
59
	/**
60
	 */
61
	public boolean isValid() {
62
		return (this.errors == 0 && this.warnings == 0 && this.informations == 0);
63
	}
64
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java (-560 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2007 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import java.io.IOException;
14
import java.io.UnsupportedEncodingException;
15
import java.util.ArrayList;
16
import java.util.List;
17
18
import org.eclipse.core.filebuffers.ITextFileBuffer;
19
import org.eclipse.core.resources.IContainer;
20
import org.eclipse.core.resources.IFile;
21
import org.eclipse.core.resources.IProject;
22
import org.eclipse.core.resources.IResource;
23
import org.eclipse.core.resources.ResourcesPlugin;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.core.runtime.IConfigurationElement;
26
import org.eclipse.core.runtime.IExecutableExtension;
27
import org.eclipse.core.runtime.IPath;
28
import org.eclipse.core.runtime.IProgressMonitor;
29
import org.eclipse.core.runtime.IStatus;
30
import org.eclipse.core.runtime.NullProgressMonitor;
31
import org.eclipse.core.runtime.OperationCanceledException;
32
import org.eclipse.core.runtime.Path;
33
import org.eclipse.core.runtime.Platform;
34
import org.eclipse.core.runtime.Status;
35
import org.eclipse.core.runtime.content.IContentDescription;
36
import org.eclipse.core.runtime.content.IContentType;
37
import org.eclipse.core.runtime.content.IContentTypeManager;
38
import org.eclipse.core.runtime.jobs.ISchedulingRule;
39
import org.eclipse.jface.text.IDocument;
40
import org.eclipse.jface.text.IRegion;
41
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeConstants;
42
import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
43
import org.eclipse.wst.html.ui.internal.Logger;
44
import org.eclipse.wst.sse.core.StructuredModelManager;
45
import org.eclipse.wst.sse.core.internal.FileBufferModelManager;
46
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
47
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
48
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
49
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
50
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
51
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
52
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
53
import org.eclipse.wst.sse.core.internal.util.URIResolver;
54
import org.eclipse.wst.sse.core.internal.validate.ValidationAdapter;
55
import org.eclipse.wst.sse.core.utils.StringUtils;
56
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
57
import org.eclipse.wst.validation.AbstractValidator;
58
import org.eclipse.wst.validation.ValidationResult;
59
import org.eclipse.wst.validation.ValidationState;
60
import org.eclipse.wst.validation.internal.core.Message;
61
import org.eclipse.wst.validation.internal.core.ValidationException;
62
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
63
import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
64
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
65
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
66
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
67
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
68
import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
69
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
70
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
71
import org.w3c.dom.Text;
72
73
public class HTMLValidator extends AbstractValidator implements IValidatorJob, ISourceValidator, IExecutableExtension {
74
	private static final String ORG_ECLIPSE_WST_HTML_CORE_HTMLSOURCE = "org.eclipse.wst.html.core.htmlsource"; //$NON-NLS-1$
75
76
	static boolean shouldValidate(IFile file) {
77
		IResource resource = file;
78
		do {
79
			if (resource.isDerived() || resource.isTeamPrivateMember() || !resource.isAccessible() || (resource.getName().charAt(0) == '.' && resource.getType() == IResource.FOLDER)) {
80
				return false;
81
			}
82
			resource = resource.getParent();
83
		}
84
		while ((resource.getType() & IResource.PROJECT) == 0);
85
		return true;
86
	}
87
88
	private IDocument fDocument;
89
	private IContentTypeManager fContentTypeManager;
90
	private IContentType[] fOtherSupportedContentTypes = null;
91
	private String[] fAdditionalContentTypesIDs = null;
92
	private IContentType fHTMLContentType;
93
94
	public HTMLValidator() {
95
		super();
96
		fContentTypeManager = Platform.getContentTypeManager();
97
		fHTMLContentType = fContentTypeManager.getContentType(ORG_ECLIPSE_WST_HTML_CORE_HTMLSOURCE);
98
	}
99
100
	/**
101
	 */
102
	public void cleanup(IReporter reporter) {
103
		// nothing to do
104
	}
105
106
	/**
107
	 * Gets list of content types this validator is interested in
108
	 * 
109
	 * @return All HTML-related content types
110
	 */
111
	private IContentType[] getOtherSupportedContentTypes() {
112
		if (fOtherSupportedContentTypes == null) {
113
			List contentTypes = new ArrayList(3);
114
			if (fAdditionalContentTypesIDs != null) {
115
				for (int i = 0; i < fAdditionalContentTypesIDs.length; i++) {
116
					IContentType type = Platform.getContentTypeManager().getContentType(fAdditionalContentTypesIDs[i]);
117
					if (type != null) {
118
						contentTypes.add(type);
119
					}
120
				}
121
			}
122
			fOtherSupportedContentTypes = (IContentType[]) contentTypes.toArray(new IContentType[contentTypes.size()]);
123
		}
124
		return fOtherSupportedContentTypes;
125
	}
126
127
128
	/**
129
	 */
130
	protected IDOMModel getModel(IProject project, IFile file) {
131
		if (project == null || file == null)
132
			return null;
133
		if (!file.exists())
134
			return null;
135
		if (!canHandle(file))
136
			return null;
137
138
		IStructuredModel model = null;
139
		IModelManager manager = StructuredModelManager.getModelManager();
140
		try {
141
			file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
142
		}
143
		catch (CoreException e) {
144
			Logger.logException(e);
145
		}
146
		try {
147
			try {
148
				model = manager.getModelForRead(file);
149
			}
150
			catch (UnsupportedEncodingException ex) {
151
				// retry ignoring META charset for invalid META charset
152
				// specification
153
				// recreate input stream, because it is already partially read
154
				model = manager.getModelForRead(file, new String(), null);
155
			}
156
		}
157
		catch (UnsupportedEncodingException ex) {
158
		}
159
		catch (IOException ex) {
160
		}
161
		catch (CoreException e) {
162
			Logger.logException(e);
163
		}
164
165
		if (model == null)
166
			return null;
167
		if (!(model instanceof IDOMModel)) {
168
			releaseModel(model);
169
			return null;
170
		}
171
		return (IDOMModel) model;
172
	}
173
174
	/**
175
	 */
176
	protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
177
		return new HTMLValidationReporter(this, reporter, file, model);
178
	}
179
180
	/**
181
	 * Check file extension to validate
182
	 */
183
	private boolean canHandle(IFile file) {
184
		boolean result = false;
185
		if (file != null) {
186
			try {
187
				IContentDescription contentDescription = file.getContentDescription();
188
				if (contentDescription != null) {
189
					IContentType fileContentType = contentDescription.getContentType();
190
					if (fileContentType.isKindOf(fHTMLContentType)) {
191
						result = true;
192
					}
193
					else {
194
						IContentType[] otherTypes = getOtherSupportedContentTypes();
195
						for (int i = 0; i < otherTypes.length; i++) {
196
							result = result || fileContentType.isKindOf(otherTypes[i]);
197
						}
198
					}
199
				}
200
				else if (fHTMLContentType != null) {
201
					result = fHTMLContentType.isAssociatedWith(file.getName());
202
				}
203
			}
204
			catch (CoreException e) {
205
				// should be rare, but will ignore to avoid logging "encoding
206
				// exceptions" and the like here.
207
				// Logger.logException(e);
208
			}
209
		}
210
		return result;
211
	}
212
213
	/**
214
	 */
215
	private boolean hasHTMLFeature(IDOMDocument document) {
216
		DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
217
		if (adapter == null)
218
			return false;
219
		return adapter.hasFeature(HTMLDocumentTypeConstants.HTML);
220
	}
221
222
	/**
223
	 */
224
	protected void releaseModel(IStructuredModel model) {
225
		if (model != null)
226
			model.releaseFromRead();
227
	}
228
229
	/**
230
	 */
231
	public void validate(IValidationContext helper, IReporter reporter) {
232
		if (helper == null)
233
			return;
234
		if ((reporter != null) && (reporter.isCancelled() == true)) {
235
			throw new OperationCanceledException();
236
		}
237
		String[] deltaArray = helper.getURIs();
238
		if (deltaArray != null && deltaArray.length > 0) {
239
			validateDelta(helper, reporter);
240
		}
241
		else {
242
			validateFull(helper, reporter);
243
		}
244
	}
245
246
	/**
247
	 * This validate call is for the ISourceValidator partial document
248
	 * validation approach
249
	 * 
250
	 * @param dirtyRegion
251
	 * @param helper
252
	 * @param reporter
253
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
254
	 */
255
	public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
256
257
		if (helper == null || fDocument == null)
258
			return;
259
260
		if ((reporter != null) && (reporter.isCancelled() == true)) {
261
			throw new OperationCanceledException();
262
		}
263
264
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
265
		if (model == null)
266
			return; // error
267
268
		try {
269
270
			IDOMDocument document = null;
271
			if (model instanceof IDOMModel) {
272
				document = ((IDOMModel) model).getDocument();
273
			}
274
275
			if (document == null || !hasHTMLFeature(document)) {
276
				// handled in finally clause
277
				// model.releaseFromRead();
278
				return; //ignore
279
			}
280
			
281
			IPath filePath = null;
282
			IFile file = null;
283
284
			ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument);
285
			if (fb != null) {
286
				filePath = fb.getLocation();
287
288
				if (filePath.segmentCount() > 1) {
289
					file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
290
					if (!file.isAccessible()) {
291
						file = null;
292
					}
293
				}
294
			}
295
			else {
296
				filePath = new Path(model.getId());
297
			}
298
299
			// this will be the wrong region if it's Text (instead of Element)
300
			// we don't know how to validate Text
301
			IndexedRegion ir = getCoveringNode(dirtyRegion); //  model.getIndexedRegion(dirtyRegion.getOffset());
302
			if (ir instanceof Text) {
303
				while (ir != null && ir instanceof Text) {
304
					// it's assumed that this gets the IndexedRegion to
305
					// the right of the end offset
306
					ir = model.getIndexedRegion(ir.getEndOffset());
307
				}
308
			}
309
			
310
			if (ir instanceof INodeNotifier) {
311
312
				INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
313
				ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir);
314
				if (adapter == null)
315
					return; // error
316
317
				if (reporter != null) {
318
					HTMLValidationReporter rep = null;
319
					rep = getReporter(reporter, file, (IDOMModel) model);
320
					rep.clear();
321
					adapter.setReporter(rep);
322
323
					Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, filePath.toString().substring(1));
324
					reporter.displaySubtask(this, mess);
325
				}
326
				adapter.validate(ir);
327
			}
328
		}
329
		finally {
330
			if (model != null)
331
				model.releaseFromRead();
332
		}
333
	}
334
335
	private IndexedRegion getCoveringNode(IRegion dirtyRegion) {
336
		
337
		IndexedRegion largestRegion = null;
338
		if(fDocument instanceof IStructuredDocument) {
339
			IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument).getStructuredDocumentRegions(dirtyRegion.getOffset(), dirtyRegion.getLength());
340
			largestRegion = getLargest(regions);
341
		}
342
		return largestRegion;
343
	}
344
	protected IndexedRegion getLargest(IStructuredDocumentRegion[] sdRegions) {
345
		
346
		if(sdRegions == null || sdRegions.length == 0)
347
			return null;
348
		 
349
		IndexedRegion currentLargest = getCorrespondingNode(sdRegions[0]);
350
		for (int i = 0; i < sdRegions.length; i++) {
351
		    if(!sdRegions[i].isDeleted()) {
352
    			IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);
353
    			
354
    			if(currentLargest instanceof Text)
355
    				currentLargest = corresponding;
356
    			
357
                if(corresponding != null) {
358
                	if(!(corresponding instanceof Text)) {
359
	        			if (corresponding.getStartOffset() <= currentLargest.getStartOffset()  
360
	        						&&  corresponding.getEndOffset() >= currentLargest.getEndOffset() )
361
	        				currentLargest = corresponding;
362
                	}
363
                }
364
                
365
            }
366
		}
367
		return currentLargest;
368
	}
369
	protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
370
		IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
371
        IndexedRegion indexedRegion = null;
372
        try {
373
            if (sModel != null) 
374
                indexedRegion = sModel.getIndexedRegion(sdRegion.getStart());    
375
        } finally {
376
            if (sModel != null)
377
                sModel.releaseFromRead();
378
        }
379
        return indexedRegion;
380
    }
381
382
	/**
383
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
384
	 */
385
	public void connect(IDocument document) {
386
		fDocument = document;
387
	}
388
389
	/**
390
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
391
	 */
392
	public void disconnect(IDocument document) {
393
		fDocument = null;
394
	}
395
396
	/**
397
	 */
398
	protected HTMLValidationResult validate(IDOMModel model, IFile file) {
399
		IProject prj = null;
400
		if (file != null) {
401
			prj = file.getProject();
402
		}
403
		if ((prj == null) && (model != null)) {
404
			URIResolver res = model.getResolver();
405
			if (res != null) {
406
				prj = res.getProject();
407
			}
408
		}
409
		final WorkbenchReporter reporter = new WorkbenchReporter(prj, new NullProgressMonitor());
410
		return validate(reporter, file, model);
411
	}
412
413
	/**
414
	 */
415
	private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) {
416
		if (file == null || model == null)
417
			return null; // error
418
		IDOMDocument document = model.getDocument();
419
		if (document == null)
420
			return null; // error
421
		if (!hasHTMLFeature(document))
422
			return null; // ignore
423
424
		INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
425
		ValidationAdapter adapter = (ValidationAdapter) factory.adapt(document);
426
		if (adapter == null)
427
			return null; // error
428
429
		HTMLValidationReporter rep = getReporter(reporter, file, model);
430
		rep.clear();
431
		adapter.setReporter(rep);
432
		adapter.validate(document);
433
		return rep.getResult();
434
	}
435
436
	/**
437
	 */
438
	private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) {
439
		try {
440
			IResource[] resourceArray = container.members(false);
441
			for (int i = 0; i < resourceArray.length; i++) {
442
				IResource resource = resourceArray[i];
443
				if (resource == null || reporter.isCancelled())
444
					continue;
445
				if (resource instanceof IFile) {
446
					Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, resource.getFullPath().toString().substring(1));
447
					reporter.displaySubtask(this, message);
448
					validateFile(helper, reporter, (IFile) resource);
449
				}
450
				else if (resource instanceof IContainer) {
451
					validateContainer(helper, reporter, (IContainer) resource);
452
				}
453
			}
454
		}
455
		catch (CoreException ex) {
456
		}
457
	}
458
459
	/**
460
	 */
461
	private void validateDelta(IValidationContext helper, IReporter reporter) {
462
		String[] deltaArray = helper.getURIs();
463
		for (int i = 0; i < deltaArray.length; i++) {
464
			String delta = deltaArray[i];
465
			if (delta == null)
466
				continue;
467
468
			if (reporter != null) {
469
				Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, delta.substring(1));
470
				reporter.displaySubtask(this, message);
471
			}
472
473
			IResource resource = getResource(delta);
474
			if (resource == null || !(resource instanceof IFile))
475
				continue;
476
			validateFile(helper, reporter, (IFile) resource);
477
		}
478
	}
479
480
	/**
481
	 */
482
	private void validateFile(IValidationContext helper, IReporter reporter, IFile file) {
483
		if ((reporter != null) && (reporter.isCancelled() == true)) {
484
			throw new OperationCanceledException();
485
		}
486
		if (!shouldValidate(file)) {
487
			return;
488
		}
489
		IDOMModel model = getModel(file.getProject(), file);
490
		if (model == null)
491
			return;
492
493
		try {
494
			validate(reporter, file, model);
495
		}
496
		finally {
497
			releaseModel(model);
498
		}
499
	}
500
501
	/**
502
	 */
503
	private void validateFull(IValidationContext helper, IReporter reporter) {
504
		IProject project = null;
505
		String[] fileDelta = helper.getURIs();
506
		if (helper instanceof IWorkbenchContext) {
507
			IWorkbenchContext wbHelper = (IWorkbenchContext) helper;
508
			project = wbHelper.getProject();
509
		}
510
		else if(fileDelta.length > 0){
511
			// won't work for project validation (b/c nothing in file delta)
512
			project = getResource(fileDelta[0]).getProject();
513
		}
514
		if (project == null)
515
			return;
516
		validateContainer(helper, reporter, project);
517
	}
518
519
	/*
520
	 * added to get rid or dependency on IWorkbenchHelper
521
	 * 
522
	 */
523
	public IResource getResource(String delta) {
524
		return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta));
525
	}
526
527
	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
528
		return null;
529
	}
530
531
	public IStatus validateInJob(IValidationContext helper, IReporter reporter) throws ValidationException {
532
		// Exception catching was removed, see
533
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=123600
534
		IStatus status = Status.OK_STATUS;
535
		validate(helper, reporter);
536
		return status;
537
	}
538
	
539
	/**
540
	 * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
541
	 *      java.lang.String, java.lang.Object)
542
	 */
543
	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
544
		fAdditionalContentTypesIDs = new String[0];
545
		if (data != null) {
546
			if (data instanceof String && data.toString().length() > 0) {
547
				fAdditionalContentTypesIDs = StringUtils.unpack(data.toString());
548
			}
549
		}
550
	}
551
552
	public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
553
		if (resource.getType() != IResource.FILE)
554
			return null;
555
		ValidationResult result = new ValidationResult();
556
		IReporter reporter = result.getReporter(monitor);
557
		validateFile(null, reporter, (IFile) resource);
558
		return result;
559
	}
560
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/LocalizedMessage.java (-65 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import java.util.Locale;
14
15
import org.eclipse.core.resources.IResource;
16
import org.eclipse.wst.validation.internal.core.Message;
17
18
/**
19
 * copied from org.eclipse.wst.validation.internal.operations.LocalizedMessage
20
 * 
21
 * This class is provided for validators which run only in Eclipse and whose messages, because they
22
 * come from another tool, are already localized. LocalizedMessage cannot be used by any validator
23
 * which needs to run in both WebSphere and Eclipse.
24
 */
25
public class LocalizedMessage extends Message {
26
	private String _message = null;
27
28
	public LocalizedMessage(int severity, String messageText) {
29
		this(severity, messageText, null);
30
	}
31
32
	public LocalizedMessage(int severity, String messageText, IResource targetObject) {
33
		this(severity, messageText, (Object) targetObject);
34
	}
35
36
	public LocalizedMessage(int severity, String messageText, Object targetObject) {
37
		super(null, severity, null);
38
		setLocalizedMessage(messageText);
39
		setTargetObject(targetObject);
40
	}
41
42
	public void setLocalizedMessage(String message) {
43
		_message = message;
44
	}
45
46
	public String getLocalizedMessage() {
47
		return _message;
48
	}
49
50
	public String getText() {
51
		return getLocalizedMessage();
52
	}
53
54
	public String getText(ClassLoader cl) {
55
		return getLocalizedMessage();
56
	}
57
58
	public String getText(Locale l) {
59
		return getLocalizedMessage();
60
	}
61
62
	public String getText(Locale l, ClassLoader cl) {
63
		return getLocalizedMessage();
64
	}
65
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/TaskListHelper.java (-44 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IResource;
14
import org.eclipse.core.runtime.CoreException;
15
16
/**
17
 * 
18
 * Class to help this Problem's list.
19
 * 
20
 */
21
class TaskListHelper {
22
	private static TaskListHelper _taskListHelper = null;
23
24
	public static TaskListHelper getTaskList() {
25
		if (_taskListHelper == null) {
26
			_taskListHelper = new TaskListHelper();
27
		}
28
		return _taskListHelper;
29
	}
30
31
	/**
32
	 * This method adds a message to a resource in the task list.
33
	 */
34
	public void addTask(String pluginId, IResource resource, String location, String messageId, String message, int markerType, String targetObjectName, String groupName, int offset, int length) throws CoreException {
35
		TaskListUtility.addTask(pluginId, resource, location, messageId, message, markerType, targetObjectName, groupName, offset, length);
36
	}
37
38
	/**
39
	 * This method removes all messages from a resource in the task list.
40
	 */
41
	public void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
42
		TaskListUtility.removeAllTasks(resource, owner, objectName);
43
	}
44
}
(-)src-html-validation/org/eclipse/wst/html/internal/validation/TaskListUtility.java (-436 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2007 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
 *******************************************************************************/
11
package org.eclipse.wst.html.internal.validation;
12
13
import org.eclipse.core.resources.IMarker;
14
import org.eclipse.core.resources.IProject;
15
import org.eclipse.core.resources.IResource;
16
import org.eclipse.core.resources.IWorkspaceRoot;
17
import org.eclipse.core.resources.ResourcesPlugin;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.wst.html.ui.internal.HTMLUIPlugin;
20
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
21
22
/**
23
 * This class must be called only by the validation framework.
24
 * 
25
 * This singleton interacts with the eclipse workbench's Task list.
26
 * TaskListUtility adds and removes tasks from the list.
27
 * 
28
 * This class must not be called outside of an IWorkspaceRunnable or
29
 * IRunnableWithProgress. Many resource deltas can be generated by the methods
30
 * in this class.
31
 * 
32
 * This came from TaskListUtility
33
 */
34
public class TaskListUtility {
35
	// private static final String PLUGIN_ID = ValidationPlugin.PLUGIN_ID;
36
	private static final String PLUGIN_ID = HTMLUIPlugin.ID;
37
	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
38
	private static final String VALIDATION_MARKER_OWNER = "owner"; //$NON-NLS-1$ // The IValidator who owns the IMarker on the task list
39
	private static final String VALIDATION_MARKER_SEVERITY = "validationSeverity"; //$NON-NLS-1$ // one of the IMessage values
40
	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.
41
	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.
42
	private static final String VALIDATION_MARKER_MESSAGEID = "messageId"; //$NON-NLS-1$ // Persist the message id of the message, not just the translated text.
43
	private static final int DEPTH_INFINITE = IResource.DEPTH_INFINITE;
44
	private static final int DEPTH_ZERO = IResource.DEPTH_ZERO;
45
	private final static IMarker[] NO_MARKERS = new IMarker[0];
46
47
	/**
48
	 * This method adds a message to a resource in the task list.
49
	 */
50
	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 {
51
		if ((message == null) || (resource == null)) {
52
			return null;
53
		}
54
55
		int severity = getSeverity(markerType);
56
57
		// Allow duplicate entries in the task list.
58
		// Prior to a full validation, the validation framework will remove
59
		// all messages owned
60
		// by a validator before it is executed.
61
		// Prior to an incremental validation, the validation framework will
62
		// remove all messages,
63
		// on each of the changed resources, owned by a validator before it is
64
		// invoked.
65
		// 
66
		// It is up to the validator to make sure that it is not adding the
67
		// same message
68
		// in more than one place, and also to clear out any old messages
69
		// which are not cleared
70
		// by the validation framework.
71
		IMarker item = resource.createMarker(VALIDATION_MARKER); // add a
72
																	// validation
73
																	// marker
74
75
		// For performance reasons, replace the multiple setAttribute
76
		// calls above with a single setAttributes call.
77
		boolean offsetSet = ((offset != IMessage.OFFSET_UNSET) && (length != IMessage.OFFSET_UNSET));
78
		int size = (offsetSet) ? 10 : 8; // add CHAR_START, CHAR_END only
79
											// if the offset is set. If the
80
											// offset is set, it takes
81
											// precendence over the line
82
											// number. (eclipse's rule, not
83
											// mine.)
84
		String[] attribNames = new String[size];
85
		Object[] attribValues = new Object[size];
86
87
		// Very first thing, add the owner. That way, if the code dies
88
		// before things are persisted, hopefully this marker will be
89
		// persisted.
90
		// Hopefully, eclipse WILL persist this field, as requested.
91
		attribNames[0] = VALIDATION_MARKER_OWNER;
92
		attribValues[0] = pluginId;
93
		attribNames[1] = VALIDATION_MARKER_SEVERITY; // this validation
94
														// severity is stored,
95
														// in addition to the
96
														// marker severity, to
97
														// enable more than
98
														// one severity of
99
														// message to be
100
														// displayed. e.g.
101
														// ERROR | WARNING
102
														// (using binary OR).
103
														// The IMarker
104
														// constants are
105
														// regular decimal
106
														// constants.
107
		attribValues[1] = new Integer(markerType);
108
		attribNames[2] = VALIDATION_MARKER_TARGETOBJECT; // to distinguish
109
															// between
110
															// messages which
111
															// are registered
112
															// on an
113
															// IResource, but
114
															// against
115
															// different
116
															// target objects
117
		attribValues[2] = ((targetObjectName == null) ? "" : targetObjectName); //$NON-NLS-1$
118
		attribNames[3] = VALIDATION_MARKER_GROUP;
119
		attribValues[3] = ((groupName == null) ? "" : groupName); //$NON-NLS-1$
120
		attribNames[4] = IMarker.MESSAGE;
121
		attribValues[4] = message;
122
		attribNames[5] = VALIDATION_MARKER_MESSAGEID;
123
		attribValues[5] = messageId;
124
125
		attribNames[6] = IMarker.SEVERITY; // IMarker.SEVERITY_ERROR,
126
											// IMarker.SEVERITY_WARNING,
127
											// IMarker.SEVERITY_INFO
128
		attribValues[6] = new Integer(severity);
129
		try {
130
			// If the location is a line number, store it as a line number
131
			Integer lineNumber = Integer.valueOf(location);
132
			attribNames[7] = IMarker.LINE_NUMBER;
133
			attribValues[7] = lineNumber;
134
		}
135
		catch (NumberFormatException exc) {
136
			// Otherwise, store it as a text location
137
			attribNames[7] = IMarker.LOCATION;
138
			attribValues[7] = location;
139
		}
140
141
		if (offsetSet) {
142
			attribNames[8] = IMarker.CHAR_START;
143
			attribValues[8] = new Integer(offset);
144
			attribNames[9] = IMarker.CHAR_END;
145
			attribValues[9] = new Integer(offset + length);
146
		}
147
148
		item.setAttributes(attribNames, attribValues);
149
150
		return item;
151
	}
152
153
	/**
154
	 * Given one of the SeverityEnum severities, return the IMarker severity
155
	 * int that is its equivalent.
156
	 */
157
	private static int getSeverity(int severityEnumValue) {
158
		switch (severityEnumValue) {
159
			case (IMessage.HIGH_SEVERITY) : {
160
				return IMarker.SEVERITY_ERROR;
161
			}
162
163
			case (IMessage.LOW_SEVERITY) : {
164
				return IMarker.SEVERITY_INFO;
165
			}
166
167
			case (IMessage.NORMAL_SEVERITY) : {
168
				return IMarker.SEVERITY_WARNING;
169
			}
170
171
			case (IMessage.ALL_MESSAGES) :
172
			case (IMessage.ERROR_AND_WARNING) :
173
			default : {
174
				// assume it's a warning.
175
				return IMarker.SEVERITY_WARNING;
176
			}
177
		}
178
	}
179
180
	private static int getDepth(IResource resource) {
181
		if (resource instanceof IProject) {
182
			return DEPTH_INFINITE; // DEPTH_INFINITE means get this project's
183
									// markers, and the markers belonging to
184
									// the project's children.
185
		}
186
		else if (resource instanceof IWorkspaceRoot) {
187
			// Needed for the ValidationMigrator when it checks for orphan
188
			// tasks.
189
			return DEPTH_INFINITE; // DEPTH_INFINITE means get all of the
190
									// markers in the workspace
191
		}
192
193
		return DEPTH_ZERO; // DEPTH_ZERO means just this resource, not its
194
							// children
195
	}
196
197
	private static IMarker[] getValidationTasks(IResource resource, int severity, int depth) {
198
		IMarker[] tempMarkers = null;
199
		int validCount = 0;
200
		try {
201
			IMarker[] allMarkers = null;
202
			try {
203
				allMarkers = resource.findMarkers(VALIDATION_MARKER, false, depth); // false
204
																					// means
205
																					// only
206
																					// consider
207
																					// PROBLEM_MARKER,
208
																					// not
209
																					// variants
210
																					// of
211
																					// PROBLEM_MARKER.
212
																					// Since
213
																					// addTask
214
																					// only
215
																					// adds
216
																					// PROBLEM_MARKER,
217
																					// we
218
																					// don't
219
																					// need
220
																					// to
221
																					// consider
222
																					// its
223
																					// subtypes.
224
			}
225
			catch (CoreException exc) {
226
				// Logger logger =
227
				// ValidationPlugin.getPlugin().getMsgLogger();
228
				// if (logger.isLoggingLevel(Level.SEVERE)) {
229
				// LogEntry entry = ValidationPlugin.getLogEntry();
230
				// entry.setSourceID("TaskListUtility.getValidationTasks(IResource,
231
				// int)"); //$NON-NLS-1$
232
				// entry.setTargetException(exc);
233
				// logger.write(Level.SEVERE, entry);
234
				// }
235
				return NO_MARKERS;
236
			}
237
238
			// Now filter in the markers, based on severity type.
239
			if (allMarkers.length != 0) {
240
				tempMarkers = new IMarker[allMarkers.length];
241
				for (int i = 0; i < allMarkers.length; i++) {
242
					IMarker marker = allMarkers[i];
243
					Integer filterSeverity = (Integer) marker.getAttribute(VALIDATION_MARKER_SEVERITY);
244
					if (filterSeverity == null) {
245
						// odd...marker wasn't created correctly. How could
246
						// this happen?
247
						// Default to the current severity and add it to the
248
						// list.
249
						try {
250
							marker.setAttribute(IMarker.SEVERITY, getSeverity(severity));
251
						}
252
						catch (CoreException exc) {
253
							// Logger logger =
254
							// ValidationPlugin.getPlugin().getMsgLogger();
255
							// if (logger.isLoggingLevel(Level.SEVERE)) {
256
							// LogEntry entry =
257
							// ValidationPlugin.getLogEntry();
258
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
259
							// IResource, int)"); //$NON-NLS-1$
260
							// entry.setTargetException(exc);
261
							// logger.write(Level.SEVERE, entry);
262
							// }
263
							continue;
264
						}
265
						catch (Exception exc) {
266
							// Logger logger =
267
							// ValidationPlugin.getPlugin().getMsgLogger();
268
							// if (logger.isLoggingLevel(Level.SEVERE)) {
269
							// LogEntry entry =
270
							// ValidationPlugin.getLogEntry();
271
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
272
							// IResource, int)"); //$NON-NLS-1$
273
							// entry.setTargetException(exc);
274
							// logger.write(Level.SEVERE, entry);
275
							// }
276
							continue;
277
						}
278
					}
279
					else if ((severity & filterSeverity.intValue()) == 0) {
280
						continue;
281
					}
282
					tempMarkers[validCount++] = marker;
283
				}
284
			}
285
		}
286
		catch (CoreException exc) {
287
			// Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
288
			// if (logger.isLoggingLevel(Level.SEVERE)) {
289
			// LogEntry entry = ValidationPlugin.getLogEntry();
290
			// entry.setSourceID("TaskListUtility.getValidationTasks(int,
291
			// IResource, int)"); //$NON-NLS-1$
292
			// entry.setTargetException(exc);
293
			// logger.write(Level.SEVERE, entry);
294
			// }
295
		}
296
297
		if (validCount == 0) {
298
			return NO_MARKERS;
299
		}
300
301
		IMarker[] validMarkers = new IMarker[validCount];
302
		System.arraycopy(tempMarkers, 0, validMarkers, 0, validCount);
303
		return validMarkers;
304
	}
305
306
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwners, int depth) {
307
		IMarker[] markers = getValidationTasks(resource, IMessage.ALL_MESSAGES, depth);
308
		if (markers.length == 0) {
309
			return NO_MARKERS;
310
		}
311
312
		IMarker[] temp = new IMarker[markers.length];
313
		int validCount = 0;
314
		for (int i = 0; i < markers.length; i++) {
315
			IMarker marker = markers[i];
316
317
			try {
318
				Object owner = marker.getAttribute(VALIDATION_MARKER_OWNER);
319
				if ((owner == null) || !(owner instanceof String)) {
320
					// The ValidationMigrator will remove any "unowned"
321
					// validation markers.
322
					continue;
323
				}
324
325
				for (int j = 0; j < messageOwners.length; j++) {
326
					String messageOwner = messageOwners[j];
327
					if (((String) owner).equals(messageOwner)) {
328
						temp[validCount++] = marker;
329
						break;
330
					}
331
				}
332
			}
333
			catch (CoreException exc) {
334
				// Logger logger =
335
				// ValidationPlugin.getPlugin().getMsgLogger();
336
				// if (logger.isLoggingLevel(Level.SEVERE)) {
337
				// LogEntry entry = ValidationPlugin.getLogEntry();
338
				// entry.setSourceID("TaskListUtility.getValidationTasks(project,
339
				// String[])"); //$NON-NLS-1$
340
				// entry.setTargetException(exc);
341
				// logger.write(Level.SEVERE, entry);
342
				// }
343
				return NO_MARKERS;
344
			}
345
		}
346
347
		IMarker[] result = new IMarker[validCount];
348
		System.arraycopy(temp, 0, result, 0, validCount);
349
		return result;
350
	}
351
352
	/**
353
	 * This method retrieves all validation tasks from the resource. If depth
354
	 * is INFINITE, child tasks are returned as well. Only the tasks which are
355
	 * owned by the specified messageOwner, and apply to the named IMessage's
356
	 * target object (objectName) will be returned.
357
	 */
358
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwner, String objectName, String groupName, int depth) throws CoreException {
359
		if ((messageOwner == null) || (resource == null)) {
360
			return NO_MARKERS;
361
		}
362
363
		int validCount = 0;
364
		IMarker[] validList = null;
365
		IMarker[] markers = getValidationTasks(resource, messageOwner, depth);
366
		if (markers != null) {
367
			validList = new IMarker[markers.length];
368
			for (int i = 0; i < markers.length; i++) {
369
				IMarker marker = markers[i];
370
371
				// If more than one target object resolves to the same
372
				// resource, removing one target's
373
				// messages should not remove the other target object's
374
				// messages.
375
				if (objectName != null) {
376
					Object targetObject = marker.getAttribute(VALIDATION_MARKER_TARGETOBJECT);
377
					if ((targetObject == null) || !(targetObject instanceof String) || !(((String) targetObject).equals(objectName))) {
378
						continue;
379
					}
380
				}
381
382
				if (groupName != null) {
383
					Object group = marker.getAttribute(VALIDATION_MARKER_GROUP);
384
					if ((group == null) || !(group instanceof String) || !(((String) group).equals(groupName))) {
385
						continue;
386
					}
387
				}
388
389
				validList[validCount++] = marker;
390
			}
391
		}
392
393
		if (validCount == 0) {
394
			return NO_MARKERS;
395
		}
396
397
		IMarker[] result = new IMarker[validCount];
398
		System.arraycopy(validList, 0, result, 0, validCount);
399
		return result;
400
	}
401
402
	/**
403
	 * This method removes all messages from a resource in the task list.
404
	 */
405
	public static void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
406
		removeAllTasks(resource, new String[]{owner}, objectName);
407
	}
408
409
	public static void removeAllTasks(IResource resource, String[] owners, String objectName) throws CoreException {
410
		removeAllTasks(resource, owners, objectName, getDepth(resource));
411
	}
412
413
	protected static void removeAllTasks(IResource resource, String[] owners, String objectName, int depth) throws CoreException {
414
		removeTaskSubset(resource, owners, objectName, null, depth); // null
415
																		// means
416
																		// no
417
																		// group
418
																		// name
419
	}
420
421
	/**
422
	 * This method removes a subset of tasks from the project, including child
423
	 * tasks. Every task which belongs to the group, identified by groupName,
424
	 * will be removed.
425
	 */
426
	protected static void removeTaskSubset(IResource resource, String[] owners, String objectName, String groupName, int depth) throws CoreException {
427
		if ((owners == null) || (resource == null)) {
428
			return;
429
		}
430
431
		IMarker[] allTasks = getValidationTasks(resource, owners, objectName, groupName, depth);
432
		if (allTasks.length > 0) {
433
			ResourcesPlugin.getWorkspace().deleteMarkers(allTasks);
434
		}
435
	}
436
}

Return to bug 338111