david_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 1 | /******************************************************************************* |
| 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_williams | 96643dd | 2005-04-13 04:35:24 +0000 | [diff] [blame^] | 11 | package org.eclipse.wst.html.internal.validation; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 12 | |
| 13 | import java.io.IOException; |
| 14 | import java.io.UnsupportedEncodingException; |
| 15 | |
| 16 | import org.eclipse.core.resources.IContainer; |
| 17 | import org.eclipse.core.resources.IFile; |
| 18 | import org.eclipse.core.resources.IProject; |
| 19 | import org.eclipse.core.resources.IResource; |
| 20 | import org.eclipse.core.resources.ResourcesPlugin; |
| 21 | import org.eclipse.core.runtime.CoreException; |
| 22 | import org.eclipse.core.runtime.NullProgressMonitor; |
| 23 | import org.eclipse.core.runtime.OperationCanceledException; |
| 24 | import org.eclipse.core.runtime.Path; |
david_williams | 5677702 | 2005-04-11 06:21:55 +0000 | [diff] [blame] | 25 | import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory; |
david_williams | 3a2ab2d | 2005-04-11 16:32:45 +0000 | [diff] [blame] | 26 | import org.eclipse.wst.html.ui.internal.HTMLUIMessages; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 27 | import org.eclipse.wst.sse.core.IModelManager; |
david_williams | 3a2ab2d | 2005-04-11 16:32:45 +0000 | [diff] [blame] | 28 | import org.eclipse.wst.sse.core.INodeAdapterFactory; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 29 | import org.eclipse.wst.sse.core.IStructuredModel; |
| 30 | import org.eclipse.wst.sse.core.StructuredModelManager; |
| 31 | import org.eclipse.wst.sse.core.util.URIResolver; |
| 32 | import org.eclipse.wst.sse.core.validate.ValidationAdapter; |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 33 | import org.eclipse.wst.validation.internal.operations.IWorkbenchContext; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 34 | import org.eclipse.wst.validation.internal.operations.WorkbenchReporter; |
david_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 35 | import org.eclipse.wst.validation.internal.provisional.core.IMessage; |
| 36 | import org.eclipse.wst.validation.internal.provisional.core.IReporter; |
| 37 | import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; |
| 38 | import org.eclipse.wst.validation.internal.provisional.core.IValidator; |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 39 | import org.eclipse.wst.xml.core.document.IDOMDocument; |
| 40 | import org.eclipse.wst.xml.core.document.IDOMModel; |
david_williams | 646a5e2 | 2005-04-02 07:16:27 +0000 | [diff] [blame] | 41 | import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter; |
nitind | 86040ef | 2005-03-11 22:06:40 +0000 | [diff] [blame] | 42 | import org.eclispe.wst.validation.internal.core.Message; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 43 | |
| 44 | public 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_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 59 | protected IDOMModel getModel(IProject project, IFile file) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 60 | 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_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 75 | // retry ignoring META charset for invalid META charset |
| 76 | // specification |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 77 | // 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_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 90 | if (!(model instanceof IDOMModel)) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 91 | releaseModel(model); |
| 92 | return null; |
| 93 | } |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 94 | return (IDOMModel) model; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | /** |
| 98 | */ |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 99 | protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 100 | 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_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 130 | private boolean hasHTMLFeature(IDOMDocument document) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 131 | 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 | */ |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 146 | public void validate(IValidationContext helper, IReporter reporter) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 147 | if (helper == null) |
| 148 | return; |
| 149 | if ((reporter != null) && (reporter.isCancelled() == true)) { |
| 150 | throw new OperationCanceledException(); |
| 151 | } |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 152 | String[] deltaArray = helper.getURIs(); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 153 | if (deltaArray != null && deltaArray.length > 0) { |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 154 | validateDelta(helper, reporter); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 155 | } |
| 156 | else { |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 157 | validateFull(helper, reporter); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 158 | } |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | */ |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 163 | protected HTMLValidationResult validate(IDOMModel model, IFile file) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 164 | IProject prj = null; |
| 165 | if (file != null) { |
| 166 | prj = file.getProject(); |
| 167 | } |
david_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 168 | if ((prj == null) && (model != null)) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 169 | URIResolver res = model.getResolver(); |
| 170 | if (res != null) { |
| 171 | prj = res.getProject(); |
| 172 | } |
| 173 | } |
| 174 | final WorkbenchReporter reporter = new WorkbenchReporter(prj, new NullProgressMonitor()); |
david_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 175 | return validate(reporter, file, model); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | /** |
| 179 | */ |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 180 | private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 181 | if (file == null || model == null) |
| 182 | return null; // error |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 183 | IDOMDocument document = model.getDocument(); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 184 | if (document == null) |
| 185 | return null; // error |
| 186 | if (!hasHTMLFeature(document)) |
| 187 | return null; // ignore |
| 188 | |
david_williams | 285ee2d | 2005-04-10 18:21:21 +0000 | [diff] [blame] | 189 | INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance(); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 190 | 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_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 199 | |
| 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_williams | 3a2ab2d | 2005-04-11 16:32:45 +0000 | [diff] [blame] | 204 | Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, HTMLUIMessages.MESSAGE_HTML_VALIDATION_MESSAGE_UI_); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 205 | mess.setParams(args); |
| 206 | reporter.displaySubtask(this, mess); |
| 207 | } |
| 208 | adapter.validate(document); |
| 209 | return rep.getResult(); |
| 210 | } |
| 211 | |
| 212 | /** |
| 213 | */ |
david_williams | 4327167 | 2005-04-01 05:19:26 +0000 | [diff] [blame] | 214 | private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 215 | 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 | */ |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 235 | private void validateDelta(IValidationContext helper, IReporter reporter) { |
| 236 | String[] deltaArray = helper.getURIs(); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 237 | for (int i = 0; i < deltaArray.length; i++) { |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 238 | String delta = deltaArray[i]; |
| 239 | if (delta == null) |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 240 | 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_williams | 4327167 | 2005-04-01 05:19:26 +0000 | [diff] [blame] | 250 | private void validateFile(IValidationContext helper, IReporter reporter, IFile file) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 251 | if ((reporter != null) && (reporter.isCancelled() == true)) { |
| 252 | throw new OperationCanceledException(); |
| 253 | } |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 254 | IDOMModel model = getModel(file.getProject(), file); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 255 | if (model == null) |
| 256 | return; |
| 257 | |
| 258 | try { |
| 259 | validate(reporter, file, model); |
| 260 | } |
| 261 | finally { |
| 262 | releaseModel(model); |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | /** |
| 267 | */ |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 268 | private void validateFull(IValidationContext helper, IReporter reporter) { |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 269 | IProject project = null; |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 270 | String[] fileDelta = helper.getURIs(); |
| 271 | if (helper instanceof IWorkbenchContext) { |
| 272 | IWorkbenchContext wbHelper = (IWorkbenchContext) helper; |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 273 | 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_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 284 | /* |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 285 | * added to get rid or dependency on IWorkbenchHelper |
david_williams | 49d24fb | 2005-04-08 21:16:59 +0000 | [diff] [blame] | 286 | * |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 287 | * @see com.ibm.sse.editor.extensions.validator.IWorkbenchHelper#getResource(com.ibm.sse.editor.extensions.validator.IFileDelta) |
| 288 | */ |
vbhadrir | 271d28a | 2005-04-12 19:36:05 +0000 | [diff] [blame] | 289 | public IResource getResource(String delta) { |
| 290 | return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta)); |
pavery | e6107e6 | 2005-02-23 18:01:10 +0000 | [diff] [blame] | 291 | } |
| 292 | } |