]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge "Fixed ProfileObserver.update race with multiple query threads"
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 17 Mar 2020 10:54:14 +0000 (10:54 +0000)
committerGerrit Code Review <gerrit2@simantics>
Tue, 17 Mar 2020 10:54:14 +0000 (10:54 +0000)
16 files changed:
bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java
bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java
bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.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/QueryProcessor.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.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/SessionImplVirtual.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java
bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java
bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java

index e9523c0c899628ee03fb29a4130067131044708a..dfb5780f96da2edfe4e8f7079c20812a8dfd051f 100644 (file)
@@ -33,7 +33,6 @@ import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.request.WriteRequest;
-import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.CancelTransactionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncListener;
@@ -63,9 +62,13 @@ import org.simantics.db.request.WriteOnlyResult;
 import org.simantics.db.request.WriteResult;
 import org.simantics.utils.DataContainer;
 import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(MergingGraphRequestProcessor.class);
+
     private static class SyncWriteRequestAdapter implements Write {
 
         private Semaphore semaphore = new Semaphore(0);
@@ -128,7 +131,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
             try {
                 semaphore.acquire();
             } catch (InterruptedException e) {
-                       Logger.defaultLogError(e);
+                LOGGER.error("SyncWriteRequestAdapter interrupted", e);
             }
         }
 
@@ -223,7 +226,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
                             try {
                                 MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod);
                             } catch (InterruptedException e) {
-                                       Logger.defaultLogError(e);
+                                LOGGER.error("MergedRead interrupted", e);
                             }
                             if (requestQueue.isEmpty())
                                 break;
@@ -262,7 +265,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
                     } catch(Throwable t) {
 
-                               Logger.defaultLogError(t);
+                        LOGGER.error("MergedRead failed", t);
 
 //                        if(currentRequest.second instanceof AsyncProcedure<?>) {
 //                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
@@ -281,7 +284,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
                 } else {
 
-                    try{
+                    try {
 
                         if(currentRequest.second instanceof AsyncProcedure<?>) {
                             if(currentRequest.first instanceof AsyncRead) {
@@ -298,7 +301,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
                     } catch(Throwable t) {
 
-                               Logger.defaultLogError(t);
+                        LOGGER.error("MergedRead failed", t);
 
 //                        if(currentRequest.second instanceof AsyncProcedure<?>) {
 //                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
@@ -355,7 +358,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
                             try {
                                 MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod);
                             } catch (InterruptedException e) {
-                                       Logger.defaultLogError(e);
+                                LOGGER.error("RunnerWriteGraphRequest interrupted", e);
                             }
                             if (requestQueue.isEmpty())
                                 break;
@@ -385,7 +388,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
                         graph.syncRequest(adapter);
                         if(callback != null) callback.accept(null);
                     } catch(Throwable t) {
-                               Logger.defaultLogError(t);
+                        LOGGER.error("RunnerWriteGraphRequest failed", t);
                         if(callback != null) callback.accept(t);
                     }
 
@@ -399,7 +402,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
                         else if(currentRequest.first instanceof DelayedWrite) graph.syncRequest((DelayedWrite)currentRequest.first); 
                         if(callback != null) callback.accept(null);
                     } catch(Throwable t) {
-                               Logger.defaultLogError(t);
+                        LOGGER.error("RunnerWriteGraphRequest failed", t);
                         if(callback != null) callback.accept(t);
                     }
 
@@ -572,7 +575,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
         Throwable t = throwable.get();
 
         if(t != null) {
-               Logger.defaultLogError(t);
+            LOGGER.error("syncRequest(AsyncMultiRead, AsyncMultiProcedure) failed", t);
             throw new RuntimeException(t.getMessage());
         }
         
@@ -625,7 +628,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
         Throwable t = throwable.get();
 
         if(t != null) {
-               Logger.defaultLogError(t);
+            LOGGER.error("syncRequest(AsyncRead, AsyncProcedure) failed", t);
             throw new RuntimeException(t.getMessage());
         }
         
@@ -691,7 +694,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
             @Override
             public void exception(Throwable t) {
-                       Logger.defaultLogError(t);
+                LOGGER.error("asyncRequest(AsyncRead) failed", t);
             }
 
         });
