]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.services/src/org/simantics/db/services/activation/ActivationManager.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.services / src / org / simantics / db / services / activation / ActivationManager.java
diff --git a/bundles/org.simantics.db.services/src/org/simantics/db/services/activation/ActivationManager.java b/bundles/org.simantics.db.services/src/org/simantics/db/services/activation/ActivationManager.java
new file mode 100644 (file)
index 0000000..6c80c8c
--- /dev/null
@@ -0,0 +1,206 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.db.services.activation;\r
+\r
+import org.simantics.db.Disposable;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.CommonDBUtils;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.queries.QueryExecutor2;\r
+import org.simantics.layer0.utils.triggers.IActivation;\r
+import org.simantics.layer0.utils.triggers.IActivationManager;\r
+import org.simantics.layer0.utils.triggers.IModification;\r
+import org.simantics.layer0.utils.triggers.ITrigger;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.utils.logging.TimeLogger;\r
+import org.simantics.utils.threads.logger.IThreadLogger;\r
+import org.simantics.utils.threads.logger.ThreadLogger;\r
+\r
+@SuppressWarnings("deprecation") // No replacement given so now way to fix this error.\r
+public class ActivationManager implements IActivationManager, Disposable {\r
+\r
+       Session session;\r
+       static IThreadLogger threadLogger = ThreadLogger.getInstance();\r
+\r
+       class Activation extends QueryExecutor2 implements IActivation {\r
+               final boolean DEBUG = false;\r
+               final boolean BREAK_INFINITE_ACTIVATION_LOOPS = true;\r
+\r
+               /**\r
+                * After {@value InfiniteLoop} the activation will be forcibly\r
+                * deactivated if {@link #BREAK_INFINITE_ACTIVATION_LOOPS} is\r
+                * <code>true</code>.\r
+                */\r
+               final int INFINITE_LOOP_COUNT = 100;\r
+\r
+               Resource resource;\r
+               int transactionCount = 0;\r
+               boolean disposed = false;\r
+               boolean runOnce = false;\r
+\r
+               public Activation(Resource resource) {\r
+                       this.resource = resource;\r
+               }\r
+\r
+               public void runOnceAndDeactivate() {\r
+                       runOnce = true;\r
+               }\r
+\r
+               @Override\r
+               public void run(ReadGraph g) throws DatabaseException {\r
+//                     ITask task = threadLogger.begin("Activation.perform");\r
+                       Layer0X L0X = Layer0X.getInstance(g);\r
+                       for(Resource r : g.getObjects(resource, L0X.HasTrigger))\r
+                               if(calcModification(g, r) != null)\r
+                                       execute(g, r);\r
+//                     task.finish();\r
+               }\r
+\r
+               private IModification calcModification(ReadGraph g, Resource trigger) throws DatabaseException {\r
+//                     new Exception().printStackTrace();\r
+                       //ITask task = ThreadLogger.getInstance().begin("Activation.calcModification");\r
+                       IModification modi = g.syncRequest(g.adapt(trigger, ITrigger.class));\r
+                       //task.finish();\r
+                       return modi;\r
+               }\r
+\r
+               private WriteRequest getRequest(final Resource trigger) {\r
+                       return new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph g) throws DatabaseException {\r
+                    int count = 0;\r
+                    while (true) {\r
+                       \r
+                       CommonDBUtils.selectClusterSet(g, trigger);\r
+                       \r
+                       TimeLogger.log("ActivationManager: start calculating modification");\r
+                        IModification modification = calcModification(g, trigger);\r
+                        TimeLogger.log("ActivationManager: finished calculating modification");\r
+                        if (modification != null)\r
+                            ++count;\r
+                        else {\r
+                            if (count > 0) {\r
+                                CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
+                                String msg = "ActivationManager modification count=" + count;\r
+                                g.addMetadata(cm.add(msg));\r
+                                if (DEBUG)\r
+                                    System.out.println("DEBUG: " + msg);\r
+                            }\r
+                            if(runOnce)\r
+                                deactivate();\r
+                            return;    \r
+                        }\r
+                        if (BREAK_INFINITE_ACTIVATION_LOOPS) {\r
+                            if (count > INFINITE_LOOP_COUNT) {\r
+                                deactivate();\r
+                                String msg = "Possible dynamic activation loop. Forcing break."\r
+                                        + "Loop count was " + count\r
+                                        + ". Activated resource was "\r
+                                        + NameUtils.getURIOrSafeNameInternal(g, resource) + ".";\r
+                                System.out.println("WARNING: " + msg);\r
+                                throw new DatabaseException(msg);\r
+                            }\r
+                        }\r
+                        try {\r
+                            modification.perform(g);\r
+                            TimeLogger.log("ActivationManager: performed modification");\r
+                        } catch (DatabaseException e) {\r
+                            deactivate();\r
+                            throw e;\r
+                        }\r
+                    }\r
+                }\r
+            };\r
+               }\r
+               \r
+        private void executeOnce(WriteGraph graph, final Resource trigger) throws DatabaseException {\r
+            getRequest(trigger).perform(graph);\r
+//             graph.syncRequest(getRequest(trigger));\r
+        }\r
+\r
+               private void execute(final ReadGraph graph, final Resource trigger) {\r
+            graph.asyncRequest(getRequest(trigger)); \r
+        }\r
+\r
+               @Override\r
+               public void deactivate() {\r
+                       disposed = true;                        \r
+               }\r
+\r
+               @Override\r
+               public boolean isDisposed() {\r
+                       return disposed || session == null;\r
+               }\r
+               \r
+       }\r
+       \r
+       public ActivationManager(Session session) {\r
+               this.session = session;\r
+       }\r
+\r
+       @Override\r
+       public IActivation activate(Resource r) {\r
+           Session s = session;\r
+           if (s == null)\r
+               throw new IllegalStateException("ActivationManager is disposed");\r
+               Activation activation = new Activation(r);\r
+               try {\r
+                       activation.execute(session);\r
+               } catch (DatabaseException e) {\r
+                       Logger.defaultLogError(e);\r
+               }\r
+               return activation;\r
+       }\r
+\r
+       @Override\r
+       public IActivation activate(WriteGraph graph, Resource r) throws DatabaseException {\r
+           Session s = session;\r
+           if (s == null)\r
+               throw new IllegalStateException("ActivationManager is disposed");\r
+               Activation activation = new Activation(r);\r
+               activation.execute(graph);\r
+               return activation;\r
+       }\r
+\r
+       @Override\r
+       public void activateOnce(Resource resource) {\r
+               activate(resource).runOnceAndDeactivate();              \r
+       }\r
+       \r
+       @Override\r
+       public void activateOnce(WriteGraph graph, Resource resource) throws DatabaseException {\r
+               \r
+           Session s = session;\r
+           if (s == null)\r
+               throw new IllegalStateException("ActivationManager is disposed");\r
+           \r
+           Layer0X L0X = Layer0X.getInstance(graph);\r
+               for(Resource r : graph.getObjects(resource, L0X.HasTrigger)) {\r
+                       new Activation(resource).executeOnce(graph, r);\r
+               }\r
+\r
+               \r
+       }\r
+\r
+       @Override\r
+       public void dispose() {\r
+           session = null;\r
+       }\r
+\r
+}\r