]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java
Merge "(refs #7585) Added MList.set"
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / issue / SCLExpressionIssueProvider.java
1 package org.simantics.modeling.scl.issue;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Set;
6 import java.util.TreeSet;
7
8 import org.eclipse.jface.viewers.StructuredSelection;
9 import org.eclipse.swt.widgets.Display;
10 import org.eclipse.swt.widgets.Shell;
11 import org.simantics.Simantics;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.Resource;
14 import org.simantics.db.common.procedure.adapter.SyncListenerAdapter;
15 import org.simantics.db.common.request.UniqueRead;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.layer0.util.Layer0Utils;
18 import org.simantics.db.layer0.variable.Variable;
19 import org.simantics.db.layer0.variable.Variables;
20 import org.simantics.layer0.Layer0;
21 import org.simantics.modeling.ModelingUtils;
22 import org.simantics.scl.compiler.errors.CompilationError;
23 import org.simantics.scl.compiler.errors.Locations;
24 import org.simantics.scl.osgi.issues.SCLIssueProviderFactory;
25 import org.simantics.scl.osgi.issues.SCLIssueProviderFactory.SCLIssueProvider;
26 import org.simantics.scl.osgi.issues.SCLIssuesTableEntry;
27 import org.simantics.scl.runtime.SCLContext;
28 import org.simantics.scl.runtime.function.Function1;
29 import org.simantics.structural.stubs.StructuralResource2;
30 import org.simantics.ui.workbench.action.DefaultActions;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 public class SCLExpressionIssueProvider implements SCLIssueProvider {
35
36     public static class SCLExpressionIssueProviderFactory implements SCLIssueProviderFactory {
37
38         @Override
39         public SCLIssueProvider getSCLIssueProvider() {
40             return new SCLExpressionIssueProvider();
41         }
42
43     }
44
45     private static final Logger LOGGER = LoggerFactory.getLogger(SCLExpressionIssueProvider.class);
46     private List<SCLIssuesTableEntry> currentIssues = new ArrayList<>();
47     private boolean disposed = false;
48
49     SCLExpressionIssueProvider() {
50     }
51
52     @Override
53     public void listenIssues(Runnable callback) {
54         Simantics.getSession().asyncRequest(new UniqueRead<List<SCLIssuesTableEntry>>() {
55
56             @Override
57             public List<SCLIssuesTableEntry> perform(ReadGraph graph) throws DatabaseException {
58                 Layer0 L0 = Layer0.getInstance(graph);
59                 Set<Resource> indexRoots = new TreeSet<Resource>();
60                 for(Resource ontology : Layer0Utils.listOntologies(graph)) {
61                     if (graph.isInstanceOf(ontology, L0.SharedOntology)) {
62                         indexRoots.add(ontology);
63                     }
64                 }
65
66                 for(Resource child : graph.getObjects(Simantics.getProjectResource(), L0.ConsistsOf)) {
67                     if (graph.isInstanceOf(child, L0.IndexRoot)) {
68                         indexRoots.add(child);
69                     }
70                 }
71
72                 StructuralResource2 STR = StructuralResource2.getInstance(graph);
73
74                 List<SCLIssuesTableEntry> results = new ArrayList<>();
75
76                 for (Resource ontology : indexRoots) {
77                     List<Resource> components = ModelingUtils.searchByTypeShallow(graph, ontology, STR.Component);
78                     for (Resource component : components) {
79
80                         for (Resource predicate : graph.getPredicates(component)) {
81                             if (graph.isSubrelationOf(predicate, L0.HasProperty)) {
82                                 for (Resource object : graph.getObjects(component, predicate)) {
83                                     if (graph.isInstanceOf(object, L0.SCLValue)) {
84                                         Resource type = graph.getPossibleType(object, L0.SCLValue);
85                                         Variable typeVariable = Variables.getVariable(graph, type);
86
87                                         Function1<Variable, String> func = typeVariable.getPossiblePropertyValue(graph, "validator");
88                                         if (func == null) {
89                                             // No validator available
90                                             if (LOGGER.isTraceEnabled())
91                                                 LOGGER.trace("No validator available for " + typeVariable.getURI(graph));
92                                             continue;
93                                         }
94
95                                         Variable componentVariable = Variables.getVariable(graph, component);
96                                         Variable propertyVariable = componentVariable.getProperty(graph, predicate);
97
98                                         SCLContext sclContext = SCLContext.getCurrent();
99                                         Object oldGraph = sclContext.get("graph");
100                                         try {
101                                             sclContext.put("graph", graph);
102                                             String validatorValue = func.apply(propertyVariable);
103                                             if (validatorValue != null && !validatorValue.isEmpty()) {
104                                                 results.add(new SCLIssuesTableEntry(propertyVariable.getURI(graph), new CompilationError(Locations.NO_LOCATION, validatorValue.replace("\n", " "))) {
105                                                     @Override
106                                                     public void openLocation() {
107                                                         openResource(Display.getCurrent().getActiveShell(), component);
108                                                     }
109                                                 });
110                                             }
111                                         } catch (Throwable t) {
112                                             LOGGER.error("Failed to invoke type validator function " + func, t);
113                                         } finally {
114                                             sclContext.put("graph", oldGraph);
115                                         }
116                                     }
117                                 }
118                             }
119                         }
120                     }
121                 }
122                 return results;
123             }
124         }, new SyncListenerAdapter<List<SCLIssuesTableEntry>>() {
125
126             @Override
127             public void execute(ReadGraph graph, List<SCLIssuesTableEntry> result) {
128                 synchronized (currentIssues) {
129                     currentIssues.clear();
130                     currentIssues.addAll(result);
131                 }
132                 if (callback != null)
133                     callback.run();
134             }
135
136             @Override
137             public void exception(ReadGraph graph, Throwable t) {
138                 LOGGER.error("Could not get SCL issues", t);
139             }
140
141             @Override
142             public boolean isDisposed() {
143                 return disposed;
144             }
145         });
146     }
147
148     @Override
149     public List<SCLIssuesTableEntry> getIssues() {
150         synchronized (currentIssues) {
151             List<SCLIssuesTableEntry> results = new ArrayList<>(currentIssues);
152             return results;
153         }
154     }
155
156     @Override
157     public void dispose() {
158         disposed = true;
159     }
160
161     private static void openResource(Shell shell, Resource resource) {
162         DefaultActions.performDefaultAction(shell, new StructuredSelection(resource));
163     }
164
165 }