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 {
55 public static ComponentTypeViewerPropertyInfo readPropertyInfo(ReadGraph graph, Resource relation, Resource componentType, boolean typeIsImmutable) throws DatabaseException {
57 Layer0 L0 = Layer0.getInstance(graph);
58 Layer0X L0X = Layer0X.getInstance(graph);
59 StructuralResource2 STR = StructuralResource2.getInstance(graph);
61 String name = graph.getRelatedValue(relation, L0.HasName);
62 String type = graph.getPossibleRelatedValue(relation, L0.RequiresValueType);
63 String label = graph.getPossibleRelatedValue(relation, L0.HasLabel);
65 label = ""; //$NON-NLS-1$
66 String description = graph.getPossibleRelatedValue(relation, L0.HasDescription);
67 if (description == null)
68 description = ""; //$NON-NLS-1$
69 NumberType numberType = null;
71 type = "Double"; //$NON-NLS-1$
72 String unit = graph.getPossibleRelatedValue(relation, L0X.HasUnit, Bindings.STRING);
73 String defaultValue = "0"; //$NON-NLS-1$
74 String expression = null;
76 if(componentType != null) {
77 for(Resource assertion : graph.getAssertedObjects(componentType, relation)) {
79 expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);
80 if(expression != null) {
81 defaultValue = "=" + expression; //$NON-NLS-1$
82 } else if (graph.sync(new IsEnumeratedValue(assertion))) {
83 defaultValue = CommonDBUtils.getEnumerationValueName(graph, assertion);
85 Datatype dt = getPossibleDatatype(graph, assertion);
88 if (dt instanceof NumberType)
89 numberType = (NumberType) dt;
90 Binding binding = Bindings.getBinding(dt);
91 Object value = graph.getValue(assertion, binding);
93 defaultValue = binding.toString(value, true);
94 } catch (BindingException e) {
95 ErrorLogger.defaultLogError(e);
98 } catch(DatabaseException e) {
99 ErrorLogger.defaultLogError(e);
104 String valid = expression != null ? validateMonitorExpression(graph, componentType, relation, expression) : null;
106 boolean immutable = typeIsImmutable || graph.isImmutable(relation);
107 ComponentTypeViewerPropertyInfo info =
108 new ComponentTypeViewerPropertyInfo(relation, name, type, defaultValue, numberType, unit, label, description, expression, valid, immutable);
115 public ComponentTypePropertiesResult perform(ReadGraph graph) throws DatabaseException {
116 List<ComponentTypeViewerPropertyInfo> result = new ArrayList<>();
117 List<NamedResource> connectionPoints = new ArrayList<>();
118 Layer0 L0 = Layer0.getInstance(graph);
119 StructuralResource2 STR = StructuralResource2.getInstance(graph);
121 boolean typeIsImmutable = graph.isImmutable(componentType)
122 || graph.hasStatement(componentType, STR.ComponentType_Locked)
123 || Layer0Utils.isPublished(graph, componentType)
124 || Layer0Utils.isContainerPublished(graph, componentType);
126 for(Resource relation : graph.getObjects(componentType, L0.DomainOf)) {
127 if(graph.isSubrelationOf(relation, L0.HasProperty)) {
128 ComponentTypeViewerPropertyInfo info = readPropertyInfo(graph, relation, componentType, typeIsImmutable);
129 readSectionSpecificData(graph, info);
131 } else if (graph.isInstanceOf(relation, STR.ConnectionRelation)) {
132 NamedResource nr = new NamedResource(NameUtils.getSafeName(graph, relation), relation);
133 connectionPoints.add(nr);
137 Collections.sort(result);
139 return new ComponentTypePropertiesResult(result, connectionPoints, typeIsImmutable);
143 private static Datatype getPossibleDatatype(ReadGraph graph, Resource literal) throws DatabaseException {
144 Binding binding = Bindings.getBindingUnchecked(Datatype.class);
145 for (Resource dataTypeResource : graph.getObjects(literal, Layer0.getInstance(graph).HasDataType)) {
146 Datatype dt = graph.getPossibleValue(dataTypeResource, binding);
153 public static String validateMonitorExpression(final RequestProcessor processor, final Resource componentType, final Resource relation, final String expression) {
156 return processor.sync(new UniqueRead<String>() {
159 public String perform(ReadGraph graph) throws DatabaseException {
161 StructuralResource2 STR = StructuralResource2.getInstance(graph);
163 // TODO: this is a bit hackish but should get the job done in most parts and
164 // importantly indicates something for the user
165 PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheAsyncListener.<PropertyInfo>instance());
166 Variable parent = new StandardGraphChildVariable(null, null, componentType) {
168 public Resource getType(ReadGraph graph) throws DatabaseException {
169 return componentType;
172 public Variable getPossibleProperty(ReadGraph graph, String name) throws DatabaseException {
173 Variable prop = super.getPossibleProperty(graph, name);
177 return getChild(graph, name);
182 for(Resource literal : graph.getAssertedObjects(componentType, relation)) {
185 Variable context = new StandardGraphPropertyVariable(parent, null, null, info, literal);
186 if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) {
187 CompileProceduralSCLMonitorRequest.compileAndEvaluate(graph, context);
189 compileAndEvaluate(graph, context, expression);
192 } catch (Exception e) {
193 String msg = e.getMessage();
194 int index = msg.indexOf(":"); //$NON-NLS-1$
195 if(index > 0) msg = msg.substring(index);
203 } catch (DatabaseException e) {
204 LOGGER.error("Could not validate ", e);
209 public static void compileAndEvaluate(ReadGraph graph, Variable context, String expression) throws DatabaseException {
210 SCLContext sclContext = SCLContext.getCurrent();
211 Object oldGraph = sclContext.get("graph");
213 CompileSCLMonitorRequest compileSCLMonitorRequest = new ValidationCompilationRequest(graph, context, expression);
214 Function1<Variable,Object> exp = graph.syncRequest(compileSCLMonitorRequest);
215 sclContext.put("graph", graph);
216 //return exp.apply(context.getParent(graph));
217 } catch (DatabaseException e) {
218 throw (DatabaseException)e;
219 } catch (Throwable t) {
220 throw new DatabaseException(t);
222 sclContext.put("graph", oldGraph);
226 private static final class ValidationCompilationRequest extends CompileSCLMonitorRequest {
227 private final String expression;
229 private ValidationCompilationRequest(ReadGraph graph, Variable context, String expression)
230 throws DatabaseException {
231 super(graph, context);
232 this.expression = expression;
236 protected String getExpressionText(ReadGraph graph) throws DatabaseException {
241 public int hashCode() {
242 return super.hashCode() + 37 * expression.hashCode();
246 public boolean equals(Object obj) {
247 return super.equals(obj) && ((ValidationCompilationRequest)obj).expression.equals(expression);