package org.eclipse.dltk.validators.core; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dltk.validators.internal.core.ValidatorsCore; abstract class AbstractValidatorWorker { /** * Returns the problem marker id */ protected abstract String getMarkerId(); /** * Returns the message that will be logged when the <code>IResource</code> * of the object being validated is null. */ protected abstract String getNullResourceMessage(); /** * Returns the plugin id of the validator worker implementation. */ protected abstract String getPluginId(); /** * Returns the task name that will be passed to the progress monitor once * the validation begins. */ protected abstract String getTaskName(); /** * Calculates the total work that will be performed for the progress * monitor. * * <p> * Default implementation returns the number of objects in the array. * Sub-classes may override this method if they wish to provide a different * calculation. * </p> */ protected int calcTotalWork(Object[] objects) { return objects.length; } protected void clean(IResource[] resources) { final String markerType = getMarkerId(); // TODO execute single operation via IWorkspaceRunnable ? for (int i = 0; i < resources.length; ++i) { final IResource resource = resources[i]; clean(resource, markerType); } } protected void clean(final IResource resource) { clean(resource, getMarkerId()); } protected void clean(final IResource resource, final String markerType) { try { resource.deleteMarkers(markerType, true, IResource.DEPTH_INFINITE); } catch (CoreException e) { ValidatorsCore.log(e.getStatus()); } } /** * Creates an instance of an <code>IValidatorReporter</code>. * * <p> * Sub-classes are free to override in order to provide their own * implementation. * </p> */ protected IValidatorReporter createValidatorReporter() { return new ValidatorReporter(getMarkerId()); } /** * Returns <code>true</code> if the validator is configured, * <code>false</code> otherwise. * * <p> * Default returns <code>true</code>. Sub-classes are free to override to * provide any implementation specific checks. * </p> */ protected boolean isValidatorConfigured() { return true; } abstract IResource getResource(Object resource); abstract boolean isValidResource(Object object); abstract void runValidator(Object object, IValidatorOutput console, IValidatorReporter reporter, IProgressMonitor monitor) throws CoreException; final IStatus doValidate(Object[] objects, IValidatorOutput console, IProgressMonitor monitor) { if (!isValidatorConfigured()) { // don't bother continuing if we're not properly configured return Status.CANCEL_STATUS; } IValidatorReporter reporter = createValidatorReporter(); // so it begins... ;) monitor.beginTask(getTaskName(), calcTotalWork(objects)); try { for (int i = 0; i < objects.length; i++) { if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } if (getResource(objects[i]) == null) { // XXX: make this an error level instead? IStatus status = new Status(IStatus.WARNING, getPluginId(), getNullResourceMessage()); ValidatorsCore.log(status); } else { validate(objects[i], reporter, console, monitor); } monitor.worked(1); } } finally { monitor.done(); } return Status.OK_STATUS; } private void validate(Object object, IValidatorReporter reporter, IValidatorOutput console, IProgressMonitor monitor) { if (!isValidResource(object)) { return; } IResource resource = getResource(object); clean(resource); try { runValidator(object, console, reporter, monitor); } catch (CoreException e) { ValidatorsCore.log(e.getStatus()); } } }