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;
}
};
}