1 /*******************************************************************************
2 * Copyright (c) 2007, 2011 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.issues.ui.handler;
14 import java.lang.reflect.InvocationTargetException;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.List;
22 import org.eclipse.core.commands.AbstractHandler;
23 import org.eclipse.core.commands.ExecutionEvent;
24 import org.eclipse.core.commands.ExecutionException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.OperationCanceledException;
27 import org.eclipse.core.runtime.SubMonitor;
28 import org.eclipse.jface.operation.IRunnableWithProgress;
29 import org.eclipse.ui.PlatformUI;
30 import org.simantics.Simantics;
31 import org.simantics.SleepingDatabaseJob;
32 import org.simantics.db.Issue;
33 import org.simantics.db.ReadGraph;
34 import org.simantics.db.RequestProcessor;
35 import org.simantics.db.Resource;
36 import org.simantics.db.Session;
37 import org.simantics.db.common.request.Queries;
38 import org.simantics.db.common.request.ResourceRead;
39 import org.simantics.db.common.utils.ListUtils;
40 import org.simantics.db.exception.DatabaseException;
41 import org.simantics.db.layer0.request.PossibleActiveModel;
42 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
43 import org.simantics.db.layer0.util.SessionGarbageCollection;
44 import org.simantics.issues.common.BatchIssueSource;
45 import org.simantics.issues.common.BatchIssueValidationContext;
46 import org.simantics.issues.common.ManagedIssues;
47 import org.simantics.issues.common.SelectedModelBatchIssueSources;
48 import org.simantics.issues.ontology.IssueResource;
49 import org.simantics.issues.preferences.IssuePreferenceUtil;
50 import org.simantics.modeling.utils.BatchValidations;
51 import org.simantics.utils.ui.ExceptionUtils;
54 * @author Tuukka Lehtonen
56 public class RunActiveValidations extends AbstractHandler {
59 public Object execute(ExecutionEvent event) throws ExecutionException {
62 } catch (DatabaseException e) {
63 throw new ExecutionException("Error while running active validations", e);
68 public static void run() throws DatabaseException {
69 Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
74 public static void run(Resource model) {
78 public static void run(Resource model, Runnable postValidation) {
80 final Session session = Simantics.getSession();
82 // 1. query for which composites to run the validation
83 final Collection<BatchIssueSource> validations = new ArrayList<>();
84 final BatchIssueValidationContext context = new BatchIssueValidationContext();
87 SleepingDatabaseJob dbLock = new SleepingDatabaseJob(Messages.RunActiveValidations_ValidationPreparation).scheduleAndWaitForRunning();
89 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
91 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
94 toBatchIssueSources(session,
95 session.syncRequest(new SelectedModelBatchIssueSources(model)),
98 SubMonitor.convert(monitor, Messages.RunActiveValidations_MonitorPreparingResourcesForValidation, 100);
99 context.contexts = Collections.singletonList(model);
100 context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, model);
102 if (monitor.isCanceled())
103 throw new OperationCanceledException();
104 } catch (DatabaseException e) {
105 throw new InvocationTargetException(e);
112 dbLock.disposeAndJoin();
114 } catch (InvocationTargetException e) {
115 if (e.getTargetException() instanceof OperationCanceledException)
117 ExceptionUtils.logAndShowError(e.getTargetException());
119 } catch (InterruptedException e) {
120 // Operation cancelled, ignore.
124 if(!validations.isEmpty() && !context.contexts.isEmpty())
125 run(postValidation, validations, context);
129 static Collection<BatchIssueSource> toBatchIssueSources(RequestProcessor processor, Collection<Resource> sources, Collection<BatchIssueSource> result) throws DatabaseException {
130 for (Resource source : sources) {
131 BatchIssueSource bis = processor.syncRequest(Queries.adapt(source, BatchIssueSource.class, true));
138 public static void run(Runnable postValidation, final Collection<BatchIssueSource> validations, final BatchIssueValidationContext context) {
139 // Run the validations for the selected composites
140 SleepingDatabaseJob dbLock = new SleepingDatabaseJob(Messages.RunActiveValidations_Validation);
142 dbLock.scheduleAndWaitForRunning();
144 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
146 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
148 SubMonitor progress = SubMonitor.convert(monitor, Messages.RunActiveValidations_ValidateModel, 100);
149 int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
150 int writtenIssues = 0;
151 for (BatchIssueSource source : validations) {
152 Map<Resource, Set<Issue>> results = BatchValidations.validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), source, context);
153 if (progress.isCanceled())
154 throw new OperationCanceledException();
156 Collection<Resource> removed = Simantics.getSession().syncRequest(new ResourceRead<Collection<Resource>>(source.getResource()) {
158 public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
159 IssueResource ISSUE = IssueResource.getInstance(graph);
160 ArrayList<Resource> result = new ArrayList<>();
161 for (Resource issue : graph.syncRequest(new ManagedIssues(resource))) {
162 Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
163 List<Resource> l = ListUtils.toList(graph, list);
165 Resource mainContext = l.get(0);
166 if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
167 result.add(mainContext);
174 for(Resource r : removed) {
175 results.put(r, Collections.<Issue>emptySet());
177 if (progress.isCanceled())
178 throw new OperationCanceledException();
180 int wroteIssues = BatchValidations.store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), source.getResource(), results, Math.max(0, maxWrittenIssues - writtenIssues));
181 writtenIssues += wroteIssues;
183 // Try to keep resource consumption down.
184 SessionGarbageCollection.gc(null, Simantics.getSession(), true, null);
187 } catch (OperationCanceledException e) {
189 } catch (Exception e) {
190 throw new InvocationTargetException(e);
197 dbLock.disposeAndJoin();
200 if (postValidation != null)
201 postValidation.run();
203 } catch (OperationCanceledException e) {
204 // Operation cancelled, ignore.
205 } catch (InvocationTargetException e) {
206 ExceptionUtils.logAndShowError(e.getTargetException());
207 } catch (InterruptedException e) {
208 // Operation cancelled, ignore.