]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/RunActiveValidations.java
Pass model instead of null
[simantics/platform.git] / bundles / org.simantics.issues.ui / src / org / simantics / issues / ui / handler / RunActiveValidations.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2019 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *     Semantum Oy - Reorganization
12  *******************************************************************************/
13 package org.simantics.issues.ui.handler;
14
15 import java.lang.reflect.InvocationTargetException;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import org.eclipse.core.commands.AbstractHandler;
24 import org.eclipse.core.commands.ExecutionEvent;
25 import org.eclipse.core.commands.ExecutionException;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.OperationCanceledException;
28 import org.eclipse.core.runtime.SubMonitor;
29 import org.eclipse.jface.operation.IRunnableWithProgress;
30 import org.eclipse.ui.PlatformUI;
31 import org.simantics.Simantics;
32 import org.simantics.SleepingDatabaseJob;
33 import org.simantics.db.Issue;
34 import org.simantics.db.ReadGraph;
35 import org.simantics.db.RequestProcessor;
36 import org.simantics.db.Resource;
37 import org.simantics.db.Session;
38 import org.simantics.db.common.request.Queries;
39 import org.simantics.db.common.request.ResourceRead;
40 import org.simantics.db.common.utils.ListUtils;
41 import org.simantics.db.exception.DatabaseException;
42 import org.simantics.db.layer0.request.PossibleActiveModel;
43 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
44 import org.simantics.db.layer0.util.SessionGarbageCollection;
45 import org.simantics.issues.common.BatchIssueSource;
46 import org.simantics.issues.common.BatchIssueValidationContext;
47 import org.simantics.issues.common.ManagedIssues;
48 import org.simantics.issues.common.SelectedModelBatchIssueSources;
49 import org.simantics.issues.ontology.IssueResource;
50 import org.simantics.issues.preferences.IssuePreferenceUtil;
51 import org.simantics.modeling.utils.BatchValidations;
52 import org.simantics.utils.ui.ExceptionUtils;
53
54 /**
55  * @author Tuukka Lehtonen
56  */
57 public class RunActiveValidations extends AbstractHandler {
58
59     @Override
60     public Object execute(ExecutionEvent event) throws ExecutionException {
61         try {
62             run();
63         } catch (DatabaseException e) {
64             throw new ExecutionException("Error while running active validations", e);
65         }
66         return null;
67     }
68
69     public static void run() throws DatabaseException {
70         Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
71         if(model != null)
72             run(model);
73     }
74
75     public static void run(Resource model) {
76         run(model, null);
77     }
78
79     public static void run(Resource model, Runnable postValidation) {
80
81         final Session session = Simantics.getSession();
82
83         // 1. query for which composites to run the validation
84         final Collection<BatchIssueSource> validations = new ArrayList<>();
85         final BatchIssueValidationContext context = new BatchIssueValidationContext();
86
87         try {
88             SleepingDatabaseJob dbLock = new SleepingDatabaseJob(Messages.RunActiveValidations_ValidationPreparation).scheduleAndWaitForRunning();
89             try {
90                 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
91                     @Override
92                     public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
93                         try {
94
95                             toBatchIssueSources(session,
96                                     session.syncRequest(new SelectedModelBatchIssueSources(model)),
97                                     validations);
98
99                             SubMonitor.convert(monitor, Messages.RunActiveValidations_MonitorPreparingResourcesForValidation, 100);
100                             context.contexts = Collections.singletonList(model);
101                             context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, model);
102
103                             if (monitor.isCanceled())
104                                 throw new OperationCanceledException();
105                         } catch (DatabaseException e) {
106                             throw new InvocationTargetException(e);
107                         } finally {
108                             monitor.done();
109                         }
110                     }
111                 });
112             } finally {
113                 dbLock.disposeAndJoin();
114             }
115         } catch (InvocationTargetException e) {
116             if (e.getTargetException() instanceof OperationCanceledException)
117                 return;
118             ExceptionUtils.logAndShowError(e.getTargetException());
119             return;
120         } catch (InterruptedException e) {
121             // Operation cancelled, ignore.
122             return;
123         }
124
125         if(!validations.isEmpty() && !context.contexts.isEmpty())
126             run(postValidation, validations, context);
127
128     }
129
130     static Collection<BatchIssueSource> toBatchIssueSources(RequestProcessor processor, Collection<Resource> sources, Collection<BatchIssueSource> result) throws DatabaseException {
131         for (Resource source : sources) {
132             BatchIssueSource bis = processor.syncRequest(Queries.adapt(source, BatchIssueSource.class, true));
133             if (bis != null)
134                 result.add(bis);
135         }
136         return result;
137     }
138
139     public static void run(Runnable postValidation, final Collection<BatchIssueSource> validations, final BatchIssueValidationContext context) {
140         // Run the validations for the selected composites
141         SleepingDatabaseJob dbLock = new SleepingDatabaseJob(Messages.RunActiveValidations_Validation);
142         try {
143             dbLock.scheduleAndWaitForRunning();
144             try {
145                 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
146                     @Override
147                     public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
148                         try {
149                             SubMonitor progress = SubMonitor.convert(monitor, Messages.RunActiveValidations_ValidateModel, 100);
150                             int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
151                             int writtenIssues = 0;
152                             for (BatchIssueSource source : validations) {
153                                 Map<Resource, Set<Issue>> results = BatchValidations.validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), source, context);
154                                 if (progress.isCanceled())
155                                     throw new OperationCanceledException();
156
157                                 Collection<Resource> removed = Simantics.getSession().syncRequest(new ResourceRead<Collection<Resource>>(source.getResource()) {
158                                     @Override
159                                     public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
160                                         IssueResource ISSUE = IssueResource.getInstance(graph);
161                                         ArrayList<Resource> result = new ArrayList<>();
162                                         for (Resource issue : graph.syncRequest(new ManagedIssues(resource))) {
163                                             Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
164                                             List<Resource> l = ListUtils.toList(graph, list);
165                                             if (l.size() > 0) {
166                                                 Resource mainContext = l.get(0);
167                                                 if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
168                                                     result.add(mainContext);
169                                             }
170                                         }
171                                         return result;
172                                     }
173                                 });
174
175                                 for(Resource r : removed) {
176                                     results.put(r, Collections.<Issue>emptySet());
177                                 }
178                                 if (progress.isCanceled())
179                                     throw new OperationCanceledException();
180
181                                 int wroteIssues = BatchValidations.store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), source.getResource(), results, Math.max(0, maxWrittenIssues - writtenIssues));
182                                 writtenIssues += wroteIssues;
183
184                                 // Try to keep resource consumption down.
185                                 SessionGarbageCollection.gc(null, Simantics.getSession(), true, null);
186
187                             }
188                         } catch (OperationCanceledException e) {
189                             throw e;
190                         } catch (Exception e) {
191                             throw new InvocationTargetException(e);
192                         } finally {
193                             monitor.done();
194                         }
195                     }
196                 });
197             } finally {
198                 dbLock.disposeAndJoin();
199             }
200
201             if (postValidation != null)
202                 postValidation.run();
203
204         } catch (OperationCanceledException e) {
205             // Operation cancelled, ignore.
206         } catch (InvocationTargetException e) {
207             ExceptionUtils.logAndShowError(e.getTargetException());
208         } catch (InterruptedException e) {
209             // Operation cancelled, ignore.
210         }
211     }
212
213 }