@@ -736,7 +739,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
         Throwable t = throwable.get();
 
         if(t != null) {
-               Logger.defaultLogError(t);
+            LOGGER.error("syncRequest(AsyncRead) failed", t);
             throw new RuntimeException(t.getMessage());
         }
 
@@ -775,7 +778,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
         Throwable t = throwable.get();
 
         if(t != null) {
-               Logger.defaultLogError(t);
+            LOGGER.error("syncRequest(AsyncMultiRead) failed", t);
             throw new RuntimeException(t.getMessage());
         }
 
@@ -878,7 +881,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
             @Override
             public void exception(Throwable t) {
-                Logger.defaultLogError(t);
+                LOGGER.error("asyncRequest(Read) failed", t);
             }
 
         });
@@ -1305,4 +1308,9 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
                throw new UnsupportedOperationException();
        }
        
+       @Override
+       public <T> T l0() {
+               return processor.l0();
+       }
+       
 }
index 1f00ff008674e73ada990c71e297e9f01afe2f19..f47ebb3f342ac302cb2dd43bf6bfaaf56d251d28 100644 (file)
@@ -46,6 +46,11 @@ import org.simantics.db.request.WriteResult;
 
 public class ProcessorBase implements AsyncRequestProcessor {
 
+    @Override
+    public <T> T l0() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public <T> void asyncRequest(AsyncMultiRead<T> request, AsyncMultiProcedure<T> procedure) {
         throw new UnsupportedOperationException();
index b3eba37fbdb4a0e395a90ea75c21a82abd1ad089..aeea33f0276c8a1de7dc0736bda0e86f03b0f72f 100644 (file)
@@ -14,7 +14,7 @@ import org.simantics.scl.runtime.function.FunctionImpl3;
  * @author Hannu Niemist&ouml;
  */
 public class AdaptValue extends ResourceRead<Object> {
-    
+
     public AdaptValue(Resource resource) {
         super(resource);
     }
@@ -31,14 +31,14 @@ public class AdaptValue extends ResourceRead<Object> {
                }
 
        };
-    
+
     @Override
     public Object perform(ReadGraph graph) throws DatabaseException {
-        String uri = graph.getURI(resource);        
-        if(Layer0.URIs.Functions_functionApplication.equals(uri)) return functionApplication;
+        Layer0 L0 = graph.l0();
+        if (L0.Functions_functionApplication.equalsResource(resource))
+            return functionApplication;
         ComputationalValue ev = graph.adapt(resource, ComputationalValue.class);
         return ev.getValue(graph, resource);
-
     }
 
 }
index 110e1d59bbb460090a368cc1763b383f2258aa43..61580bfdcb6ae9a96680952b070261057b9a2fe6 100644 (file)
@@ -6387,4 +6387,10 @@ public class ReadGraphImpl implements AsyncReadGraph {
         else return getTopLevelGraphStatic(impl.parentGraph);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T l0() {
+        return (T) processor.getL0();
+    }
+
 }
index 6345b7375fece679ba7f20103713bf0f1eb37b79..6d9560940be2b1c19b73616c85a2996ee2b65d25 100644 (file)
@@ -4054,6 +4054,10 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                return L0;
        }
 
