]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Work in progress
authorAntti Villberg <antti.villberg@semantum.fi>
Thu, 5 Jul 2018 04:28:26 +0000 (07:28 +0300)
committerAntti Villberg <antti.villberg@semantum.fi>
Thu, 26 Jul 2018 20:59:59 +0000 (23:59 +0300)
gitlab #5
gitlab #6

Change-Id: I37da9d60fbdb476fe62dfe0f360064e924738d6f

46 files changed:
bundles/org.simantics.db.common/src/org/simantics/db/common/GraphSemaphore.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java
bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TransferableGraphConfiguration2.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java
bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java
bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java
bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/VariableDebugger.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentHistoryCollector.java
bundles/org.simantics.document.server/src/org/simantics/document/server/client/DocumentClient.java
bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java
bundles/org.simantics.document.swt.core/scl/SWT/All.scl
bundles/org.simantics.document.swt.core/scl/SWT/Types.scl
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/WidgetContainer.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/scl/SCL.java
bundles/org.simantics.layer0/graph/Layer0.pgraph
bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableBuilder.java
bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java
bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java
bundles/org.simantics.selectionview/src/org/simantics/selectionview/DebugPolicy.java
bundles/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java
bundles/org.simantics.selectionview/src/org/simantics/selectionview/TypedVariableTabContribution.java
bundles/org.simantics.structural.ontology/graph/Structural.pgraph
bundles/org.simantics.structural2/scl/Simantics/Structural.scl
bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java
bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java [new file with mode: 0644]
bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java
bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/AbstractVariableConnectionPointDescriptor.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java [new file with mode: 0644]
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java
bundles/org.simantics/src/org/simantics/SimanticsPlatform.java

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 (file)
index 0000000..2924f02
--- /dev/null
@@ -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);
+                       }
+               }
+                               
+       }
+
+               
+       }
+       
+       
+
+}
index d239c87f709aeaa47055fcc57fdd6196a5310736..da3ec4af81a95885ff06727bae7b964fdc515c97 100644 (file)
@@ -25,12 +25,14 @@ public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
        final private Object key;
     private Result result = null;
     private Throwable exception = null;
+    final private AsyncReadGraph graph;
     final private AsyncProcedure<Result> procedure;
     final private Semaphore semaphore = new Semaphore(0);
 //    final private AtomicBoolean latch;
     
-    public BlockingAsyncProcedure(AsyncProcedure<Result> procedure, Object key) {
+    public BlockingAsyncProcedure(AsyncReadGraph graph, AsyncProcedure<Result> 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<Result> implements AsyncProcedure<Result> {
         
     }
     
-    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;
index f9517f7bbe0c495ba6e6ab9b32b5c2b1d6b3e8fe..53ee12219747f28970872bc3f1b3d86455990f99 100644 (file)
  *******************************************************************************/
 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<Map<String, Resour
        
        @Override
        public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
-           Layer0 L0 = Layer0.getInstance(graph);
-           Collection<Resource> objects = graph.getObjects(resource, L0.ConsistsOf);
-           CollectionSupport cs = graph.getService(CollectionSupport.class);
-           Map<String,Resource> 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<Resource> objects = graph.getObjects(resource, L0.ConsistsOf);
+//         CollectionSupport cs = graph.getService(CollectionSupport.class);
+//         Map<String,Resource> 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;
        }       
        
 }
index fb771a35ae606e1bdb0bebebdd55c501c0339ec7..c1a1726258eb71e1a4f575f406c967980e27f4f6 100644 (file)
@@ -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]) {
index f0147e047e001cf6f82d809a269aec65e100ed13..fe0e3fcee535b983e119730e00e7d239e789474d 100644 (file)
@@ -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<String, Resource> 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<T> procedure = new AsyncReadProcedure<T>();
-               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(null, request);
+               BlockingAsyncProcedure<T> 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<T> ap = new BlockingAsyncProcedure<>(procedure, request);
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
                
 //             final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
 //                             procedure, request);
@@ -2180,7 +2207,7 @@ public class ReadGraphImpl implements ReadGraph {
                ListenerBase listener = getListenerBase(procedure);
                assert(listener == null);
 
-               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(procedure, request);
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
                
 //             final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
 //                             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<T>(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());
+       }
     
 }
