From: Antti Villberg Date: Thu, 5 Jul 2018 04:28:26 +0000 (+0300) Subject: Work in progress X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=1f8b50d81a1aa1bbd67a77f7cbc1060f2eb805d4;p=simantics%2Fplatform.git Work in progress gitlab #5 gitlab #6 Change-Id: I37da9d60fbdb476fe62dfe0f360064e924738d6f --- diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/GraphSemaphore.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/GraphSemaphore.java new file mode 100644 index 000000000..2924f0275 --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/GraphSemaphore.java @@ -0,0 +1,48 @@ +package org.simantics.db.common; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.exception.DatabaseException; + +public class GraphSemaphore extends Semaphore { + + private static final long serialVersionUID = 2114861433176831938L; + + private final AsyncReadGraph graph; + + public GraphSemaphore(AsyncReadGraph graph, int permits) { + super(permits); + this.graph = graph; + } + + public void waitFor(int permits) throws DatabaseException, InterruptedException { + + boolean success = false; + success = tryAcquire(permits); + if(success) return; + + while(!success) { + + if(graph.performPending()) { + // Some task was done + success = tryAcquire(permits); + } else { + // Nothing to do - just wait + try { + success = tryAcquire(permits, 10, TimeUnit.SECONDS); + if(!success) throw new DatabaseException("Timeout while waiting for async request to complete."); + } catch (InterruptedException e) { + throw new DatabaseException(e); + } + } + + } + + + } + + + +} diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java index d239c87f7..da3ec4af8 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java @@ -25,12 +25,14 @@ public class BlockingAsyncProcedure implements AsyncProcedure { final private Object key; private Result result = null; private Throwable exception = null; + final private AsyncReadGraph graph; final private AsyncProcedure procedure; final private Semaphore semaphore = new Semaphore(0); // final private AtomicBoolean latch; - public BlockingAsyncProcedure(AsyncProcedure procedure, Object key) { + public BlockingAsyncProcedure(AsyncReadGraph graph, AsyncProcedure procedure, Object key) { // assert(procedure != null); + this.graph = graph; this.key = key; this.procedure = procedure; if(key == null) @@ -74,14 +76,34 @@ public class BlockingAsyncProcedure implements AsyncProcedure { } - public Result get() throws DatabaseException { + private void waitFor() throws DatabaseException { + + boolean success = false; + success = semaphore.tryAcquire(); + if(success) return; + + while(!success) { + + if(graph.performPending()) { + // Some task was done + success = semaphore.tryAcquire(); + } else { + // Nothing to do - just wait + try { + success = semaphore.tryAcquire(10, TimeUnit.SECONDS); + if(!success) throw new DatabaseException("Timeout while waiting for async request to complete: " + key); + } catch (InterruptedException e) { + throw new DatabaseException(e); + } + } + + } - try { - boolean success = semaphore.tryAcquire(10, TimeUnit.SECONDS); - if(!success) throw new DatabaseException("Timeout while waiting for async request to complete: " + key); - } catch (InterruptedException e) { - throw new DatabaseException(e); - } + } + + public Result get() throws DatabaseException { + + waitFor(); if(exception != null) { if(exception instanceof DatabaseException) throw (DatabaseException)exception; diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java index f9517f7bb..53ee12219 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java @@ -11,17 +11,12 @@ *******************************************************************************/ package org.simantics.db.common.uri; -import java.util.Collection; import java.util.Map; -import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.service.CollectionSupport; -import org.simantics.layer0.Layer0; -import org.simantics.utils.Development; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,22 +30,23 @@ public class UnescapedChildMapOfResource extends ResourceRead perform(ReadGraph graph) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Collection objects = graph.getObjects(resource, L0.ConsistsOf); - CollectionSupport cs = graph.getService(CollectionSupport.class); - Map result = cs.createObjectResourceMap(String.class, objects.size()); - for(Resource r : objects) { - String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); - if(name != null) { - Resource old = result.put(name, r); - if (old != null) - LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ")."); - } else { - if(Development.DEVELOPMENT) - LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ")."); - } - } - return result; + return graph.getChildren(resource); +// Layer0 L0 = Layer0.getInstance(graph); +// Collection objects = graph.getObjects(resource, L0.ConsistsOf); +// CollectionSupport cs = graph.getService(CollectionSupport.class); +// Map result = cs.createObjectResourceMap(String.class, objects.size()); +// for(Resource r : objects) { +// String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); +// if(name != null) { +// Resource old = result.put(name, r); +// if (old != null) +// LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ")."); +// } else { +// if(Development.DEVELOPMENT) +// LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ")."); +// } +// } +// return result; } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java index fb771a35a..c1a172625 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java @@ -323,9 +323,9 @@ final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrie if(Development.DEVELOPMENT) { - impl.processor.threadLocks[0].lock(); +// impl.processor.threadLocks[0].lock(); // System.err.println("-queues=" + impl.processor.queues[0].size()); - impl.processor.threadLocks[0].unlock(); +// impl.processor.threadLocks[0].unlock(); // System.err.println("-own=" + impl.processor.ownTasks[0].size()); // System.err.println("-ownSync=" + impl.processor.ownSyncTasks[0].size()); // for(SessionTask task : impl.processor.ownSyncTasks[0]) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index f0147e047..fe0e3fcee 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -26,6 +26,7 @@ import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.Set; import java.util.function.Consumer; @@ -350,6 +351,32 @@ public class ReadGraphImpl implements ReadGraph { } } + + @Override + public Map getChildren(Resource resource) throws ValidationException, ServiceException { + + assert (resource != null); + + try { + + int rId = processor.querySupport.getId(resource); + return QueryCache.resultChildMap(this, rId, parent, null); + + } catch (ValidationException e) { + + throw new ValidationException(e); + + } catch (ServiceException e) { + + throw new ServiceException(e); + + } catch (DatabaseException e) { + + throw new ServiceException(INTERNAL_ERROR_STRING, e); + + } + + } final public Resource getRootLibrary() { return processor.getRootLibraryResource(); @@ -2065,7 +2092,7 @@ public class ReadGraphImpl implements ReadGraph { assert (request != null); // AsyncReadProcedure procedure = new AsyncReadProcedure(); - BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(null, request); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, null, request); syncRequest(request, ap); return ap.get(); // procedure.checkAndThrow(); @@ -2101,7 +2128,7 @@ public class ReadGraphImpl implements ReadGraph { ListenerBase listener = getListenerBase(procedure); - BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(procedure, request); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, procedure, request); // final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( // procedure, request); @@ -2180,7 +2207,7 @@ public class ReadGraphImpl implements ReadGraph { ListenerBase listener = getListenerBase(procedure); assert(listener == null); - BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(procedure, request); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, procedure, request); // final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( // procedure, request); @@ -5425,7 +5452,7 @@ public class ReadGraphImpl implements ReadGraph { assert (request != null); assert (procedure != null); - processor.schedule(Integer.MIN_VALUE, new SessionTask(request, processor.THREAD_MASK+1, -1) { + processor.schedule(new SessionTask(false) { @Override public void run(int thread) { @@ -5439,50 +5466,6 @@ public class ReadGraphImpl implements ReadGraph { }); - -// quer -// -// final ListenerBase listener = getListenerBase(procedure); -// -// if (parent != null || listener != null) { -// -// try { -// QueryCache.runnerReadEntry(this, request, parent, listener, procedure); -// //processor.query(this, request, parent, procedure,listener); -// } catch (DatabaseException e) { -// Logger.defaultLogError(e); -// // This throwable has already been transferred to procedure at this point - do nothing about it -// // -// } -// -// } else { -// -//// final ReadGraphImpl newGraph = newSync(); -// -// try { -// -// T result = request.perform(this); -// -// try { -// procedure.execute(this, result); -// } catch (Throwable t) { -// Logger.defaultLogError(t); -// } -// -// } catch (Throwable t) { -// -// try { -// procedure.exception(this, t); -// } catch (Throwable t2) { -// Logger.defaultLogError(t2); -// } -// -// } finally { -// -// } -// -// } - } public static ReadGraphImpl createAsync(QueryProcessor support) { @@ -5553,9 +5536,7 @@ public class ReadGraphImpl implements ReadGraph { assert (request != null); assert (procedure != null); - //final ListenerBase listener = getListenerBase(procedure); - - processor.schedule(Integer.MIN_VALUE, new SessionTask(request, processor.THREAD_MASK+1, -1) { + processor.schedule(new SessionTask(false) { @Override public void run(int thread) { @@ -5569,40 +5550,6 @@ public class ReadGraphImpl implements ReadGraph { }); - - - -// if (parent != null || listener != null) { -// -// try { -// QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure); -// //processor.query(this, request, parent, procedure, listener); -// } catch (DatabaseException e) { -// Logger.defaultLogError(e); -// } -// -// } else { -// -// try { -// -// request.perform(this, new CallWrappedSingleQueryProcedure4(procedure, request)); -// -// } catch (Throwable t) { -// -// if (t instanceof DatabaseException) -// procedure.exception(this, t); -// else -// procedure -// .exception( -// this, -// new DatabaseException( -// "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)", -// t)); -// -// } -// -// } - } @Override @@ -6874,5 +6821,10 @@ public class ReadGraphImpl implements ReadGraph { public Object getModificationCounter() { return processor.getSession().getModificationCounter(); } + + @Override + public boolean performPending() { + return processor.performPending(processor.thread.get()); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java index 008faeea5..cd540eaad 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java @@ -54,10 +54,10 @@ public class CodeGen { line(content, " return;"); line(content, " }"); } - line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(" + signature[1] + (genAsync ? ", isSync" : "") + ");"); + line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(graph, " + signature[1] + (genAsync ? ", isSync" : "") + ");"); if(genAsync) { line(content, " if(entry == null) {"); - line(content, " graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) {"); + line(content, " graph.processor.schedule(new SessionTask(false) {"); line(content, " @Override"); line(content, " public void run(int thread) {"); line(content, " try {"); @@ -102,7 +102,7 @@ public class CodeGen { String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1); - line(content, "" + clazz + " getOrCreate" + clazz + "(" + signature[0] + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {"); + line(content, "" + clazz + " getOrCreate" + clazz + "(ReadGraphImpl graph, " + signature[0] + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {"); line(content, " " + clazz + " existing = null;"); line(content, " synchronized(" + lower + "Map) {"); line(content, " existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");"); @@ -121,11 +121,11 @@ public class CodeGen { line(content, " }"); if(genAsync) { line(content, " if(existing.isPending()) {"); - line(content, " if(isSync) waitPending(existing);"); + line(content, " if(isSync) waitPending(graph, existing);"); line(content, " else return null;"); line(content, " }"); } else { - line(content, " if(existing.isPending()) waitPending(existing);"); + line(content, " if(existing.isPending()) waitPending(graph, existing);"); } line(content, " return existing;"); line(content, "}"); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java index 3e7a25190..5a6f5d0ba 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java @@ -24,7 +24,7 @@ public class QueryCache extends QueryCacheBase { super(querySupport, threads); } - Objects getOrCreateObjects(int r1, int r2) throws DatabaseException { + Objects getOrCreateObjects(ReadGraphImpl graph, int r1, int r2) throws DatabaseException { Objects existing = null; synchronized(objectsMap) { existing = (Objects)objectsMap.get(r1,r2); @@ -41,7 +41,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -57,7 +57,7 @@ public class QueryCache extends QueryCacheBase { Objects.computeForEach(graph, r1,r2, null, procedure); return; } - Objects entry = (Objects)cache.getOrCreateObjects(r1,r2); + Objects entry = (Objects)cache.getOrCreateObjects(graph, r1,r2); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureObjects; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -68,7 +68,7 @@ public class QueryCache extends QueryCacheBase { } } - Statements getOrCreateStatements(int r1, int r2) throws DatabaseException { + Statements getOrCreateStatements(ReadGraphImpl graph, int r1, int r2) throws DatabaseException { Statements existing = null; synchronized(statementsMap) { existing = (Statements)statementsMap.get(r1,r2); @@ -85,7 +85,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -101,7 +101,7 @@ public class QueryCache extends QueryCacheBase { Statements.computeForEach(graph, r1,r2, null, procedure); return; } - Statements entry = (Statements)cache.getOrCreateStatements(r1,r2); + Statements entry = (Statements)cache.getOrCreateStatements(graph, r1,r2); TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureStatements; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -112,7 +112,7 @@ public class QueryCache extends QueryCacheBase { } } - DirectObjects getOrCreateDirectObjects(int r1, int r2) throws DatabaseException { + DirectObjects getOrCreateDirectObjects(ReadGraphImpl graph, int r1, int r2) throws DatabaseException { DirectObjects existing = null; synchronized(directObjectsMap) { existing = (DirectObjects)directObjectsMap.get(r1,r2); @@ -129,7 +129,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -145,7 +145,7 @@ public class QueryCache extends QueryCacheBase { DirectObjects.computeForEach(graph, r1,r2, null, procedure); return; } - DirectObjects entry = (DirectObjects)cache.getOrCreateDirectObjects(r1,r2); + DirectObjects entry = (DirectObjects)cache.getOrCreateDirectObjects(graph, r1,r2); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectObjects; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -156,7 +156,7 @@ public class QueryCache extends QueryCacheBase { } } - RelationInfoQuery getOrCreateRelationInfoQuery(int r) throws DatabaseException { + RelationInfoQuery getOrCreateRelationInfoQuery(ReadGraphImpl graph, int r) throws DatabaseException { RelationInfoQuery existing = null; synchronized(relationInfoQueryMap) { existing = (RelationInfoQuery)relationInfoQueryMap.get(r); @@ -173,7 +173,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -189,7 +189,7 @@ public class QueryCache extends QueryCacheBase { RelationInfoQuery.computeForEach(graph, r, null, procedure); return; } - RelationInfoQuery entry = (RelationInfoQuery)cache.getOrCreateRelationInfoQuery(r); + RelationInfoQuery entry = (RelationInfoQuery)cache.getOrCreateRelationInfoQuery(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureRelationInfoQuery; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -200,7 +200,7 @@ public class QueryCache extends QueryCacheBase { } } - URIToResource getOrCreateURIToResource(String id) throws DatabaseException { + URIToResource getOrCreateURIToResource(ReadGraphImpl graph, String id) throws DatabaseException { URIToResource existing = null; synchronized(uRIToResourceMap) { existing = (URIToResource)uRIToResourceMap.get(id); @@ -217,7 +217,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -233,7 +233,7 @@ public class QueryCache extends QueryCacheBase { URIToResource.computeForEach(graph, id, null, procedure); return; } - URIToResource entry = (URIToResource)cache.getOrCreateURIToResource(id); + URIToResource entry = (URIToResource)cache.getOrCreateURIToResource(graph, id); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureURIToResource; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -244,7 +244,7 @@ public class QueryCache extends QueryCacheBase { } } - ValueQuery getOrCreateValueQuery(int r) throws DatabaseException { + ValueQuery getOrCreateValueQuery(ReadGraphImpl graph, int r) throws DatabaseException { ValueQuery existing = null; synchronized(valueQueryMap) { existing = (ValueQuery)valueQueryMap.get(r); @@ -261,7 +261,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -277,7 +277,7 @@ public class QueryCache extends QueryCacheBase { ValueQuery.computeForEach(graph, r, null, procedure); return; } - ValueQuery entry = (ValueQuery)cache.getOrCreateValueQuery(r); + ValueQuery entry = (ValueQuery)cache.getOrCreateValueQuery(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureValueQuery; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -288,7 +288,7 @@ public class QueryCache extends QueryCacheBase { } } - OrderedSet getOrCreateOrderedSet(int r) throws DatabaseException { + OrderedSet getOrCreateOrderedSet(ReadGraphImpl graph, int r) throws DatabaseException { OrderedSet existing = null; synchronized(orderedSetMap) { existing = (OrderedSet)orderedSetMap.get(r); @@ -305,7 +305,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -321,7 +321,7 @@ public class QueryCache extends QueryCacheBase { OrderedSet.computeForEach(graph, r, null, procedure); return; } - OrderedSet entry = (OrderedSet)cache.getOrCreateOrderedSet(r); + OrderedSet entry = (OrderedSet)cache.getOrCreateOrderedSet(graph, r); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureOrderedSet; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -332,7 +332,7 @@ public class QueryCache extends QueryCacheBase { } } - PrincipalTypes getOrCreatePrincipalTypes(int r) throws DatabaseException { + PrincipalTypes getOrCreatePrincipalTypes(ReadGraphImpl graph, int r) throws DatabaseException { PrincipalTypes existing = null; synchronized(principalTypesMap) { existing = (PrincipalTypes)principalTypesMap.get(r); @@ -349,7 +349,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -365,7 +365,7 @@ public class QueryCache extends QueryCacheBase { PrincipalTypes.computeForEach(graph, r, null, procedure); return; } - PrincipalTypes entry = (PrincipalTypes)cache.getOrCreatePrincipalTypes(r); + PrincipalTypes entry = (PrincipalTypes)cache.getOrCreatePrincipalTypes(graph, r); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedurePrincipalTypes; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -376,7 +376,7 @@ public class QueryCache extends QueryCacheBase { } } - DirectPredicates getOrCreateDirectPredicates(int r) throws DatabaseException { + DirectPredicates getOrCreateDirectPredicates(ReadGraphImpl graph, int r) throws DatabaseException { DirectPredicates existing = null; synchronized(directPredicatesMap) { existing = (DirectPredicates)directPredicatesMap.get(r); @@ -393,7 +393,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -409,7 +409,7 @@ public class QueryCache extends QueryCacheBase { DirectPredicates.computeForEach(graph, r, null, procedure); return; } - DirectPredicates entry = (DirectPredicates)cache.getOrCreateDirectPredicates(r); + DirectPredicates entry = (DirectPredicates)cache.getOrCreateDirectPredicates(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectPredicates; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -420,7 +420,7 @@ public class QueryCache extends QueryCacheBase { } } - Predicates getOrCreatePredicates(int r) throws DatabaseException { + Predicates getOrCreatePredicates(ReadGraphImpl graph, int r) throws DatabaseException { Predicates existing = null; synchronized(predicatesMap) { existing = (Predicates)predicatesMap.get(r); @@ -437,7 +437,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -453,7 +453,7 @@ public class QueryCache extends QueryCacheBase { Predicates.computeForEach(graph, r, null, procedure); return; } - Predicates entry = (Predicates)cache.getOrCreatePredicates(r); + Predicates entry = (Predicates)cache.getOrCreatePredicates(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedurePredicates; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -464,7 +464,7 @@ public class QueryCache extends QueryCacheBase { } } - ReadEntry getOrCreateReadEntry(Read r, boolean isSync) throws DatabaseException { + ReadEntry getOrCreateReadEntry(ReadGraphImpl graph, Read r, boolean isSync) throws DatabaseException { ReadEntry existing = null; synchronized(readEntryMap) { existing = (ReadEntry)readEntryMap.get(r); @@ -482,7 +482,7 @@ public class QueryCache extends QueryCacheBase { } } if(existing.isPending()) { - if(isSync) waitPending(existing); + if(isSync) waitPending(graph, existing); else return null; } return existing; @@ -500,9 +500,9 @@ public class QueryCache extends QueryCacheBase { ReadEntry.computeForEach(graph, r, null, procedure); return; } - ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(r, isSync); + ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(graph, r, isSync); if(entry == null) { - graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) { + graph.processor.schedule(new SessionTask(false) { @Override public void run(int thread) { try { @@ -525,7 +525,7 @@ public class QueryCache extends QueryCacheBase { } } - AsyncReadEntry getOrCreateAsyncReadEntry(AsyncRead r, boolean isSync) throws DatabaseException { + AsyncReadEntry getOrCreateAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, boolean isSync) throws DatabaseException { AsyncReadEntry existing = null; synchronized(asyncReadEntryMap) { existing = (AsyncReadEntry)asyncReadEntryMap.get(r); @@ -543,7 +543,7 @@ public class QueryCache extends QueryCacheBase { } } if(existing.isPending()) { - if(isSync) waitPending(existing); + if(isSync) waitPending(graph, existing); else return null; } return existing; @@ -561,9 +561,9 @@ public class QueryCache extends QueryCacheBase { AsyncReadEntry.computeForEach(graph, r, null, procedure); return; } - AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(r, isSync); + AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(graph, r, isSync); if(entry == null) { - graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) { + graph.processor.schedule(new SessionTask(false) { @Override public void run(int thread) { try { @@ -586,7 +586,7 @@ public class QueryCache extends QueryCacheBase { } } - Types getOrCreateTypes(int r) throws DatabaseException { + Types getOrCreateTypes(ReadGraphImpl graph, int r) throws DatabaseException { Types existing = null; synchronized(typesMap) { existing = (Types)typesMap.get(r); @@ -603,7 +603,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -619,7 +619,7 @@ public class QueryCache extends QueryCacheBase { Types.computeForEach(graph, r, null, procedure); return; } - Types entry = (Types)cache.getOrCreateTypes(r); + Types entry = (Types)cache.getOrCreateTypes(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureTypes; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -630,7 +630,7 @@ public class QueryCache extends QueryCacheBase { } } - ChildMap getOrCreateChildMap(int r) throws DatabaseException { + ChildMap getOrCreateChildMap(ReadGraphImpl graph, int r) throws DatabaseException { ChildMap existing = null; synchronized(childMapMap) { existing = (ChildMap)childMapMap.get(r); @@ -647,7 +647,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -663,7 +663,7 @@ public class QueryCache extends QueryCacheBase { ChildMap.computeForEach(graph, r, null, procedure); return; } - ChildMap entry = (ChildMap)cache.getOrCreateChildMap(r); + ChildMap entry = (ChildMap)cache.getOrCreateChildMap(graph, r); InternalProcedure> procedure_ = procedure != null ? procedure : emptyProcedureChildMap; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -674,7 +674,7 @@ public class QueryCache extends QueryCacheBase { } } - AssertedStatements getOrCreateAssertedStatements(int r1, int r2) throws DatabaseException { + AssertedStatements getOrCreateAssertedStatements(ReadGraphImpl graph, int r1, int r2) throws DatabaseException { AssertedStatements existing = null; synchronized(assertedStatementsMap) { existing = (AssertedStatements)assertedStatementsMap.get(r1,r2); @@ -691,7 +691,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -703,7 +703,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - AssertedStatements entry = (AssertedStatements)cache.getOrCreateAssertedStatements(r1,r2); + AssertedStatements entry = (AssertedStatements)cache.getOrCreateAssertedStatements(graph, r1,r2); TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedStatements; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -714,7 +714,7 @@ public class QueryCache extends QueryCacheBase { } } - AssertedPredicates getOrCreateAssertedPredicates(int r) throws DatabaseException { + AssertedPredicates getOrCreateAssertedPredicates(ReadGraphImpl graph, int r) throws DatabaseException { AssertedPredicates existing = null; synchronized(assertedPredicatesMap) { existing = (AssertedPredicates)assertedPredicatesMap.get(r); @@ -731,7 +731,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -743,7 +743,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerAssertedPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - AssertedPredicates entry = (AssertedPredicates)cache.getOrCreateAssertedPredicates(r); + AssertedPredicates entry = (AssertedPredicates)cache.getOrCreateAssertedPredicates(graph, r); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedPredicates; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -754,7 +754,7 @@ public class QueryCache extends QueryCacheBase { } } - DirectSuperRelations getOrCreateDirectSuperRelations(int r) throws DatabaseException { + DirectSuperRelations getOrCreateDirectSuperRelations(ReadGraphImpl graph, int r) throws DatabaseException { DirectSuperRelations existing = null; synchronized(directSuperRelationsMap) { existing = (DirectSuperRelations)directSuperRelationsMap.get(r); @@ -771,7 +771,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -783,7 +783,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerDirectSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - DirectSuperRelations entry = (DirectSuperRelations)cache.getOrCreateDirectSuperRelations(r); + DirectSuperRelations entry = (DirectSuperRelations)cache.getOrCreateDirectSuperRelations(graph, r); IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectSuperRelations; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -794,7 +794,7 @@ public class QueryCache extends QueryCacheBase { } } - SuperTypes getOrCreateSuperTypes(int r) throws DatabaseException { + SuperTypes getOrCreateSuperTypes(ReadGraphImpl graph, int r) throws DatabaseException { SuperTypes existing = null; synchronized(superTypesMap) { existing = (SuperTypes)superTypesMap.get(r); @@ -811,7 +811,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -823,7 +823,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(r); + SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureSuperTypes; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -834,7 +834,7 @@ public class QueryCache extends QueryCacheBase { } } - TypeHierarchy getOrCreateTypeHierarchy(int r) throws DatabaseException { + TypeHierarchy getOrCreateTypeHierarchy(ReadGraphImpl graph, int r) throws DatabaseException { TypeHierarchy existing = null; synchronized(typeHierarchyMap) { existing = (TypeHierarchy)typeHierarchyMap.get(r); @@ -851,7 +851,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -863,7 +863,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerTypeHierarchy(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(r); + TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureTypeHierarchy; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -874,7 +874,7 @@ public class QueryCache extends QueryCacheBase { } } - SuperRelations getOrCreateSuperRelations(int r) throws DatabaseException { + SuperRelations getOrCreateSuperRelations(ReadGraphImpl graph, int r) throws DatabaseException { SuperRelations existing = null; synchronized(superRelationsMap) { existing = (SuperRelations)superRelationsMap.get(r); @@ -891,7 +891,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -903,7 +903,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(r); + SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(graph, r); InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureSuperRelations; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -914,7 +914,7 @@ public class QueryCache extends QueryCacheBase { } } - MultiReadEntry getOrCreateMultiReadEntry(MultiRead r) throws DatabaseException { + MultiReadEntry getOrCreateMultiReadEntry(ReadGraphImpl graph, MultiRead r) throws DatabaseException { MultiReadEntry existing = null; synchronized(multiReadEntryMap) { existing = (MultiReadEntry)multiReadEntryMap.get(r); @@ -931,7 +931,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -943,7 +943,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerMultiReadEntry(ReadGraphImpl graph, MultiRead r, CacheEntry parent, ListenerBase listener, final AsyncMultiProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - MultiReadEntry entry = (MultiReadEntry)cache.getOrCreateMultiReadEntry(r); + MultiReadEntry entry = (MultiReadEntry)cache.getOrCreateMultiReadEntry(graph, r); AsyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureMultiReadEntry; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -954,7 +954,7 @@ public class QueryCache extends QueryCacheBase { } } - AsyncMultiReadEntry getOrCreateAsyncMultiReadEntry(AsyncMultiRead r) throws DatabaseException { + AsyncMultiReadEntry getOrCreateAsyncMultiReadEntry(ReadGraphImpl graph, AsyncMultiRead r) throws DatabaseException { AsyncMultiReadEntry existing = null; synchronized(asyncMultiReadEntryMap) { existing = (AsyncMultiReadEntry)asyncMultiReadEntryMap.get(r); @@ -971,7 +971,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -983,7 +983,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerAsyncMultiReadEntry(ReadGraphImpl graph, AsyncMultiRead r, CacheEntry parent, ListenerBase listener, final AsyncMultiProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - AsyncMultiReadEntry entry = (AsyncMultiReadEntry)cache.getOrCreateAsyncMultiReadEntry(r); + AsyncMultiReadEntry entry = (AsyncMultiReadEntry)cache.getOrCreateAsyncMultiReadEntry(graph, r); AsyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncMultiReadEntry; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); @@ -994,7 +994,7 @@ public class QueryCache extends QueryCacheBase { } } - ExternalReadEntry getOrCreateExternalReadEntry(ExternalRead r) throws DatabaseException { + ExternalReadEntry getOrCreateExternalReadEntry(ReadGraphImpl graph, ExternalRead r) throws DatabaseException { ExternalReadEntry existing = null; synchronized(externalReadEntryMap) { existing = (ExternalReadEntry)externalReadEntryMap.get(r); @@ -1011,7 +1011,7 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) waitPending(graph, existing); return existing; } @@ -1023,7 +1023,7 @@ public class QueryCache extends QueryCacheBase { public static void runnerExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - ExternalReadEntry entry = (ExternalReadEntry)cache.getOrCreateExternalReadEntry(r); + ExternalReadEntry entry = (ExternalReadEntry)cache.getOrCreateExternalReadEntry(graph, r); AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureExternalReadEntry; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) entry.performFromCache(graph, procedure_); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java index 24a2dbe96..a75d69010 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java @@ -13,6 +13,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.DebugPolicy; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; +import org.simantics.db.impl.query.QueryProcessor.SessionTask; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.db.procedure.Listener; @@ -634,31 +635,38 @@ public class QueryCacheBase { } } - public static void waitPending(CacheEntry entry) throws DatabaseException { + public static void waitPending(ReadGraphImpl graph, CacheEntry entry) throws DatabaseException { + + QueryProcessor processor = graph.processor; int counter = 0; while(entry.isPending()) { try { - Thread.sleep(1); - counter++; - if(counter > 5000) { - CacheEntryBase base = ((CacheEntryBase)entry); -// if(base.created != null) { -// System.err.println("created:"); -// base.created.printStackTrace(); -// } -// if(base.performed != null) { -// System.err.println("performed:"); -// base.performed.printStackTrace(); -// } -// if(base.ready != null) { -// System.err.println("ready:"); -// base.ready.printStackTrace(); -// } - new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest().toString()).printStackTrace(); - throw new DatabaseException("Timeout waiting for request to complete."); - //System.err.println("asd"); - //base.getQuery().recompute(null, null, entry); + SessionTask task = processor.getOwnTask(processor.thread.get()); + if(task != null) { + task.run(processor.thread.get()); + } else { + Thread.sleep(1); + counter++; + if(counter > 5000) { + CacheEntryBase base = ((CacheEntryBase)entry); +// if(base.created != null) { +// System.err.println("created:"); +// base.created.printStackTrace(); +// } +// if(base.performed != null) { +// System.err.println("performed:"); +// base.performed.printStackTrace(); +// } +// if(base.ready != null) { +// System.err.println("ready:"); +// base.ready.printStackTrace(); +// } + new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest().toString()).printStackTrace(); + throw new DatabaseException("Timeout waiting for request to complete."); + //System.err.println("asd"); + //base.getQuery().recompute(null, null, entry); + } } } catch (InterruptedException e) { } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java index 2908bd43a..5945589a3 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java @@ -162,8 +162,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap } public ThreadState[] threadStates; - public ReentrantLock[] threadLocks; - public Condition[] threadConditions; +// public ReentrantLock[] threadLocks; +// public Condition[] threadConditions; //public ArrayList[] ownTasks; @@ -178,31 +178,41 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap public void close() { } + SessionTask getOwnTask(int thread) { + synchronized(querySupportLock) { + int index = 0; + while(index < freeScheduling.size()) { + SessionTask task = freeScheduling.get(index); + if(task.thread == thread && !task.systemCall) + return freeScheduling.remove(index); + index++; + } + } + return null; + } + + public boolean performPending(int thread) { + SessionTask task = getOwnTask(thread); + if(task != null) { + task.run(thread); + return true; + } else { + return false; + } + } + // final public void scheduleOwn(int caller, SessionTask request) { // ownTasks[caller].add(request); // } - final public void scheduleAlways(int caller, SessionTask request) { - -// int performer = request.thread; -// if(caller == performer) { -// ownTasks[caller].add(request); -// } else { -// schedule(caller, request); -// } - - schedule(caller, request); - - } - - final public void schedule(int caller, SessionTask request) { + final public void schedule(SessionTask request) { int performer = request.thread; if(DebugPolicy.SCHEDULE) - System.out.println("schedule " + request + " " + caller + " -> " + performer); + System.out.println("schedule " + request + " " + " -> " + performer); - assert(performer >= 0); + //assert(performer >= 0); assert(request != null); @@ -214,18 +224,22 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap synchronized(querySupportLock) { + //new Exception().printStackTrace(); + freeScheduling.add(request); + + querySupportLock.notifyAll(); //System.err.println("schedule free task " + request + " => " + freeScheduling.size()); - for(int i=0;i throwable; - public SessionRead(Object object, DataContainer throwable, Semaphore notify, int thread) { - super(object, thread, thread); - this.throwable = throwable; - this.notify = notify; - } - - public SessionRead(Object object, DataContainer throwable, Semaphore notify, int thread, int syncThread) { - super(object, thread, syncThread); + public SessionRead(DataContainer throwable, Semaphore notify) { + super(true); this.throwable = throwable; this.notify = notify; } @@ -340,8 +350,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap executors = new QueryThread[THREADS]; // queues = new ArrayList[THREADS]; - threadLocks = new ReentrantLock[THREADS]; - threadConditions = new Condition[THREADS]; +// threadLocks = new ReentrantLock[THREADS]; +// threadConditions = new Condition[THREADS]; threadStates = new ThreadState[THREADS]; // ownTasks = new ArrayList[THREADS]; // ownSyncTasks = new ArrayList[THREADS]; @@ -359,8 +369,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap // ownTasks[i] = new ArrayList(); // ownSyncTasks[i] = new ArrayList(); // queues[i] = new ArrayList(); - threadLocks[i] = new ReentrantLock(); - threadConditions[i] = threadLocks[i].newCondition(); +// threadLocks[i] = new ReentrantLock(); +// threadConditions[i] = threadLocks[i].newCondition(); // limits[i] = false; threadStates[i] = ThreadState.INIT; @@ -4459,5 +4469,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap } return L0; } + + public static ThreadLocal thread = new ThreadLocal() { + protected Integer initialValue() { + return -1; + } + }; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java index 07a390a51..f7c56a213 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java @@ -2,6 +2,7 @@ package org.simantics.db.impl.query; import java.util.ArrayList; import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -27,15 +28,15 @@ class QueryThread extends Thread implements SessionThread { // final private ArrayList own; // final private ArrayList ownSync; // final private ArrayList queue; - final private ReentrantLock lock; - final private Condition condition; +// final private ReentrantLock lock; +// final private Condition condition; final private Object querySupportLock; final private int THREADS; final private AtomicInteger sleepers; final private ThreadState[] threadStates; // final private ArrayList[] delayQueues; - final private QueryThread[] executors; - final private ReentrantLock[] threadLocks; +// final private QueryThread[] executors; +// final private ReentrantLock[] threadLocks; // final private ArrayList[] queues; // final private ArrayList[] ownSyncTasks; @@ -47,16 +48,16 @@ class QueryThread extends Thread implements SessionThread { // own = processor.ownTasks[index]; // ownSync = processor.ownSyncTasks[index]; // queue = processor.queues[index]; - lock = processor.threadLocks[index]; - condition = processor.threadConditions[index]; +// lock = processor.threadLocks[index]; +// condition = processor.threadConditions[index]; querySupportLock = processor.querySupportLock; THREADS = processor.THREADS; sleepers = processor.sleepers; querySupport = processor.querySupport; threadStates = processor.threadStates; // delayQueues = processor.delayQueues; - executors = processor.executors; - threadLocks = processor.threadLocks; +// executors = processor.executors; +// threadLocks = processor.threadLocks; // queues = processor.queues; // ownSyncTasks = processor.ownSyncTasks; } @@ -66,9 +67,9 @@ class QueryThread extends Thread implements SessionThread { // System.err.println("qt dispose"); disposed = true; - lock.lock(); - condition.signalAll(); - lock.unlock(); +// lock.lock(); +// condition.signalAll(); +// lock.unlock(); try { exited.acquire(); @@ -96,29 +97,20 @@ class QueryThread extends Thread implements SessionThread { } + private boolean pumpTask() { + if(!processor.freeScheduling.isEmpty()) { + tasks.add(processor.freeScheduling.removeFirst()); + return true; + } + return false; + } + ArrayList newTasks(boolean doWait, ArrayList tasks) { try { while(true) { - // Perform own tasks first -// if(tasks.addAll(own)) { -// own.clear(); -// } else if (doWait && !ownSync.isEmpty()) { -// tasks.add(ownSync.remove(ownSync.size()-1)); -// } - - // Try some queued tasks -// lock.lock(); -// if(tasks.addAll(queue)) { -// queue.clear(); -// lock.unlock(); -// return tasks; -// } else { -// lock.unlock(); -// } - // Return tasks if some were found if(!tasks.isEmpty()) return tasks; @@ -126,23 +118,10 @@ class QueryThread extends Thread implements SessionThread { synchronized (querySupportLock) { -// System.err.println("check free tasks for QT " + index + " (" + processor.freeScheduling + ")"); - - if(!processor.freeScheduling.isEmpty()) { - tasks.add(processor.freeScheduling.removeFirst()); + if(pumpTask()) return tasks; - } - lock.lock(); - - // Just maybe someone inserted tasks and notified just before synchronized block -// if(tasks.addAll(queue)) { -// queue.clear(); -// lock.unlock(); -// return tasks; -// } - -// System.err.println("QT " + index + ", sleepers = " + sleepers); +// lock.lock(); // We are the last one awake if(sleepers.incrementAndGet() == THREADS) { @@ -153,12 +132,8 @@ class QueryThread extends Thread implements SessionThread { if(querySupport == null) System.err.println("null qs"); querySupport.ceased(index); -// if(tasks.addAll(own)) { -// own.clear(); -// } - // System.err.println("tasks after ceased: " + tasks.size()); - if(!tasks.isEmpty()) { - lock.unlock(); + if(pumpTask()) { +// lock.unlock(); return tasks; } @@ -175,25 +150,38 @@ class QueryThread extends Thread implements SessionThread { // We are done if(isDisposed()) { threadStates[index] = ThreadState.DISPOSED; - lock.unlock(); +// lock.unlock(); return null; } + threadStates[index] = ThreadState.SLEEP; - condition.await(); + + synchronized (querySupportLock) { + querySupportLock.wait(100); + + } + +// boolean woken = condition.await(10, TimeUnit.MILLISECONDS); +// if(!woken) { +// synchronized (querySupportLock) { +// if(!processor.freeScheduling.isEmpty()) +// System.err.println("some tasks are available!"); +// } +// } sleepers.decrementAndGet(); // We are done if(isDisposed()) { threadStates[index] = ThreadState.DISPOSED; - lock.unlock(); + //lock.unlock(); return null; } threadStates[index] = ThreadState.RUN; - lock.unlock(); + //lock.unlock(); } @@ -249,6 +237,8 @@ class QueryThread extends Thread implements SessionThread { @Override public void run() { + processor.thread.set(index); + QuerySupport support = this.querySupport; try { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TransferableGraphConfiguration2.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TransferableGraphConfiguration2.java index 27ca18f6a..e06506d66 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TransferableGraphConfiguration2.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TransferableGraphConfiguration2.java @@ -24,7 +24,11 @@ public class TransferableGraphConfiguration2 { public static class SeedSpec { public static enum SeedSpecType { - INTERNAL, ROOT, SPECIAL_ROOT + // These seeds and all their child resources (ConsistsOfProcess) are internal + INTERNAL, + // These seeds are reported as root entries in TG, + ROOT, + SPECIAL_ROOT } public final Resource resource; diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java index d9366b132..9ab54dcf6 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java @@ -39,6 +39,8 @@ import org.simantics.db.layer0.variable.RVI.ResourceRVIPart; import org.simantics.db.layer0.variable.RVI.StringRVIPart; import org.simantics.db.layer0.variable.Variables.Role; import org.simantics.layer0.Layer0; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function2; /** * Abstract implementation of Variable -interface. @@ -187,18 +189,6 @@ public abstract class AbstractVariable implements Variable { return graph.getPossibleRelatedValue2(represents, graph.getService(Layer0.class).HasLabel, getParent(graph), Bindings.STRING); } - public Resource getType(ReadGraph graph) throws DatabaseException { - - Resource resource = getPossibleRepresents(graph); - if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); - throw new DatabaseException("No type for " + getURI(graph)); - } - return graph.getSingleType(resource); - - } - public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException { throw new UnsupportedOperationException(); } @@ -950,8 +940,62 @@ public abstract class AbstractVariable implements Variable { } } + public Resource getType(ReadGraph graph) throws DatabaseException { + + Variable custom = getPossibleProperty(graph, "typeResource"); + if(custom != null) { + + Object o = custom.getPossibleValue(graph); + Function2 fn = (Function2)o; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource)fn.apply(this, Layer0.getInstance(graph).Entity); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + + } + + Resource resource = getPossibleRepresents(graph); + if(resource == null) { + String uri = getPossiblePropertyValue(graph, "typeURI"); + if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); + throw new DatabaseException("No type for " + getURI(graph)); + } + return graph.getSingleType(resource); + + } + + @Override public Resource getPossibleType(ReadGraph graph) throws DatabaseException { + + Variable custom = getPossibleProperty(graph, "typeResource"); + if(custom != null) { + + Object o = custom.getPossibleValue(graph); + Function2 fn = (Function2)o; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource)fn.apply(this, Layer0.getInstance(graph).Entity); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + + } + Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); @@ -962,6 +1006,27 @@ public abstract class AbstractVariable implements Variable { } public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException { + + Variable custom = getPossibleProperty(graph, "typeResource"); + if(custom != null) { + + Object o = custom.getPossibleValue(graph); + Function2 fn = (Function2)o; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource)fn.apply(this, baseType); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + + } + Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); @@ -973,6 +1038,26 @@ public abstract class AbstractVariable implements Variable { @Override public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException { + + Variable custom = getPossibleProperty(graph, "typeResource"); + if(custom != null) { + Object o = custom.getPossibleValue(graph); + Function2 fn = (Function2)o; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource)fn.apply(this, baseType); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + + } + Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index 08d740f26..c0c4948b7 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -412,7 +412,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleWrite(new SessionTask(request, thread, thread) { + requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { @@ -550,7 +550,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleWrite(new SessionTask(request, thread) { + requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { @@ -636,7 +636,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleWrite(new SessionTask(request, thread) { + requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { @@ -1375,7 +1375,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleWrite(new SessionTask(request, thread, thread) { + requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { @@ -1475,7 +1475,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleWrite(new SessionTask(request, thread) { + requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { @@ -1499,7 +1499,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule //int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleRead(new SessionRead(request, throwable, notify, queryProvider2.THREAD_MASK + 1, -1) { + requestManager.scheduleRead(new SessionRead(throwable, notify) { @Override public void run(int thread) { @@ -1617,7 +1617,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleRead(new SessionRead(request, null, notify, thread) { + requestManager.scheduleRead(new SessionRead(null, notify) { @Override public void run(int thread) { @@ -1643,7 +1643,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule // final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( // procedure, "request"); - BlockingAsyncProcedure wrap = new BlockingAsyncProcedure(procedure, request); + BlockingAsyncProcedure wrap = new BlockingAsyncProcedure(newGraph, procedure, request); try { @@ -1683,7 +1683,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int sync = notify != null ? thread : -1; - requestManager.scheduleRead(new SessionRead(request, null, notify, thread, sync) { + requestManager.scheduleRead(new SessionRead(null, notify) { @Override public void run(int thread) { @@ -1737,7 +1737,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleRead(new SessionRead(request, throwable, notify, thread, thread) { + requestManager.scheduleRead(new SessionRead(throwable, notify) { @Override public void run(int thread) { @@ -3524,7 +3524,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule public int getAmountOfQueryThreads() { // This must be a power of two - return 16; + return 1; // return Integer.highestOneBit(Runtime.getRuntime().availableProcessors()); } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java index fb2e1e720..2902274b9 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java @@ -118,7 +118,7 @@ public class SessionRequestManager { public synchronized void startRead(int thread, final SessionRead task) { - session.queryProvider2.scheduleAlways(thread, new SessionTask(task.object, task.thread, task.syncCaller) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { @@ -142,7 +142,7 @@ public class SessionRequestManager { public synchronized void startReadUpdate(int thread) { - session.queryProvider2.scheduleAlways(thread, new SessionTask(null, thread) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { @@ -163,7 +163,7 @@ public class SessionRequestManager { public synchronized void startWrite(int thread, final SessionTask task) { - session.queryProvider2.scheduleAlways(thread, new SessionTask((WriteTraits)task.object, task.thread) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { @@ -184,7 +184,7 @@ public class SessionRequestManager { public synchronized void startWriteUpdate(int thread) { - session.queryProvider2.scheduleAlways(thread, new SessionTask(null, thread) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { @@ -271,7 +271,7 @@ public class SessionRequestManager { if (!reads.isEmpty()) { final SessionRead read = reads.poll(); - session.queryProvider2.scheduleAlways(thread, new SessionTask(read.object, read.thread, read.syncCaller) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { @@ -312,7 +312,7 @@ public class SessionRequestManager { assert(State.INIT != state); if(State.READ == state) { - session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(task.object, task.thread, task.syncCaller) { + session.queryProvider2.schedule(new SessionTask(true) { @Override public void run(int thread) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java index 0f8d9706c..9a0097b11 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java @@ -44,7 +44,7 @@ public class UndoRedoSupportImpl implements UndoRedoSupport { final Operation fop = (Operation)ops.toArray()[0]; final DataContainer id = new DataContainer(0L); final TaskHelper th = new TaskHelper("Undo"); - session.requestManager.scheduleWrite(new SessionTask(null, 0) { + session.requestManager.scheduleWrite(new SessionTask(true) { @Override public void run(int thread) { session.flushCounter = 0; diff --git a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java index 7cc87e30b..859481727 100644 --- a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java +++ b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java @@ -39,6 +39,8 @@ import org.simantics.layer0.Layer0; import org.simantics.utils.datastructures.Pair; public class AdaptionService2 implements AdaptionService { + + int foobaz; THashMap,Class>, AdapterDeclaration> adapters = new THashMap,Class>, AdapterDeclaration>(); @@ -586,10 +588,11 @@ public class AdaptionService2 implements AdaptionService { Adapter adapter = getAdapter(g, r, context, contextClass, targetClass, possible); if(adapter == null) return null; - BlockingAsyncProcedure ap = new BlockingAsyncProcedure(null, adapter); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure(g, null, adapter); // SyncReadProcedure procedure = new SyncReadProcedure(); adapter.adapt(g, r, context, ap); + return ap.get(); // procedure.checkAndThrow(); // return procedure.result; diff --git a/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java b/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java index 088c10daa..35e3d0d8a 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java +++ b/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java @@ -1135,4 +1135,6 @@ public interface AsyncReadGraph extends AsyncRequestProcessor { boolean isImmutable(Resource resource) throws DatabaseException; + boolean performPending(); + } diff --git a/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java b/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java index bead66644..91bb052e9 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java +++ b/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java @@ -12,6 +12,7 @@ package org.simantics.db; import java.util.Collection; +import java.util.Map; import java.util.Set; import org.simantics.databoard.accessor.Accessor; @@ -108,6 +109,18 @@ public interface ReadGraph extends AsyncReadGraph, RequestProcessor { */ Resource getPossibleResource(String uri) throws ResourceNotFoundException, ValidationException, ServiceException; + /** + * Computes a map of objects related to resource with L0.ConsistsOf that also contain a L0.HasName property + * + * @param resource the resource + * @return the children + * @throws ValidationException if a resource could not be produced due to + * invalid semantics + * @throws ServiceException on connection and database failures + * @see AsyncReadGraph#forResourceByURI + */ + Map getChildren(Resource resource) throws ValidationException, ServiceException; + /** * Gets a builtin resource. For a list of builtin resources see TODO Wiki * diff --git a/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/VariableDebugger.java b/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/VariableDebugger.java index a27cd3083..285b41ee3 100644 --- a/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/VariableDebugger.java +++ b/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/VariableDebugger.java @@ -560,7 +560,10 @@ public class VariableDebugger extends Composite { if(o instanceof Connection) { Connection c = (Connection)o; ArrayList result = new ArrayList(); - for(VariableConnectionPointDescriptor v : c.getConnectionPointDescriptors(graph, base, null)) { + System.err.println("base: " + base.getURI(graph)); + for(VariableConnectionPointDescriptor v : c.getConnectionPointDescriptors(graph, base.getParent(graph), null)) { + Variable asd = v.getVariable(graph); + System.err.println("spadopo " + asd.getURI(graph)); result.add(v.getRelativeRVI(graph, base)); } return "c " + result.toString(); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java index fe7479e5d..845adb4cc 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java @@ -11,26 +11,17 @@ *******************************************************************************/ package org.simantics.diagram.adapter; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TIntProcedure; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Collection; import java.util.Set; -import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; -import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.common.primitiverequest.OrderedSet; +import org.simantics.db.common.GraphSemaphore; import org.simantics.db.common.procedure.adapter.ProcedureAdapter; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.procedure.AsyncMultiProcedure; -import org.simantics.db.procedure.AsyncProcedure; import org.simantics.diagram.content.ConnectionPartData; import org.simantics.diagram.content.ConnectionPartRequest; import org.simantics.diagram.content.DiagramContents; @@ -41,6 +32,11 @@ import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.synchronization.ErrorHandler; import org.simantics.g2d.canvas.ICanvasContext; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.set.hash.THashSet; + /** * @author Tuukka Lehtonen */ @@ -78,7 +74,7 @@ public class DiagramContentRequest extends BaseRequest components = OrderedSetUtils.toList(g, data); - Semaphore s = new Semaphore(0); + GraphSemaphore s = new GraphSemaphore(g, 0); for(Resource component : components) { @@ -162,9 +158,9 @@ public class DiagramContentRequest extends BaseRequest> getContent(Listener listener, String location, int sequenceNumber) { + System.err.println("getContent " + location); DocumentHistory history = getHistory(location, true); return history.getContent(listener, location, sequenceNumber); } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/DocumentClient.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/DocumentClient.java index b61df8cc6..ed92a30e2 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/DocumentClient.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/DocumentClient.java @@ -28,7 +28,10 @@ abstract public class DocumentClient implements Document { @Override public WidgetManager getManager(JSONObject object) { - return mapping.getWidget(object.getType()); + WidgetManager result = mapping.getWidget(object.getType()); + if(result == null) + throw new RuntimeException("No manager for type " + object.getType()); + return result; } @Override diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java index 87b244c88..1726887cb 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java @@ -10,6 +10,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import org.simantics.db.ReadGraph; +import org.simantics.db.common.GraphSemaphore; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.VariableRead; @@ -79,7 +80,7 @@ public class DocumentRequest extends VariableRead> { System.out.println(" " + node.getURI(graph)); }*/ - Semaphore done = new Semaphore(0); + GraphSemaphore done = new GraphSemaphore(graph, 0); for(Variable node : nodes) { @@ -111,12 +112,7 @@ public class DocumentRequest extends VariableRead> { } try { - boolean success = done.tryAcquire(nodes.size(), 10, TimeUnit.MILLISECONDS); - while(!success) { - success = done.tryAcquire(nodes.size(), 10, TimeUnit.MILLISECONDS); - System.err.println("still trying to acquire semaphore, avail = " + done.availablePermits() ); - } - + done.waitFor(nodes.size()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/bundles/org.simantics.document.swt.core/scl/SWT/All.scl b/bundles/org.simantics.document.swt.core/scl/SWT/All.scl index 0ef41f97c..6b616c82a 100644 --- a/bundles/org.simantics.document.swt.core/scl/SWT/All.scl +++ b/bundles/org.simantics.document.swt.core/scl/SWT/All.scl @@ -29,4 +29,9 @@ importJava "org.simantics.document.swt.core.scl.SCL" where propertyValueSetter :: Variable -> String -> AbstractEventHandler + columnsBean :: Resource -> ColumnsBean + columnBeans :: ColumnsBean -> [ColumnBean] + + columnBeanKey :: ColumnBean -> String + columnBeanLabel :: ColumnBean -> String \ No newline at end of file diff --git a/bundles/org.simantics.document.swt.core/scl/SWT/Types.scl b/bundles/org.simantics.document.swt.core/scl/SWT/Types.scl index 03fd4d9a0..28a942b78 100644 --- a/bundles/org.simantics.document.swt.core/scl/SWT/Types.scl +++ b/bundles/org.simantics.document.swt.core/scl/SWT/Types.scl @@ -2,6 +2,9 @@ importJava "org.simantics.document.swt.core.bean.ColumnBean" where data ColumnBean +importJava "org.simantics.document.swt.core.bean.ColumnsBean" where + data ColumnsBean + importJava "org.simantics.browsing.ui.StatePersistor" where data StatePersistor diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/WidgetContainer.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/WidgetContainer.java index 4fb21b2bf..f49ea2246 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/WidgetContainer.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/WidgetContainer.java @@ -38,6 +38,8 @@ public abstract class WidgetContainer { // TODO: pc may be disposed, how to handle this and why is it happening? if(pc != null && !pc.isDisposed()) createControl(document, pc, object); + else + System.err.println("whatta!"); } } return (T)control; diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/scl/SCL.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/scl/SCL.java index ad5cf7091..83fc51972 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/scl/SCL.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/scl/SCL.java @@ -1,5 +1,6 @@ package org.simantics.document.swt.core.scl; +import java.util.ArrayList; import java.util.List; import org.simantics.databoard.Bindings; @@ -17,6 +18,8 @@ import org.simantics.document.server.io.CommandContext; import org.simantics.document.server.io.CommandResult; import org.simantics.document.server.serverResponse.ServerResponse; import org.simantics.document.swt.core.SWTViews; +import org.simantics.document.swt.core.bean.ColumnBean; +import org.simantics.document.swt.core.bean.ColumnsBean; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function1; import org.simantics.scl.runtime.reporting.SCLReportingHandler; @@ -107,5 +110,23 @@ public class SCL { public static Resource wseResource(ReadGraph graph, WorkbenchSelectionElement wse) throws DatabaseException { return WorkbenchSelectionUtils.getPossibleResource(wse); } + + public static ColumnsBean columnsBean(ReadGraph graph, Resource value) throws DatabaseException { + return graph.getValue(value, ColumnsBean.BINDING); + } + + public static List columnBeans(ColumnsBean bean) { + ArrayList result = new ArrayList<>(); + for(ColumnBean b : bean.columns) result.add(b); + return result; + } + + public static String columnBeanKey(ColumnBean bean) { + return bean.key; + } + + public static String columnBeanLabel(ColumnBean bean) { + return bean.label; + } } diff --git a/bundles/org.simantics.layer0/graph/Layer0.pgraph b/bundles/org.simantics.layer0/graph/Layer0.pgraph index ec2048acb..f38e7f58c 100644 --- a/bundles/org.simantics.layer0/graph/Layer0.pgraph +++ b/bundles/org.simantics.layer0/graph/Layer0.pgraph @@ -25,6 +25,12 @@ L0.Entity : L0.Type >-- L0.typeURI L0.String + >-- L0.typeResource "Variable -> Resource -> Resource" + >-- L0.representsResource "Variable -> Resource" >-- L0.HasComment --> L0.String -- L0.ConsistsOf --> L0.Entity implements VariableBuilder< @Override public Variable buildChild(ReadGraph graph, Variable parent, VariableNode node, Resource child) throws DatabaseException { boolean isImmutable = graph.isImmutable(child); - Resource possibleIndexRoot = graph.syncRequest(new PossibleIndexRoot(child)); - if(possibleIndexRoot != null) { -// String puri = graph.getURI(possibleIndexRoot); -// if(puri.contains("ModelBroker")) -// isImmutable = true; -// if(NameUtils.getSafeName(graph, child).equals("Project")) -// isImmutable = false; - } if(isImmutable) { -// System.err.println("ImmutableComponentVariableContentRequest " + parent.getURI(graph) + " " + NameUtils.getSafeName(graph, child)); - ImmutableComponentVariableContent content = graph.syncRequest(new ImmutableComponentVariableContentRequest(child), TransientCacheListener.instance()); - return new ImmutableComponentVariable(parent, content); +// ImmutableComponentVariableContent content = graph.syncRequest(new ImmutableComponentVariableContentRequest(child), TransientCacheListener.instance()); +// return new ImmutableComponentVariable(parent, content); + return new StandardGraphChildVariable(parent, node, child); } else { return new StandardGraphChildVariable(parent, node, child); } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java index cef62c242..33daefbc4 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java @@ -14,7 +14,6 @@ import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource; import org.simantics.layer0.Layer0; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.ConnectionImpl; -import org.simantics.structural2.Functions.StructuralChildMapOfResource; import org.simantics.structural2.queries.ConnectionPointMapOfResource; public class ImmutableComponentVariableContentRequest extends ResourceRead { @@ -59,7 +58,15 @@ public class ImmutableComponentVariableContentRequest extends ResourceRead childSet = null; - for(Resource child : graph.syncRequest(new StructuralChildMapOfResource(resource)).values()) { + + Resource container = resource; + Resource possibleType = graph.getPossibleType(resource, STR.Component); + if(possibleType != null) { + Resource def = graph.getPossibleObject(possibleType, STR.IsDefinedBy); + if(def != null) container = def; + } + + for(Resource child : graph.getChildren(container).values()) { if(childSet == null) childSet = new HashSet<>(); childSet.add(child); diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java index d5c88782a..5298df922 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java @@ -26,7 +26,9 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; +import java.util.List; import java.util.Map.Entry; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; @@ -62,7 +64,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class contains utilities for managing bundles in a active platform. + * This class contains utilities for managing bundles in a active platform. * */ @SuppressWarnings("restriction") @@ -82,13 +84,15 @@ public class PlatformUtil { /** * Get the manifest file of a bundle * - * @param bundle bundle + * @param bundle + * bundle * @return manifest or null if doesn't not exist - * @throws IOException + * @throws IOException */ public static Manifest getManifest(Bundle bundle) throws IOException { URL url = bundle.getEntry("META-INF/MANIFEST.MF"); - if (url==null) return null; + if (url == null) + return null; try (InputStream is = url.openStream()) { return new Manifest(is); } @@ -97,39 +101,41 @@ public class PlatformUtil { /** * Get the manifest file of a bundle * - * @param bundle bundle + * @param bundle + * bundle * @return manifest or null if doesn't not exist - * @throws IOException + * @throws IOException */ public static Manifest getSimanticsManifest(Bundle bundle) throws IOException { URL url = bundle.getEntry("META-INF/SIMANTICS.MF"); - if (url==null) return null; + if (url == null) + return null; try (InputStream is = url.openStream()) { return new Manifest(is); } } - + /** - * Get a list (BundleIds) of all user installable units. These are the - * top-level items that are visible for the end-user. - * The list is acquired from the bundles of the current application. + * Get a list (BundleIds) of all user installable units. These are the top-level + * items that are visible for the end-user. The list is acquired from the + * bundles of the current application. * - * @param list of simantics features URIs - * @throws IOException + * @param list + * of simantics features URIs + * @throws IOException */ - public static void getUserInstallableUnits(Collection list) - throws IOException - { + public static void getUserInstallableUnits(Collection list) throws IOException { for (Bundle bundle : getBundles()) { Manifest manifest = getSimanticsManifest(bundle); - if (manifest==null) continue; + if (manifest == null) + continue; Attributes attributes = manifest.getMainAttributes(); for (Entry entry2 : attributes.entrySet()) { Object key = entry2.getKey(); - if (key.toString().contains("Installable-Unit")) { - String bid = entry2.getValue().toString(); - list.add( bid ); - } + if (key.toString().contains("Installable-Unit")) { + String bid = entry2.getValue().toString(); + list.add(bid); + } } } } @@ -137,69 +143,72 @@ public class PlatformUtil { /** * Get all transferable graphs in the platform * - * @param result collection to be filled with transferable graph info + * @param result + * collection to be filled with transferable graph info */ public static void getPlatformTGInfos(Collection result) { for (Bundle bundle : getBundles()) { Enumeration e = bundle.findEntries("graphs/", "*.tg", false); - if (e==null) continue; + if (e == null) + continue; while (e.hasMoreElements()) { org.osgi.framework.Version osgiVersion = bundle.getVersion(); - Version p2Version = Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), osgiVersion.getQualifier()); + Version p2Version = Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), + osgiVersion.getMicro(), osgiVersion.getQualifier()); String id = bundle.getSymbolicName(); TGInfo info = new TGInfo(); info.location = e.nextElement(); info.bundle = bundle; info.vid = new VersionedId(id, p2Version); - result.add( info ); + result.add(info); + } + } + } + + private static void uncheckedClose(Closeable closeable) { + try { + if (closeable != null) + closeable.close(); + } catch (IOException e) { + // ignore + } + } + + private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException { + FileOutputStream os = null; + InputStream is = null; + try { + if (targetFile.exists()) + targetFile.delete(); + + is = url.openStream(); + int read; + byte[] buffer = new byte[16384]; + os = new FileOutputStream(targetFile); + while ((read = is.read(buffer)) != -1) { + os.write(buffer, 0, read); } + os.close(); + is.close(); + + return targetFile; + } finally { + uncheckedClose(os); + uncheckedClose(is); } } - private static void uncheckedClose(Closeable closeable) { - try { - if (closeable != null) - closeable.close(); - } catch (IOException e) { - //ignore - } - } - - private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException { - FileOutputStream os = null; - InputStream is = null; - try { - if (targetFile.exists()) - targetFile.delete(); - - is = url.openStream(); - int read; - byte [] buffer = new byte [16384]; - os = new FileOutputStream (targetFile); - while ((read = is.read (buffer)) != -1) { - os.write(buffer, 0, read); - } - os.close (); - is.close (); - - return targetFile; - } finally { - uncheckedClose(os); - uncheckedClose(is); - } - } - - private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException { - String tmpDirStr = System.getProperty("java.io.tmpdir"); - if (tmpDirStr == null) - throw new NullPointerException("java.io.tmpdir property is null"); - File tmpDir = new File(tmpDirStr); - File libFile = new File(tmpDir, libName); - return copyResource(libURL, libFile); - } - - private static File url2file(URL url, String fileName) { + private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException { + String tmpDirStr = System.getProperty("java.io.tmpdir"); + if (tmpDirStr == null) + throw new NullPointerException("java.io.tmpdir property is null"); + File tmpDir = new File(tmpDirStr); + File libFile = new File(tmpDir, libName); + return copyResource(libURL, libFile); + } + + private static File url2file(URL url, String fileName) { if ("file".equals(url.getProtocol())) { try { File path = new File(URLDecoder.decode(url.getPath(), "UTF-8")); @@ -218,27 +227,41 @@ public class PlatformUtil { } } else { LOGGER.error("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName); - } + } return null; } + public static Collection getTGFiles(Bundle b) { + Enumeration enu = b.findEntries("/", "*.tg", false); + if (enu == null) + return Collections.emptyList(); + if (!enu.hasMoreElements()) + return Collections.emptyList(); + ArrayList result = new ArrayList<>(); + while (enu.hasMoreElements()) { + result.add(enu.nextElement()); + } + return result; + } + public static void compile(Bundle b) throws Exception { Collection sources = new ArrayList<>(); Collection dependencies = new ArrayList<>(); for (Bundle b2 : getBundles()) { - if(b.equals(b2)) continue; - URL url = b2.getEntry("graph.tg"); - if (url==null) continue; - File graphFile = url2file(FileLocator.resolve(b2.getEntry("/graph.tg")), b2.toString()); - dependencies.add(GraphCompiler.read(graphFile)); + if (b.equals(b2)) + continue; + for (URL url : getTGFiles(b2)) { + File graphFile = url2file(url, b2.toString() + url.toString()); + dependencies.add(GraphCompiler.read(graphFile)); + } } File bundleFile = FileLocator.getBundleFile(b); - if(bundleFile.isDirectory()) { + if (bundleFile.isDirectory()) { File folder = new File(bundleFile, "dynamicGraph"); - for(File f : folder.listFiles(new FilenameFilter() { + for (File f : folder.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { @@ -250,22 +273,23 @@ public class PlatformUtil { } } -// System.out.println("source is " + tmpFile.getAbsolutePath()); + // System.out.println("source is " + tmpFile.getAbsolutePath()); final StringBuilder errorStringBuilder = new StringBuilder(); GraphCompilerPreferences prefs = new GraphCompilerPreferences(); prefs.validate = true; prefs.validateRelationRestrictions = ValidationMode.ERROR; prefs.validateResourceHasType = ValidationMode.ERROR; - String currentLayer0Version = OntologyVersions.getInstance().currentOntologyVersion("http://www.simantics.org/Layer0-0.0"); + String currentLayer0Version = OntologyVersions.getInstance() + .currentOntologyVersion("http://www.simantics.org/Layer0-0.0"); CompilationResult result = GraphCompiler.compile(currentLayer0Version, sources, dependencies, null, prefs); - for(Problem problem : result.getErrors()) + for (Problem problem : result.getErrors()) errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n"); - for(Problem problem : result.getWarnings()) + for (Problem problem : result.getWarnings()) errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n"); - if(errorStringBuilder.length() > 0) { + if (errorStringBuilder.length() > 0) { LOGGER.error(errorStringBuilder.toString()); } else { GraphCompiler.write(new File(bundleFile, "graph.tg"), result.getGraph()); @@ -281,15 +305,15 @@ public class PlatformUtil { */ public static void compileAllDynamicOntologies() { for (Bundle bundle : getBundles()) { - if(bundle.getEntry("dynamicGraph") != null) { + if (bundle.getEntry("dynamicGraph") != null) { try { File bundleFile = FileLocator.getBundleFile(bundle); - if(bundleFile.isDirectory()) { + if (bundleFile.isDirectory()) { File tg = new File(bundleFile, "graph.tg"); long tgLastModified = tg.lastModified(); File folder = new File(bundleFile, "dynamicGraph"); - for(File f : folder.listFiles()) { - if(f.isFile() && f.getName().endsWith(".pgraph") && f.lastModified() > tgLastModified) { + for (File f : folder.listFiles()) { + if (f.isFile() && f.getName().endsWith(".pgraph") && f.lastModified() > tgLastModified) { compile(bundle); break; } @@ -311,24 +335,45 @@ public class PlatformUtil { public static Collection getAllGraphs() throws IOException { AtomicReference problem = new AtomicReference<>(); + // Collection gbundles = Arrays.stream(getBundles()) + // // #7806: Due to databoard Binding/Serializer construction process + // thread-unsafety + // // not even the DataContainer.readHeader invocations can run in parallel, + // most likely + // // due to recurring serializer construction for Variant datatypes. + // // Therefore, we must disable parallel loading for now. + // //.parallel() + // .map(b -> { + // try { + // return problem.get() == null ? getGraph(b) : null; + // } catch (IOException e) { + // if (LOGGER.isDebugEnabled()) + // LOGGER.debug("Could not get graph from bundle {}", b, e); + // problem.set(e); + // return null; + // } + // }) + // .filter(Objects::nonNull) + // .collect(Collectors.toList()); + Collection gbundles = Arrays.stream(getBundles()) - // #7806: Due to databoard Binding/Serializer construction process thread-unsafety - // not even the DataContainer.readHeader invocations can run in parallel, most likely + // #7806: Due to databoard Binding/Serializer construction process + // thread-unsafety + // not even the DataContainer.readHeader invocations can run in parallel, most + // likely // due to recurring serializer construction for Variant datatypes. // Therefore, we must disable parallel loading for now. - //.parallel() + // .parallel() .map(b -> { try { - return problem.get() == null ? getGraph(b) : null; + return problem.get() == null ? getGraphs(b) : null; } catch (IOException e) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Could not get graph from bundle {}", b, e); problem.set(e); return null; } - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + }).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList()); if (problem.get() != null) throw problem.get(); @@ -336,24 +381,27 @@ public class PlatformUtil { } /** - * Get bundle + * Get bundle * * @param symbolicName - * @return bundle or null if there is no bundle or graph + * @return bundle or null if there is no bundle or graph * @throws IOException */ public static GraphBundle getGraph(String symbolicName) throws IOException { Bundle bundle = Platform.getBundle(symbolicName); - if (bundle == null) return null; - return getGraph( bundle ); + if (bundle == null) + return null; + return getGraph(bundle); } /** - * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the root. + * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the + * root. * * @param bundle - * @return transferable graph, or null if there is no graph in the bundle. - * @throws IOException + * @return transferable graph, or null if there is no graph in the + * bundle. + * @throws IOException */ public static GraphBundleEx getGraph(Bundle bundle) throws IOException { URL url = bundle.getEntry("graph.tg"); @@ -363,13 +411,24 @@ public class PlatformUtil { return result != null ? result : getCompleteGraph(bundle, url); } + public static Collection getGraphs(Bundle bundle) throws IOException { + return getTGFiles(bundle).stream().map(url -> { + try { + GraphBundleEx result = tryGetOnDemandGraph(bundle, url); + return result != null ? result : getCompleteGraph(bundle, url); + } catch (IOException e) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Could not get graph from bundle url {}", url, e); + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toList()); + } + private static GraphBundleEx getCompleteGraph(Bundle bundle, URL url) throws IOException { try { - String id = bundle.getSymbolicName(); - return new GraphBundleEx( - getBundleName(bundle, id), - readTG(url), - new VersionedId(id, toP2Version(bundle)), + String id = tgFileId(bundle, url); + System.err.println("getCompleteGraph " + id); + return new GraphBundleEx(getBundleName(bundle, id), readTG(url), new VersionedId(id, toP2Version(bundle)), isImmutable(bundle)); } catch (Exception e) { throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e); @@ -378,13 +437,21 @@ public class PlatformUtil { throw e; } } + + private static String tgFileId(Bundle bundle, URL url) { + String urlString = url.toString(); + String file = urlString.substring(urlString.lastIndexOf("/")+1); + return bundle.getSymbolicName() + "_" + file; + } /** - * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the root. + * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the + * root. * * @param bundle - * @return transferable graph, or null if there is no graph in the bundle. - * @throws IOException + * @return transferable graph, or null if there is no graph in the + * bundle. + * @throws IOException */ private static GraphBundleEx tryGetOnDemandGraph(Bundle bundle, URL url) throws IOException { try { @@ -405,14 +472,12 @@ public class PlatformUtil { } }; - String id = bundle.getSymbolicName(); + String id = tgFileId(bundle, url); + + System.err.println("tryGetOnDemandGraph: " + id); - return new GraphBundleEx( - getBundleName(bundle, id), - graphSource, - cachedHash, - new VersionedId(id, toP2Version(bundle)), - isImmutable(bundle)); + return new GraphBundleEx(getBundleName(bundle, id), graphSource, cachedHash, + new VersionedId(id, toP2Version(bundle)), isImmutable(bundle)); } catch (Exception e) { throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e); } @@ -438,7 +503,8 @@ public class PlatformUtil { private static Version toP2Version(Bundle bundle) { org.osgi.framework.Version osgiVersion = bundle.getVersion(); - return Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), osgiVersion.getQualifier()); + return Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), + osgiVersion.getQualifier()); } private static String getBundleName(Bundle bundle, String id) { diff --git a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/DebugPolicy.java b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/DebugPolicy.java index 1e00e441e..563885854 100644 --- a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/DebugPolicy.java +++ b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/DebugPolicy.java @@ -6,6 +6,6 @@ package org.simantics.selectionview; */ public final class DebugPolicy { - public static final boolean DEBUG = false; + public static final boolean DEBUG = true; } diff --git a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java index 797302c44..d17c77cab 100644 --- a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java +++ b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java @@ -71,13 +71,16 @@ public class StandardSelectionProcessor implements SelectionProcessor contribution = graph.adapt(r, TabContribution.class); contributions.add(contribution); if(DebugPolicy.DEBUG) LOGGER.debug("-contribution " + graph.getURI(r)); + System.err.println("-contribution " + graph.getURI(r)); } ArrayList transforms = new ArrayList<>(); transforms.addAll(transformationFinder.find(graph, index)); if(DebugPolicy.DEBUG) { - for(Resource r : transforms) + for(Resource r : transforms) { LOGGER.debug("-transform " + NameUtils.getSafeLabel(graph, r)); + System.err.println("-transform " + NameUtils.getSafeLabel(graph, r)); + } } HashSet inputs = new HashSet<>(); @@ -100,8 +103,10 @@ public class StandardSelectionProcessor implements SelectionProcessor result = new HashSet<>(); @@ -138,6 +143,7 @@ public class StandardSelectionProcessor implements SelectionProcessor { Collection ts = graph.getTypes(resource); + for(Resource r : ts) + System.err.println("ts: " + graph.getURI(r)); + for(Resource r : types) + System.err.println("types: " + graph.getURI(r)); + if (!Collections.disjoint(types, ts)) { for(Resource r : graph.getObjects(configuration, SEL.VariableTabContribution_HasTest)) { diff --git a/bundles/org.simantics.structural.ontology/graph/Structural.pgraph b/bundles/org.simantics.structural.ontology/graph/Structural.pgraph index aa31879c5..d6d2c4aec 100644 --- a/bundles/org.simantics.structural.ontology/graph/Structural.pgraph +++ b/bundles/org.simantics.structural.ontology/graph/Structural.pgraph @@ -36,12 +36,15 @@ STR.AbstractDefinedComponentType -- STR.ProceduralComponentType.code --> STR.ProceduralComponentTypeCode -- STR.ProceduralComponentType.environment --> L0.SCLValue.Environment L0.String Resource -> Resource" STR.Run @L0.assert L0.domainChildren @@ -332,6 +336,12 @@ STR.input -- STR.TypeOverride.HasOriginalType --> STR.ComponentType -- STR.TypeOverride.HasReplacementType --> STR.ComponentType STR.TypeOverride StructuralConnection -> Resource -> [Variable] + structuralTypeResource :: Variable -> Resource -> Resource \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java index e67851f34..ea8c83b54 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java @@ -66,6 +66,7 @@ public class ConnectionImpl implements Connection { @Override public Collection getConnectionPointDescriptors(ReadGraph graph, Variable component, Resource relationType) throws DatabaseException { + System.err.println("getConnectionPointDescriptors " + component.getURI(graph)); return ConnectionBrowser.flatten(graph, component, predicate, relationType); } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java new file mode 100644 index 000000000..7b31d1108 --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java @@ -0,0 +1,47 @@ +package org.simantics.structural2; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.Functions.InterfaceResolution; + +public class DefinedUCInterfaceMap extends ResourceRead> { + + public DefinedUCInterfaceMap(Resource resource) { + super(resource); + } + + @Override + public Collection perform(ReadGraph graph) + throws DatabaseException { + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy); + if(definition != null) { + Collection result = new ArrayList(); + Layer0 L0 = Layer0.getInstance(graph); + for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) { + String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING); + for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) { + Statement stm = graph.getPossibleStatement(conn, STR.Connects); + if(stm == null) continue; + Resource component = stm.getObject(); + String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); + result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate()))); + } + } + return result; + } + return null; + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java index 19c2e8c80..bff637c34 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java @@ -27,6 +27,7 @@ import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.PossibleObjectWithType; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.uri.UnescapedChildMapOfResource; import org.simantics.db.exception.DatabaseException; @@ -47,6 +48,7 @@ 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.VariableNode; +import org.simantics.db.service.CollectionSupport; import org.simantics.issues.common.IssueUtils; import org.simantics.layer0.Layer0; import org.simantics.scl.reflection.annotations.SCLValue; @@ -66,9 +68,12 @@ import org.simantics.structural2.queries.ConnectionPointMapOfResource; import org.simantics.structural2.queries.PossibleConnectionPointInfo; import org.simantics.structural2.scl.CompileStructuralValueRequest; import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest; +import org.simantics.structural2.utils.StructuralUtils; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.Connection; import org.simantics.structural2.variables.StandardProceduralChildVariable; import org.simantics.utils.datastructures.MapList; +import org.simantics.utils.datastructures.Pair; import gnu.trove.map.hash.THashMap; @@ -277,7 +282,7 @@ public class Functions { }; - public static class StructuralChildMapOfResource extends ResourceRead> { + /*public static class StructuralChildMapOfResource extends ResourceRead> { public StructuralChildMapOfResource(Resource resource) { super(resource); @@ -299,12 +304,12 @@ public class Functions { return directChildren; } - } + }*/ - public static class StructuralChildMapOfResourceT extends ResourceRead> { + /*public static class StructuralChildMapOfResourceT extends ResourceRead> { - public StructuralChildMapOfResourceT(Resource resource) { - super(resource); + public StructuralChildMapOfResourceT(Resource type) { + super(type); } @Override @@ -319,9 +324,9 @@ public class Functions { return Collections.emptyMap(); } - } + }*/ - static class StructuralRunChildMapOfResource extends ResourceRead> { + /*static class StructuralRunChildMapOfResource extends ResourceRead> { public StructuralRunChildMapOfResource(Resource resource) { super(resource); @@ -351,6 +356,34 @@ public class Functions { } + }*/ + + static class StructuralRunContext extends ResourceRead { + + public StructuralRunContext(Resource resource) { + super(resource); + } + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + Resource model = graph.sync(new PossibleIndexRoot(resource)); + if(graph.isInstanceOf(model, L0.RVIContext)) { + return model; + } + Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration); + if(configuration != null) { + if(graph.isInstanceOf(configuration, L0.RVIContext)) { + return configuration; + } + } + + return null; + + } + } private static class SubstructureRequest extends VariableRead> { @@ -452,60 +485,279 @@ public class Functions { } } + public static class StructuralTypeOverrideMap extends ResourceRead> { + + protected StructuralTypeOverrideMap(Resource composite) { + super(composite); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + + CollectionSupport cs = graph.getService(CollectionSupport.class); + + Map result = null; + + for(Resource override : graph.getObjects(resource, STR.HasTypeOverride)) { + Resource original = graph.getSingleObject(override, STR.TypeOverride_HasOriginalType); + Resource replacement = graph.getSingleObject(override, STR.TypeOverride_HasReplacementType); + if(result == null) result = cs.createMap(Resource.class); + result.put(original, replacement); + } + + if(result == null) return Collections.emptyMap(); + + return result; + + } + + } + + public static class StructuralOverrideData { + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((actualRepresents == null) ? 0 : actualRepresents.hashCode()); + result = prime * result + ((actualType == null) ? 0 : actualType.hashCode()); + result = prime * result + ((overrideType == null) ? 0 : overrideType.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StructuralOverrideData other = (StructuralOverrideData) obj; + if (actualRepresents == null) { + if (other.actualRepresents != null) + return false; + } else if (!actualRepresents.equals(other.actualRepresents)) + return false; + if (actualType == null) { + if (other.actualType != null) + return false; + } else if (!actualType.equals(other.actualType)) + return false; + if (overrideType == null) { + if (other.overrideType != null) + return false; + } else if (!overrideType.equals(other.overrideType)) + return false; + return true; + } + Resource actualRepresents; + Resource actualType; + Resource overrideType; + public StructuralOverrideData(Resource actualRepresents, Resource actualType, Resource overrideType) { + this.actualRepresents = actualRepresents; + this.actualType = actualType; + this.overrideType = overrideType; + } + + public static StructuralOverrideData compute(ReadGraph graph, Variable context) throws DatabaseException { + return graph.syncRequest(new StructuralOverrideDataRequest(context)); + } + + public Resource type() { + if(overrideType != null) + return overrideType; + return actualType; + } + + public Resource represents() { + return actualRepresents; + } + + } + + public static class StructuralOverrideDataRequest extends VariableRead { + + public StructuralOverrideDataRequest(Variable component) { + super(component); + } + + public StructuralOverrideData walk(ReadGraph graph, Variable component, Resource actualRepresents, Resource actualType) throws DatabaseException { + System.err.println("walk: " + component.getURI(graph)); + Resource represents = component.getPossibleRepresents(graph); + if(represents != null) { + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource container = graph.syncRequest(new PossibleObjectWithType(represents, L0.PartOf, STR.Composite)); + if(container != null) { + Map overrides = graph.syncRequest(new StructuralTypeOverrideMap(container)); + if(!overrides.isEmpty()) { + System.err.println("Check overrides for " + graph.getPossibleURI(actualType)); + for(Resource r : overrides.keySet()) { + System.err.println("-available OR: " + graph.getPossibleURI(r) + " = > " + graph.getPossibleURI(overrides.get(r))); + } + } + Resource override = overrides.get(actualType); + if(override != null) { + System.err.println("Override! " + graph.getPossibleURI(actualType) + " = > " + graph.getPossibleURI(override)); + return new StructuralOverrideData(actualRepresents, actualType, override); + } + } + } + Variable parent = component.getParent(graph); + if(parent == null) return new StructuralOverrideData(actualRepresents, actualType, null); + else return walk(graph, parent, represents, actualType); + } + + @Override + public StructuralOverrideData perform(ReadGraph graph) throws DatabaseException { + + if(variable.getURI(graph).endsWith("/Alternative/Panel2")) + System.err.println("walk1: " + variable.getURI(graph)); + + Resource represents = variable.getPossibleRepresents(graph); + if(represents == null) { + String uri = variable.getPossiblePropertyValue(graph, "typeURI"); + if(uri != null) { + Resource actualType = graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); + return walk(graph, variable, null, actualType); + } + throw new DatabaseException("No type for " + variable.getURI(graph)); + } else { + return walk(graph, variable, represents, graph.getPossibleType(represents, Layer0.getInstance(graph).Entity)); + } + + } + + } + @SCLValue(type = "VariableMap") public static VariableMap structuralChildDomainChildren = new VariableMapImpl() { +// private Variable childWithTypeOverrides(ReadGraph graph, Variable parent, Resource child, String name) throws DatabaseException { +// return All.getStandardChildDomainChildVariable(graph, parent, child, name); +// } +// +// private Map childrenWithTypeOverrides(ReadGraph graph, Variable parent, Map children, Map map) throws DatabaseException { +// return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, parent, children, map); +// } + @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { + + System.err.println("foobar1: " + context.getURI(graph)); - final Resource type = context.getPossibleType(graph); - if(type != null) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - if(graph.isInstanceOf(type, STR.ProceduralComponentType)) { - Map map = graph.syncRequest(new ProceduralSubstructureRequest(context), - TransientCacheListener.>instance()); - if(map != null) return map.get(name); - } - } - - Resource represents = context.getPossibleRepresents(graph); - if(represents == null) { - Map children = graph.syncRequest(new StructuralChildMapOfResourceT(type)); + Resource type = context.getPossibleType(graph); + if(type == null) return null; + + StructuralComponentClass clazz = StructuralComponentClass.get(graph, type); + if(StructuralComponentClass.PROCEDURAL.equals(clazz)) { + Map map = graph.syncRequest(new ProceduralSubstructureRequest(context), + TransientCacheListener.>instance()); + if(map != null) return map.get(name); + return null; + } else if (StructuralComponentClass.DEFINED.equals(clazz)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource def = graph.getSingleObject(type, STR.IsDefinedBy); + Map children = graph.getChildren(def); Resource child = children.get(name); - return All.getStandardChildDomainChildVariable(graph, context, child, name); - } - Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); - Resource child = children.get(name); - return All.getStandardChildDomainChildVariable(graph, context, child, name); + if(child == null) return null; + return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); + } else { + Resource represents = context.getPossibleRepresents(graph); + if(represents == null) return null; + Map children = graph.getChildren(represents); + Resource child = children.get(name); + if(child == null) return null; + return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); + } + +// StructuralOverrideData od = StructuralOverrideData.compute(graph, context); +// if(od.type() != null) { +// StructuralResource2 STR = StructuralResource2.getInstance(graph); +// if(graph.isInstanceOf(od.type(), STR.ProceduralComponentType)) { +// Map map = graph.syncRequest(new ProceduralSubstructureRequest(context), +// TransientCacheListener.>instance()); +// if(map != null) return map.get(name); +// } +// } +// +// Resource type = context.getPossibleType(graph, baseType); +// +// Resource represents = od.represents(); +// if(represents == null) { +// Map children = graph.syncRequest(new StructuralChildMapOfResourceT(od.type())); +// Resource child = children.get(name); +// return childWithTypeOverrides(graph, context, child, name); +// } +// Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); +// Resource child = children.get(name); +// return childWithTypeOverrides(graph, context, child, name); + } @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { - final Resource type = context.getPossibleType(graph); - if(type != null) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - if(graph.isInstanceOf(type, STR.ProceduralComponentType)) { - Map mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context), - TransientCacheListener.>instance()); - if(mapPrime != null) { - if(map != null) { - map.putAll(mapPrime); - return map; - } - else - return mapPrime; - } - } - } - Resource represents = context.getPossibleRepresents(graph); - if(represents == null) { - Map children = graph.syncRequest(new StructuralChildMapOfResourceT(type)); + System.err.println("foobar2: " + context.getURI(graph)); + + Resource type = context.getPossibleType(graph); + if(type == null) return null; + + StructuralComponentClass clazz = StructuralComponentClass.get(graph, type); + if(StructuralComponentClass.PROCEDURAL.equals(clazz)) { + Map mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context), + TransientCacheListener.>instance()); + if(mapPrime != null) { + if(map != null) { + map.putAll(mapPrime); + return map; + } + else + return mapPrime; + } + return map; + } else if (StructuralComponentClass.DEFINED.equals(clazz)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource def = graph.getSingleObject(type, STR.IsDefinedBy); + Map children = graph.getChildren(def); return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); - } - Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); - return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); + } else { + Resource represents = context.getPossibleRepresents(graph); + if(represents == null) return null; + Map children = graph.getChildren(represents); + return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); + } + + +// StructuralOverrideData od = StructuralOverrideData.compute(graph, context); +// if(od.type() != null) { +// StructuralResource2 STR = StructuralResource2.getInstance(graph); +// if(graph.isInstanceOf(od.type(), STR.ProceduralComponentType)) { +// Map mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context), +// TransientCacheListener.>instance()); +// if(mapPrime != null) { +// if(map != null) { +// map.putAll(mapPrime); +// return map; +// } +// else +// return mapPrime; +// } +// } +// } +// +// Resource represents = od.represents(); +// if(represents == null) { +// Map children = graph.syncRequest(new StructuralChildMapOfResourceT(od.type())); +// return childrenWithTypeOverrides(graph, context, children, map); +// } +// Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); +// return childrenWithTypeOverrides(graph, context, children, map); + } }; @@ -515,15 +767,18 @@ public class Functions { @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { - Map children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph))); + Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph))); + if(ctx == null) return null; + Map children = graph.getChildren(ctx); Resource child = children.get(name); return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); } @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { - StandardGraphChildVariable variable = (StandardGraphChildVariable)context; - Map children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource)); + Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph))); + if(ctx == null) return map; + Map children = graph.getChildren(ctx); return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); } @@ -729,38 +984,6 @@ public class Functions { } - static class DefinedUCInterfaceMap extends ResourceRead> { - - public DefinedUCInterfaceMap(Resource resource) { - super(resource); - } - - @Override - public Collection perform(ReadGraph graph) - throws DatabaseException { - - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy); - if(definition != null) { - Collection result = new ArrayList(); - Layer0 L0 = Layer0.getInstance(graph); - for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) { - String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING); - for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) { - Statement stm = graph.getPossibleStatement(conn, STR.Connects); - if(stm == null) continue; - Resource component = stm.getObject(); - String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); - result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate()))); - } - } - return result; - } - return null; - } - - } - public static final Collection BUILTIN_STRUCTURAL_CPS = new ArrayList(); @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java index 3181dd7c4..97038c635 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java @@ -13,6 +13,7 @@ import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.WriteGraph; import org.simantics.db.common.CommentMetadata; +import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.PossibleTypedParent; import org.simantics.db.common.utils.NameUtils; @@ -23,6 +24,7 @@ import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.Functions.StructuralOverrideData; import org.simantics.structural2.internal.queries.ConnectedTo; import org.simantics.structural2.internal.queries.RelatedConnections; import org.simantics.structural2.internal.queries.RelatedConnectionsOfConnectionJoin; @@ -39,6 +41,24 @@ import gnu.trove.set.hash.THashSet; */ public class StructuralUtils { + public static enum StructuralComponentClass { + + PRIMITIVE,REPLACEABLE,DEFINED,PROCEDURAL; + + public static StructuralComponentClass get(ReadGraph graph, Resource componentType) throws DatabaseException { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) + return StructuralComponentClass.PROCEDURAL; + else if(graph.hasStatement(componentType, STR.IsDefinedBy)) + return StructuralComponentClass.DEFINED; + else if(graph.isInstanceOf(componentType, STR.ReplaceableDefinedComponentType)) + return StructuralComponentClass.REPLACEABLE; + else + return StructuralComponentClass.PRIMITIVE; + } + + } + public static Collection getConnectionRelations(ReadGraph graph, Resource componentType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); @@ -168,6 +188,7 @@ public class StructuralUtils { * Returns the component type of the given component or null if the * parameter is not a component. */ + @Deprecated public static Resource getComponentType(ReadGraph g, Resource component) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(g); return g.getPossibleType(component, STR.Component); @@ -290,5 +311,35 @@ public class StructuralUtils { public static List structuralConnectionConnectionPoints(ReadGraph graph, Variable component, Connection conn, Resource relationType) throws DatabaseException { return new ArrayList(conn.getConnectionPoints(graph, component, relationType)); } + + public static Resource structuralTypeResource(ReadGraph graph, Variable component, Resource baseType) throws DatabaseException { + + if(component.getURI(graph).endsWith("/Alternative/Alternative/Panel2")) + System.err.println("structuralTypeResource " + component.getURI(graph)); + + StructuralOverrideData od = StructuralOverrideData.compute(graph, component); + return od.type(); + +// Resource represents = component.getPossibleRepresents(graph); +// if(represents == null) { +// String uri = component.getPossiblePropertyValue(graph, "typeURI"); +// if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); +// throw new DatabaseException("No type for " + component.getURI(graph)); +// } +// return graph.getPossibleType(represents, baseType); +// +// Pair representsAndType = graph.syncRequest(new PossibleRepresentsAndTypeWithOverrides(component)); +// return representsAndType.second; + + } + + public static Resource getComponentType(ReadGraph graph, Variable configuration, Resource component) throws DatabaseException { + + Variable componentVariable = configuration.browse(graph, component); + return componentVariable.getType(graph); + + } + + } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/AbstractVariableConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/AbstractVariableConnectionPointDescriptor.java index 382c52e3f..64ea863f4 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/AbstractVariableConnectionPointDescriptor.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/AbstractVariableConnectionPointDescriptor.java @@ -23,7 +23,12 @@ abstract public class AbstractVariableConnectionPointDescriptor implements Varia @Override public Collection perform(ReadGraph graph) throws DatabaseException { - return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph)); + Variable var = parameter.getVariable(graph); + System.err.println("ComputeInterfaceDescription " + var.getURI(graph)); + Collection res = Functions.computeInterfacePaths(graph, var.getParent(graph)); + for(InterfaceResolution r : res) + System.err.println("-res " + r); + return res; } } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java index e0b93837e..249c7fc8a 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java @@ -14,50 +14,95 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.DefinedUCInterfaceMap; import org.simantics.structural2.Functions; import org.simantics.structural2.Functions.InterfaceResolution; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.ConnectionBrowser.IsLeafType; /* - * This connection descriptor variable + * This connection descriptor + * * -has not been lifted into interface * -has a structural configuration defined as resources - * -has not been drilled + * -might not be drilled + * + * Note: these are constructed after climb (before drill) phase of the connection browser. This means that + * the component can still contain sub structure during connection browsing. This means that some descriptors + * are not final and are replaced by correct descriptors during drill phase. + * */ class ActualConnectionDescriptor extends AbstractVariableConnectionPointDescriptor { - final private Variable root; - final private Resource component; - final private Resource cp; + /* + * This is the nearest known ancestor variable + */ + final Variable root; + /* + * A component on variable path under the root variable. + */ + final Resource component; + /* + * TODO + */ + final Resource componentType; + /* + * The connection point that has type of the component as its domain + */ + final Resource cp; - public ActualConnectionDescriptor(Variable root, Resource component, Resource cp) { + public ActualConnectionDescriptor(Variable root, Resource component, Resource componentType, Resource cp) { this.root = root; this.component = component; + this.componentType = componentType; this.cp = cp; } - static class ComputeInterfaceDescription extends UnaryRead> { + static class ActualConnectionDescriptorInterfaceDescription extends UnaryRead> { - public ComputeInterfaceDescription(ActualConnectionDescriptor desc) { + public ActualConnectionDescriptorInterfaceDescription(ActualConnectionDescriptor desc) { super(desc); } @Override public Collection perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource type = graph.getPossibleType(parameter.component, STR.Component); - if(graph.syncRequest(new IsLeafType(type))) return null; - - return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph)); + System.err.println("ActualConnectionDescriptorInterfaceDescription"); + + ConnectionBrowser.reportDescriptor(graph, parameter); + + /* + * The componentType is the possibly replaced (STR.ReplaceableDefinedComponentType) type + */ + StructuralComponentClass clazz = StructuralComponentClass.get(graph, parameter.componentType); + if(StructuralComponentClass.PRIMITIVE.equals(clazz)) { + return null; + } else if(StructuralComponentClass.DEFINED.equals(clazz)) { + final Collection interfaces = graph.syncRequest(new DefinedUCInterfaceMap(parameter.componentType)); + if(interfaces != null) return interfaces; + else return Functions.BUILTIN_STRUCTURAL_CPS; + } else if(StructuralComponentClass.REPLACEABLE.equals(clazz)) { + throw new DatabaseException("ConnectionBrowser does not support nested replaceable defined structural types."); + } else { + return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph)); + } } } + @Override + public boolean isLeaf(ReadGraph graph) throws DatabaseException { + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource type = graph.getPossibleType(component, STR.Component); + return graph.syncRequest(new IsLeafType(type)); + + } + @Override public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException { - return graph.syncRequest(new ComputeInterfaceDescription(this), TransientCacheAsyncListener.>instance()); + return graph.syncRequest(new ActualConnectionDescriptorInterfaceDescription(this), TransientCacheAsyncListener.>instance()); } public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java index ac1dceceb..2cc08eb3c 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java @@ -1,8 +1,5 @@ package org.simantics.structural2.variables; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -36,9 +33,14 @@ import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.Functions; import org.simantics.structural2.Functions.InterfaceResolution; import org.simantics.structural2.queries.ConnectionSet; +import org.simantics.structural2.utils.StructuralUtils; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.StandardProceduralChildVariable.FixedConnection; import org.simantics.utils.datastructures.Pair; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class ConnectionBrowser { /** @@ -79,7 +81,10 @@ public class ConnectionBrowser { Resource relation = graph.getInverse(stat.getPredicate()); //System.out.println(NameUtils.getSafeName(graph, component) + "." + NameUtils.getSafeName(graph, relation)); Resource boundConnection = graph.getPossibleObject(relation, STR.IsBoundBy); - Resource type = graph.getPossibleObject(component, L0.InstanceOf); + Resource type = StructuralUtils.getComponentType(graph, configuration, component); + // + //Resource type = StructuralUtils.getComponentType(graph, configuration, component); + //Resource type = newContext != null ? newContext.getPossibleType(graph) : graph.getPossibleObject(component, L0.InstanceOf); Resource def = type != null ? graph.getPossibleObject(type, STR.IsDefinedBy) : null; if(boundConnection != null && def != null) { // The connection point is bound in component type @@ -356,7 +361,13 @@ public class ConnectionBrowser { HashSet result = new HashSet(); for(Resource c : conns) { List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.>instance()); + for(Resource r : rs) { + System.err.println("--connections " + NameUtils.getSafeName(graph, r)); + } result.addAll(graph.syncRequest(ConnectionVariables.forStructural(graph, curConfiguration, rs))); + for(VariableConnectionPointDescriptor desc2 : result) { + reportDescriptor(graph, desc2); + } } return result; @@ -365,6 +376,9 @@ public class ConnectionBrowser { Resource connection = graph.getPossibleObject(represents, res); if(connection != null) { List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, connection), TransientCacheAsyncListener.>instance()); + for(Resource r : rs) { + System.err.println("--connections " + NameUtils.getSafeName(graph, r)); + } return graph.syncRequest(ConnectionVariables.forConfiguration(graph, curConfiguration, rs)); } else { @@ -383,6 +397,21 @@ public class ConnectionBrowser { } + public static void reportDescriptor(ReadGraph graph, VariableConnectionPointDescriptor d) throws DatabaseException { + + if(d instanceof ActualConnectionDescriptor) { + ActualConnectionDescriptor d2 = (ActualConnectionDescriptor)d; + + System.err.println("--ActualConnectionPointDescriptor2"); + System.err.println("---root: " + d2.root.getURI(graph)); + System.err.println("---component: " + graph.getPossibleURI(d2.component)); + System.err.println("---type: " + graph.getPossibleURI(d2.componentType)); + System.err.println("---cp: " + graph.getPossibleURI(d2.cp)); + System.err.println("---var: " + d2.getVariable(graph).getURI(graph)); + } + + } + public static class ConnectionVariables extends BinaryRead, Collection> { private ConnectionVariables(Variable parameter1, List parameter2) { @@ -427,15 +456,25 @@ public class ConnectionBrowser { @Override public Collection perform(ReadGraph graph) throws DatabaseException { if(parameter == null) return Collections.emptyList(); + System.err.println("ConnectionVariables " + parameter.getURI(graph)); StructuralResource2 STR = StructuralResource2.getInstance(graph); ArrayList result = null; for(int i=1;i(); - result.add(new ActualConnectionDescriptor(parameter, component, connectionPoint)); + String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); + if(parameter.getURI(graph).endsWith("SelectionView/Instance") && componentName.equals("Explorer1")) + System.err.println("asd"); + Variable possibleChild = parameter.getPossibleChild(graph, componentName); + if(possibleChild != null) { + result.add(new ActualConnectionDescriptor(parameter, component, possibleChild.getType(graph), connectionPoint)); + } else { + throw new DatabaseException("No child with name " + componentName + " could be resolved for variable " + parameter.getURI(graph)); + } } } if(result == null) return Collections.emptyList(); @@ -453,12 +492,8 @@ public class ConnectionBrowser { @Override public Boolean perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - - if(graph.isInstanceOf(resource, STR.ProceduralComponentType)) return false; - if(graph.hasStatement(resource, STR.IsDefinedBy)) return false; - - return true; + StructuralComponentClass clazz = StructuralComponentClass.get(graph, resource); + return StructuralComponentClass.PRIMITIVE.equals(clazz); } @@ -591,28 +626,52 @@ public class ConnectionBrowser { public static Collection doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { - Collection climbed = climb(graph, child, cp, null); - boolean needDrill = false; + Set result = null; + Set needDrill = null; + + String debug = child.getURI(graph) + " " + NameUtils.getSafeLabel(graph, cp); + System.err.println("doFlatten " + debug); + + if(debug.endsWith("01/TreeTable01 parent")) + System.err.println("asd"); + + Collection climbed = climb(graph, child, cp, null); for(VariableConnectionPointDescriptor desc : climbed) { if(!desc.isLeaf(graph)) { - needDrill = true; - break; + if(needDrill == null) + needDrill = new THashSet(climbed.size()); + needDrill.add(desc); + } else { + if(result == null) + result = new THashSet(climbed.size()); + result.add(desc); } } - if(!needDrill) { + if(needDrill == null) { + /* + * All descriptors were already flat - just take case of filtering + */ if(relationType != null) { ArrayList filtered = new ArrayList(climbed.size()); for(VariableConnectionPointDescriptor desc : climbed) if(filterByRelationType(graph, desc, relationType)) filtered.add(desc); return filtered; + } else { + return climbed; } - return climbed; } - THashSet result = new THashSet(climbed.size()); - for(VariableConnectionPointDescriptor top : climbed) { + + /* + * There were some descriptors that require drill + */ + for(VariableConnectionPointDescriptor top : needDrill) { + + if(debug.endsWith("01/TreeTable01 parent")) + System.err.println("asd"); + Collection drilled = drill(graph, top); if(drilled != null) { for(VariableConnectionPointDescriptor drill : drilled) { @@ -620,10 +679,22 @@ public class ConnectionBrowser { if(!filterByRelationType(graph, drill, relationType)) continue; } + if(result == null) + result = new THashSet(climbed.size()); result.add(drill); } } } + + System.err.println("doFlatten finished: " + debug); + + if(debug.endsWith("01/TreeTable01 parent")) + System.err.println("asd"); + + for(VariableConnectionPointDescriptor desc2 : result) { + reportDescriptor(graph, desc2); + } + return result; } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java new file mode 100644 index 000000000..2723dc34f --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java @@ -0,0 +1,14 @@ +package org.simantics.structural2.variables; + +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.structural2.Functions.InterfaceResolution; + +public interface ConnectionBrowserConnectionPointDescriptor { + + public boolean isLeaf(ReadGraph graph) throws DatabaseException; + public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException; + +} diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java index 403280aea..c4a3fee48 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java @@ -1,21 +1,16 @@ package org.simantics.structural2.variables; -import java.util.Collection; - import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; -import org.simantics.structural2.Functions.InterfaceResolution; -public interface VariableConnectionPointDescriptor { +public interface VariableConnectionPointDescriptor extends ConnectionBrowserConnectionPointDescriptor { public boolean isFlattenedFrom(ReadGraph graph, Variable possiblyStructuralCp) throws DatabaseException; public Variable getVariable(ReadGraph graph) throws DatabaseException; public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException; public String getURI(ReadGraph graph) throws DatabaseException; - public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException; - public boolean isLeaf(ReadGraph graph) throws DatabaseException; public boolean hasClassification(ReadGraph graph, String classification) throws DatabaseException; public String getRelativeRVI(ReadGraph graph, Variable base) throws DatabaseException; diff --git a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java index ad3b86d9c..03342b111 100644 --- a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java +++ b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java @@ -297,6 +297,7 @@ public class SimanticsPlatform implements LifecycleListener { monitor.subTask(message); LOGGER.info(message); Collection tgs = PlatformUtil.getAllGraphs(); + System.err.println("getAllGraphs " + tgs.size()); message = "extend bundles to compile versions"; monitor.subTask(message); LOGGER.info(message);