blob: 6e886ae1511d98aee35e1bc1bdd5fe84a0781da0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.html.internal.validation;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
import org.eclipse.wst.html.ui.internal.HTMLUIMessages;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.util.URIResolver;
import org.eclipse.wst.sse.core.internal.validate.ValidationAdapter;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
import org.eclipse.wst.xml.core.internal.document.DocumentTypeAdapter;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
public class HTMLValidator implements IValidator {
/**
*/
public HTMLValidator() {
super();
}
/**
*/
public void cleanup(IReporter reporter) {
// nothing to do
}
/**
*/
protected IDOMModel getModel(IProject project, IFile file) {
if (project == null || file == null)
return null;
if (!file.exists())
return null;
if (!canHandle(file))
return null;
IStructuredModel model = null;
IModelManager manager = StructuredModelManager.getModelManager();
try {
try {
model = manager.getModelForRead(file);
}
catch (UnsupportedEncodingException ex) {
// retry ignoring META charset for invalid META charset
// specification
// recreate input stream, because it is already partially read
model = manager.getModelForRead(file, new String(), null);
}
}
catch (UnsupportedEncodingException ex) {
}
catch (IOException ex) {
}
catch (CoreException ex) {
}
if (model == null)
return null;
if (!(model instanceof IDOMModel)) {
releaseModel(model);
return null;
}
return (IDOMModel) model;
}
/**
*/
protected HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
return new HTMLValidationReporter(this, reporter, file, model);
}
/**
* Check file extension to validate
*/
private boolean canHandle(IFile file) {
if (file == null)
return false;
String name = file.getFullPath().toString();
if (name == null)
return false;
int index = name.lastIndexOf('.');
if (index < 0)
return false;
String ext = name.substring(index + 1);
if (ext == null || ext.length() == 0)
return false;
ext = ext.toLowerCase();
return (ext.startsWith("htm") || //$NON-NLS-1$
ext.startsWith("jsp") || //$NON-NLS-1$
ext.equals("jsf") || //$NON-NLS-1$
ext.startsWith("xht") || //$NON-NLS-1$
ext.startsWith("shtm") || //$NON-NLS-1$
ext.startsWith("wml") || //$NON-NLS-1$
ext.equals("jhtml"));//$NON-NLS-1$
}
/**
*/
private boolean hasHTMLFeature(IDOMDocument document) {
DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
if (adapter == null)
return false;
return adapter.hasFeature("HTML");//$NON-NLS-1$
}
/**
*/
protected void releaseModel(IStructuredModel model) {
if (model != null)
model.releaseFromRead();
}
/**
*/
public void validate(IValidationContext helper, IReporter reporter) {
if (helper == null)
return;
if ((reporter != null) && (reporter.isCancelled() == true)) {
throw new OperationCanceledException();
}
String[] deltaArray = helper.getURIs();
if (deltaArray != null && deltaArray.length > 0) {
validateDelta(helper, reporter);
}
else {
validateFull(helper, reporter);
}
}
/**
*/
protected HTMLValidationResult validate(IDOMModel model, IFile file) {
IProject prj = null;
if (file != null) {
prj = file.getProject();
}
if ((prj == null) && (model != null)) {
URIResolver res = model.getResolver();
if (res != null) {
prj = res.getProject();
}
}
final WorkbenchReporter reporter = new WorkbenchReporter(prj, new NullProgressMonitor());
return validate(reporter, file, model);
}
/**
*/
private HTMLValidationResult validate(IReporter reporter, IFile file, IDOMModel model) {
if (file == null || model == null)
return null; // error
IDOMDocument document = model.getDocument();
if (document == null)
return null; // error
if (!hasHTMLFeature(document))
return null; // ignore
INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
ValidationAdapter adapter = (ValidationAdapter) factory.adapt(document);
if (adapter == null)
return null; // error
HTMLValidationReporter rep = getReporter(reporter, file, model);
rep.clear();
adapter.setReporter(rep);
if (reporter != null) {
String args[] = new String[]{file.getFullPath().toString()};
// Message mess = new Message("HTMLValidation", //$NON-NLS-1$
// SeverityEnum.LOW_SEVERITY,
// "MESSAGE_HTML_VALIDATION_MESSAGE_UI_", //$NON-NLS-1$
// args);
Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, HTMLUIMessages.MESSAGE_HTML_VALIDATION_MESSAGE_UI_);
mess.setParams(args);
reporter.displaySubtask(this, mess);
}
adapter.validate(document);
return rep.getResult();
}
/**
*/
private void validateContainer(IValidationContext helper, IReporter reporter, IContainer container) {
try {
IResource[] resourceArray = container.members(false);
for (int i = 0; i < resourceArray.length; i++) {
IResource resource = resourceArray[i];
if (resource == null)
continue;
if (resource instanceof IFile) {
validateFile(helper, reporter, (IFile) resource);
}
else if (resource instanceof IContainer) {
validateContainer(helper, reporter, (IContainer) resource);
}
}
}
catch (CoreException ex) {
}
}
/**
*/
private void validateDelta(IValidationContext helper, IReporter reporter) {
String[] deltaArray = helper.getURIs();
for (int i = 0; i < deltaArray.length; i++) {
String delta = deltaArray[i];
if (delta == null)
continue;
IResource resource = getResource(delta);
if (resource == null || !(resource instanceof IFile))
continue;
validateFile(helper, reporter, (IFile) resource);
}
}
/**
*/
private void validateFile(IValidationContext helper, IReporter reporter, IFile file) {
if ((reporter != null) && (reporter.isCancelled() == true)) {
throw new OperationCanceledException();
}
IDOMModel model = getModel(file.getProject(), file);
if (model == null)
return;
try {
validate(reporter, file, model);
}
finally {
releaseModel(model);
}
}
/**
*/
private void validateFull(IValidationContext helper, IReporter reporter) {
IProject project = null;
String[] fileDelta = helper.getURIs();
if (helper instanceof IWorkbenchContext) {
IWorkbenchContext wbHelper = (IWorkbenchContext) helper;
project = wbHelper.getProject();
}
else {
// won't work for project validation (b/c nothing in file delta)
project = getResource(fileDelta[0]).getProject();
}
if (project == null)
return;
validateContainer(helper, reporter, project);
}
/*
* added to get rid or dependency on IWorkbenchHelper
*
* @see com.ibm.sse.editor.extensions.validator.IWorkbenchHelper#getResource(com.ibm.sse.editor.extensions.validator.IFileDelta)
*/
public IResource getResource(String delta) {
return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta));
}
}