+       public Layer0 getL0() {
+               return L0;
+       }
+
     public static ThreadLocal<Integer> thread = new ThreadLocal<Integer>() {
         protected Integer initialValue() {
             return -1;
index 517ce761ed4d7d8686ae501ae942090f5854fc61..6ad6315b989c8b0704c78f53519131864fa53fc2 100644 (file)
@@ -27,41 +27,43 @@ import org.simantics.scl.runtime.function.FunctionImpl3;
  */
 public abstract class ContextualRelatedValue implements ConverterComputationalValue {
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T> T getValue(ReadGraph graph, Resource resource) throws DatabaseException {
-        return (T) new FunctionImpl3<ReadGraph, Resource, Object, Object>() {
-            @Override
-            public Object apply(ReadGraph graph, Resource converter, Object context) {
-                SCLContext sclContext = SCLContext.getCurrent();
-                Object oldGraph = sclContext.get("graph");
-                try {
-                    if (context instanceof Variable) {
-                        Variable variable = (Variable)context;
-                        try {
-                            Function1<Object,Object> fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph));
-                            sclContext.put("graph", graph);
-                            return fn.apply(variable);
-                        } catch (DatabaseException e) {
-                            throw new RuntimeDatabaseException(e);
-                        }
-                    } if (context instanceof Resource) {
-                        Resource resource = (Resource)context;
-                        try {
-                            // Here converter is the object and context is the subject
-                            Function1<Object,Object> fn = getFunction(graph, resource, converter, null);
-                            return fn.apply(resource);
-                        } catch (DatabaseException e) {
-                            throw new RuntimeDatabaseException(e);
-                        }
-                    } else {
-                        throw new IllegalStateException("Unknown context " + context);
+    private final FunctionImpl3<ReadGraph, Resource, Object, Object> function = new FunctionImpl3<ReadGraph, Resource, Object, Object>() {
+        @Override
+        public Object apply(ReadGraph graph, Resource converter, Object context) {
+            SCLContext sclContext = SCLContext.getCurrent();
+            Object oldGraph = sclContext.get("graph");
+            try {
+                if (context instanceof Variable) {
+                    Variable variable = (Variable)context;
+                    try {
+                        Function1<Object,Object> fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph));
+                        sclContext.put("graph", graph);
+                        return fn.apply(variable);
+                    } catch (DatabaseException e) {
+                        throw new RuntimeDatabaseException(e);
+                    }
+                } if (context instanceof Resource) {
+                    Resource resource = (Resource)context;
+                    try {
+                        // Here converter is the object and context is the subject
+                        Function1<Object,Object> fn = getFunction(graph, resource, converter, null);
+                        return fn.apply(resource);
+                    } catch (DatabaseException e) {
+                        throw new RuntimeDatabaseException(e);
                     }
-                } finally {
-                    sclContext.put("graph", oldGraph);
+                } else {
+                    throw new IllegalStateException("Unknown context " + context);
                 }
+            } finally {
+                sclContext.put("graph", oldGraph);
             }
-        };
+        }
+    };
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T getValue(ReadGraph graph, Resource resource) throws DatabaseException {
+        return (T) function;
     }
 
 }
index 4e775e08a22e12597044218f138aef3cfcaf6637..f52148c2a6b2306d9c8d4b6c0ce9e31cb5e89efe 100644 (file)
@@ -139,7 +139,7 @@ public class All {
                                                return graph.getValue2(object, variable);
                                        } else {
                                                for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
-                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                       if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) {
                                                                return graph.getValue2(assertion.second, variable);
                                                        }
                                                }
@@ -201,7 +201,7 @@ public class All {
                                                return graph.getValue2(object, variable, binding);
                                        } else {
                                                for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
-                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                       if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) {
                                                                return graph.getValue2(assertion.second, variable, binding);
                                                        }
                                                }
@@ -1164,8 +1164,11 @@ public class All {
        if(property instanceof StandardGraphPropertyVariable) {
                StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)property;
                if (variable.parentResource != null) {
-                       Statement stm = graph.getPossibleStatement(variable.parentResource, variable.property.predicate);
-                       return stm != null && stm.isAsserted(variable.parentResource);
+                       Resource predicate = variable.getPossiblePredicateResource(graph);
+                       if (predicate != null) {
+                                       Statement stm = graph.getPossibleStatement(variable.parentResource, predicate);
+                                       return stm != null && stm.isAsserted(variable.parentResource);
+                       }
                        }
        }
        return Boolean.FALSE;
