1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2011 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.issues.ui.handler;
\r
14 import java.lang.reflect.InvocationTargetException;
\r
15 import java.util.ArrayList;
\r
16 import java.util.Collection;
\r
17 import java.util.Collections;
\r
18 import java.util.List;
\r
19 import java.util.Map;
\r
20 import java.util.Set;
\r
22 import org.eclipse.core.commands.AbstractHandler;
\r
23 import org.eclipse.core.commands.ExecutionEvent;
\r
24 import org.eclipse.core.commands.ExecutionException;
\r
25 import org.eclipse.core.runtime.IProgressMonitor;
\r
26 import org.eclipse.core.runtime.OperationCanceledException;
\r
27 import org.eclipse.core.runtime.SubMonitor;
\r
28 import org.eclipse.jface.operation.IRunnableWithProgress;
\r
29 import org.eclipse.ui.PlatformUI;
\r
30 import org.simantics.Simantics;
\r
31 import org.simantics.SleepingDatabaseJob;
\r
32 import org.simantics.db.Issue;
\r
33 import org.simantics.db.ReadGraph;
\r
34 import org.simantics.db.Resource;
\r
35 import org.simantics.db.Session;
\r
36 import org.simantics.db.common.request.Queries;
\r
37 import org.simantics.db.common.request.ResourceRead;
\r
38 import org.simantics.db.common.utils.ListUtils;
\r
39 import org.simantics.db.exception.DatabaseException;
\r
40 import org.simantics.db.layer0.request.PossibleActiveModel;
\r
41 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
\r
42 import org.simantics.db.layer0.util.SessionGarbageCollection;
\r
43 import org.simantics.issues.common.BatchIssueSource;
\r
44 import org.simantics.issues.common.BatchIssueValidationContext;
\r
45 import org.simantics.issues.common.ManagedIssues;
\r
46 import org.simantics.issues.common.SelectedModelBatchIssueSources;
\r
47 import org.simantics.issues.ontology.IssueResource;
\r
48 import org.simantics.issues.preferences.IssuePreferenceUtil;
\r
49 import org.simantics.modeling.utils.BatchValidations;
\r
50 import org.simantics.utils.ui.ExceptionUtils;
\r
53 * @author Tuukka Lehtonen
\r
55 public class RunActiveValidations extends AbstractHandler {
\r
58 public Object execute(ExecutionEvent event) throws ExecutionException {
\r
59 Runnable postValidation = null;
\r
60 run(postValidation);
\r
64 public void run(Runnable postValidation) {
\r
66 final Session session = Simantics.getSession();
\r
68 // 1. query for which composites to run the validation
\r
69 final Collection<BatchIssueSource> validations = new ArrayList<BatchIssueSource>();
\r
70 final BatchIssueValidationContext context = new BatchIssueValidationContext();
\r
73 SleepingDatabaseJob dbLock = new SleepingDatabaseJob("Validation Preparation").scheduleAndWaitForRunning();
\r
75 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
\r
77 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
\r
79 Resource model = session.sync(new PossibleActiveModel(Simantics.getProjectResource()));
\r
80 if(model == null) return;
\r
82 Collection<Resource> activeSources = session.syncRequest(new SelectedModelBatchIssueSources(model));
\r
83 for(Resource source : activeSources) {
\r
84 BatchIssueSource bis = session.syncRequest(Queries.adapt(source, BatchIssueSource.class, true));
\r
86 validations.add(bis);
\r
89 SubMonitor.convert(monitor, "Preparing resources for validation", 100);
\r
90 context.contexts = Collections.singletonList(model);
\r
91 context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, model);
\r
93 if (monitor.isCanceled())
\r
94 throw new OperationCanceledException();
\r
95 } catch (DatabaseException e) {
\r
96 throw new InvocationTargetException(e);
\r
103 dbLock.disposeAndJoin();
\r
105 } catch (InvocationTargetException e) {
\r
106 if (e.getTargetException() instanceof OperationCanceledException)
\r
108 ExceptionUtils.logAndShowError(e.getTargetException());
\r
110 } catch (InterruptedException e) {
\r
111 // Operation cancelled, ignore.
\r
115 if(!validations.isEmpty() && !context.contexts.isEmpty())
\r
116 run(postValidation, validations, context);
\r
120 public static void run(Runnable postValidation, final Collection<BatchIssueSource> validations, final BatchIssueValidationContext context) {
\r
121 // Run the validations for the selected composites
\r
122 SleepingDatabaseJob dbLock = new SleepingDatabaseJob("Validation");
\r
124 dbLock.scheduleAndWaitForRunning();
\r
126 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
\r
128 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
\r
130 SubMonitor progress = SubMonitor.convert(monitor, "Validate Model", 100);
\r
131 int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
\r
132 int writtenIssues = 0;
\r
133 for (BatchIssueSource source : validations) {
\r
134 Map<Resource, Set<Issue>> results = BatchValidations.validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), source, context);
\r
135 if (progress.isCanceled())
\r
136 throw new OperationCanceledException();
\r
138 Collection<Resource> removed = Simantics.getSession().syncRequest(new ResourceRead<Collection<Resource>>(source.getResource()) {
\r
140 public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
\r
141 IssueResource ISSUE = IssueResource.getInstance(graph);
\r
142 ArrayList<Resource> result = new ArrayList<Resource>();
\r
143 for (Resource issue : graph.syncRequest(new ManagedIssues(resource))) {
\r
144 Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
\r
145 List<Resource> l = ListUtils.toList(graph, list);
\r
146 if (l.size() > 0) {
\r
147 Resource mainContext = l.get(0);
\r
148 if (!graph.hasStatement(mainContext))
\r
149 result.add(mainContext);
\r
156 for(Resource r : removed) {
\r
157 results.put(r, Collections.<Issue>emptySet());
\r
159 if (progress.isCanceled())
\r
160 throw new OperationCanceledException();
\r
162 int wroteIssues = BatchValidations.store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), source.getResource(), results, Math.max(0, maxWrittenIssues - writtenIssues));
\r
163 writtenIssues += wroteIssues;
\r
165 // Try to keep resource consumption down.
\r
166 SessionGarbageCollection.gc(null, Simantics.getSession(), true, null);
\r
169 } catch (OperationCanceledException e) {
\r
171 } catch (Exception e) {
\r
172 throw new InvocationTargetException(e);
\r
179 dbLock.disposeAndJoin();
\r
182 if (postValidation != null)
\r
183 postValidation.run();
\r
185 } catch (OperationCanceledException e) {
\r
186 // Operation cancelled, ignore.
\r
187 } catch (InvocationTargetException e) {
\r
188 ExceptionUtils.logAndShowError(e.getTargetException());
\r
189 } catch (InterruptedException e) {
\r
190 // Operation cancelled, ignore.
\r