| /******************************************************************************* |
| * Copyright (c) 2005, 2017 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 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.validators.core; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.TransformerException; |
| |
| 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.ListenerList; |
| import org.eclipse.core.runtime.Preferences; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.DLTKLanguageManager; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ISourceModule; |
| import org.eclipse.dltk.validators.internal.core.ValidatorDefinitionsContainer; |
| import org.eclipse.dltk.validators.internal.core.ValidatorManager; |
| import org.eclipse.dltk.validators.internal.core.ValidatorsCore; |
| import org.xml.sax.InputSource; |
| |
| public final class ValidatorRuntime { |
| |
| public static final String PREF_VALIDATOR_XML = ValidatorsCore.PLUGIN_ID + ".PREF_VALIDATOR_XML"; //$NON-NLS-1$ |
| |
| /** |
| * EMF validators configuration |
| */ |
| public static final String PREF_CONFIGURATION = ValidatorsCore.PLUGIN_ID + ".configuration"; //$NON-NLS-1$ |
| |
| // public static final String MARKER_VALIDATOR = ValidatorsCore.PLUGIN_ID |
| // + ".marker_validator_id"; //$NON-NLS-1$ |
| |
| // lock for interpreter initialization |
| private static final Object fgValidatorLock = new Object(); |
| private static boolean fgInitializingValidators = false; |
| private static boolean isInitialized = false; |
| // |
| private static final ListenerList<IValidatorChangedListener> fgValidatorListeners = new ListenerList<>( |
| ListenerList.IDENTITY); |
| |
| public static final String ANY_NATURE = "#"; //$NON-NLS-1$ |
| |
| private ValidatorRuntime() { |
| } |
| |
| public static IValidatorType getValidatorType(String id) { |
| IValidatorType[] types = getValidatorTypes(); |
| for (int i = 0; i < types.length; i++) { |
| if (types[i].getID().equals(id)) { |
| return types[i]; |
| } |
| } |
| return null; |
| } |
| |
| public static IValidatorType[] getValidatorTypes() { |
| initializeValidators(); |
| try { |
| return ValidatorManager.getAllValidatorTypes(); |
| } catch (CoreException e) { |
| if (DLTKCore.DEBUG) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| } |
| |
| public static IValidatorType[] getValidatorTypes(String nature) { |
| initializeValidators(); |
| try { |
| return ValidatorManager.getValidators(nature); |
| } catch (CoreException e) { |
| if (DLTKCore.DEBUG) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| } |
| |
| public static void saveValidatorConfiguration() throws CoreException { |
| IValidatorType[] vals = getValidatorTypes(); |
| if (vals == null || vals.length == 0) { |
| // if the Interpreter types have not been instantiated, there can be |
| // no changes. |
| return; |
| } |
| try { |
| String xml = getValidatorsAsXML(); |
| getPreferences().setValue(PREF_VALIDATOR_XML, xml); |
| savePreferences(); |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.ERROR, ValidatorsCore.PLUGIN_ID, IStatus.OK, |
| Messages.ValidatorRuntime_exceptionOccurred, e)); |
| } catch (ParserConfigurationException e) { |
| throw new CoreException(new Status(IStatus.ERROR, ValidatorsCore.PLUGIN_ID, IStatus.OK, |
| Messages.ValidatorRuntime_exceptionOccurred, e)); |
| } catch (TransformerException e) { |
| throw new CoreException(new Status(IStatus.ERROR, ValidatorsCore.PLUGIN_ID, IStatus.OK, |
| Messages.ValidatorRuntime_exceptionOccurred, e)); |
| } |
| } |
| |
| private static String getValidatorsAsXML() throws IOException, ParserConfigurationException, TransformerException { |
| ValidatorDefinitionsContainer container = new ValidatorDefinitionsContainer(); |
| |
| IValidatorType[] validatorTypes = getValidatorTypes(); |
| for (int i = 0; i < validatorTypes.length; ++i) { |
| container.addValidators(validatorTypes[i].getValidators()); |
| } |
| return container.getAsXML(); |
| } |
| |
| private static boolean addPersistedValidators(ValidatorDefinitionsContainer interpreterDefs) throws IOException { |
| |
| String validatorXMLString = getPreferences().getString(PREF_VALIDATOR_XML); |
| |
| if (validatorXMLString.length() > 0) { |
| try { |
| interpreterDefs.parseXML(new InputSource(new StringReader(validatorXMLString))); |
| return false; |
| } catch (IOException ioe) { |
| // DLTKLaunchingPlugin.log(ioe); |
| } |
| } |
| return true; |
| } |
| |
| public static Preferences getPreferences() { |
| return ValidatorsCore.getDefault().getPluginPreferences(); |
| } |
| |
| public static void savePreferences() { |
| ValidatorsCore.getDefault().savePluginPreferences(); |
| } |
| |
| /** |
| * Perform Interpreter type and Interpreter install initialization. Does not |
| * hold locks while performing change notification. |
| */ |
| private static void initializeValidators() { |
| ValidatorDefinitionsContainer validatorDefs = null; |
| boolean setPref = false; |
| synchronized (fgValidatorLock) { |
| if (isInitialized) { |
| return; |
| } |
| isInitialized = true; |
| try { |
| fgInitializingValidators = true; |
| // 1. load Validators type extensions |
| // initializeValidatorTypeExtensions(); |
| try { |
| validatorDefs = new ValidatorDefinitionsContainer(); |
| |
| // 2. add persisted Validators |
| setPref = addPersistedValidators(validatorDefs); |
| |
| // 4. load contributed Validators installs |
| // addValidatorExtensions(InterpreterDefs); |
| |
| } catch (IOException e) { |
| // DLTKLaunchingPlugin.log(e); |
| } |
| } finally { |
| fgInitializingValidators = false; |
| } |
| } |
| if (validatorDefs != null) { |
| // notify of initial Interpreters for backwards compatibility |
| IValidatorType[] validatorTypes = null; |
| try { |
| validatorTypes = ValidatorManager.getAllValidatorTypes(); |
| } catch (CoreException e1) { |
| return; |
| } |
| // register loaded validators with corresponding types |
| for (Iterator i = validatorDefs.getValidatorList().iterator(); i.hasNext();) { |
| final IValidator validator = (IValidator) i.next(); |
| final String typeId = validator.getValidatorType().getID(); |
| for (int j = 0; j < validatorTypes.length; ++j) { |
| final IValidatorType validatorType = validatorTypes[j]; |
| if (typeId.equals(validatorType.getID())) { |
| if (validatorType.findValidator(validator.getID()) == null) { |
| validatorType.addValidator(validator); |
| } |
| break; |
| } |
| } |
| } |
| |
| // save settings if required |
| if (setPref) { |
| try { |
| String xml = validatorDefs.getAsXML(); |
| getPreferences().setValue(PREF_VALIDATOR_XML, xml); |
| } catch (ParserConfigurationException e) { |
| // DLTKLaunchingPlugin.log(e); |
| } catch (IOException e) { |
| // DLTKLaunchingPlugin.log(e); |
| } catch (TransformerException e) { |
| // DLTKLaunchingPlugin.log(e); |
| } |
| |
| } |
| |
| } |
| } |
| |
| public static void addValidatorChangedListener(IValidatorChangedListener listener) { |
| fgValidatorListeners.add(listener); |
| } |
| |
| public static void removeValidatorChangedListener(IValidatorChangedListener listener) { |
| fgValidatorListeners.remove(listener); |
| } |
| |
| public static void fireValidatorChanged(IValidator validator) { |
| for (IValidatorChangedListener listener : fgValidatorListeners) { |
| // IValidatorChangedListener listener = (IValidatorChangedListener) |
| // listeners[i]; |
| // listener.validatorChanged(validator); |
| } |
| } |
| |
| public static void fireValidatorAdded(IValidator Interpreter) { |
| if (!fgInitializingValidators) { |
| for (IValidatorChangedListener listener : fgValidatorListeners) { |
| // IValidatorChangedListener listener = |
| // (IValidatorChangedListener) listeners[i]; |
| // listener.validatorAdded(Interpreter); |
| } |
| } |
| } |
| |
| public static void fireValidatorRemoved(IValidator Interpreter) { |
| for (IValidatorChangedListener listener : fgValidatorListeners) { |
| // IValidatorChangedListener listener = (IValidatorChangedListener) |
| // listeners[i]; |
| // listener.validatorRemoved(Interpreter); |
| } |
| } |
| |
| /** |
| * Returns array of validator types which are not built-in, i.e. new instances |
| * of that types could be added by the user. |
| * |
| * @return |
| */ |
| public static IValidatorType[] getPossibleValidatorTypes() { |
| List<IValidatorType> possible = new ArrayList<>(); |
| IValidatorType[] vals = getValidatorTypes(); |
| for (int i = 0; i < vals.length; i++) { |
| if (!vals[i].isBuiltin()) { |
| possible.add(vals[i]); |
| } |
| } |
| return possible.toArray(new IValidatorType[possible.size()]); |
| } |
| |
| public static IValidator[] getAllValidators() { |
| List<IValidator> possible = new ArrayList<>(); |
| IValidatorType[] vals = getValidatorTypes(); |
| for (int i = 0; i < vals.length; i++) { |
| IValidator[] v = vals[i].getValidators(); |
| for (int j = 0; j < v.length; j++) { |
| if (!possible.contains(v[j])) { |
| possible.add(v[j]); |
| } |
| } |
| } |
| return possible.toArray(new IValidator[possible.size()]); |
| } |
| |
| private static ISourceModule[] filterModulesForValidator(List elements, IValidator v, IProgressMonitor monitor) { |
| final List<ISourceModule> result = new ArrayList<>(); |
| final String nature = v.getValidatorType().getNature(); |
| for (Iterator iterator = elements.iterator(); iterator.hasNext();) { |
| IModelElement el = (IModelElement) iterator.next(); |
| if (el instanceof ISourceModule) { |
| ISourceModule module = (ISourceModule) el; |
| IDLTKLanguageToolkit toolkit = null; |
| toolkit = DLTKLanguageManager.getLanguageToolkit(module); |
| |
| if (toolkit != null && toolkit.getNatureId().equals(nature) || nature.equals(ANY_NATURE)) { |
| result.add(module); |
| } |
| } |
| } |
| return result.toArray(new ISourceModule[result.size()]); |
| } |
| |
| public static void executeCleanAllValidatorsWithConsole(List elements, List resources) { |
| executeCleanAllValidatorsWithConsole(elements, resources); |
| } |
| |
| /** |
| * @deprecated |
| */ |
| @Deprecated |
| public static final IValidatorPredicate AUTOMATIC = validator -> validator.isAutomatic(); |
| |
| public static class AutomaticValidatorPredicate implements IValidatorPredicate { |
| |
| private final IScriptProject project; |
| |
| public AutomaticValidatorPredicate(IScriptProject project) { |
| this.project = project; |
| } |
| |
| @Override |
| public boolean evaluate(IValidator validator) { |
| return validator.isAutomatic(project); |
| } |
| |
| } |
| |
| public static final IValidatorPredicate ALL = validator -> true; |
| |
| public static IValidator[] getProjectValidators(IScriptProject project, Class validatorType, |
| IValidatorPredicate predicate) { |
| String[] natureIds; |
| try { |
| natureIds = project.getProject().getDescription().getNatureIds(); |
| } catch (CoreException e) { |
| ValidatorsCore.log(e.getStatus()); |
| natureIds = new String[0]; |
| } |
| final List<IValidator> result = new ArrayList(); |
| final IValidatorType[] types = ValidatorRuntime.getValidatorTypes(); |
| for (int i = 0; i < types.length; ++i) { |
| final IValidatorType type = types[i]; |
| if (checkValidatorTypeNature(type, natureIds) && type.supports(validatorType)) { |
| final IValidator[] validators = type.getValidators(); |
| for (int j = 0; j < validators.length; ++j) { |
| final IValidator validator = validators[j]; |
| if (predicate.evaluate(validator) && validator.isValidatorValid(project)) { |
| result.add(validator); |
| } |
| } |
| } |
| } |
| return result.toArray(new IValidator[result.size()]); |
| } |
| |
| /** |
| * @param type |
| * @param natureIds |
| * @return |
| */ |
| private static boolean checkValidatorTypeNature(IValidatorType type, String[] natureIds) { |
| final String natureId = type.getNature(); |
| if (ANY_NATURE.equals(natureId)) { |
| return true; |
| } |
| for (int i = 0; i < natureIds.length; ++i) { |
| if (natureId.equals(natureIds[i])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public static IStatus executeSourceModuleValidators(IScriptProject project, List sourceModules, |
| IValidatorOutput output, IValidatorPredicate predicate, IProgressMonitor monitor) { |
| final IValidator[] validators = getProjectValidators(project, ISourceModuleValidator.class, predicate); |
| if (validators.length != 0) { |
| return executeSourceModuleValidators(project, sourceModules, output, validators, monitor); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| public static IStatus executeSourceModuleValidators(IScriptProject project, List sourceModules, |
| IValidatorOutput output, final IValidator[] validators, IProgressMonitor monitor) { |
| monitor.beginTask(Messages.ValidatorRuntime_runningValidators, validators.length * 100); |
| for (int i = 0; i < validators.length; ++i) { |
| if (monitor.isCanceled()) { |
| return Status.CANCEL_STATUS; |
| } |
| final IValidator validator = validators[i]; |
| final ISourceModuleValidator mValidator = (ISourceModuleValidator) validator.getValidator(project, |
| ISourceModuleValidator.class); |
| if (mValidator != null) { |
| final ISourceModule[] mArray = filterModulesForValidator(sourceModules, validator, monitor); |
| if (monitor.isCanceled()) { |
| return Status.CANCEL_STATUS; |
| } |
| final IProgressMonitor submonitor = new SubProgressMonitor(monitor, 100); |
| if (mArray.length != 0) { |
| mValidator.validate(mArray, output, submonitor); |
| } |
| submonitor.done(); |
| } |
| } |
| monitor.done(); |
| return Status.OK_STATUS; |
| } |
| |
| public static IStatus executeAutomaticResourceValidators(IScriptProject project, List resources, |
| IValidatorOutput output, IProgressMonitor monitor) { |
| return executeResourceValidators(project, resources, output, new AutomaticValidatorPredicate(project), monitor); |
| } |
| |
| public static IStatus executeResourceValidators(IScriptProject project, List resources, IValidatorOutput output, |
| IValidatorPredicate predicate, IProgressMonitor monitor) { |
| final IValidator[] validators = getProjectValidators(project, IResourceValidator.class, predicate); |
| if (validators.length != 0) { |
| final IResource[] resArray = (IResource[]) resources.toArray(new IResource[resources.size()]); |
| monitor.beginTask(Messages.ValidatorRuntime_runningValidators, validators.length * 100); |
| for (int i = 0; i < validators.length; ++i) { |
| if (monitor.isCanceled()) { |
| return Status.CANCEL_STATUS; |
| } |
| final IValidator validator = validators[i]; |
| final IResourceValidator resourceValidator = (IResourceValidator) validator.getValidator(project, |
| IResourceValidator.class); |
| if (resourceValidator != null) { |
| final IProgressMonitor submonitor = new SubProgressMonitor(monitor, 100); |
| resourceValidator.validate(resArray, output, submonitor); |
| submonitor.done(); |
| } |
| } |
| monitor.done(); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * @param project |
| * @param modules |
| * @param resources |
| * @param monitor |
| */ |
| public static void cleanAll(IScriptProject project, ISourceModule[] modules, IResource[] resources, |
| IProgressMonitor monitor) { |
| final IValidatorType[] types = ValidatorRuntime.getValidatorTypes(); |
| for (int i = 0; i < types.length; ++i) { |
| final IValidatorType type = types[i]; |
| final IValidator[] validators = type.getValidators(); |
| for (int j = 0; j < validators.length; ++j) { |
| final IValidator validator = validators[j]; |
| final ISourceModuleValidator smValidator = (ISourceModuleValidator) validator.getValidator(project, |
| ISourceModuleValidator.class); |
| if (smValidator != null) { |
| smValidator.clean(modules); |
| } |
| final IResourceValidator rValidator = (IResourceValidator) validator.getValidator(project, |
| IResourceValidator.class); |
| if (rValidator != null) { |
| rValidator.clean(resources); |
| } |
| } |
| } |
| } |
| |
| public static void fireValidatorChanged() { |
| synchronized (fgValidatorLock) { |
| isInitialized = false; |
| } |
| Object[] listeners = fgValidatorListeners.getListeners(); |
| for (int i = 0; i < listeners.length; i++) { |
| IValidatorChangedListener listener = (IValidatorChangedListener) listeners[i]; |
| listener.validatorChanged(); |
| } |
| } |
| |
| } |