/** * Copyright (c) 2012 committers of YAKINDU 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.ui.editor.validation; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.transaction.RunnableWithResult; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.validation.CheckMode; import org.eclipse.xtext.validation.IResourceValidator; import org.eclipse.xtext.validation.Issue; import org.yakindu.sct.model.sgraph.resource.AbstractSCTResource; import org.yakindu.sct.ui.editor.DiagramActivator; /** * The default implementation executes the validation within a readonly * transaction on the transactional editing domain. during validation the model * is locked and can not be changed. * * @author andreas muelder - Initial contribution and API * */ public class DefaultValidationJob extends ValidationJob { public static class TransactionalValidationRunner extends RunnableWithResult.Impl<List<Issue>> { private IResourceValidator validator; private Resource resource; private CheckMode checkMode; private CancelIndicator indicator; public TransactionalValidationRunner(IResourceValidator validator, Resource resource, CheckMode checkMode, CancelIndicator indicator) { this.validator = validator; this.resource = resource; this.checkMode = checkMode; this.indicator = indicator; } public void run() { try { List<Issue> result = validator.validate(resource, checkMode, indicator); setResult(result); setStatus(Status.OK_STATUS); } catch (OperationCanceledException ex) { setStatus(Status.CANCEL_STATUS); } } } @Override protected IStatus runInternal(final IProgressMonitor monitor) { try { if (!resource.isLoaded()) return Status.CANCEL_STATUS; if (resource instanceof AbstractSCTResource) { relinkModel(monitor, (AbstractSCTResource) resource); } if (monitor.isCanceled()) return Status.CANCEL_STATUS; TransactionalValidationRunner runner = new TransactionalValidationRunner(validator, resource, CheckMode.FAST_ONLY, new CancelIndicator() { public boolean isCanceled() { return monitor.isCanceled(); } }); TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(resource); if (editingDomain == null) return Status.CANCEL_STATUS; try { editingDomain.runExclusive(runner); } catch (Throwable ex) { // Since xtext 2.8 this may throw an OperationCanceledError return Status.CANCEL_STATUS; } final List<Issue> issues = runner.getResult(); if (issues == null) return Status.CANCEL_STATUS; validationIssueProcessor.processIssues(issues, monitor); } catch (Exception ex) { ex.printStackTrace(); return new Status(IStatus.ERROR, DiagramActivator.PLUGIN_ID, ex.getMessage()); } return Status.OK_STATUS; } protected void relinkModel(final IProgressMonitor monitor, final AbstractSCTResource eResource) throws ExecutionException { AbstractTransactionalCommand cmd = new AbstractTransactionalCommand(TransactionUtil.getEditingDomain(eResource), "", null) { @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { eResource.linkSpecificationElements(); return CommandResult.newOKCommandResult(); } }; cmd.execute(monitor, null); } }