/** * <copyright> * * Copyright (c) 2004, 2009 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 * * </copyright> * * $Id: ValidateAction.java,v 1.27 2008/08/08 17:27:59 marcelop Exp $ */ package net.enilink.komma.edit.ui.action; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ISetSelectionTarget; import net.enilink.komma.common.AbstractKommaPlugin; import net.enilink.komma.common.adapter.IAdapterFactory; import net.enilink.komma.common.ui.EclipseUtil; import net.enilink.komma.common.ui.dialogs.DiagnosticDialog; import net.enilink.komma.common.util.BasicDiagnostic; import net.enilink.komma.common.util.Diagnostic; import net.enilink.komma.common.util.DiagnosticChain; import net.enilink.komma.edit.domain.AdapterFactoryEditingDomain; import net.enilink.komma.edit.domain.IEditingDomain; import net.enilink.komma.edit.domain.IEditingDomainProvider; import net.enilink.komma.edit.provider.IItemLabelProvider; import net.enilink.komma.edit.ui.KommaEditUIPlugin; import net.enilink.komma.edit.ui.util.EditUIMarkerHelper; import net.enilink.komma.edit.ui.util.EditUIUtil; import net.enilink.komma.em.concepts.IClass; import net.enilink.komma.em.concepts.IResource; import net.enilink.komma.model.IModel; import net.enilink.komma.model.IObject; import net.enilink.komma.model.ModelPlugin; import net.enilink.komma.model.ModelUtil; import net.enilink.komma.model.validation.Diagnostician; import net.enilink.komma.model.validation.IValidator; import net.enilink.komma.core.URIs; public class ValidateAction extends AbstractActionHandler { public static final String DIAGNOSTIC_SOURCE = "net.enilink.komma"; public static class EclipseResourcesUtil extends EditUIMarkerHelper { public IRunnableWithProgress getWorkspaceModifyOperation( IRunnableWithProgress runnableWithProgress) { return EclipseUtil .createWorkspaceModifyOperation(runnableWithProgress); } @Override protected String getMarkerID() { return IValidator.MARKER; } public void createMarkers(IModel model, Diagnostic diagnostic) { try { createMarkers(getFile(model), diagnostic, null); } catch (CoreException e) { KommaEditUIPlugin.INSTANCE.log(e); } } @Override protected String composeMessage(Diagnostic diagnostic, Diagnostic parentDiagnostic) { String message = diagnostic.getMessage(); if (parentDiagnostic != null) { String parentMessage = parentDiagnostic.getMessage(); if (parentMessage != null) { message = message != null ? parentMessage + ". " + message : parentMessage; } } return message; } @Override protected void adjustMarker(IMarker marker, Diagnostic diagnostic, Diagnostic parentDiagnostic) throws CoreException { List<?> data = diagnostic.getData(); StringBuilder relatedURIs = new StringBuilder(); boolean first = true; for (Object object : data) { if (object instanceof IObject) { IObject iObject = (IObject) object; if (first) { first = false; marker.setAttribute(IValidator.URI_ATTRIBUTE, iObject .getURI() == null ? "" : iObject.getURI() .toString()); } else { if (relatedURIs.length() != 0) { relatedURIs.append(' '); } relatedURIs.append(URIs.encodeFragment( iObject.getURI() == null ? "" : iObject .getURI().toString(), false)); } } } if (relatedURIs.length() > 0) { marker.setAttribute(IValidator.RELATED_URIS_ATTRIBUTE, relatedURIs.toString()); } super.adjustMarker(marker, diagnostic, parentDiagnostic); } } protected ISelectionProvider selectionProvider; protected List<IObject> selectedObjects; protected IEditingDomain domain; protected EclipseResourcesUtil eclipseResourcesUtil = AbstractKommaPlugin.IS_RESOURCES_BUNDLE_AVAILABLE ? new EclipseResourcesUtil() : null; public ValidateAction(IWorkbenchPage page) { super(page); setText(KommaEditUIPlugin.INSTANCE.getString("_UI_Validate_menu_item")); setDescription(KommaEditUIPlugin.INSTANCE .getString("_UI_Validate_simple_description")); } @Override public void doRun(IProgressMonitor progressMonitor) { 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(); } } }; if (eclipseResourcesUtil != null) { runnableWithProgress = eclipseResourcesUtil .getWorkspaceModifyOperation(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) { KommaEditUIPlugin.INSTANCE.log(exception); } } /** * This simply execute the command. */ protected Diagnostic validate(IProgressMonitor progressMonitor) { int selectionSize = selectedObjects.size(); int count = selectionSize; for (IObject iObject : selectedObjects) { for (Iterator<?> i = iObject.getContents().iterator(); i.hasNext(); i .next()) { ++count; } } progressMonitor.beginTask("", count); IAdapterFactory 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(DIAGNOSTIC_SOURCE, 0, KommaEditUIPlugin.INSTANCE.getString( "_UI_DiagnosisOfNObjects_message", new Object[] { Integer.toString(selectionSize) }), selectedObjects.toArray()); } Map<Object, Object> context = diagnostician.createDefaultContext(); for (IObject eObject : selectedObjects) { progressMonitor.setTaskName(KommaEditUIPlugin.INSTANCE.getString( "_UI_Validating_message", new Object[] { diagnostician.getObjectLabel(eObject) })); diagnostician.validate(eObject, diagnostic, context); } return diagnostic; } protected Diagnostician createDiagnostician( final IAdapterFactory adapterFactory, final IProgressMonitor progressMonitor) { return new Diagnostician(ModelPlugin.getDefault() .getValidatorRegistry()) { @Override public String getObjectLabel(IResource object) { if (adapterFactory != null) { IItemLabelProvider itemLabelProvider = (IItemLabelProvider) adapterFactory .adapt(object, IItemLabelProvider.class); if (itemLabelProvider != null) { return itemLabelProvider.getText(object); } } return super.getObjectLabel(object); } @Override public boolean validate(Collection<? extends IClass> classes, IResource object, DiagnosticChain diagnostics, Map<Object, Object> context) { progressMonitor.worked(1); return super.validate(classes, object, 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 = KommaEditUIPlugin.INSTANCE .getString("_UI_ValidationProblems_title"); message = KommaEditUIPlugin.INSTANCE .getString("_UI_ValidationProblems_message"); } else { title = KommaEditUIPlugin.INSTANCE .getString("_UI_ValidationResults_title"); message = KommaEditUIPlugin.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); } IModel model = eclipseResourcesUtil != null ? domain.getModelSet() .getModels().iterator().next() : null; if (model != null) { eclipseResourcesUtil.deleteMarkers(model); } if (result == Window.OK) { if (!diagnostic.getChildren().isEmpty()) { List<?> data = (diagnostic.getChildren().get(0)).getData(); if (!data.isEmpty() && data.get(0) instanceof IObject) { Object part = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage() .getActivePart(); if (part instanceof ISetSelectionTarget) { ((ISetSelectionTarget) part) .selectReveal(new StructuredSelection(data .get(0))); } else if (part instanceof ISelectionProvider) { ((ISelectionProvider) part) .setSelection(new StructuredSelection(data .get(0))); } } } if (model != null) { for (Diagnostic childDiagnostic : diagnostic.getChildren()) { eclipseResourcesUtil.createMarkers(model, childDiagnostic); } } } } @Override public void refresh() { IStructuredSelection selection = getStructuredSelection(); selectedObjects = new ArrayList<IObject>(); for (Iterator<?> objects = selection.iterator(); objects.hasNext();) { Object object = AdapterFactoryEditingDomain.unwrap(objects.next()); if (object instanceof IObject) { selectedObjects.add((IObject) object); } else { setEnabled(false); return; } } selectedObjects = ModelUtil.filterDescendants(selectedObjects); setEnabled(!selectedObjects.isEmpty()); } public void setWorkbenchPart(IWorkbenchPart workbenchPart) { super.setWorkbenchPart(workbenchPart); domain = AdapterFactoryEditingDomain.getEditingDomainFor(workbenchPart); } }