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