@@ -1313,7 +1316,7 @@ public class All {
                        throw new InvalidVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");
 
                try {
-                       return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
+                       return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable);
                } catch (NoSingleResultException e) {
                        throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                } catch (DoesNotContainValueException e) {
@@ -1334,9 +1337,10 @@ public class All {
 
                if (variable.parentResource == null)
                        throw new MissingVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").", context.getPossibleRepresents(graph));
+               
 
                try {
-                       return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
+                       return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable);
                } catch (NoSingleResultException e) {
                        throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                } catch (DoesNotContainValueException e) {
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java
new file mode 100644 (file)
index 0000000..a1b7463
--- /dev/null
@@ -0,0 +1,34 @@
+package org.simantics.db.layer0.variable;
+
+import org.simantics.db.Resource;
+import org.simantics.db.exception.AssumptionException;
+
+public class NoPredicateResourceException extends AssumptionException {
+
+       private static final long serialVersionUID = -374051341908276908L;
+
+       public NoPredicateResourceException(Throwable cause) {
+               super(cause);
+       }
+
+       public NoPredicateResourceException(String message, Throwable cause, Resource... rs) {
+               super(message, cause, rs);
+       }
+
+       public NoPredicateResourceException(String message, Resource... resources) {
+               super(message, resources);
+       }
+
+       public NoPredicateResourceException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+       public NoPredicateResourceException(String message, int... args) {
+               super(message, args);
+       }
+
+       public NoPredicateResourceException(String message) {
+               super(message);
+       }
+
+}
index b7eaf075edea1c1e051981662954629f70673cf1..c9214e398c69577da69642536c8b932e67e5bc69 100644 (file)
@@ -21,6 +21,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.DatatypeNotFoundException;
 import org.simantics.db.exception.ValidationException;
 import org.simantics.db.layer0.exception.InvalidVariableException;
+import org.simantics.db.layer0.exception.MissingVariableException;
 import org.simantics.db.layer0.exception.MissingVariableValueException;
 import org.simantics.db.layer0.exception.PendingVariableException;
 import org.simantics.db.layer0.function.All;
@@ -100,11 +101,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
 
        @Override
        public String getPossibleLabel(ReadGraph graph) throws DatabaseException {
+               if (property.predicate == null)
+                       return null;
                return graph.getPossibleRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
        }
 
        @Override
        public String getLabel(ReadGraph graph) throws DatabaseException {
+               if (property.predicate == null)
+                       throw new NoPredicateResourceException("No predicate resource for property " + getName(graph));
                return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
        }
 
@@ -124,10 +129,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
                
                if(Development.DEVELOPMENT) {
                        if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
-                               String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
-                               if(error != null) {
-                                   LOGGER.error(error);
-                                       throw new ValidationException(error);
+                               if (property.predicate != null) {
+                                       String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
+                                       if(error != null) {
+                                           LOGGER.error(error);
+                                               throw new ValidationException(error);
+                                       }
                                }
                        }
                }
@@ -145,10 +152,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
 
                if(Development.DEVELOPMENT) {
                        if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
-                               String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
-                               if(error != null) {
-                                       LOGGER.error(error);
-                                       throw new ValidationException(error);
+                               if (property.predicate != null) {
+                                       String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
+                                       if(error != null) {
+                                               LOGGER.error(error);
+                                               throw new ValidationException(error);
+                                       }
                                }
                        }
                }
@@ -183,10 +192,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
                
                if(Development.DEVELOPMENT) {
                        if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
-                               String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
-                               if(error != null) {
-                                       LOGGER.error(error);
-                                       throw new ValidationException(error);
+                               if (property.predicate != null) {
+                                       String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
+                                       if(error != null) {
+                                               LOGGER.error(error);
+                                               throw new ValidationException(error);
+                                       }
                                }
                        }
                }
@@ -200,10 +211,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
                
                if(Development.DEVELOPMENT) {
                        if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
-                               String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
-                               if(error != null) {
-                                       LOGGER.error(error);
-                                       throw new ValidationException(error);
+                               if (property.predicate != null) {
+                                       String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
+                                       if(error != null) {
+                                               LOGGER.error(error);
+                                               throw new ValidationException(error);
+                                       }
                                }
                        }
                }
@@ -324,11 +337,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
        
        @Override
        public Variable getPredicate(ReadGraph graph) throws DatabaseException {
+               if (property.predicate == null)
+                       throw new MissingVariableException("No predicate for property " + getName(graph));
                return Variables.getVariable(graph, graph.getURI(property.predicate));
        }
        
        @Override
        public Resource getPredicateResource(ReadGraph graph) throws DatabaseException {
+               if (property.predicate == null)
+                       throw new NoPredicateResourceException("No predicate for property " + getName(graph));
                return property.predicate;
        }
        
index 92c5e9dda255a93b19ffeb21954a2c4153c7c674..0178e805fd29d09b99cce3ecc5ff7d8a4b3e8fec 100644 (file)
@@ -18,7 +18,6 @@ import org.simantics.db.SessionManager;
 import org.simantics.db.SessionReference;
 import org.simantics.db.VirtualGraph;
 import org.simantics.db.authentication.UserAuthenticationAgent;
-import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.InvalidAuthenticationException;
 import org.simantics.db.exception.InvalidUserException;
@@ -30,9 +29,13 @@ import org.simantics.db.impl.graph.WriteSupport;
 import org.simantics.db.impl.query.QueryProcessor;
 import org.simantics.db.impl.query.QuerySupport;
 import org.simantics.db.service.ServerInformation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 final public class SessionImplDb extends SessionImplSocket {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplDb.class);
+
     /**
      * Cached ServerInformation structure fetched from the server at connection
      * time. It should never change during a single session and therefore it
@@ -58,7 +61,7 @@ final public class SessionImplDb extends SessionImplSocket {
         try {
             newId = cluster.createResource(clusterTranslator);
         } catch (DatabaseException e) {
-            Logger.defaultLogError(e);
+            LOGGER.error("createResource failed", e);
             return null;
         }
         return new ResourceImpl(resourceSupport, newId);
@@ -114,8 +117,7 @@ final public class SessionImplDb extends SessionImplSocket {
 //            clusterTable.dispose(); clusterTable = null;
 //            throw e;
         } catch (Throwable e) {
-            e.printStackTrace();
-            Logger.defaultLogError("Unhandled error. See exception for details.", e);
+            LOGGER.error("Unhandled error. See exception for details.", e);
             graphSession = null;
             clusterTable.dispose(); clusterTable = null;
             throw new Exception(e);
index f8fd7d17ddab55e7274388ff259155918227486f..29c70445bd208dd190c9796b60f2e31f46408dca 100644 (file)
@@ -328,7 +328,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         try {
             getClusterTable().refresh(csid, this, clusterUID);
         } catch (Throwable t) {
-            Logger.defaultLogError("Refesh failed.", t);
+            LOGGER.error("refresh({}, {}) failed", thread, csid, t);
         }
     }
 
@@ -468,7 +468,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                         assert (null != writer);
                     } catch (Throwable t) {
                         if (!(t instanceof CancelTransactionException))
-                            Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", t);
+                            LOGGER.error("Write transaction caused an unexpected error, see exception.", t);
                         writeState.except(t);
                     } finally {
                         writer.asyncBarrier.dec();
@@ -482,7 +482,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
                     // Log it first, just to be safe that the error is always logged.
                     if (!(e instanceof CancelTransactionException))
-                    Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e);
+                        LOGGER.error("Write transaction caused an unexpected error, see exception.", e);
 
 //                    writeState.getGraph().state.barrier.dec();
 //                    writeState.getGraph().waitAsync(request);
@@ -626,7 +626,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                             if (t instanceof DatabaseException) callback.accept((DatabaseException) t);
                             else callback.accept(new DatabaseException(t));
                         } else
-                            Logger.defaultLogError("Unhandled exception", t);
+                            LOGGER.error("Unhandled exception", t);
                     }
                 };
 
@@ -1324,7 +1324,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                 callback.exception(new DatabaseException(e));
 
             state.stopWriteTransaction(clusterStream);
-            Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e);
+            LOGGER.error("Write transaction caused an unexpected error, see exception.", e);
 
         } finally  {
 
@@ -1530,7 +1530,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                                 if(throwable != null) {
                                     throwable.set(th);
                                 } else {
-                                    Logger.defaultLogError("Unhandled exception", th);
+                                    LOGGER.error("Unhandled exception", th);
                                 }
 
                             }
@@ -1543,7 +1543,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                             if(throwable != null) {
                                 throwable.set(t);
                             } else {
-                                Logger.defaultLogError("Unhandled exception", t);
+                                LOGGER.error("Unhandled exception", t);
                             }
 
                             try {
@@ -1555,7 +1555,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                                 if(throwable != null) {
                                     throwable.set(t2);
                                 } else {
-                                    Logger.defaultLogError("Unhandled exception", t2);
+                                    LOGGER.error("Unhandled exception", t2);
                                 }
 
                             }
@@ -2511,39 +2511,41 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
      */
     @SuppressWarnings("unchecked")
     @Override
-    public synchronized <T> T peekService(Class<T> api) {
-
-               if(serviceKey1 == api) {
-                       return (T)service1;
-               } else if (serviceKey2 == api) {
-                       // Promote this key
-                       Object result = service2;
-                       service2 = service1;
-                       serviceKey2 = serviceKey1;
-                       service1 = result;
-                       serviceKey1 = api;
-                       return (T)result;
-               }
+    public <T> T peekService(Class<T> api) {
+        if (Layer0.class == api)
+            return (T) L0;
 
-       if (Layer0.class == api)
-               return (T) L0;
-        if (ServerInformation.class == api)
-            return (T) getCachedServerInformation();
-        else if (WriteGraphImpl.class == api)
-            return (T) writeState.getGraph();
-        else if (ClusterBuilder.class == api)
-            return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport);
-        else if (ClusterBuilderFactory.class == api)
-            return (T)new ClusterBuilderFactoryImpl(this);
+        synchronized (this) {
+            if (serviceKey1 == api) {
+                return (T) service1;
+            }
+            if (serviceKey2 == api) {
+                // Promote this key
+                Object result = service2;
+                service2 = service1;
+                serviceKey2 = serviceKey1;
+                service1 = result;
+                serviceKey1 = api;
+                return (T)result;
+            }
 
-               service2 = service1;
-               serviceKey2 = serviceKey1;
+            if (ServerInformation.class == api)
+                return (T) getCachedServerInformation();
+            else if (WriteGraphImpl.class == api)
+                return (T) writeState.getGraph();
+            else if (ClusterBuilder.class == api)
+                return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport);
+            else if (ClusterBuilderFactory.class == api)
+                return (T)new ClusterBuilderFactoryImpl(this);
 
-        service1 = serviceLocator.peekService(api);
-        serviceKey1 = api;
+            service2 = service1;
+            serviceKey2 = serviceKey1;
 
-        return (T)service1;
+            service1 = serviceLocator.peekService(api);
+            serviceKey1 = api;
 
+            return (T)service1;
+        }
     }
 
     /*
@@ -2590,9 +2592,9 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
             try {
                 h.valuesChanged(ctx);
             } catch (Exception e) {
-                Logger.defaultLogError("monitor handler notification produced the following exception", e);
+                LOGGER.error("monitor handler notification produced the following exception", e);
             } catch (LinkageError e) {
-                Logger.defaultLogError("monitor handler notification produced a linkage error", e);
+                LOGGER.error("monitor handler notification produced a linkage error", e);
             }
         }
     }
@@ -3579,4 +3581,10 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         state.setCombine(false);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T l0() {
+        return (T) L0;
+    }
+
 }
index 50184528e6f7641719c2f0e3da3caf8e7212bf10..d90f2c3a530a06b6d9fb47bca020005c7c2e5bb4 100644 (file)
@@ -16,7 +16,6 @@ import java.io.IOException;
 import org.simantics.db.ServerI;
 import org.simantics.db.VirtualGraph;
 import org.simantics.db.authentication.UserAuthenticationAgent;
-import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.InvalidAuthenticationException;
 import org.simantics.db.exception.InvalidUserException;
@@ -24,6 +23,8 @@ import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.VirtualGraphImpl;
 import org.simantics.db.impl.query.QueryProcessor;
 import org.simantics.db.service.ServerInformation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import fi.vtt.simantics.procore.BackdoorAuthenticator;
 import fi.vtt.simantics.procore.ProCoreServerReference;
@@ -31,6 +32,9 @@ import fi.vtt.simantics.procore.ProCoreSessionReference;
 import fi.vtt.simantics.procore.SessionManagerSource;
 
 public class SessionImplVirtual extends SessionImplSocket {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplVirtual.class);
+
     protected VirtualGraphImpl virtualGraphImpl;
     public SessionImplVirtual(UserAuthenticationAgent authAgent)
     throws DatabaseException {
@@ -75,12 +79,11 @@ public class SessionImplVirtual extends SessionImplSocket {
         } catch (InvalidUserException e) {
             throw e;
         } catch (IOException e) {
-               Logger.defaultLogError("I/O error. See exception for details.", e);
+            LOGGER.error("I/O error. See exception for details.", e);
             graphSession = null;
             throw new DatabaseException(e);
         } catch (Throwable e) {
-            e.printStackTrace();
-            Logger.defaultLogError("Unhandled error. See exception for details.", e);
+            LOGGER.error("Unhandled error. See exception for details.", e);
             graphSession = null;
             throw new DatabaseException(e);
         }
@@ -108,7 +111,7 @@ public class SessionImplVirtual extends SessionImplSocket {
         try {
             return gs.getServerInformation();
         } catch (DatabaseException e) {
-            Logger.defaultLogError("Failed to get server info.", e);
+            LOGGER.error("Failed to get server info.", e);
             return null;
         }
     }
index ea4319ace00c464095ab59547d93f6ce2da11ba7..247df4645c5b207c13f2e19dbb94d84af31bc850 100644 (file)
@@ -8,7 +8,6 @@ import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.MetadataUtils;
 import org.simantics.db.common.exception.DebugException;
-import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ImmutableException;
 import org.simantics.db.exception.ServiceException;
@@ -28,9 +27,13 @@ import org.simantics.db.request.WriteOnly;
 import org.simantics.db.request.WriteResult;
 import org.simantics.db.request.WriteTraits;
 import org.simantics.db.service.ByteReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class WriteSupportImpl implements WriteSupport {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(WriteSupportImpl.class);
+
     final private SessionImplSocket session;
     final private QueryProcessor queryProcessor;
     final private State state;
@@ -122,7 +125,7 @@ public class WriteSupportImpl implements WriteSupport {
                 try {
                     addSetValue(((ResourceImpl) resource).id, value, value.length);
                 } catch (DatabaseException e) {
-                    Logger.defaultLogError(e);
+                    LOGGER.error("writeOnly setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e);
                 }
             }
         } else {
@@ -134,7 +137,7 @@ public class WriteSupportImpl implements WriteSupport {
                 try {
                     addSetValue(((ResourceImpl) resource).id, value, value.length);
                 } catch (DatabaseException e) {
-                    Logger.defaultLogError(e);
+                    LOGGER.error("setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e);
                 }
             }
             queryProcessor.releaseWrite(session.writeState.getGraph());
@@ -199,7 +202,7 @@ public class WriteSupportImpl implements WriteSupport {
             try { 
                 cluster.removeValue(key, session.clusterTranslator);
             } catch (DatabaseException e) {
-                Logger.defaultLogError(e);
+                LOGGER.error("denyValue({}, {}) failed", provider, resource, e);
                 return;
             }
             queryProcessor.updateValue(key);
@@ -460,7 +463,7 @@ public class WriteSupportImpl implements WriteSupport {
             if (null != c && c != cluster)
                 session.clusterTable.replaceCluster(c);
         } catch (DatabaseException e) {
-            Logger.defaultLogError(e);
+            LOGGER.error("claimImpl({}, {}, {}) failed", subject, predicate, object, e);
             throw new RuntimeException(e);
         }
         queryProcessor.updateStatements(subject, predicate);
@@ -480,7 +483,7 @@ public class WriteSupportImpl implements WriteSupport {
             if (null != c && c != cluster)
                 session.clusterTable.replaceCluster(c);
         } catch (DatabaseException e) {
-            Logger.defaultLogError(e);
+            LOGGER.error("claimImpl2({}, {}, {}) failed", subject, predicate, object, e);
         }
         if (cluster.isWriteOnly())
             return;
@@ -504,7 +507,7 @@ public class WriteSupportImpl implements WriteSupport {
         try {
             cluster.denyRelation(subject, predicate, object, session.clusterTranslator);
         } catch (DatabaseException e) {
-            Logger.defaultLogError(e);
+            LOGGER.error("removeStatement({}, {}, {}) failed", subject, predicate, object, e);
             return false;
         }
         queryProcessor.updateStatements(subject, predicate);
index 5e818cb995c32408a9f04377c0b0885767d95513..924ccffb02ec855e492230e6a21e9d47bdad2b3f 100644 (file)
@@ -62,7 +62,7 @@ import org.simantics.db.request.WriteInterface;
  * @see MergingGraphRequestProcessor
  * @see AsyncRequestProcessor
  */
