--- /dev/null
+package org.simantics.scl.commands.internal;\r
+\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
+import org.simantics.scl.compiler.module.repository.ImportFailureException;\r
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
+import org.simantics.scl.compiler.top.ExpressionEvaluator;\r
+import org.simantics.scl.compiler.top.SCLExpressionCompilationException;\r
+import org.simantics.scl.compiler.top.ValueNotFound;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+import org.simantics.scl.runtime.function.Function2;\r
+\r
+@SuppressWarnings({"rawtypes", "unchecked"})\r
+public class StringConverterFactory {\r
+ private static final ConcurrentHashMap<Type, Function2> CONVERTER_CACHE = \r
+ new ConcurrentHashMap<Type, Function2>();\r
+ private static RuntimeEnvironment environment;\r
+ \r
+ private static final Type ALLOWED_EFFECT = Types.union(new Type[] {Types.READ_GRAPH, Types.PROC});\r
+ \r
+ /**\r
+ * Creates a string converter for given type.\r
+ * @throws ValueNotFound \r
+ */\r
+ public static Function2<Resource,Object,String> stringConverterFor(Type type) throws SCLExpressionCompilationException, ImportFailureException {\r
+ Function2 converter = CONVERTER_CACHE.get(type);\r
+ if(converter == null) {\r
+ if(environment == null) {\r
+ // no need to synchronize access to environment\r
+ environment = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(\r
+ EnvironmentSpecification.of(\r
+ "Simantics/GShow", "",\r
+ "Simantics/RouteGraph", "",\r
+ "Prelude", ""\r
+ ), StringConverterFactory.class.getClassLoader()\r
+ );\r
+ }\r
+ converter = (Function2)new ExpressionEvaluator(environment, "\\ctx r -> gshow ctx (Par 0 r)")\r
+ .expectedType(Types.function(Types.RESOURCE, Types.functionE(type, ALLOWED_EFFECT, Types.STRING)))\r
+ .eval();\r
+ CONVERTER_CACHE.put(type, converter);\r
+ }\r
+ return converter;\r
+ }\r
+}\r