1 package org.simantics.modeling.scl.issue;
3 import java.util.ArrayList;
6 import java.util.TreeSet;
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;
34 public class SCLExpressionIssueProvider implements SCLIssueProvider {
36 public static class SCLExpressionIssueProviderFactory implements SCLIssueProviderFactory {
39 public SCLIssueProvider getSCLIssueProvider() {
40 return new SCLExpressionIssueProvider();
45 private static final Logger LOGGER = LoggerFactory.getLogger(SCLExpressionIssueProvider.class);
46 private List<SCLIssuesTableEntry> currentIssues = new ArrayList<>();
47 private boolean disposed = false;
49 SCLExpressionIssueProvider() {
53 public void listenIssues(Runnable callback) {
54 Simantics.getSession().asyncRequest(new UniqueRead<List<SCLIssuesTableEntry>>() {
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);
66 for(Resource child : graph.getObjects(Simantics.getProjectResource(), L0.ConsistsOf)) {
67 if (graph.isInstanceOf(child, L0.IndexRoot)) {
68 indexRoots.add(child);
72 StructuralResource2 STR = StructuralResource2.getInstance(graph);
74 List<SCLIssuesTableEntry> results = new ArrayList<>();
76 for (Resource ontology : indexRoots) {
77 List<Resource> components = ModelingUtils.searchByTypeShallow(graph, ontology, STR.Component);
78 for (Resource component : components) {
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);
87 Function1<Variable, String> func = typeVariable.getPossiblePropertyValue(graph, "validator");
89 // No validator available
90 if (LOGGER.isTraceEnabled())
91 LOGGER.trace("No validator available for " + typeVariable.getURI(graph));
95 Variable componentVariable = Variables.getVariable(graph, component);
96 Variable propertyVariable = componentVariable.getProperty(graph, predicate);
98 SCLContext sclContext = SCLContext.getCurrent();
99 Object oldGraph = sclContext.get("graph");
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", " "))) {
106 public void openLocation() {
107 openResource(Display.getCurrent().getActiveShell(), component);
111 } catch (Throwable t) {
112 LOGGER.error("Failed to invoke type validator function " + func, t);
114 sclContext.put("graph", oldGraph);
124 }, new SyncListenerAdapter<List<SCLIssuesTableEntry>>() {
127 public void execute(ReadGraph graph, List<SCLIssuesTableEntry> result) {
128 synchronized (currentIssues) {
129 currentIssues.clear();
130 currentIssues.addAll(result);
132 if (callback != null)
137 public void exception(ReadGraph graph, Throwable t) {
138 LOGGER.error("Could not get SCL issues", t);
142 public boolean isDisposed() {
149 public List<SCLIssuesTableEntry> getIssues() {
150 synchronized (currentIssues) {
151 List<SCLIssuesTableEntry> results = new ArrayList<>(currentIssues);
157 public void dispose() {
161 private static void openResource(Shell shell, Resource resource) {
162 DefaultActions.performDefaultAction(shell, new StructuredSelection(resource));