index 008faeea51589b1671a51a18d3f06ef4e72f5701..cd540eaadbf59a63c3e450999254ead404a9cefe 100644 (file)
@@ -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, "}");
index 3e7a25190df94fe225f803bea23215c770727417..5a6f5d0ba67bb120e9bfe4f4cb08e06d80e8b50c 100644 (file)
@@ -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<RelationInfo> 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<Integer> 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<byte[]> 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<IntSet> 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<IntSet> 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<IntSet> 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<ObjectResourceIdMap<String>> 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<IntSet> procedure) throws DatabaseException {
         QueryCache cache  = graph.processor.cache;
-        SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(r);
+        SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(graph, r);
         InternalProcedure<IntSet> 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<IntSet> procedure) throws DatabaseException {
         QueryCache cache  = graph.processor.cache;
-        TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(r);
+        TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(graph, r);
         InternalProcedure<IntSet> 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<IntSet> procedure) throws DatabaseException {
         QueryCache cache  = graph.processor.cache;
-        SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(r);
+        SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(graph, r);
         InternalProcedure<IntSet> 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_);
index 24a2dbe960be9ec03877a241ca0580f79ef4b3ab..a75d6901079fa6d4bab47e41fe24c8524825c5fe 100644 (file)
@@ -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) {
                        }
index 2908bd43a83680fc7f24e3fe2faafb1b25bc1b53..5945589a331c2460f83e0479f4f56f2b7425ebf2 100644 (file)
@@ -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<SessionTask>[]                           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<THREADS;i++) {
-                                               ReentrantLock queueLock = threadLocks[i];
-                                               queueLock.lock();
-                                               //queues[performer].add(request);
-                                               //if(ThreadState.SLEEP == threadStates[i]) sleepers.decrementAndGet();
-                                               threadConditions[i].signalAll();
-                                               queueLock.unlock();
-                                       }
+//                                     for(int i=0;i<THREADS;i++) {
+//                                             ReentrantLock queueLock = threadLocks[i];
+//                                             queueLock.lock();
+//                                             //queues[performer].add(request);
+//                                             //if(ThreadState.SLEEP == threadStates[i]) sleepers.decrementAndGet();
+//                                             threadConditions[i].signalAll();
+//                                             queueLock.unlock();
+//                                     }
 
                                }
 
