package org.simantics.modeling; import gnu.trove.map.hash.THashMap; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import org.simantics.common.color.Color; import org.simantics.common.format.Formatter; import org.simantics.databoard.Bindings; import org.simantics.databoard.Databoard; import org.simantics.databoard.adapter.AdaptException; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.URIStringUtils; import org.simantics.datatypes.literal.DecimalFormatFormatter; import org.simantics.datatypes.literal.RGB; import org.simantics.datatypes.literal.Vec2d; import org.simantics.db.ReadGraph; import org.simantics.db.RelationContext; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.impl.EntityNameModifier; import org.simantics.db.layer0.request.PossibleActiveExperiment; import org.simantics.db.layer0.request.PossibleVariableModel; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.variable.ProxyChildVariable; import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.ValueAccessor; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableMap; import org.simantics.db.layer0.variable.VariableMapImpl; import org.simantics.db.layer0.variable.Variables; import org.simantics.layer0.Layer0; import org.simantics.modeling.query.QueryProxyChildVariable; import org.simantics.modeling.scl.CompileProceduralSCLMonitorRequest; import org.simantics.modeling.scl.CompileSCLMonitorRequest; import org.simantics.modeling.scl.CompileSCLQueryRequest; import org.simantics.scenegraph.loader.ScenegraphLoaderUtils; import org.simantics.scl.reflection.annotations.SCLValue; import org.simantics.scl.runtime.function.FunctionImpl1; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.scl.CompileStructuralValueRequest; public class All { private static String formatted(String text, String color, int size) { return "" + text + ""; } @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") public static String issueDocumentHeader(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context); String label = selection.getLabel(graph); String severity = selection.getPropertyValue(graph, "severity", Bindings.STRING); String result = "== " + label + " ==\r\n" + formatted("An issue with severity ", "#000000", 12) + formatted(severity, "#5050aa", 15) + "\r\n\r\n
"; return result; } @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") public static Object sclValue(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { return CompileStructuralValueRequest.compileAndEvaluate(graph, context); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") public static Object queryValue(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { return CompileSCLQueryRequest.compileAndEvaluate(graph, context); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean") public static Boolean monitorReadOnly(ReadGraph graph, Resource converter, Variable ro) throws DatabaseException { Variable context = ro.getParent(graph); Layer0 L0 = Layer0.getInstance(graph); String expression = graph.getPossibleRelatedValue(context.getRepresents(graph), L0.SCLValue_expression, Bindings.STRING); if(expression == null) return true; return !InvertBasicExpressionVisitor.isInvertible(graph, context.getParent(graph), expression); } @SCLValue(type = "ValueAccessor") public static ValueAccessor monitorValueAccessor = new ValueAccessor() { @Override public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException { setValue(graph, context, value); } @Override public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); String expression = graph.getPossibleRelatedValue(context.getRepresents(graph), L0.SCLValue_expression, Bindings.STRING); if(expression == null) return; InvertBasicExpressionVisitor.invert(graph, context.getParent(graph), expression, value); } @Override public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException { try { Object value = getValue(graph, context); Binding srcBinding = Bindings.OBJECT.getContentBinding(value); return Bindings.adapt(value, srcBinding, binding); } catch (AdaptException e) { throw new DatabaseException(e); } catch (BindingException e) { throw new DatabaseException(e); } } private boolean isProcedural(ReadGraph graph, Variable context) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource type = context.getParent(graph).getPossibleType(graph); return graph.isInstanceOf(type, STR.ProceduralComponentType); } @Override public Object getValue(ReadGraph graph, Variable context) throws DatabaseException { if(isProcedural(graph, context)) return CompileProceduralSCLMonitorRequest.compileAndEvaluate(graph, context); else return CompileSCLMonitorRequest.compileAndEvaluate(graph, context); } @Override public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException { return org.simantics.db.layer0.function.All.getDatatypeFromValue(graph, context); } }; @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> String") public static String obtainedString(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, Bindings.STRING); } @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> Double") public static Double obtainedDouble(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, Bindings.DOUBLE); } @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> Boolean") public static Boolean obtainedBoolean(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, Bindings.BOOLEAN); } @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> Color") public static Color obtainedColor(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, RGB.Integer.BINDING); } @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> Vec2d") public static Vec2d obtainedVec2d(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, Vec2d.BINDING); } @SCLValue(type = "ReadGraph -> Resource -> RelationContext -> Formatter") public static Formatter obtainedFormatter(ReadGraph graph, Resource converter, RelationContext context) throws DatabaseException { return Layer0Utils.possibleObtainedValue(graph, context, DecimalFormatFormatter.BINDING); } public static final SimpleDateFormat sdfShort = new SimpleDateFormat("d.M.yyyy"); public static final SimpleDateFormat sdfLong = new SimpleDateFormat("d.M.yyyy H:mm:ss"); @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") public static String modificationTimeTextShort(ReadGraph graph, Resource r, Variable variable) throws DatabaseException { Long millis = variable.getParent(graph).getValue(graph, Bindings.LONG); return sdfShort.format(new Date(millis)); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") public static String modificationTimeTextLong(ReadGraph graph, Resource r, Variable variable) throws DatabaseException { Long millis = variable.getParent(graph).getValue(graph, Bindings.LONG); return sdfLong.format(new Date(millis)); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") public static String variableIdDisplayValue(ReadGraph graph, Resource r, Variable variable) throws DatabaseException { Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class ); RVI rvi = variable.getParent(graph).getPossibleValue(graph, rviBinding); if (rvi == null) return "Undefined, invalid subscription item"; Resource model = graph.sync( new PossibleVariableModel(variable) ); Resource run = model != null ? graph.sync( new PossibleActiveExperiment(model) ) : null; Variable base = run != null ? Variables.getPossibleVariable(graph, run) : null; Variable var = base != null ? rvi.resolvePossible(graph, base) : null; String rvistr = base != null ? rvi.toPossibleString(graph, base) : null; String result = rvistr != null ? URIStringUtils.unescape( rvistr ) : ""; return var != null ? result : result + " (INVALID)"; } @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") public static Object nameInputValidator(ReadGraph graph, Resource r, Variable variable) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource container = variable.getParent(graph).getParent(graph).getParent(graph).getPossibleRepresents(graph); if(container == null) return null; Resource name = graph.getSingleObject(container, L0.HasName); final EntityNameModifier modifier = new EntityNameModifier(graph, container, name); return new FunctionImpl1() { @Override public String apply(String proposition) { return modifier.isValid(proposition); } }; } @SCLValue(type = "VariableMap") public static VariableMap queryChildMap = new VariableMapImpl() { private Variable getProxy(ReadGraph graph, Variable context) throws DatabaseException { Variable root = Variables.getRootVariable(graph); return new QueryProxyChildVariable(context, context, root, ProxyChildVariable.CONTEXT_BEGIN); } @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { if(ProxyChildVariable.CONTEXT_BEGIN.equals(name)) return getProxy(graph, context); return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariable(graph, context, name); } @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { map = org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map); if(map == null) map = new THashMap(); map.put(ProxyChildVariable.CONTEXT_BEGIN, getProxy(graph, context)); return map; } }; }