1 package org.simantics.modeling.utils;
3 import java.util.ArrayList;
4 import java.util.Collections;
7 import org.simantics.databoard.Bindings;
8 import org.simantics.databoard.binding.Binding;
9 import org.simantics.databoard.binding.error.BindingException;
10 import org.simantics.databoard.type.Datatype;
11 import org.simantics.databoard.type.NumberType;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.RequestProcessor;
14 import org.simantics.db.Resource;
15 import org.simantics.db.common.NamedResource;
16 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
17 import org.simantics.db.common.request.IsEnumeratedValue;
18 import org.simantics.db.common.request.UniqueRead;
19 import org.simantics.db.common.utils.CommonDBUtils;
20 import org.simantics.db.common.utils.NameUtils;
21 import org.simantics.db.exception.DatabaseException;
22 import org.simantics.db.layer0.request.PropertyInfo;
23 import org.simantics.db.layer0.request.PropertyInfoRequest;
24 import org.simantics.db.layer0.util.Layer0Utils;
25 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
26 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
27 import org.simantics.db.layer0.variable.Variable;
28 import org.simantics.layer0.Layer0;
29 import org.simantics.modeling.scl.CompileProceduralSCLMonitorRequest;
30 import org.simantics.modeling.scl.CompileSCLMonitorRequest;
31 import org.simantics.operation.Layer0X;
32 import org.simantics.scl.runtime.SCLContext;
33 import org.simantics.scl.runtime.function.Function1;
34 import org.simantics.structural.stubs.StructuralResource2;
35 import org.simantics.utils.ui.ErrorLogger;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class HeadlessComponentTypePropertiesResultRequest extends UniqueRead<ComponentTypePropertiesResult> {
41 private static final Logger LOGGER = LoggerFactory.getLogger(HeadlessComponentTypePropertiesResultRequest.class);
43 protected final Resource componentType;
46 * @param componentTypeViewer
48 public HeadlessComponentTypePropertiesResultRequest(Resource componentType) {
49 this.componentType = componentType;
52 protected void readSectionSpecificData(ReadGraph graph, ComponentTypeViewerPropertyInfo info) throws DatabaseException {
56 public ComponentTypePropertiesResult perform(ReadGraph graph) throws DatabaseException {
57 List<ComponentTypeViewerPropertyInfo> result = new ArrayList<>();
58 List<NamedResource> connectionPoints = new ArrayList<>();
59 Layer0 L0 = Layer0.getInstance(graph);
60 Layer0X L0X = Layer0X.getInstance(graph);
61 StructuralResource2 STR = StructuralResource2.getInstance(graph);
63 boolean typeIsImmutable = graph.isImmutable(componentType)
64 || graph.hasStatement(componentType, STR.ComponentType_Locked)
65 || Layer0Utils.isPublished(graph, componentType)
66 || Layer0Utils.isContainerPublished(graph, componentType);
68 for(Resource relation : graph.getObjects(componentType, L0.DomainOf)) {
69 if(graph.isSubrelationOf(relation, L0.HasProperty)) {
70 String name = graph.getRelatedValue(relation, L0.HasName);
71 String type = graph.getPossibleRelatedValue(relation, L0.RequiresValueType);
72 String label = graph.getPossibleRelatedValue(relation, L0.HasLabel);
74 label = ""; //$NON-NLS-1$
75 String description = graph.getPossibleRelatedValue(relation, L0.HasDescription);
76 if (description == null)
77 description = ""; //$NON-NLS-1$
78 NumberType numberType = null;
80 type = "Double"; //$NON-NLS-1$
81 String unit = graph.getPossibleRelatedValue(relation, L0X.HasUnit, Bindings.STRING);
82 String defaultValue = "0"; //$NON-NLS-1$
83 String expression = null;
85 for(Resource assertion : graph.getAssertedObjects(componentType, relation)) {
87 expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);
88 if(expression != null) {
89 defaultValue = "=" + expression; //$NON-NLS-1$
90 } else if (graph.sync(new IsEnumeratedValue(assertion))) {
91 defaultValue = CommonDBUtils.getEnumerationValueName(graph, assertion);
93 Datatype dt = getPossibleDatatype(graph, assertion);
96 if (dt instanceof NumberType)
97 numberType = (NumberType) dt;
98 Binding binding = Bindings.getBinding(dt);
99 Object value = graph.getValue(assertion, binding);
101 defaultValue = binding.toString(value, true);
102 } catch (BindingException e) {
103 ErrorLogger.defaultLogError(e);
106 } catch(DatabaseException e) {
107 ErrorLogger.defaultLogError(e);
111 String valid = expression != null ? validateMonitorExpression(graph, componentType, relation, expression) : null;
113 boolean immutable = typeIsImmutable || graph.isImmutable(relation);
114 ComponentTypeViewerPropertyInfo info =
115 new ComponentTypeViewerPropertyInfo(relation, name, type, defaultValue, numberType, unit, label, description, expression, valid, immutable);
117 readSectionSpecificData(graph, info);
121 } else if (graph.isInstanceOf(relation, STR.ConnectionRelation)) {
122 NamedResource nr = new NamedResource(NameUtils.getSafeName(graph, relation), relation);
123 connectionPoints.add(nr);
126 Collections.sort(result);
127 return new ComponentTypePropertiesResult(result, connectionPoints, typeIsImmutable);
130 private Datatype getPossibleDatatype(ReadGraph graph, Resource literal) throws DatabaseException {
131 Binding binding = Bindings.getBindingUnchecked(Datatype.class);
132 for (Resource dataTypeResource : graph.getObjects(literal, Layer0.getInstance(graph).HasDataType)) {
133 Datatype dt = graph.getPossibleValue(dataTypeResource, binding);
140 public static String validateMonitorExpression(final RequestProcessor processor, final Resource componentType, final Resource relation, final String expression) {
143 return processor.sync(new UniqueRead<String>() {
146 public String perform(ReadGraph graph) throws DatabaseException {
148 StructuralResource2 STR = StructuralResource2.getInstance(graph);
150 // TODO: this is a bit hackish but should get the job done in most parts and
151 // importantly indicates something for the user
152 PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheAsyncListener.<PropertyInfo>instance());
153 Variable parent = new StandardGraphChildVariable(null, null, componentType) {
155 public Resource getType(ReadGraph graph) throws DatabaseException {
156 return componentType;
159 public Variable getPossibleProperty(ReadGraph graph, String name) throws DatabaseException {
160 Variable prop = super.getPossibleProperty(graph, name);
164 return getChild(graph, name);
169 for(Resource literal : graph.getAssertedObjects(componentType, relation)) {
172 Variable context = new StandardGraphPropertyVariable(parent, null, null, info, literal);
173 if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) {
174 CompileProceduralSCLMonitorRequest.compileAndEvaluate(graph, context);
176 compileAndEvaluate(graph, context, expression);
179 } catch (Exception e) {
180 String msg = e.getMessage();
181 int index = msg.indexOf(":"); //$NON-NLS-1$
182 if(index > 0) msg = msg.substring(index);
190 } catch (DatabaseException e) {
191 LOGGER.error("Could not validate ", e);
196 public static void compileAndEvaluate(ReadGraph graph, Variable context, String expression) throws DatabaseException {
197 SCLContext sclContext = SCLContext.getCurrent();
198 Object oldGraph = sclContext.get("graph");
200 CompileSCLMonitorRequest compileSCLMonitorRequest = new ValidationCompilationRequest(graph, context, expression);
201 Function1<Variable,Object> exp = graph.syncRequest(compileSCLMonitorRequest);
202 sclContext.put("graph", graph);
203 //return exp.apply(context.getParent(graph));
204 } catch (DatabaseException e) {
205 throw (DatabaseException)e;
206 } catch (Throwable t) {
207 throw new DatabaseException(t);
209 sclContext.put("graph", oldGraph);
213 private static final class ValidationCompilationRequest extends CompileSCLMonitorRequest {
214 private final String expression;
216 private ValidationCompilationRequest(ReadGraph graph, Variable context, String expression)
217 throws DatabaseException {
218 super(graph, context);
219 this.expression = expression;
223 protected String getExpressionText(ReadGraph graph) throws DatabaseException {
228 public int hashCode() {
229 return super.hashCode() + 37 * expression.hashCode();
233 public boolean equals(Object obj) {
234 return super.equals(obj) && ((ValidationCompilationRequest)obj).expression.equals(expression);