blob: 5ff15a1656694e4b77df12ede196b070a0811351 [file] [log] [blame]
paverye6107e62005-02-23 18:01:10 +00001package org.eclipse.wst.html.validation;
2
3import java.io.IOException;
4import java.io.UnsupportedEncodingException;
5
6import org.eclipse.core.resources.IContainer;
7import org.eclipse.core.resources.IFile;
8import org.eclipse.core.resources.IProject;
9import org.eclipse.core.resources.IResource;
10import org.eclipse.core.resources.ResourcesPlugin;
11import org.eclipse.core.runtime.CoreException;
12import org.eclipse.core.runtime.NullProgressMonitor;
13import org.eclipse.core.runtime.OperationCanceledException;
14import org.eclipse.core.runtime.Path;
15import org.eclipse.wst.html.core.validate.HTMLValidationAdapterFactory;
david_williamsd36efd92005-03-29 03:39:23 +000016import org.eclipse.wst.sse.core.IAdapterFactory;
paverye6107e62005-02-23 18:01:10 +000017import org.eclipse.wst.sse.core.IModelManager;
18import org.eclipse.wst.sse.core.IStructuredModel;
19import org.eclipse.wst.sse.core.StructuredModelManager;
20import org.eclipse.wst.sse.core.util.URIResolver;
21import org.eclipse.wst.sse.core.validate.ValidationAdapter;
22import org.eclipse.wst.validation.core.IFileDelta;
nitind86040ef2005-03-11 22:06:40 +000023import org.eclipse.wst.validation.core.IMessage;
paverye6107e62005-02-23 18:01:10 +000024import org.eclipse.wst.validation.core.IReporter;
david_williams43271672005-04-01 05:19:26 +000025import org.eclipse.wst.validation.core.IValidationContext;
paverye6107e62005-02-23 18:01:10 +000026import org.eclipse.wst.validation.core.IValidator;
paverye6107e62005-02-23 18:01:10 +000027import org.eclipse.wst.validation.internal.operations.IWorkbenchHelper;
28import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
david_williamsc39caaf2005-04-05 06:07:16 +000029import org.eclipse.wst.xml.core.document.IDOMDocument;
30import org.eclipse.wst.xml.core.document.IDOMModel;
david_williams646a5e22005-04-02 07:16:27 +000031import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
nitind86040ef2005-03-11 22:06:40 +000032import org.eclispe.wst.validation.internal.core.Message;
paverye6107e62005-02-23 18:01:10 +000033
34public class HTMLValidator implements IValidator {
35 /**
36 */
37 public HTMLValidator() {
38 super();
39 }
40
41 /**
42 */
43 public void cleanup(IReporter reporter) {
44 // nothing to do
45 }
46
47 /**
48 */
david_williamsc39caaf2005-04-05 06:07:16 +000049 protected IDOMModel getModel(IProject project, IFile file) {
paverye6107e62005-02-23 18:01:10 +000050 if (project == null || file == null)
51 return null;
52 if (!file.exists())
53 return null;
54 if (!canHandle(file))
55 return null;
56
57 IStructuredModel model = null;
58 IModelManager manager = StructuredModelManager.getModelManager();
59
60 try {
61 try {
62 model = manager.getModelForRead(file);
63 }
64 catch (UnsupportedEncodingException ex) {
65 // retry ignoring META charset for invalid META charset specification
66 // recreate input stream, because it is already partially read
67 model = manager.getModelForRead(file, new String(), null);
68 }
69 }
70 catch (UnsupportedEncodingException ex) {
71 }
72 catch (IOException ex) {
73 }
74 catch (CoreException ex) {
75 }
76
77 if (model == null)
78 return null;
david_williamsc39caaf2005-04-05 06:07:16 +000079 if (!(model instanceof IDOMModel)) {
paverye6107e62005-02-23 18:01:10 +000080 releaseModel(model);
81 return null;
82 }
david_williamsc39caaf2005-04-05 06:07:16 +000083 return (IDOMModel) model;
paverye6107e62005-02-23 18:01:10 +000084 }
85
86 /**
87 */
david_williamsc39caaf2005-04-05 06:07:16 +000088 protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
paverye6107e62005-02-23 18:01:10 +000089 return new HTMLValidationReporter(this, reporter, file, model);
90 }
91
92 /**
93 * Check file extension to validate
94 */
95 private boolean canHandle(IFile file) {
96 if (file == null)
97 return false;
98 String name = file.getFullPath().toString();
99 if (name == null)
100 return false;
101 int index = name.lastIndexOf('.');
102 if (index < 0)
103 return false;
104 String ext = name.substring(index + 1);
105 if (ext == null || ext.length() == 0)
106 return false;
107 ext = ext.toLowerCase();
108 return (ext.startsWith("htm") || //$NON-NLS-1$
109 ext.startsWith("jsp") || //$NON-NLS-1$
110 ext.equals("jsf") || //$NON-NLS-1$
111 ext.startsWith("xht") || //$NON-NLS-1$
112 ext.startsWith("shtm") || //$NON-NLS-1$
113 ext.startsWith("wml") || //$NON-NLS-1$
114 ext.equals("jhtml"));//$NON-NLS-1$
115 }
116
117 /**
118 */
david_williamsc39caaf2005-04-05 06:07:16 +0000119 private boolean hasHTMLFeature(IDOMDocument document) {
paverye6107e62005-02-23 18:01:10 +0000120 DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
121 if (adapter == null)
122 return false;
123 return adapter.hasFeature("HTML");//$NON-NLS-1$
124 }
125
126 /**
127 */
128 protected void releaseModel(IStructuredModel model) {
129 if (model != null)
130 model.releaseFromRead();
131 }
132
133 /**
134 */
david_williams43271672005-04-01 05:19:26 +0000135 public void validate(IValidationContext helper, IReporter reporter, IFileDelta[] deltaArray) {
paverye6107e62005-02-23 18:01:10 +0000136 if (helper == null)
137 return;
138 if ((reporter != null) && (reporter.isCancelled() == true)) {
139 throw new OperationCanceledException();
140 }
141 if (deltaArray != null && deltaArray.length > 0) {
142 validateDelta(helper, reporter, deltaArray);
143 }
144 else {
145 validateFull(helper, reporter, deltaArray);
146 }
147 }
148
149 /**
150 */
david_williamsc39caaf2005-04-05 06:07:16 +0000151 protected HTMLValidationResult validate(IDOMModel model, IFile file) {
paverye6107e62005-02-23 18:01:10 +0000152 IProject prj = null;
153 if (file != null) {
154 prj = file.getProject();
155 }
156 if ((prj == null) && (model != null)){
157 URIResolver res = model.getResolver();
158 if (res != null) {
159 prj = res.getProject();
160 }
161 }
162 final WorkbenchReporter reporter = new WorkbenchReporter(prj, new NullProgressMonitor());
163 return validate( reporter, file, model);
164 }
165
166 /**
167 */
david_williamsc39caaf2005-04-05 06:07:16 +0000168 private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) {
paverye6107e62005-02-23 18:01:10 +0000169 if (file == null || model == null)
170 return null; // error
david_williamsc39caaf2005-04-05 06:07:16 +0000171 IDOMDocument document = model.getDocument();
paverye6107e62005-02-23 18:01:10 +0000172 if (document == null)
173 return null; // error
174 if (!hasHTMLFeature(document))
175 return null; // ignore
176
david_williamsd36efd92005-03-29 03:39:23 +0000177 IAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
paverye6107e62005-02-23 18:01:10 +0000178 ValidationAdapter adapter = (ValidationAdapter) factory.adapt(document);
179 if (adapter == null)
180 return null; // error
181
182 HTMLValidationReporter rep = getReporter(reporter, file, model);
183 rep.clear();
184 adapter.setReporter(rep);
185 if (reporter != null) {
186 String args[] = new String[]{file.getFullPath().toString()};
187
188// Message mess = new Message("HTMLValidation", //$NON-NLS-1$
189// SeverityEnum.LOW_SEVERITY, "MESSAGE_HTML_VALIDATION_MESSAGE_UI_", //$NON-NLS-1$
190// args);
nitind86040ef2005-03-11 22:06:40 +0000191 Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, "MESSAGE_HTML_VALIDATION_MESSAGE_UI_");
paverye6107e62005-02-23 18:01:10 +0000192 mess.setParams(args);
193 reporter.displaySubtask(this, mess);
194 }
195 adapter.validate(document);
196 return rep.getResult();
197 }
198
199 /**
200 */
david_williams43271672005-04-01 05:19:26 +0000201 private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) {
paverye6107e62005-02-23 18:01:10 +0000202 try {
203 IResource[] resourceArray = container.members(false);
204 for (int i = 0; i < resourceArray.length; i++) {
205 IResource resource = resourceArray[i];
206 if (resource == null)
207 continue;
208 if (resource instanceof IFile) {
209 validateFile(helper, reporter, (IFile) resource);
210 }
211 else if (resource instanceof IContainer) {
212 validateContainer(helper, reporter, (IContainer) resource);
213 }
214 }
215 }
216 catch (CoreException ex) {
217 }
218 }
219
220 /**
221 */
david_williams43271672005-04-01 05:19:26 +0000222 private void validateDelta(IValidationContext helper, IReporter reporter, IFileDelta[] deltaArray) {
paverye6107e62005-02-23 18:01:10 +0000223 for (int i = 0; i < deltaArray.length; i++) {
224 IFileDelta delta = deltaArray[i];
225 if (delta == null || delta.getDeltaType() == IFileDelta.DELETED)
226 continue;
227 IResource resource = getResource(delta);
228 if (resource == null || !(resource instanceof IFile))
229 continue;
230 validateFile(helper, reporter, (IFile) resource);
231 }
232 }
233
234 /**
235 */
david_williams43271672005-04-01 05:19:26 +0000236 private void validateFile(IValidationContext helper, IReporter reporter, IFile file) {
paverye6107e62005-02-23 18:01:10 +0000237 if ((reporter != null) && (reporter.isCancelled() == true)) {
238 throw new OperationCanceledException();
239 }
david_williamsc39caaf2005-04-05 06:07:16 +0000240 IDOMModel model = getModel(file.getProject(), file);
paverye6107e62005-02-23 18:01:10 +0000241 if (model == null)
242 return;
243
244 try {
245 validate(reporter, file, model);
246 }
247 finally {
248 releaseModel(model);
249 }
250 }
251
252 /**
253 */
david_williams43271672005-04-01 05:19:26 +0000254 private void validateFull(IValidationContext helper, IReporter reporter, IFileDelta[] fileDelta) {
paverye6107e62005-02-23 18:01:10 +0000255 IProject project = null;
256 if(helper instanceof IWorkbenchHelper) {
257 IWorkbenchHelper wbHelper = (IWorkbenchHelper)helper;
258 project = wbHelper.getProject();
259 }
260 else {
261 // won't work for project validation (b/c nothing in file delta)
262 project = getResource(fileDelta[0]).getProject();
263 }
264 if (project == null)
265 return;
266 validateContainer(helper, reporter, project);
267 }
268
269 /*
270 * added to get rid or dependency on IWorkbenchHelper
271 * @see com.ibm.sse.editor.extensions.validator.IWorkbenchHelper#getResource(com.ibm.sse.editor.extensions.validator.IFileDelta)
272 */
273 public IResource getResource(IFileDelta delta) {
274 IResource res = null;
275 if (delta instanceof IResource)
276 res = (IResource) delta;
277 else
278 res = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta.getFileName()));
279 return res;
280 }
281}