blob: 574c16c518e6c413294151ed23d2fcbdec0c3259 [file] [log] [blame]
david_williams49d24fb2005-04-08 21:16:59 +00001/*******************************************************************************
2 * Copyright (c) 2001, 2004 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 *******************************************************************************/
david_williams96643dd2005-04-13 04:35:24 +000011package org.eclipse.wst.html.internal.validation;
paverye6107e62005-02-23 18:01:10 +000012
13import java.io.IOException;
14import java.io.UnsupportedEncodingException;
15
16import org.eclipse.core.resources.IContainer;
17import org.eclipse.core.resources.IFile;
18import org.eclipse.core.resources.IProject;
19import org.eclipse.core.resources.IResource;
20import org.eclipse.core.resources.ResourcesPlugin;
21import org.eclipse.core.runtime.CoreException;
22import org.eclipse.core.runtime.NullProgressMonitor;
23import org.eclipse.core.runtime.OperationCanceledException;
24import org.eclipse.core.runtime.Path;
david_williams56777022005-04-11 06:21:55 +000025import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
david_williams3a2ab2d2005-04-11 16:32:45 +000026import org.eclipse.wst.html.ui.internal.HTMLUIMessages;
paverye6107e62005-02-23 18:01:10 +000027import org.eclipse.wst.sse.core.IModelManager;
david_williams3a2ab2d2005-04-11 16:32:45 +000028import org.eclipse.wst.sse.core.INodeAdapterFactory;
paverye6107e62005-02-23 18:01:10 +000029import org.eclipse.wst.sse.core.IStructuredModel;
30import org.eclipse.wst.sse.core.StructuredModelManager;
31import org.eclipse.wst.sse.core.util.URIResolver;
32import org.eclipse.wst.sse.core.validate.ValidationAdapter;
vbhadrir271d28a2005-04-12 19:36:05 +000033import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
paverye6107e62005-02-23 18:01:10 +000034import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
david_williams49d24fb2005-04-08 21:16:59 +000035import org.eclipse.wst.validation.internal.provisional.core.IMessage;
36import org.eclipse.wst.validation.internal.provisional.core.IReporter;
37import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
38import org.eclipse.wst.validation.internal.provisional.core.IValidator;
david_williamsc39caaf2005-04-05 06:07:16 +000039import org.eclipse.wst.xml.core.document.IDOMDocument;
40import org.eclipse.wst.xml.core.document.IDOMModel;
david_williams646a5e22005-04-02 07:16:27 +000041import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
nitind86040ef2005-03-11 22:06:40 +000042import org.eclispe.wst.validation.internal.core.Message;
paverye6107e62005-02-23 18:01:10 +000043
44public class HTMLValidator implements IValidator {
45 /**
46 */
47 public HTMLValidator() {
48 super();
49 }
50
51 /**
52 */
53 public void cleanup(IReporter reporter) {
54 // nothing to do
55 }
56
57 /**
58 */
david_williamsc39caaf2005-04-05 06:07:16 +000059 protected IDOMModel getModel(IProject project, IFile file) {
paverye6107e62005-02-23 18:01:10 +000060 if (project == null || file == null)
61 return null;
62 if (!file.exists())
63 return null;
64 if (!canHandle(file))
65 return null;
66
67 IStructuredModel model = null;
68 IModelManager manager = StructuredModelManager.getModelManager();
69
70 try {
71 try {
72 model = manager.getModelForRead(file);
73 }
74 catch (UnsupportedEncodingException ex) {
david_williams49d24fb2005-04-08 21:16:59 +000075 // retry ignoring META charset for invalid META charset
76 // specification
paverye6107e62005-02-23 18:01:10 +000077 // recreate input stream, because it is already partially read
78 model = manager.getModelForRead(file, new String(), null);
79 }
80 }
81 catch (UnsupportedEncodingException ex) {
82 }
83 catch (IOException ex) {
84 }
85 catch (CoreException ex) {
86 }
87
88 if (model == null)
89 return null;
david_williamsc39caaf2005-04-05 06:07:16 +000090 if (!(model instanceof IDOMModel)) {
paverye6107e62005-02-23 18:01:10 +000091 releaseModel(model);
92 return null;
93 }
david_williamsc39caaf2005-04-05 06:07:16 +000094 return (IDOMModel) model;
paverye6107e62005-02-23 18:01:10 +000095 }
96
97 /**
98 */
david_williamsc39caaf2005-04-05 06:07:16 +000099 protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
paverye6107e62005-02-23 18:01:10 +0000100 return new HTMLValidationReporter(this, reporter, file, model);
101 }
102
103 /**
104 * Check file extension to validate
105 */
106 private boolean canHandle(IFile file) {
107 if (file == null)
108 return false;
109 String name = file.getFullPath().toString();
110 if (name == null)
111 return false;
112 int index = name.lastIndexOf('.');
113 if (index < 0)
114 return false;
115 String ext = name.substring(index + 1);
116 if (ext == null || ext.length() == 0)
117 return false;
118 ext = ext.toLowerCase();
119 return (ext.startsWith("htm") || //$NON-NLS-1$
120 ext.startsWith("jsp") || //$NON-NLS-1$
121 ext.equals("jsf") || //$NON-NLS-1$
122 ext.startsWith("xht") || //$NON-NLS-1$
123 ext.startsWith("shtm") || //$NON-NLS-1$
124 ext.startsWith("wml") || //$NON-NLS-1$
125 ext.equals("jhtml"));//$NON-NLS-1$
126 }
127
128 /**
129 */
david_williamsc39caaf2005-04-05 06:07:16 +0000130 private boolean hasHTMLFeature(IDOMDocument document) {
paverye6107e62005-02-23 18:01:10 +0000131 DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
132 if (adapter == null)
133 return false;
134 return adapter.hasFeature("HTML");//$NON-NLS-1$
135 }
136
137 /**
138 */
139 protected void releaseModel(IStructuredModel model) {
140 if (model != null)
141 model.releaseFromRead();
142 }
143
144 /**
145 */
vbhadrir271d28a2005-04-12 19:36:05 +0000146 public void validate(IValidationContext helper, IReporter reporter) {
paverye6107e62005-02-23 18:01:10 +0000147 if (helper == null)
148 return;
149 if ((reporter != null) && (reporter.isCancelled() == true)) {
150 throw new OperationCanceledException();
151 }
vbhadrir271d28a2005-04-12 19:36:05 +0000152 String[] deltaArray = helper.getURIs();
paverye6107e62005-02-23 18:01:10 +0000153 if (deltaArray != null && deltaArray.length > 0) {
vbhadrir271d28a2005-04-12 19:36:05 +0000154 validateDelta(helper, reporter);
paverye6107e62005-02-23 18:01:10 +0000155 }
156 else {
vbhadrir271d28a2005-04-12 19:36:05 +0000157 validateFull(helper, reporter);
paverye6107e62005-02-23 18:01:10 +0000158 }
159 }
160
161 /**
162 */
david_williamsc39caaf2005-04-05 06:07:16 +0000163 protected HTMLValidationResult validate(IDOMModel model, IFile file) {
paverye6107e62005-02-23 18:01:10 +0000164 IProject prj = null;
165 if (file != null) {
166 prj = file.getProject();
167 }
david_williams49d24fb2005-04-08 21:16:59 +0000168 if ((prj == null) && (model != null)) {
paverye6107e62005-02-23 18:01:10 +0000169 URIResolver res = model.getResolver();
170 if (res != null) {
171 prj = res.getProject();
172 }
173 }
174 final WorkbenchReporter reporter = new WorkbenchReporter(prj, new NullProgressMonitor());
david_williams49d24fb2005-04-08 21:16:59 +0000175 return validate(reporter, file, model);
paverye6107e62005-02-23 18:01:10 +0000176 }
177
178 /**
179 */
david_williamsc39caaf2005-04-05 06:07:16 +0000180 private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) {
paverye6107e62005-02-23 18:01:10 +0000181 if (file == null || model == null)
182 return null; // error
david_williamsc39caaf2005-04-05 06:07:16 +0000183 IDOMDocument document = model.getDocument();
paverye6107e62005-02-23 18:01:10 +0000184 if (document == null)
185 return null; // error
186 if (!hasHTMLFeature(document))
187 return null; // ignore
188
david_williams285ee2d2005-04-10 18:21:21 +0000189 INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
paverye6107e62005-02-23 18:01:10 +0000190 ValidationAdapter adapter = (ValidationAdapter) factory.adapt(document);
191 if (adapter == null)
192 return null; // error
193
194 HTMLValidationReporter rep = getReporter(reporter, file, model);
195 rep.clear();
196 adapter.setReporter(rep);
197 if (reporter != null) {
198 String args[] = new String[]{file.getFullPath().toString()};
david_williams49d24fb2005-04-08 21:16:59 +0000199
200 // Message mess = new Message("HTMLValidation", //$NON-NLS-1$
201 // SeverityEnum.LOW_SEVERITY,
202 // "MESSAGE_HTML_VALIDATION_MESSAGE_UI_", //$NON-NLS-1$
203 // args);
david_williams3a2ab2d2005-04-11 16:32:45 +0000204 Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, HTMLUIMessages.MESSAGE_HTML_VALIDATION_MESSAGE_UI_);
paverye6107e62005-02-23 18:01:10 +0000205 mess.setParams(args);
206 reporter.displaySubtask(this, mess);
207 }
208 adapter.validate(document);
209 return rep.getResult();
210 }
211
212 /**
213 */
david_williams43271672005-04-01 05:19:26 +0000214 private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) {
paverye6107e62005-02-23 18:01:10 +0000215 try {
216 IResource[] resourceArray = container.members(false);
217 for (int i = 0; i < resourceArray.length; i++) {
218 IResource resource = resourceArray[i];
219 if (resource == null)
220 continue;
221 if (resource instanceof IFile) {
222 validateFile(helper, reporter, (IFile) resource);
223 }
224 else if (resource instanceof IContainer) {
225 validateContainer(helper, reporter, (IContainer) resource);
226 }
227 }
228 }
229 catch (CoreException ex) {
230 }
231 }
232
233 /**
234 */
vbhadrir271d28a2005-04-12 19:36:05 +0000235 private void validateDelta(IValidationContext helper, IReporter reporter) {
236 String[] deltaArray = helper.getURIs();
paverye6107e62005-02-23 18:01:10 +0000237 for (int i = 0; i < deltaArray.length; i++) {
vbhadrir271d28a2005-04-12 19:36:05 +0000238 String delta = deltaArray[i];
239 if (delta == null)
paverye6107e62005-02-23 18:01:10 +0000240 continue;
241 IResource resource = getResource(delta);
242 if (resource == null || !(resource instanceof IFile))
243 continue;
244 validateFile(helper, reporter, (IFile) resource);
245 }
246 }
247
248 /**
249 */
david_williams43271672005-04-01 05:19:26 +0000250 private void validateFile(IValidationContext helper, IReporter reporter, IFile file) {
paverye6107e62005-02-23 18:01:10 +0000251 if ((reporter != null) && (reporter.isCancelled() == true)) {
252 throw new OperationCanceledException();
253 }
david_williamsc39caaf2005-04-05 06:07:16 +0000254 IDOMModel model = getModel(file.getProject(), file);
paverye6107e62005-02-23 18:01:10 +0000255 if (model == null)
256 return;
257
258 try {
259 validate(reporter, file, model);
260 }
261 finally {
262 releaseModel(model);
263 }
264 }
265
266 /**
267 */
vbhadrir271d28a2005-04-12 19:36:05 +0000268 private void validateFull(IValidationContext helper, IReporter reporter) {
paverye6107e62005-02-23 18:01:10 +0000269 IProject project = null;
vbhadrir271d28a2005-04-12 19:36:05 +0000270 String[] fileDelta = helper.getURIs();
271 if (helper instanceof IWorkbenchContext) {
272 IWorkbenchContext wbHelper = (IWorkbenchContext) helper;
paverye6107e62005-02-23 18:01:10 +0000273 project = wbHelper.getProject();
274 }
275 else {
276 // won't work for project validation (b/c nothing in file delta)
277 project = getResource(fileDelta[0]).getProject();
278 }
279 if (project == null)
280 return;
281 validateContainer(helper, reporter, project);
282 }
283
david_williams49d24fb2005-04-08 21:16:59 +0000284 /*
paverye6107e62005-02-23 18:01:10 +0000285 * added to get rid or dependency on IWorkbenchHelper
david_williams49d24fb2005-04-08 21:16:59 +0000286 *
paverye6107e62005-02-23 18:01:10 +0000287 * @see com.ibm.sse.editor.extensions.validator.IWorkbenchHelper#getResource(com.ibm.sse.editor.extensions.validator.IFileDelta)
288 */
vbhadrir271d28a2005-04-12 19:36:05 +0000289 public IResource getResource(String delta) {
290 return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta));
paverye6107e62005-02-23 18:01:10 +0000291 }
292}