if(!operations.isEmpty() || !tasks.isEmpty()) return 0;
long start = System.nanoTime();
- System.err.println("start =" + start);
try {
wait(5000);
assert (request != null);
- //ITask task = ThreadLogger.task(request);
ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
- T result = QueryCache.resultReadEntry(this, request, parent, listener, procedure);
- //task.finish();
+ T result = (T)QueryCache.runnerReadEntry(this, request, parent, listener, procedure, true);
return result;
}
}
}
- ReadEntry getOrCreateReadEntry(ReadGraphImpl graph, Read<?> r, boolean needsToBlock) throws DatabaseException {
+ private final ReadEntry getOrCreateReadEntry(ReadGraphImpl graph, Read<?> r, boolean needsToBlock) throws DatabaseException {
ReadEntry existing = null;
synchronized(readEntryMap) {
existing = (ReadEntry)readEntryMap.get(r);
return wrap.get();
}
- public static <T> T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
- return (T)QueryCache.runnerReadEntry(graph, r, parent, listener, procedure, true);
- }
-
public static <T> T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
return (T)QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, procedure, true);
}
private Consumer<Runnable> consumer;
private Map<ListenerBase,ListenerEntry> addedEntries = new HashMap<>();
- int execCount=0;
- int queueCount = 0;
-
static class TL extends ThreadLocal<ArrayList<Runnable>> {
Map<Thread,ArrayList<Runnable>> allQueues = new HashMap<>();
return !scheduledListeners.isEmpty();
}
- public synchronized void dispatch(Runnable r) {
- queueCount++;
- consumer.accept(r);
+ static class RegisterParentRunnable implements Runnable {
+
+ final CacheEntry parent;
+ final CacheEntry child;
+
+ public RegisterParentRunnable(CacheEntry parent, CacheEntry child) {
+ this.parent = parent;
+ this.child = child;
+ }
+
+ @Override
+ public void run() {
+ child.addParent(parent);
+ if (Development.DEVELOPMENT) {
+ if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_DEPENDENCIES, Bindings.BOOLEAN)) {
+ System.out.println(child + " -> " + parent);
+ }
+ }
+ }
+
+ }
+
+ static class RegisterListenerRunnable implements Runnable {
+
+ final QueryListening queryListening;
+ final ListenerBase base;
+ final Object procedure;
+ final CacheEntry parent;
+ final CacheEntry entry;
+
+ public RegisterListenerRunnable(QueryListening queryListening, ListenerBase base, Object procedure, CacheEntry parent, CacheEntry entry) {
+ this.queryListening = queryListening;
+ this.base = base;;
+ this.procedure = procedure;
+ this.parent = parent;
+ this.entry = entry;
+ }
+
+ @Override
+ public void run() {
+ queryListening.addListener(entry, base, procedure);
+ }
+
}
void registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
- dispatch(() -> {
+ if(inferred) {
+ assert(listener == null);
+ return;
+ }
- if (parent != null && !inferred) {
- try {
- if(!child.isImmutable(graph))
- child.addParent(parent);
- } catch (DatabaseException e) {
- LOGGER.error("Error while registering query dependencies", e);
- }
- if (Development.DEVELOPMENT) {
- if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_DEPENDENCIES, Bindings.BOOLEAN)) {
- System.out.println(child + " -> " + parent);
- }
- }
+ if(parent != null) {
+ try {
+ if(!child.isImmutable(graph))
+ consumer.accept(new RegisterParentRunnable(parent, child));
+ } catch (DatabaseException e) {
+ LOGGER.error("Error while registering query dependencies", e);
}
+ }
- if (listener != null)
- registerListener(child, listener, procedure);
-
- });
+ if(listener != null)
+ if(!listener.isDisposed())
+ consumer.accept(new RegisterListenerRunnable(this, listener, procedure, parent, child));
}
if(base == null) return;
- dispatch(() -> {
-
+ consumer.accept(() -> {
ListenerEntry entry = addedEntries.get(base);
if(entry != null) entry.setLastKnown(result);
-
});
}
- public ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
-
- assert (entry != null);
-
- if (base.isDisposed())
- return null;
-
- return addListener(entry, base, procedure);
-
- }
-
/*
* Registers a listener and returns an entry iff the entry was added
*/
public class PropertyInfo {
public final Resource predicate;
public final String name;
+ public final boolean isImmutable;
public final boolean isHasProperty;
public final boolean isFunctional;
public final Set<String> classifications;
public final Map<String,Pair<Resource, ChildReference>> subliteralPredicates;
public final ValueAccessor valueAccessor;
public final boolean hasEnumerationRange;
- public PropertyInfo(Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) {
+ public PropertyInfo(Resource predicate, String name, boolean isImmutable, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) {
this.predicate = predicate;
this.name = name;
+ this.isImmutable = isImmutable;
this.isFunctional = isFunctional;
this.isHasProperty = isHasProperty;
this.classifications = classifications;
Binding defaultBinding = requiredDatatype != null ? Bindings.getBinding(requiredDatatype) : null;
- return new PropertyInfo(predicate, name, isFunctional, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange);
+ return new PropertyInfo(predicate, name, graph.isImmutable(predicate), isFunctional, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange);
}
public boolean hasClassification(String classification) {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((builder == null) ? 0 : builder.hashCode());
- result = prime * result + ((classifications == null) ? 0 : classifications.hashCode());
- result = prime * result + ((defaultBinding == null) ? 0 : defaultBinding.hashCode());
- result = prime * result + ((definedUnit == null) ? 0 : definedUnit.hashCode());
- result = prime * result + (hasEnumerationRange ? 1231 : 1237);
- result = prime * result + (isFunctional ? 1231 : 1237);
- result = prime * result + (isHasProperty ? 1231 : 1237);
- result = prime * result + ((literalRange == null) ? 0 : literalRange.hashCode());
- result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
- result = prime * result + ((requiredDatatype == null) ? 0 : requiredDatatype.hashCode());
- result = prime * result + ((requiredValueType == null) ? 0 : requiredValueType.hashCode());
- result = prime * result + ((subliteralPredicates == null) ? 0 : subliteralPredicates.hashCode());
- result = prime * result + ((valueAccessor == null) ? 0 : valueAccessor.hashCode());
+ if(!isImmutable) {
+ result = prime * result + ((builder == null) ? 0 : builder.hashCode());
+ result = prime * result + ((classifications == null) ? 0 : classifications.hashCode());
+ result = prime * result + ((defaultBinding == null) ? 0 : defaultBinding.hashCode());
+ result = prime * result + ((definedUnit == null) ? 0 : definedUnit.hashCode());
+ result = prime * result + (hasEnumerationRange ? 1231 : 1237);
+ result = prime * result + (isFunctional ? 1231 : 1237);
+ result = prime * result + (isHasProperty ? 1231 : 1237);
+ result = prime * result + ((literalRange == null) ? 0 : literalRange.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((requiredDatatype == null) ? 0 : requiredDatatype.hashCode());
+ result = prime * result + ((requiredValueType == null) ? 0 : requiredValueType.hashCode());
+ result = prime * result + ((subliteralPredicates == null) ? 0 : subliteralPredicates.hashCode());
+ result = prime * result + ((valueAccessor == null) ? 0 : valueAccessor.hashCode());
+ }
return result;
}
@Override
if (getClass() != obj.getClass())
return false;
PropertyInfo other = (PropertyInfo) obj;
+ if (predicate == null) {
+ if (other.predicate != null)
+ return false;
+ } else if (!predicate.equals(other.predicate))
+ return false;
+ if(isImmutable)
+ return true;
if (builder == null) {
if (other.builder != null)
return false;
return false;
} else if (!name.equals(other.name))
return false;
- if (predicate == null) {
- if (other.predicate != null)
- return false;
- } else if (!predicate.equals(other.predicate))
- return false;
if (requiredDatatype == null) {
if (other.requiredDatatype != null)
return false;
return DEFAULT_EXPECTED_EFFECT;
}
- private ExpressionEvaluator prepareEvaluator(final ReadGraph graph, final CompilationContext context, Type expectedType) throws DatabaseException {
+ protected ExpressionEvaluator prepareEvaluator(final ReadGraph graph, final CompilationContext context, Type expectedType) throws DatabaseException {
final Variable contextVariable = new Variable("context", getContextVariableType());
LocalEnvironment localEnvironment = new AbstractLocalEnvironment() {
THashMap<String,Pair<Variable,Expression>> precalculatedVariables = new THashMap<String,Pair<Variable,Expression>>();
}
@SuppressWarnings("unchecked")
- private Function1<EvaluationContext, Object> eval(ExpressionEvaluator evaluator, ReadGraph graph) throws DatabaseException {
+ protected Function1<EvaluationContext, Object> eval(ExpressionEvaluator evaluator, ReadGraph graph) throws DatabaseException {
Object oldGraph = SCLContext.getCurrent().put("graph", graph);
try {
return (Function1<EvaluationContext,Object>)evaluator.eval();
if(_monitor == null) _monitor = new NullProgressMonitor();
QueryControl qc = graph.getService(QueryControl.class);
ClusterControl cc = graph.getService(ClusterControl.class);
-// _monitor.beginTask("Collect clusters", IProgressMonitor.UNKNOWN);
-// cc.gc(graph, clusterTarget);
-// _monitor.beginTask("Collect queries", IProgressMonitor.UNKNOWN);
-// qc.gc(graph, allowedTimeInMs);
+ _monitor.beginTask("Collect clusters", IProgressMonitor.UNKNOWN);
+ cc.gc(graph, clusterTarget);
+ _monitor.beginTask("Collect queries", IProgressMonitor.UNKNOWN);
+ qc.gc(graph, allowedTimeInMs);
}
/**
public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
private static final Logger LOGGER = LoggerFactory.getLogger(StandardGraphPropertyVariable.class);
- protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null,
+ protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null, true,
false, false, Collections.<String> emptySet(), null, null, null, null, null, null,
Collections.<String, Pair<Resource, ChildReference>> emptyMap(),
null, false);
public int getAmountOfQueryThreads() {
// This must be a power of two
- return 4;
+ return 32;
// return Integer.highestOneBit(Runtime.getRuntime().availableProcessors());
}
package org.simantics.document.server.request;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.simantics.db.Resource;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
import org.simantics.db.common.request.IndexRoot;
-import org.simantics.db.common.request.PossibleTypedParent;
import org.simantics.db.common.request.UnaryRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext;
-import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest;
import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2;
import org.simantics.db.layer0.variable.Variable;
-import org.simantics.document.base.ontology.DocumentationResource;
-import org.simantics.document.server.request.ServerSCLHandlerValueRequest.CompilationContext;
import org.simantics.layer0.Layer0;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.MultiFunction;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.FunctionImpl1;
import org.simantics.structural2.scl.ComponentTypeProperty;
import org.simantics.structural2.scl.FindPossibleComponentTypeRequest;
import org.simantics.structural2.scl.ReadComponentTypeInterfaceRequest;
import org.simantics.utils.datastructures.Pair;
-public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationRequest<CompilationContext, Object> {
-
- private final Pair<Resource,Resource> componentTypeAndRoot;
- private final Resource literal;
- protected String possibleExpectedValueType;
-
- public static class CompilationContext extends AbstractExpressionCompilationContext {
- public final Map<String, ComponentTypeProperty> propertyMap;
-
- public CompilationContext(RuntimeEnvironment runtimeEnvironment,
- Map<String, ComponentTypeProperty> propertyMap) {
- super(runtimeEnvironment);
- this.propertyMap = propertyMap;
- }
- }
-
- private ServerSCLHandlerValueRequest(Pair<Resource,Resource> componentTypeAndRoot, Resource literal, String possibleExpectedValueType) {
- assert(literal != null);
- this.literal = literal;
- this.componentTypeAndRoot = componentTypeAndRoot;
- this.possibleExpectedValueType = possibleExpectedValueType;
- }
-
- public ServerSCLHandlerValueRequest(ReadGraph graph, Variable context) throws DatabaseException {
- this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context.getPredicateResource(graph)));
- }
-
- public ServerSCLHandlerValueRequest(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
- this(getComponentTypeAndRoot(graph, s, o), o, resolveExpectedValueType(graph, p));
- }
-
- private static Pair<Resource,Resource> getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException {
- Variable parent = property.getParent(graph);
- Resource represents = parent.getRepresents(graph);
- if(represents != null) {
- Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(represents));
- if(type != null) {
- Resource root = graph.syncRequest(new IndexRoot(type));
- return Pair.make(type, root);
- }
- }
- parent = parent.getParent(graph);
- Resource root = graph.syncRequest(new IndexRoot(property.getRepresents(graph)));
- return Pair.make(parent.getType(graph), root);
- }
-
- private static Pair<Resource,Resource> getComponentTypeAndRoot(ReadGraph graph, Resource component, Resource literal) throws DatabaseException {
- if(component != null) {
- Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(component));
- if(type != null) {
- Resource root = graph.syncRequest(new IndexRoot(type));
- return Pair.make(type, root);
- } else {
- Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document));
- Resource componentType = graph.getSingleType(doc);
- Resource root = graph.syncRequest(new IndexRoot(doc));
- return Pair.make(componentType, root);
- }
- // TODO: For Antti to consider and fix later
- // Introduced to handle procedural user components where component == null
- } else if (literal != null) {
- Resource root = graph.syncRequest(new IndexRoot(literal));
- return Pair.make(null, root);
- } else {
- throw new DatabaseException("Couldn't resolve component type and root for component == null && literal == null");
- }
- //throw new IllegalStateException();
- }
+public class ServerSCLHandlerValueRequest extends ServerSCLValueRequestBase<org.simantics.document.server.request.ServerSCLHandlerValueRequest.CompilationContext> {
+
+ private final Pair<Resource,Resource> componentTypeAndRoot;
+ private final Resource literal;
+ protected String possibleExpectedValueType;
+
+ public static class CompilationContext extends AbstractExpressionCompilationContext {
+ public final Map<String, ComponentTypeProperty> propertyMap;
+
+ public CompilationContext(RuntimeEnvironment runtimeEnvironment,
+ Map<String, ComponentTypeProperty> propertyMap) {
+ super(runtimeEnvironment);
+ this.propertyMap = propertyMap;
+ }
+ }
+
+ private ServerSCLHandlerValueRequest(Pair<Resource,Resource> componentTypeAndRoot, Resource literal, String possibleExpectedValueType) {
+ assert(literal != null);
+ this.literal = literal;
+ this.componentTypeAndRoot = componentTypeAndRoot;
+ this.possibleExpectedValueType = possibleExpectedValueType;
+ }
+
+ public ServerSCLHandlerValueRequest(ReadGraph graph, Variable context) throws DatabaseException {
+ this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context.getPredicateResource(graph)));
+ }
+
+ public ServerSCLHandlerValueRequest(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
+ this(getComponentTypeAndRoot(graph, s, o), o, resolveExpectedValueType(graph, p));
+ }
+
+ private static Pair<Resource,Resource> getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException {
+ Variable parent = property.getParent(graph);
+ Resource represents = parent.getRepresents(graph);
+ if(represents != null) {
+ Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(represents));
+ if(type != null) {
+ Resource root = graph.syncRequest(new IndexRoot(type));
+ return Pair.make(type, root);
+ }
+ }
+ parent = parent.getParent(graph);
+ Resource root = graph.syncRequest(new IndexRoot(property.getRepresents(graph)));
+ return Pair.make(parent.getType(graph), root);
+ }
+
public static List<TCon> getEffects(ReadGraph graph, Variable context) throws DatabaseException {
+ HandlerFn fn = (HandlerFn)compile(graph, context);
+ return fn.effects;
+ }
+
+ public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
try {
- ServerSCLHandlerValueRequest req = new ServerSCLHandlerValueRequest(graph, context);
- return req.getExpressionEffects(graph);
+ Function1<Object,Object> exp = graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context),
+ TransientCacheListener.instance());
+ sclContext.put("graph", graph);
+ return exp.apply(context);
} catch (DatabaseException e) {
throw (DatabaseException)e;
} catch (Throwable t) {
throw new DatabaseException(t);
+ } finally {
+ sclContext.put("graph", oldGraph);
}
}
- public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
- SCLContext sclContext = SCLContext.getCurrent();
- Object oldGraph = sclContext.get("graph");
- try {
- Function1<Object,Object> exp = graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context),
- TransientCacheListener.instance());
- sclContext.put("graph", graph);
- return exp.apply(context);
- } catch (DatabaseException e) {
- throw (DatabaseException)e;
- } catch (Throwable t) {
- throw new DatabaseException(t);
- } finally {
- sclContext.put("graph", oldGraph);
- }
- }
-
- public static Function1<Object, Object> compile(ReadGraph graph, Variable context) throws DatabaseException {
- return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), TransientCacheListener.instance());
- }
-
- public static Function1<Object, Object> compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
- return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, s, o, p), TransientCacheListener.<Function1<Object,Object>>instance());
- }
-
- @Override
- protected String getExpressionText(ReadGraph graph)
- throws DatabaseException {
- Layer0 L0 = Layer0.getInstance(graph);
- String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
- return "\\context -> " + exp;
- }
-
- protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) {
- return new RuntimeEnvironmentRequest2(componentType, indexRoot) {
- @Override
- protected void fillEnvironmentSpecification(
- EnvironmentSpecification environmentSpecification) {
- }
- };
- }
-
- @Override
- protected CompilationContext getCompilationContext(ReadGraph graph) throws DatabaseException {
- return graph.syncRequest(new UnaryRead<Pair<Resource,Resource>,CompilationContext>(componentTypeAndRoot) {
- @Override
- public CompilationContext perform(ReadGraph graph) throws DatabaseException {
- RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second));
+ public static Function1<Object, Object> compile(ReadGraph graph, Variable context) throws DatabaseException {
+ return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), TransientCacheListener.instance());
+ }
+
+ public static Function1<Object, Object> compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
+ return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, s, o, p), TransientCacheListener.instance());
+ }
+
+ public static class HandlerFn extends FunctionImpl1<Object,Object> {
+
+ Function1<Object,Object> handler;
+ ArrayList<TCon> effects;
+
+ HandlerFn(Function1<Object,Object> handler, Type type) {
+ try {
+ this.handler = handler;
+ this.effects = new ArrayList<TCon>();
+ MultiFunction mfun = Types.matchFunction(type, 1);
+ mfun.effect.collectConcreteEffects(this.effects);
+ } catch(MatchException e) {
+ // Should not happen!
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Object apply(Object p0) {
+ return handler.apply(p0);
+ }
+
+ }
+
+ @Override
+ public Function1<Object, Object> perform(ReadGraph graph) throws DatabaseException {
+
+ CompilationContext context = getCompilationContext(graph);
+ Type expectedType = getExpectedType(graph, context);
+ Function1<Object,Object> handler = eval(prepareEvaluator(graph, context, expectedType), graph);
+ return new HandlerFn(handler, expectedType);
+
+ }
+
+ @Override
+ protected String getExpressionText(ReadGraph graph)
+ throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
+ return "\\context -> " + exp;
+ }
+
+ protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) {
+ return new RuntimeEnvironmentRequest2(componentType, indexRoot) {
+ @Override
+ protected void fillEnvironmentSpecification(
+ EnvironmentSpecification environmentSpecification) {
+ }
+ };
+ }
+
+ @Override
+ protected CompilationContext getCompilationContext(ReadGraph graph) throws DatabaseException {
+ return graph.syncRequest(new UnaryRead<Pair<Resource,Resource>,CompilationContext>(componentTypeAndRoot) {
+ @Override
+ public CompilationContext perform(ReadGraph graph) throws DatabaseException {
+ RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second));
Map<String, ComponentTypeProperty> propertyMap;
if (parameter.first != null) {
propertyMap =
- graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
- TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
+ graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
+ TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
} else {
// TODO: Antti to consider
// To handle procedural user components
// Map<String, ComponentTypeProperty> propertyMap =
// graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
// TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
- return new CompilationContext(runtimeEnvironment, propertyMap);
- }
- });
- }
-
- @Override
- protected Type getContextVariableType() {
- return VARIABLE;
- }
-
- private static Expression accessInputVariable(Environment environment,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) {
- SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT);
- return new EApply(new EConstant(variableParentFunction),
- new EApply(new EConstant(variableParentFunction),
- new EVariable(contextVariable)));
- }
-
- protected static Expression standardGetProperty(
- Environment environment,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name,
- Type type) {
- return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type);
- }
-
- @Override
- protected Expression getVariableAccessExpression(
- ReadGraph graph,
- CompilationContext context,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name) throws DatabaseException {
- ComponentTypeProperty property = context.propertyMap.get(name);
- if(property != null)
- return standardGetProperty(
- context.runtimeEnvironment.getEnvironment(),
- contextVariable,
- name,
- property.type == null ? Types.metaVar(Kinds.STAR) : property.type);
- else {
-
+ return new CompilationContext(runtimeEnvironment, propertyMap);
+ }
+ });
+ }
+
+ @Override
+ protected Type getContextVariableType() {
+ return VARIABLE;
+ }
+
+ private static Expression accessInputVariable(Environment environment,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) {
+ SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT);
+ return new EApply(new EConstant(variableParentFunction),
+ new EApply(new EConstant(variableParentFunction),
+ new EVariable(contextVariable)));
+ }
+
+ protected static Expression standardGetProperty(
+ Environment environment,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name,
+ Type type) {
+ return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type);
+ }
+
+ @Override
+ protected Expression getVariableAccessExpression(
+ ReadGraph graph,
+ CompilationContext context,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name) throws DatabaseException {
+ ComponentTypeProperty property = context.propertyMap.get(name);
+ if(property != null)
+ return standardGetProperty(
+ context.runtimeEnvironment.getEnvironment(),
+ contextVariable,
+ name,
+ property.type == null ? Types.metaVar(Kinds.STAR) : property.type);
+ else {
+
// if(context.propertyMap.containsKey(name)) {
//
// org.simantics.scl.compiler.elaboration.expressions.Variable parametersVariable = new org.simantics.scl.compiler.elaboration.expressions.Variable("context", COMMAND_CONTEXT);
// new ELiteral(new StringConstant(name)));
//
// }
-
- return getSpecialVariableAccessExpression(graph, context, contextVariable, name);
-
- }
- }
-
- protected Expression getSpecialVariableAccessExpression(ReadGraph graph,
- CompilationContext context,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name) throws DatabaseException {
- if(name.equals("input")) {
- Environment environment = context.runtimeEnvironment.getEnvironment();
- return accessInputVariable(environment, contextVariable);
- } else if(name.equals("self"))
- return new EVariable(contextVariable);
- else
- return null;
- }
+
+ return getSpecialVariableAccessExpression(graph, context, contextVariable, name);
+
+ }
+ }
+
+ protected Expression getSpecialVariableAccessExpression(ReadGraph graph,
+ CompilationContext context,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name) throws DatabaseException {
+ if(name.equals("input")) {
+ Environment environment = context.runtimeEnvironment.getEnvironment();
+ return accessInputVariable(environment, contextVariable);
+ } else if(name.equals("self"))
+ return new EVariable(contextVariable);
+ else
+ return null;
+ }
@Override
protected Type getExpectedType(ReadGraph graph, CompilationContext context) throws DatabaseException {
return super.getExpectedType(graph, context);
}
- @Override
- public int hashCode() {
- return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest) obj;
- return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot);
- }
+ @Override
+ public int hashCode() {
+ return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest) obj;
+ return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot);
+ }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest<CompilationContext, Object> {
+public class ServerSCLValueRequest extends ServerSCLValueRequestBase<org.simantics.document.server.request.ServerSCLValueRequest.CompilationContext> {
private final Pair<Resource,Resource> componentTypeAndRoot;
private final Resource literal;
return Pair.make(parent.getType(graph), root);
}
- private static Pair<Resource,Resource> getComponentTypeAndRoot(ReadGraph graph, Resource component, Resource literal) throws DatabaseException {
- if(component != null) {
- Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(component));
- if(type != null) {
- Resource root = graph.syncRequest(new IndexRoot(type));
- // System.err.println("getComponentTypeAndRoot3 " + graph.getPossibleURI(component) + " => " + graph.getPossibleURI(type) + " " + graph.getPossibleURI(root));
- return Pair.make(type, root);
- } else {
- Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document));
- if(doc != null) {
- Resource componentType = graph.getSingleType(doc);
- Resource root = graph.syncRequest(new IndexRoot(doc));
- return Pair.make(componentType, root);
- } else {
- //System.err.println("component = " + component);
- Resource root = graph.syncRequest(new IndexRoot(component));
-// Resource componentType = graph.getSingleType(doc);
- return Pair.make(null, root);
- }
- }
- // TODO: For Antti to consider and fix later
- // Introduced to handle procedural user components where component == null
- } else if (literal != null) {
- Resource root = graph.syncRequest(new IndexRoot(literal));
- return Pair.make(null, root);
- } else {
- throw new DatabaseException("Couldn't resolve component type and root for component == null && literal == null");
- }
- }
-
public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
SCLContext sclContext = SCLContext.getCurrent();
- Object oldGraph = sclContext.get("graph");
+ Object oldGraph = sclContext.get("graph");
try {
Function1<Object,Object> exp = compile(graph, context);
sclContext.put("graph", graph);
} catch (Throwable t) {
throw new DatabaseException(t);
} finally {
- sclContext.put("graph", oldGraph);
+ sclContext.put("graph", oldGraph);
}
}
--- /dev/null
+package org.simantics.document.server.request;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.IndexRoot;
+import org.simantics.db.common.request.PossibleTypedParent;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext;
+import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest;
+import org.simantics.document.base.ontology.DocumentationResource;
+import org.simantics.structural2.scl.FindPossibleComponentTypeRequest;
+import org.simantics.utils.datastructures.Pair;
+
+abstract public class ServerSCLValueRequestBase<ASD extends AbstractExpressionCompilationContext> extends AbstractExpressionCompilationRequest<ASD, Object> {
+
+ static Pair<Resource,Resource> getComponentTypeAndRoot(ReadGraph graph, Resource component, Resource literal) throws DatabaseException {
+ if(component != null) {
+ Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(component));
+ if(type != null) {
+ Resource root = graph.syncRequest(new IndexRoot(type));
+ return Pair.make(type, root);
+ } else {
+ Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document));
+ if(doc != null) {
+ Resource componentType = graph.getSingleType(doc);
+ Resource root = graph.syncRequest(new IndexRoot(doc));
+ return Pair.make(componentType, root);
+ } else {
+ Resource root = graph.syncRequest(new IndexRoot(component));
+ return Pair.make(null, root);
+ }
+ }
+ // TODO: For Antti to consider and fix later
+ // Introduced to handle procedural user components where component == null
+ } else if (literal != null) {
+ Resource root = graph.syncRequest(new IndexRoot(literal));
+ return Pair.make(null, root);
+ } else {
+ throw new DatabaseException("Couldn't resolve component type and root for component == null && literal == null");
+ }
+ }
+
+}
}
private static boolean isImmutable(Bundle bundle) {
- String immutable = (String) bundle.getHeaders().get("Immutable");
- return immutable != null ? "true".equals(immutable) : true;
+ String immutable = (String) bundle.getHeaders().get("Immutable");
+ if(immutable == null)
+ return true;
+ if("false".equals(immutable))
+ return false;
+ if("trueWhenDeployed".equals(immutable)) {
+ String installHint = System.getProperty("installOntologiesAsDeployed");
+ if("true".equals(installHint))
+ return true;
+ else
+ return false;
+ }
+ return true;
}
public static class TGInfo {
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
private final ModuleRepository parentRepository;
private final ModuleSourceRepository sourceRepository;
private ConcurrentHashMap<String, ModuleEntry> moduleCache = new ConcurrentHashMap<String, ModuleEntry>();
+ public Set<RuntimeEnvironment> runtimeEnvironments = new HashSet<RuntimeEnvironment>();
private static final ThreadLocal<THashSet<String>> PENDING_MODULES = new ThreadLocal<THashSet<String>>();
THashMap<String, Module> moduleMap = mapEntriesToModules(entries);
Environment environment = createEnvironment(moduleMap, imports);
THashMap<String, RuntimeModule> runtimeModuleMap = mapEntriesToRuntimeModules(entries);
- return new RuntimeEnvironmentImpl(environment, parentClassLoader, runtimeModuleMap);
+ RuntimeEnvironmentImpl result = new RuntimeEnvironmentImpl(environment, parentClassLoader, runtimeModuleMap);
+ runtimeEnvironments.add(result);
+ return result;
}
private static Environment createEnvironment(
public void setAdvisor(ModuleCompilationOptionsAdvisor advisor) {
this.advisor = advisor;
}
+
+ public Set<RuntimeEnvironment> getRuntimeEnvironments() {
+ return runtimeEnvironments;
+ }
}
\ No newline at end of file
public static final boolean TRACE_CLASS_CREATION = false;
String basePackageName;
- THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>();
+ public THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>();
THashMap<String, RuntimeModule> runtimeModuleMap;
int transientPackageId = 0;
THashMap<Constant,Object> valueCache = new THashMap<Constant,Object>();
if(bytes == null)
throw new ClassNotFoundException(name);
- return defineClass(name, bytes, 0, bytes.length);
+ clazz = defineClass(name, bytes, 0, bytes.length);
+ resolveClass(clazz);
+
+ return clazz;
+
}
@Override
private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeModule.class);
public static final boolean VALIDATE_CLASS_NAMES = true;
- public static final boolean TRACE_CLASS_CREATION = true;
+ public static final boolean TRACE_CLASS_CREATION = false;
Module module;
ModuleClassLoader classLoader;
private Class<?> getClass(String name) throws ClassNotFoundException {
- System.out.println(moduleName + ":getClass " + name);
+ Class<?> clazz = findLoadedClass(name);
+ if(clazz != null)
+ return clazz;
// If the class is not generated from SCL, use parent class loader
if(!name.startsWith(SCL_PACKAGE_PREFIX)) {
ClassVisitor cv1 = new ClassVisitor(ASM5) {};
ClassVisitor cv = new ClassRemapper(cv1, m);
cr.accept(cv, ClassReader.SKIP_DEBUG);
- System.err.println(className + " refs: " + referencedClasses);
return referencedClasses;
} catch (Exception e) {
e.printStackTrace();
return null;
}
- public void loadReferences() {
- ConcreteModule cm = (ConcreteModule)module;
- try {
- for(String className : cm.getClasses().keySet()) {
- Set<String> refs = classReferences(className);
- for(String s : refs) {
- String internalName = s.replace('/', '.');
- try {
- classLoader.loadClass(internalName);
- } catch (Throwable e) {
- e.printStackTrace();
+ public void loadClasses() {
+ if(module instanceof ConcreteModule) {
+ ConcreteModule cm = (ConcreteModule)module;
+ try {
+ for(String className : cm.getClasses().keySet()) {
+ Set<String> refs = classReferences(className);
+ for(String s : refs) {
+ String internalName = s.replace('/', '.');
+ try {
+ classLoader.getClass(internalName);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
}
}
+ } catch (Throwable e) {
+ e.printStackTrace();
}
- } catch (Throwable e) {
- e.printStackTrace();
}
}
private Type expectedType;
private LocalEnvironment localEnvironment;
private LocalStorage localStorage;
- private boolean interpretIfPossible = false;
+ private boolean interpretIfPossible = true;
private ExpressionParseMode parseMode = ExpressionParseMode.EXPRESSION;
private boolean validateOnly;
import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.runtime.ExpressionClassLoader;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
import org.simantics.scl.compiler.runtime.RuntimeModule;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
import org.simantics.scl.compiler.testing.repository.TestRepository;
return null;
}
- public static String compileAllModules2() {
+ public static String primeClassloading() {
ArrayList<String> modulesWithErrors = new ArrayList<String>();
SCLOsgi.SOURCE_REPOSITORY.forAllModules(new TObjectProcedure<String>() {
@Override
public boolean execute(String moduleName) {
- System.out.print(moduleName);
- System.out.print(" - ");
- Failable<Module> module = SCLOsgi.MODULE_REPOSITORY.getModule(moduleName);
- if(module.didSucceed()) {
- System.out.println("succeeded");
- } else if(module == DoesNotExist.INSTANCE)
- System.out.println("does not exist"); // should not happen
- else {
- System.out.println("error");
- modulesWithErrors.add(moduleName);
- }
- return true;
- }
- });
- SCLOsgi.SOURCE_REPOSITORY.forAllModules(new TObjectProcedure<String>() {
- @Override
- public boolean execute(String moduleName) {
- System.out.print(moduleName);
- System.out.print(" - ");
Failable<Module> module = SCLOsgi.MODULE_REPOSITORY.getModule(moduleName);
if(module.didSucceed()) {
Failable<RuntimeModule> frm = SCLOsgi.MODULE_REPOSITORY.getRuntimeModule(moduleName);
RuntimeModule rm = frm.getResult();
- rm.loadReferences();
- System.out.println("succeeded");
+ rm.loadClasses();
} else if(module == DoesNotExist.INSTANCE)
System.out.println("does not exist"); // should not happen
else {
return true;
}
});
- if(!modulesWithErrors.isEmpty()) {
- StringBuilder b = new StringBuilder();
- b.append("Some SCL modules failed to compile:");
- for(String module : modulesWithErrors)
- b.append(' ').append(module);
- return b.toString();
+ for(RuntimeEnvironment env : SCLOsgi.MODULE_REPOSITORY.getRuntimeEnvironments()) {
+ ExpressionClassLoader ecl = (ExpressionClassLoader)env.getMutableClassLoader();
+ for(String name : ecl.localClasses.keySet()) {
+ try {
+ ecl.loadClass(name.replace("/", "."));
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
}
return null;
}
}
}
+ public static Function1<Variable, Object> compile(ReadGraph graph, Resource componentType) throws DatabaseException {
+ return graph.syncRequest(new CompileProceduralComponentTypeRequest(componentType), TransientCacheListener.instance());
+ }
+
@Override
protected String getExpressionText(ReadGraph graph)
throws DatabaseException {