/** * Copyright (c) 2004-2008 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 - Initial API and implementation */ package org.eclipse.emf.edit.ui.action; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ISetSelectionTarget; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.ui.dialogs.DiagnosticDialog; import org.eclipse.emf.common.ui.viewer.IViewerProvider; 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.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.ecore.util.EObjectValidator; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.emf.edit.provider.IItemLabelProvider; import org.eclipse.emf.edit.ui.EMFEditUIPlugin; public class ValidateAction extends Action implements ISelectionChangedListener { protected ISelectionProvider selectionProvider; protected List<EObject> selectedObjects; protected EditingDomain domain; public ValidateAction() { super(EMFEditUIPlugin.INSTANCE.getString("_UI_Validate_menu_item")); setDescription(EMFEditUIPlugin.INSTANCE.getString("_UI_Validate_simple_description")); } @Override public void run() { final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() { public void run(final IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException { try { final Diagnostic diagnostic = validate(progressMonitor); shell.getDisplay().asyncExec (new Runnable() { public void run() { if (progressMonitor.isCanceled()) { handleDiagnostic(Diagnostic.CANCEL_INSTANCE); } else { handleDiagnostic(diagnostic); } } }); } finally { progressMonitor.done(); } } }; 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); } } /** * This simply execute the command. */ protected Diagnostic validate(IProgressMonitor progressMonitor) { int selectionSize = selectedObjects.size(); int count = selectionSize; for (EObject eObject : selectedObjects) { for (Iterator<?> i = eObject.eAllContents(); i.hasNext(); i.next()) { ++count; } } progressMonitor.beginTask("", count); AdapterFactory adapterFactory = domain instanceof AdapterFactoryEditingDomain ? ((AdapterFactoryEditingDomain)domain).getAdapterFactory() : null; Diagnostician diagnostician = createDiagnostician(adapterFactory, progressMonitor); BasicDiagnostic diagnostic; if (selectionSize == 1) { diagnostic = diagnostician.createDefaultDiagnostic(selectedObjects.get(0)); } else { diagnostic = new BasicDiagnostic (EObjectValidator.DIAGNOSTIC_SOURCE, 0, EMFEditUIPlugin.INSTANCE.getString("_UI_DiagnosisOfNObjects_message", new String[] { Integer.toString(selectionSize) }), selectedObjects.toArray() ); } Map<Object, Object> context = diagnostician.createDefaultContext(); for (EObject eObject : selectedObjects) { progressMonitor.setTaskName(EMFEditUIPlugin.INSTANCE.getString("_UI_Validating_message", new Object [] {diagnostician.getObjectLabel(eObject)})); diagnostician.validate(eObject, diagnostic, context); } return diagnostic; } protected Diagnostician createDiagnostician(final AdapterFactory adapterFactory, final IProgressMonitor progressMonitor) { return new Diagnostician() { @Override public String getObjectLabel(EObject eObject) { if (adapterFactory != null && !eObject.eIsProxy()) { IItemLabelProvider itemLabelProvider = (IItemLabelProvider)adapterFactory.adapt(eObject, IItemLabelProvider.class); if (itemLabelProvider != null) { return itemLabelProvider.getText(eObject); } } return super.getObjectLabel(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); } }; } protected void handleDiagnostic(Diagnostic diagnostic) { int severity = diagnostic.getSeverity(); String title = null; String message = null; if (severity == Diagnostic.ERROR || severity == Diagnostic.WARNING) { title = EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_title"); message = EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_message"); } else { title = EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationResults_title"); message = EMFEditUIPlugin.INSTANCE.getString(severity == Diagnostic.OK ? "_UI_ValidationOK_message" : "_UI_ValidationResults_message"); } int result = 0; if (diagnostic.getSeverity() == Diagnostic.OK) { MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, message); result = Window.CANCEL; } else { result = DiagnosticDialog.open (PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, message, diagnostic); } if (result == Window.OK) { if (!diagnostic.getChildren().isEmpty()) { List<?> data = (diagnostic.getChildren().get(0)).getData(); if (!data.isEmpty() && data.get(0) instanceof EObject) { Object part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart(); if (part instanceof ISetSelectionTarget) { ((ISetSelectionTarget)part).selectReveal(new StructuredSelection(data.get(0))); } else if (part instanceof IViewerProvider) { Viewer viewer = ((IViewerProvider)part).getViewer(); if (viewer != null) { viewer.setSelection(new StructuredSelection(data.get(0)), true); } } } } } } public void selectionChanged(SelectionChangedEvent event) { selectionProvider = event.getSelectionProvider(); if (event.getSelection() instanceof IStructuredSelection) { setEnabled(updateSelection((IStructuredSelection)event.getSelection())); } else { setEnabled(false); } } public boolean updateSelection(IStructuredSelection selection) { selectedObjects = new ArrayList<EObject>(); for (Iterator<?> objects = selection.iterator(); objects.hasNext(); ) { Object object = AdapterFactoryEditingDomain.unwrap(objects.next()); if (object instanceof EObject) { selectedObjects.add((EObject)object); } else if (object instanceof Resource) { selectedObjects.addAll(((Resource)object).getContents()); } else { return false; } } selectedObjects = EcoreUtil.filterDescendants(selectedObjects); return !selectedObjects.isEmpty(); } /** * @since 2.1.0 */ public void setActiveWorkbenchPart(IWorkbenchPart workbenchPart) { if (workbenchPart instanceof IEditingDomainProvider) { domain = ((IEditingDomainProvider)workbenchPart).getEditingDomain(); } } }