-public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator {
+public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator, ResourceLocator {
 
     Resource getRootLibrary();
 
diff --git a/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java b/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java
new file mode 100644 (file)
index 0000000..8a8b0fa
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.43.0
+ */
+public interface ResourceLocator {
+
+    /**
+     * Layer0 is an integral part of Simantics database modelling and for performance
+     * reasons deserves simplest possible access to its resource class.
+     * 
+     * @return returns the internally cached
+     *         <code>org.simantics.layer0.Layer0</code> instance
+     */
+    public <T> T l0();
+
+}
index e8c54fa987537401d8b448c35652c6a7fe32ff16..6256891b82ae17a96391e7a05399b2ef9ae3f640 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.modeling;
 import gnu.trove.map.hash.THashMap;
 
 import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.request.PropertyInfo;
 import org.simantics.db.layer0.request.PropertyInfoRequest;
@@ -21,19 +22,28 @@ public class ProceduralSubstructureMapRequest extends VariableRead<THashMap<Stri
     public THashMap<String, Pair<String,Type>> perform(ReadGraph graph) throws DatabaseException {
         THashMap<String, Pair<String,Type>> propertyMap = new THashMap<String, Pair<String,Type>>();
         for(Variable child : variable.getChildren(graph)) {
-               for(Variable property : child.getProperties(graph)) {
-                   PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph)));
+            for(Variable property : child.getProperties(graph)) {
+                Resource predicate = property.getPossiblePredicateResource(graph);
+                if (predicate == null)
+                    continue;
+                
+                PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate));
                 propertyMap.put(child.getName(graph) + "." + propertyInfo.name,
                         Pair.make("/" + child.getName(graph) + "#" + propertyInfo.name,
                                 SCLTypeUtils.getType(propertyInfo)));
-               }
+            }
         }
-       for(Variable property : variable.getProperties(graph)) {
-           PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph)));
+        for(Variable property : variable.getProperties(graph)) {
+            Resource predicate = property.getPossiblePredicateResource(graph);
+            if (predicate == null)
+                continue;
+            
+            PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate));
             propertyMap.put(propertyInfo.name,
                     Pair.make("#" + propertyInfo.name,
                             SCLTypeUtils.getType(propertyInfo)));
-       }
+        }
+        
         return propertyMap;
     }