| /** |
| * <copyright> |
| * |
| * Copyright (c) 2004-2008 IBM Corporation and others. |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-v2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| * |
| * </copyright> |
| * |
| * $Id: ValidateAction.java,v 1.28 2009/04/30 14:24:52 emerks Exp $ |
| */ |
| package org.eclipse.egf.core.ui.diagnostic; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.egf.common.helper.EMFHelper; |
| import org.eclipse.egf.common.ui.helper.EditorHelper; |
| import org.eclipse.egf.core.platform.loader.IBundleClassLoader; |
| import org.eclipse.egf.core.preferences.IEGFModelConstants; |
| import org.eclipse.egf.core.ui.EGFCoreUIPlugin; |
| import org.eclipse.egf.core.ui.l10n.CoreUIMessages; |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.common.util.DiagnosticChain; |
| import org.eclipse.emf.common.util.UniqueEList; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.Diagnostician; |
| import org.eclipse.emf.edit.ui.EMFEditUIPlugin; |
| import org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.pde.core.plugin.IPluginModelBase; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation; |
| |
| public class EGFValidator { |
| |
| private static EclipseResourcesUtil __eclipseResourcesUtil = new EclipseResourcesUtil(); |
| |
| private Map<Resource, UniqueEList<Diagnostic>> _diagnostics; |
| |
| private IBundleClassLoader _defaultLoader; |
| |
| private List<? extends EObject> _eObjects = new ArrayList<EObject>(); |
| |
| /** |
| * Standalone validator |
| */ |
| public EGFValidator(List<? extends EObject> eObjects) { |
| _eObjects = eObjects; |
| } |
| |
| /** |
| * Validator with a default bundle class loader |
| */ |
| public EGFValidator(List<? extends EObject> eObjects, IBundleClassLoader defaultLoader) { |
| _eObjects = eObjects; |
| _defaultLoader = defaultLoader; |
| } |
| |
| public Diagnostic validate() { |
| |
| // Nothing to do |
| if (_eObjects == null || _eObjects.size() == 0) { |
| return Diagnostic.OK_INSTANCE; |
| } |
| _diagnostics = new HashMap<Resource, UniqueEList<Diagnostic>>(); |
| final Diagnostic[] diagnostic = new Diagnostic[1]; |
| final Shell shell = EGFCoreUIPlugin.getActiveWorkbenchShell(); |
| |
| IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() { |
| |
| public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| try { |
| // Validate |
| diagnostic[0] = validate(monitor); |
| shell.getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| if (monitor.isCanceled()) { |
| return; |
| } |
| // Reset Markers |
| for (Resource resource : _diagnostics.keySet()) { |
| __eclipseResourcesUtil.deleteMarkers(resource); |
| } |
| // Handle Diagnostic if applicable |
| int severity = diagnostic[0].getSeverity(); |
| if (severity == Diagnostic.ERROR || severity == Diagnostic.WARNING) { |
| handleDiagnostic(EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_title"), EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_message"), diagnostic[0]); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| // Put Markers |
| for (Resource resource : _diagnostics.keySet()) { |
| for (Diagnostic childDiagnostic : _diagnostics.get(resource)) { |
| __eclipseResourcesUtil.createMarkers(resource, childDiagnostic); |
| } |
| } |
| } |
| }); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| |
| runnableWithProgress = new WorkspaceModifyDelegatingOperation(runnableWithProgress); |
| |
| try { |
| // This runs the operation, and shows progress. |
| // (It appears to be a bad thing to fork this onto another thread.) |
| // |
| new ProgressMonitorDialog(shell).run(true, true, runnableWithProgress); |
| } catch (Exception exception) { |
| EMFEditUIPlugin.INSTANCE.log(exception); |
| } |
| |
| return diagnostic[0]; |
| |
| } |
| |
| /** |
| * This simply execute the command. |
| */ |
| protected Diagnostic validate(IProgressMonitor monitor) { |
| int selectionSize = _eObjects.size(); |
| int count = selectionSize; |
| for (EObject eObject : _eObjects) { |
| for (Iterator<EObject> i = eObject.eAllContents(); i.hasNext();) { |
| // initialize _diagnostics with existing resource, it will be used to reset markers |
| EObject innerEObject = i.next(); |
| if (innerEObject.eResource() != null) { |
| if (_diagnostics.get(innerEObject.eResource()) == null) { |
| _diagnostics.put(innerEObject.eResource(), new UniqueEList<Diagnostic>()); |
| } |
| } |
| ++count; |
| } |
| } |
| monitor.beginTask("", count); //$NON-NLS-1$ |
| Diagnostician diagnostician = createDiagnostician(monitor); |
| String message = NLS.bind(CoreUIMessages._UI_DiagnosisOfNObjects_message, Integer.toString(selectionSize)); |
| if (_eObjects.size() == 1) { |
| message = NLS.bind(CoreUIMessages._UI_DiagnosisOfNObject_message, EMFHelper.getText(_eObjects.get(0))); |
| } |
| BasicDiagnostic diagnostic = new BasicDiagnostic(EGFCoreUIPlugin.getDefault().getPluginID(), 0, message, _eObjects.toArray()); |
| Map<Object, Object> context = diagnostician.createDefaultContext(); |
| // Preferences |
| IPreferenceStore store = EGFCoreUIPlugin.getDefault().getPreferenceStore(); |
| if (store.getBoolean(IEGFModelConstants.VALIDATE_TYPES)) { |
| context.put(IEGFModelConstants.VALIDATE_TYPES, Boolean.TRUE); |
| } else { |
| context.put(IEGFModelConstants.VALIDATE_TYPES, Boolean.FALSE); |
| } |
| // Default Bundle Class Loader |
| if (_defaultLoader != null) { |
| context.put(IBundleClassLoader.DEFAULT_BUNDLE_CLASS_LOADER, _defaultLoader); |
| } |
| // Bundle Class Loader Map |
| context.put(IBundleClassLoader.BUNDLE_CLASS_LOADER_MAP, new HashMap<IPluginModelBase, IBundleClassLoader>()); |
| // Validation |
| for (EObject eObject : _eObjects) { |
| monitor.setTaskName(EMFEditUIPlugin.INSTANCE.getString("_UI_Validating_message", new Object[] { diagnostician.getObjectLabel(eObject)})); //$NON-NLS-1$ |
| diagnostician.validate(eObject, diagnostic, context); |
| } |
| // Populate diagnostics per Resource |
| for (Diagnostic childDiagnostic : diagnostic.getChildren()) { |
| List<?> data = childDiagnostic.getData(); |
| if (data.isEmpty() == false && data.get(0) instanceof EObject && ((EObject) data.get(0)).eResource() != null) { |
| EObject eObject = (EObject) data.get(0); |
| UniqueEList<Diagnostic> diagnostics = _diagnostics.get(eObject.eResource()); |
| // it shouldn't be null at this stage as we have already initialized the map |
| if (diagnostics == null) { |
| diagnostics = new UniqueEList<Diagnostic>(); |
| _diagnostics.put(eObject.eResource(), diagnostics); |
| } |
| diagnostics.add(childDiagnostic); |
| } |
| } |
| return diagnostic; |
| } |
| |
| protected Diagnostician createDiagnostician(final IProgressMonitor progressMonitor) { |
| return new Diagnostician() { |
| |
| @Override |
| public String getObjectLabel(EObject eObject) { |
| return EMFHelper.getText(eObject); |
| } |
| |
| @Override |
| public boolean validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) { |
| progressMonitor.worked(1); |
| return super.validate(eClass, eObject, diagnostics, context); |
| } |
| }; |
| } |
| |
| public static void handleDiagnostic(String title, String message, Diagnostic diagnostic) { |
| // Everything is fine |
| if (diagnostic.getSeverity() == Diagnostic.OK) { |
| return; |
| } |
| // Display Dialog |
| int result = 0; |
| EGFDiagnosticDialog dialog = new EGFDiagnosticDialog(EGFCoreUIPlugin.getActiveWorkbenchShell(), title, message, diagnostic, Diagnostic.OK | Diagnostic.INFO | Diagnostic.WARNING | Diagnostic.ERROR); |
| result = dialog.open(); |
| // Dialog has been canceled |
| if (result != Window.OK) { |
| return; |
| } |
| // Nothing to process |
| if (dialog.getSelection() == null || dialog.getSelection().isEmpty()) { |
| return; |
| } |
| // Select and reveal |
| Map<Resource, List<EObject>> resources = new HashMap<Resource, List<EObject>>(); |
| // Process selected Diagnostics |
| for (Diagnostic innerDiagnostic : dialog.getSelection()) { |
| List<?> data = innerDiagnostic.getData(); |
| if (data.isEmpty() == false && data.get(0) instanceof EObject && ((EObject) data.get(0)).eResource() != null) { |
| EObject eObject = (EObject) data.get(0); |
| List<EObject> eObjects = resources.get(eObject.eResource()); |
| if (eObjects == null) { |
| eObjects = new UniqueEList<EObject>(); |
| resources.put(eObject.eResource(), eObjects); |
| } |
| eObjects.add(eObject); |
| } |
| } |
| // Open and select |
| EditorHelper.openEditorsAndSelect(resources); |
| } |
| |
| } |