@@ -255,26 +269,28 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        public static abstract class SessionTask {
 
                final public int thread;
-               final public int syncCaller;
-               final public Object object;
-
-               public SessionTask(WriteTraits object, int thread) {
-                       this.thread = thread;
-                       this.syncCaller = -1;
-                       this.object = object;
+               final public boolean systemCall;
+//             final public int syncCaller;
+               //final public Object object;
+
+               public SessionTask(boolean systemCall) {
+                       this.thread = QueryProcessor.thread.get();
+                       this.systemCall = systemCall;
+//                     this.syncCaller = -1;
+                       //this.object = object;
                }
 
-               public SessionTask(Object object, int thread, int syncCaller) {
-                       this.thread = thread;
-                       this.syncCaller = syncCaller;
-                       this.object = object;
-               }
+//             public SessionTask(Object object, int syncCaller) {
+//                     this.thread = QueryProcessor.thread.get();
+//                     this.syncCaller = syncCaller;
+//                     this.object = object;
+//             }
 
                public abstract void run(int thread);
 
                @Override
                public String toString() {
-                       return "SessionTask[" + object + "]";
+                       return "SessionTask[" + super.toString() + "]";
                }
 
        }
@@ -284,14 +300,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                final public Semaphore notify;
                final public DataContainer<Throwable> throwable; 
 
-               public SessionRead(Object object, DataContainer<Throwable> throwable, Semaphore notify, int thread) {
-                       super(object, thread, thread);
-                       this.throwable = throwable;
-                       this.notify = notify;
-               }
-
-               public SessionRead(Object object, DataContainer<Throwable> throwable, Semaphore notify, int thread, int syncThread) {
-                       super(object, thread, syncThread);
+               public SessionRead(DataContainer<Throwable> 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<SessionTask>();
 //                     ownSyncTasks[i] = new ArrayList<SessionTask>();
 //                     queues[i] = new ArrayList<SessionTask>();
-                       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<Integer> thread = new ThreadLocal<Integer>() {
+        protected Integer initialValue() {
+            return -1;
+        }
+    };
        
 }
index 07a390a51eafa254965f919fb8f03839b56576ff..f7c56a213d83ba92844fae162b002d713fe8931d 100644 (file)
@@ -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<SessionTask> own;
 //     final private ArrayList<SessionTask> ownSync;
 //     final private ArrayList<SessionTask> 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<SessionTask>[] delayQueues;
-       final private QueryThread[] executors;
-       final private ReentrantLock[] threadLocks;
+//     final private QueryThread[] executors;
+//     final private ReentrantLock[] threadLocks;
 //     final private ArrayList<SessionTask>[] queues;
 //     final private ArrayList<SessionTask>[] 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<SessionTask> newTasks(boolean doWait, ArrayList<SessionTask> 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 {
index 27ca18f6ae98bd801be36ffc5f742dd2f6de929a..e06506d66d3f2ef2a6c81903133cc4d169bf4303 100644 (file)
@@ -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;
index d9366b132aa2a41e471bf0cd2ea7d1c9b19cef96..9ab54dcf6a4bf6579876ed5e51c5ad4664613971 100644 (file)
@@ -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.<Resource>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<Variable,Resource,Resource> fn = (Function2<Variable,Resource,Resource>)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.<Resource>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<Variable,Resource,Resource> fn = (Function2<Variable,Resource,Resource>)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<Variable,Resource,Resource> fn = (Function2<Variable,Resource,Resource>)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<Variable,Resource,Resource> fn = (Function2<Variable,Resource,Resource>)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");
index 08d740f267d55daef3c38a8f205b0a75f7919154..c0c4948b787ab8299250340b3a41cd978c8ffea0 100644 (file)
@@ -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<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
 //                                procedure, "request");
 
-                       BlockingAsyncProcedure<T> wrap = new BlockingAsyncProcedure<T>(procedure, request);
+                       BlockingAsyncProcedure<T> wrap = new BlockingAsyncProcedure<T>(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());
     }
 
index fb2e1e720c292a71824e4083bf5c490b0e591ae6..2902274b94202c9c79610f006f5acbf91365338b 100644 (file)
@@ -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) {
index 0f8d9706c6814d089120f71996a5ebcd10fd3b62..9a0097b114138b30c767f7c32953ff6f5903ee06 100644 (file)
@@ -44,7 +44,7 @@ public class UndoRedoSupportImpl implements UndoRedoSupport {
         final Operation fop = (Operation)ops.toArray()[0];
         final DataContainer<Long> id = new DataContainer<Long>(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;
index 7cc87e30b155869c4219b47ac045404cd9361b1d..859481727bfe9f701f53cbe462dc5ecb6219b83b 100644 (file)
@@ -39,6 +39,8 @@ import org.simantics.layer0.Layer0;
 import org.simantics.utils.datastructures.Pair;
 
 public class AdaptionService2 implements AdaptionService {
+       
+       int foobaz;
 
     THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
         new THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>>();
@@ -586,10 +588,11 @@ public class AdaptionService2 implements AdaptionService {
        Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
        if(adapter == null) return null;
        
-       BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<T>(null, adapter);
+       BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<T>(g, null, adapter);
        
 //             SyncReadProcedure<T> procedure = new SyncReadProcedure<T>();
        adapter.adapt(g, r, context, ap);
+       
        return ap.get();
 //             procedure.checkAndThrow();
 //             return procedure.result;
index 088c10daa645c05b832ae4d6d0a1ffc895352f14..35e3d0d8a899f9afd9a0e04033578a7ca505ff98 100644 (file)
@@ -1135,4 +1135,6 @@ public interface AsyncReadGraph extends AsyncRequestProcessor {
     
     boolean isImmutable(Resource resource) throws DatabaseException;
     
+    boolean performPending();
+    
 }
index bead66644ff103a67c6a3ad4db713457f068c2fd..91bb052e95aea782bf60ffc7383491316902d2ca 100644 (file)
@@ -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<String,Resource> getChildren(Resource resource) throws ValidationException, ServiceException;
+
     /**
      * Gets a builtin resource. For a list of builtin resources see TODO Wiki
      * 
index a27cd30837e061c9642823891fedddbc60bb6e27..285b41ee3780d088c568f9d10123a38dbbe03c9a 100644 (file)
@@ -560,7 +560,10 @@ public class VariableDebugger extends Composite {
         if(o instanceof Connection) {
             Connection c = (Connection)o;
             ArrayList<String> result = new ArrayList<String>();
-            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();
index fe7479e5df20a5dfdf0d59a605370414d754219d..845adb4cc0d95664ec816f8986063604209734ef 100644 (file)
  *******************************************************************************/
 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<Resource, DiagramContents
         
         Collection<Resource> 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<Resource, DiagramContents
              }         
                
         }
-
+        
         try {
-                       s.acquire(components.size());
+                       s.waitFor(components.size());
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
index 9d29ef9c7544d2b9b5226215a2c385821d020e4d..aa6fedab05985c4b9fe8c84b96c182f078f1f006 100644 (file)
@@ -56,6 +56,7 @@ public class DocumentHistoryCollector {
        }
 
        public static Pair<Integer, Collection<JSONObject>> getContent(Listener<Integer> listener, String location, int sequenceNumber) {
+               System.err.println("getContent " + location);
                DocumentHistory history = getHistory(location, true);
                return history.getContent(listener, location, sequenceNumber);
        }
index b61df8cc6565adbb12f1ca91c56ae4e36bcfc57c..ed92a30e29e686f2267e5d14e88645751d73b986 100644 (file)
@@ -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
index 87b244c88ba28e1c43129cdf098a43e2f7781201..1726887cb359d8f92acafb3bb34be41dbd693165 100644 (file)
@@ -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<List<JSONObject>> {
                        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<List<JSONObject>> {
                }
                
                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();
                        }
index 0ef41f97ca0c3e400ed5d1f3fa2c787625b06c79..6b616c82a1c8eb4da8b0bce58e8467edeb2c76eb 100644 (file)
@@ -29,4 +29,9 @@ importJava "org.simantics.document.swt.core.scl.SCL" where
 
     propertyValueSetter :: Variable -> String -> <ReadGraph> AbstractEventHandler
    
+    columnsBean :: Resource -> <ReadGraph> ColumnsBean
+    columnBeans :: ColumnsBean -> [ColumnBean]
+    
+    columnBeanKey :: ColumnBean -> String
+    columnBeanLabel :: ColumnBean -> String
   
\ No newline at end of file
index 03fd4d9a0cdc34fd662f9a2ad525b1ae9ee2850d..28a942b788e6b5a6649889d2e5c3ed0c6cd25018 100644 (file)
@@ -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
 
index 4fb21b2bf8ff2e4ab2ef24977913568400eef577..f49ea2246996f7d565616ed033ff6b76ad139063 100644 (file)
@@ -38,6 +38,8 @@ public abstract class WidgetContainer<C extends Control> {
                                // 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;
index ad5cf709169a75f392e0d12165b416949e3501bb..83fc51972bfd80a3d0d088bddc802f6c8126933c 100644 (file)
@@ -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<ColumnBean> columnBeans(ColumnsBean bean) {
+       ArrayList<ColumnBean> 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;
+    }
 
 }
index ec2048acbd40d158762430d95b9b0a0e8a78167f..f38e7f58c962fee0ebe9f42f02d540cf2970a488 100644 (file)
@@ -25,6 +25,12 @@ L0.Entity : L0.Type
     >-- L0.typeURI <R L0.HasProperty : L0.FunctionalRelation
         L0.HasLabel "Type URI"
         --> L0.String
+    >-- L0.typeResource <R L0.HasProperty : L0.FunctionalRelation
+        L0.HasLabel "Type Resource"
+        ==> "Variable -> Resource -> <ReadGraph> Resource"
+    >-- L0.representsResource <R L0.HasProperty : L0.FunctionalRelation
+        L0.HasLabel "Representing Resource"
+        ==> "Variable -> <ReadGraph> Resource"
     >-- L0.HasComment --> L0.String <R L0.HasProperty
     >-- L0.ConsistsOf --> L0.Entity <R L0.IsComposedOf
         L0.InverseOf L0.PartOf : L0.FunctionalRelation
index 87a342f13b9fa0284e17e961e66dfb736446a629..6d1388caf374635bd1b5d0e54fd36b83cde835df 100644 (file)
@@ -17,18 +17,10 @@ public class ImmutableComponentVariableBuilder<Node> implements VariableBuilder<
        @Override
        public Variable buildChild(ReadGraph graph, Variable parent, VariableNode<Node> 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);
                }
index cef62c242633e7708131a47a7c92dc0b0148149d..33daefbc4b72bbc660eb76cb6909ba2b569868d9 100644 (file)
@@ -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<ImmutableComponentVariableContent> {
@@ -59,7 +58,15 @@ public class ImmutableComponentVariableContentRequest extends ResourceRead<Immut
                }
                
                HashSet<Resource> 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);
index d5c88782a87e42d980773fd8542d8af087327e46..5298df922f7ab54ebfc8d48085900bd0abe59ed2 100644 (file)
@@ -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 <tt>null</tt> 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 <tt>null</tt> 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<String> list) 
-       throws IOException 
-       {
+       public static void getUserInstallableUnits(Collection<String> 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<Object, Object> 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<TGInfo> result) {
                for (Bundle bundle : getBundles()) {
                        Enumeration<URL> 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<URL> getTGFiles(Bundle b) {
+               Enumeration<URL> enu = b.findEntries("/", "*.tg", false);
+               if (enu == null)
+                       return Collections.emptyList();
+               if (!enu.hasMoreElements())
+                       return Collections.emptyList();
+               ArrayList<URL> result = new ArrayList<>();
+               while (enu.hasMoreElements()) {
+                       result.add(enu.nextElement());
+               }
+               return result;
+       }
+
        public static void compile(Bundle b) throws Exception {
 
                Collection<ISource> sources = new ArrayList<>();
                Collection<TransferableGraph1> 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<GraphBundle> getAllGraphs() throws IOException {
                AtomicReference<IOException> problem = new AtomicReference<>();
 
+               // Collection<GraphBundle> 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<GraphBundle> 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 <tt>null</tt> if there is no bundle or graph 
+        * @return bundle or <tt>null</tt> 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 <tt>null</tt> if there is no graph in the bundle. 
-        * @throws IOException 
+        * @return transferable graph, or <tt>null</tt> 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<GraphBundleEx> 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 <tt>null</tt> if there is no graph in the bundle. 
-        * @throws IOException 
+        * @return transferable graph, or <tt>null</tt> 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) {
index 1e00e441ee6e0e32c4de11c0033bcbcee20584b7..563885854dc03529365883ded9b9333f140848e5 100644 (file)
@@ -6,6 +6,6 @@ package org.simantics.selectionview;
  */
 public final class DebugPolicy {
 
-    public static final boolean  DEBUG = false;
+    public static final boolean  DEBUG = true;
 
 }
index 797302c441be509723d412fd5b9391b1c6dd2542..d17c77cabb177b20b3440add02bcc8e327ec697f 100644 (file)
@@ -71,13 +71,16 @@ public class StandardSelectionProcessor implements SelectionProcessor<Object, Re
                                        TabContribution<?> 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<Resource> 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<Object> inputs = new HashSet<>();
@@ -100,8 +103,10 @@ public class StandardSelectionProcessor implements SelectionProcessor<Object, Re
                                }
 
                                if(DebugPolicy.DEBUG) {
-                                       for(Object o : inputs)
+                                       for(Object o : inputs) {
                                                LOGGER.debug("-input " + inputName(graph, o));
+                                               System.err.println("-input " + inputName(graph, o));
+                                       }
                                }
 
                                Set<ComparableTabContributor> result = new HashSet<>();
@@ -138,6 +143,7 @@ public class StandardSelectionProcessor implements SelectionProcessor<Object, Re
 
                                if(DebugPolicy.DEBUG) {
                                        LOGGER.debug("result: " + result);
+                                       System.err.println("result: " + result);
                                }
 
                                return result;
index 68d6cdae48e66f1b0657ee605a022014cc573e89..e30c30255eb20e2f0a4f9295432263be8d44552e 100644 (file)
@@ -124,6 +124,11 @@ public class TypedVariableTabContribution implements TabContribution<Object> {
 
         Collection<Resource> 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)) {
index aa31879c524944a994d17f72065de7d328036170..d6d2c4aec34a1035b0f463b483d7680d5919f8aa 100644 (file)
@@ -36,12 +36,15 @@ STR.AbstractDefinedComponentType <T STR.ComponentType
 
 STR.DefinedComponentType <T STR.AbstractDefinedComponentType
 
+STR.ReplaceableDefinedComponentType <T STR.AbstractDefinedComponentType
+
 STR.ProceduralComponentType <T STR.AbstractDefinedComponentType
     >-- STR.ProceduralComponentType.code --> STR.ProceduralComponentTypeCode <R L0.HasProperty : L0.TotalFunction
     >-- STR.ProceduralComponentType.environment --> L0.SCLValue.Environment <R L0.IsRelatedTo : L0.FunctionalRelation
 
 STR.ProceduralComponentTypeCode <T L0.String
 
+
 //STR.proceduralConnectionPointPath --> L0.String <R L0.HasProperty : L0.FunctionalRelation
 
 /*
@@ -262,6 +265,7 @@ STR.Component
   @L0.assert L0.domainChildren 
     STR.Functions.structuralChildDomainChildren : L0.ExternalValue
       L0.HasValueType "VariableMap"
+  @L0.sclAssertion L0.typeResource "structuralTypeResource" "Variable -> Resource -> <ReadGraph> Resource"
 
 STR.Run
   @L0.assert L0.domainChildren 
@@ -332,6 +336,12 @@ STR.input <R L0.HasProperty : L0.FunctionalRelation
 
 STR.UserDefinedProperty <T L0.Entity
 
+STR.TypeOverride <T L0.Entity
+    >-- STR.TypeOverride.HasOriginalType --> STR.ComponentType <R L0.IsRelatedTo : L0.TotalFunction
+    >-- STR.TypeOverride.HasReplacementType --> STR.ComponentType <R L0.IsRelatedTo : L0.TotalFunction 
+STR.HasTypeOverride --> STR.TypeOverride <R L0.IsRelatedTo
+
+
 STR.ComponentType
     // This relation is inherited from L0.IsComposedOf because changes in the code
     // need to be propagated to the component type
index c33e7ae9d2d32535a0aa1a09c2deba8daf9586da..7bae49413977e3575b6ba879e228857ccd6d0ef5 100644 (file)
@@ -14,3 +14,4 @@ importJava "org.simantics.structural2.variables.Connection" where
 
 importJava "org.simantics.structural2.utils.StructuralUtils" where
   structuralConnectionConnectionPoints :: Variable -> StructuralConnection -> Resource -> <ReadGraph> [Variable]
+  structuralTypeResource :: Variable -> Resource -> <ReadGraph> Resource
\ No newline at end of file
index e67851f34d6bcca7c957da91549b4f5e242134a4..ea8c83b54e334492f94e0a935faedec400b4a9cd 100644 (file)
@@ -66,6 +66,7 @@ public class ConnectionImpl implements Connection {
 
        @Override
        public Collection<VariableConnectionPointDescriptor> 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 (file)
index 0000000..7b31d11
--- /dev/null
@@ -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<Collection<InterfaceResolution>> {
+
+       public DefinedUCInterfaceMap(Resource resource) {
+               super(resource);
+       }
+
+       @Override
+       public Collection<InterfaceResolution> perform(ReadGraph graph)
+                       throws DatabaseException {
+
+               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+               Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
+               if(definition != null) {
+               Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
+                       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
index 19c2e8c800d2562a5fbfdfa519ad33d37157edd7..bff637c34c40741ba304824dbc59d5990c15c6c3 100644 (file)
@@ -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<Map<String, Resource>> {
+       /*public static class StructuralChildMapOfResource extends ResourceRead<Map<String, Resource>> {
 
                public StructuralChildMapOfResource(Resource resource) {
                        super(resource);
@@ -299,12 +304,12 @@ public class Functions {
                        return directChildren;
                }
 
-       }
+       }*/
 
-    public static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {
+    /*public static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {
 
-        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<Map<String, Resource>> {
+       /*static class StructuralRunChildMapOfResource extends ResourceRead<Map<String, Resource>> {
 
                public StructuralRunChildMapOfResource(Resource resource) {
                        super(resource);
@@ -351,6 +356,34 @@ public class Functions {
                        
                }
                
+       }*/
+
+       static class StructuralRunContext extends ResourceRead<Resource> {
+
+               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<List<SubstructureElement>> {
@@ -452,60 +485,279 @@ public class Functions {
             }
         }
         
+       public static class StructuralTypeOverrideMap extends ResourceRead<Map<Resource,Resource>> {
+
+               protected StructuralTypeOverrideMap(Resource composite) {
+                       super(composite);
+               }
+
+               @Override
+               public Map<Resource, Resource> perform(ReadGraph graph) throws DatabaseException {
+                       
+                       Layer0 L0 = Layer0.getInstance(graph);
+                       
+                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                       
+                       CollectionSupport cs = graph.getService(CollectionSupport.class);
+                       
+                       Map<Resource,Resource> 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<StructuralOverrideData> {
+
+               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<Resource,Resource> 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.<Resource>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<String, Variable> childrenWithTypeOverrides(ReadGraph graph, Variable parent, Map<String, Resource> children, Map<String, Variable> 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<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
-                               TransientCacheListener.<Map<String,Variable>>instance());
-                           if(map != null) return map.get(name);
-                   }
-               }
-
-                   Resource represents = context.getPossibleRepresents(graph);
-            if(represents == null) {
-                Map<String, Resource> 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<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
+                        TransientCacheListener.<Map<String,Variable>>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<String, Resource> children = graph.getChildren(def);
                 Resource child = children.get(name);
-                return All.getStandardChildDomainChildVariable(graph, context, child, name);
-            }
-            Map<String, Resource> 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<String, Resource> 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<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
+//                             TransientCacheListener.<Map<String,Variable>>instance());
+//                         if(map != null) return map.get(name);
+//                 }
+//             }
+//             
+//             Resource type = context.getPossibleType(graph, baseType);
+//             
+//             Resource represents = od.represents();
+//            if(represents == null) {
+//                Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(od.type()));
+//                Resource child = children.get(name);
+//                return childWithTypeOverrides(graph, context, child, name);
+//            }
+//            Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
+//            Resource child = children.get(name);
+//            return childWithTypeOverrides(graph, context, child, name);
+            
                }
 
                @Override
                public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
                        
-               final Resource type = context.getPossibleType(graph);
-               if(type != null) {
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                   if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
-                       Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
-                                       TransientCacheListener.<Map<String,Variable>>instance());
-                       if(mapPrime != null) {
-                               if(map != null) {
-                                       map.putAll(mapPrime);
-                                       return map;
-                               }
-                               else
-                                       return mapPrime;
-                       }
-                   }
-               }
-            Resource represents = context.getPossibleRepresents(graph);
-            if(represents == null) {
-                Map<String, Resource> 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<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
+                               TransientCacheListener.<Map<String,Variable>>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<String, Resource> children = graph.getChildren(def);
                 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
-            }
-            Map<String, Resource> 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<String, Resource> 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<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
+//                                     TransientCacheListener.<Map<String,Variable>>instance());
+//                     if(mapPrime != null) {
+//                             if(map != null) {
+//                                     map.putAll(mapPrime);
+//                                     return map;
+//                             }
+//                             else
+//                                     return mapPrime;
+//                     }
+//                 }
+//             }
+//             
+//             Resource represents = od.represents();
+//            if(represents == null) {
+//                Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(od.type()));
+//                return childrenWithTypeOverrides(graph, context, children, map);
+//            }
+//            Map<String, Resource> 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<String, Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph)));
+                       Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph)));
+                       if(ctx == null) return null;
+                   Map<String, Resource> children = graph.getChildren(ctx);
                        Resource child = children.get(name);
             return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
                }
 
                @Override
                public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-            StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
-            Map<String,Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource));
+                       Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph)));
+                       if(ctx == null) return map;
+                   Map<String, Resource> children = graph.getChildren(ctx);
                    return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
                }
                
@@ -729,38 +984,6 @@ public class Functions {
        
     }
     
-    static class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {
-
-       public DefinedUCInterfaceMap(Resource resource) {
-               super(resource);
-       }
-
-       @Override
-       public Collection<InterfaceResolution> perform(ReadGraph graph)
-                       throws DatabaseException {
-
-               StructuralResource2 STR = StructuralResource2.getInstance(graph);
-               Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
-               if(definition != null) {
-                       Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
-                       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<InterfaceResolution> BUILTIN_STRUCTURAL_CPS = new ArrayList<InterfaceResolution>();
 
        @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
index 3181dd7c45d7ea2434eed586393a2d2c7127c5b2..97038c63548f6833ef115c30cbd6781a11156d55 100644 (file)
@@ -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<Resource> 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<Variable> structuralConnectionConnectionPoints(ReadGraph graph, Variable component, Connection conn, Resource relationType) throws DatabaseException {
        return new ArrayList<Variable>(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.<Resource>instance());
+//             throw new DatabaseException("No type for " + component.getURI(graph));
+//     }
+//     return graph.getPossibleType(represents, baseType);
+//     
+//     Pair<Resource,Resource> 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);
+       
+    }
+    
+
 
 }
index 382c52e3fe0cf38e5f380ea16fc2bcf2dc5f7f6e..64ea863f48bc33b50de537f956c2c2a4eb6cd8af 100644 (file)
@@ -23,7 +23,12 @@ abstract public class AbstractVariableConnectionPointDescriptor implements Varia
 
                @Override
                public Collection<InterfaceResolution> 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<InterfaceResolution> res = Functions.computeInterfacePaths(graph, var.getParent(graph));
+                       for(InterfaceResolution r : res)
+                               System.err.println("-res " + r);
+                       return res;
                }
                
        }
index e0b93837ee9765deac16ba1ba2ce4dc1af5e6198..249c7fc8a897c6ef2c1e987154e8131cd4c588b4 100644 (file)
@@ -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<ActualConnectionDescriptor, Collection<InterfaceResolution>> {
+       static class ActualConnectionDescriptorInterfaceDescription extends UnaryRead<ActualConnectionDescriptor, Collection<InterfaceResolution>> {
 
-               public ComputeInterfaceDescription(ActualConnectionDescriptor desc) {
+               public ActualConnectionDescriptorInterfaceDescription(ActualConnectionDescriptor desc) {
                        super(desc);
                }
 
                @Override
                public Collection<InterfaceResolution> 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<InterfaceResolution> 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<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException {
-               return graph.syncRequest(new ComputeInterfaceDescription(this), TransientCacheAsyncListener.<Collection<InterfaceResolution>>instance());
+               return graph.syncRequest(new ActualConnectionDescriptorInterfaceDescription(this), TransientCacheAsyncListener.<Collection<InterfaceResolution>>instance());
        }
        
        public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException {
index ac1dceceb3ddfce6739ece5c01909ebc7c618c7a..2cc08eb3c70f643feee67b27b0d0d207caf9c962 100644 (file)
@@ -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<VariableConnectionPointDescriptor> result = new HashSet<VariableConnectionPointDescriptor>();
                        for(Resource c : conns) {
                                List<Resource> rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.<List<Resource>>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<Resource> rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, connection), TransientCacheAsyncListener.<List<Resource>>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<Variable, List<Resource>, Collection<VariableConnectionPointDescriptor>> {
 
        private ConnectionVariables(Variable parameter1, List<Resource> parameter2) {
@@ -427,15 +456,25 @@ public class ConnectionBrowser {
                @Override
                public Collection<VariableConnectionPointDescriptor> perform(ReadGraph graph) throws DatabaseException {
                        if(parameter == null) return Collections.emptyList();
+                       System.err.println("ConnectionVariables " + parameter.getURI(graph));
                        StructuralResource2 STR = StructuralResource2.getInstance(graph);
             ArrayList<VariableConnectionPointDescriptor> result = null;
             for(int i=1;i<parameter2.size();i++) {
                Resource connRes = parameter2.get(i);
                for(Statement stm : graph.getStatements(connRes, STR.Connects)) {
+                       Layer0 L0 = Layer0.getInstance(graph);
                        Resource component = stm.getObject();
                        Resource connectionPoint = graph.getInverse(stm.getPredicate());
                        if(result == null) result = new ArrayList<VariableConnectionPointDescriptor>();
-                       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<VariableConnectionPointDescriptor> doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException {
        
-        Collection<VariableConnectionPointDescriptor> climbed = climb(graph, child, cp, null);
-        boolean needDrill = false;
+        Set<VariableConnectionPointDescriptor> result = null;
+        Set<VariableConnectionPointDescriptor> 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<VariableConnectionPointDescriptor> climbed = climb(graph, child, cp, null);
         for(VariableConnectionPointDescriptor desc : climbed) {
                if(!desc.isLeaf(graph)) {
-                       needDrill = true;
-                       break;
+                       if(needDrill == null)
+                               needDrill = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
+                       needDrill.add(desc);
+               } else {
+                       if(result == null)
+                               result = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
+                       result.add(desc);
                }
         }
         
-        if(!needDrill) {
+        if(needDrill == null) {
+               /*
+                * All descriptors were already flat - just take case of filtering
+                */
             if(relationType != null) {
                 ArrayList<VariableConnectionPointDescriptor> filtered = new ArrayList<VariableConnectionPointDescriptor>(climbed.size());
                 for(VariableConnectionPointDescriptor desc : climbed)
                     if(filterByRelationType(graph, desc, relationType))
                         filtered.add(desc);
                 return filtered;
+            } else {
+                return climbed;
             }
-            return climbed;
         }
         
-        THashSet<VariableConnectionPointDescriptor> result = new THashSet<VariableConnectionPointDescriptor>(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<VariableConnectionPointDescriptor> 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<VariableConnectionPointDescriptor>(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 (file)
index 0000000..2723dc3
--- /dev/null
@@ -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<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException;
+
+}
index 403280aea6eb0279841d21bbd0d12a4914f99c9d..c4a3fee48f448214f48415539b756ade1b07f272 100644 (file)
@@ -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<InterfaceResolution> 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;
        
index ad3b86d9c989814c64fbb1783c5a8982fe60940c..03342b1113af33eaad35b5883169b22932474367 100644 (file)
@@ -297,6 +297,7 @@ public class SimanticsPlatform implements LifecycleListener {
             monitor.subTask(message);
             LOGGER.info(message);
             Collection<GraphBundle> tgs = PlatformUtil.getAllGraphs();
+            System.err.println("getAllGraphs " + tgs.size());
             message = "extend bundles to compile versions";
             monitor.subTask(message);
             LOGGER.info(message);