1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.services.activation;
14 import org.simantics.db.Disposable;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.Session;
18 import org.simantics.db.WriteGraph;
19 import org.simantics.db.common.CommentMetadata;
20 import org.simantics.db.common.request.WriteRequest;
21 import org.simantics.db.common.utils.CommonDBUtils;
22 import org.simantics.db.common.utils.Logger;
23 import org.simantics.db.common.utils.NameUtils;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.layer0.utils.queries.QueryExecutor2;
26 import org.simantics.layer0.utils.triggers.IActivation;
27 import org.simantics.layer0.utils.triggers.IActivationManager;
28 import org.simantics.layer0.utils.triggers.IModification;
29 import org.simantics.layer0.utils.triggers.ITrigger;
30 import org.simantics.operation.Layer0X;
31 import org.simantics.utils.logging.TimeLogger;
32 import org.simantics.utils.threads.logger.IThreadLogger;
33 import org.simantics.utils.threads.logger.ThreadLogger;
35 @SuppressWarnings("deprecation") // No replacement given so now way to fix this error.
36 public class ActivationManager implements IActivationManager, Disposable {
39 static IThreadLogger threadLogger = ThreadLogger.getInstance();
41 class Activation extends QueryExecutor2 implements IActivation {
42 final boolean DEBUG = false;
43 final boolean BREAK_INFINITE_ACTIVATION_LOOPS = true;
46 * After {@value InfiniteLoop} the activation will be forcibly
47 * deactivated if {@link #BREAK_INFINITE_ACTIVATION_LOOPS} is
50 final int INFINITE_LOOP_COUNT = 100;
53 int transactionCount = 0;
54 boolean disposed = false;
55 boolean runOnce = false;
57 public Activation(Resource resource) {
58 this.resource = resource;
61 public void runOnceAndDeactivate() {
66 public void run(ReadGraph g) throws DatabaseException {
67 // ITask task = threadLogger.begin("Activation.perform");
68 Layer0X L0X = Layer0X.getInstance(g);
69 for(Resource r : g.getObjects(resource, L0X.HasTrigger))
70 if(calcModification(g, r) != null)
75 private IModification calcModification(ReadGraph g, Resource trigger) throws DatabaseException {
76 // new Exception().printStackTrace();
77 //ITask task = ThreadLogger.getInstance().begin("Activation.calcModification");
78 IModification modi = g.syncRequest(g.adapt(trigger, ITrigger.class));
83 private WriteRequest getRequest(final Resource trigger) {
84 return new WriteRequest() {
86 public void perform(WriteGraph g) throws DatabaseException {
90 CommonDBUtils.selectClusterSet(g, trigger);
92 TimeLogger.log("ActivationManager: start calculating modification");
93 IModification modification = calcModification(g, trigger);
94 TimeLogger.log("ActivationManager: finished calculating modification");
95 if (modification != null)
99 CommentMetadata cm = g.getMetadata(CommentMetadata.class);
100 String msg = "ActivationManager modification count=" + count;
101 g.addMetadata(cm.add(msg));
103 System.out.println("DEBUG: " + msg);
109 if (BREAK_INFINITE_ACTIVATION_LOOPS) {
110 if (count > INFINITE_LOOP_COUNT) {
112 String msg = "Possible dynamic activation loop. Forcing break."
113 + "Loop count was " + count
114 + ". Activated resource was "
115 + NameUtils.getURIOrSafeNameInternal(g, resource) + ".";
116 System.out.println("WARNING: " + msg);
117 throw new DatabaseException(msg);
121 modification.perform(g);
122 TimeLogger.log("ActivationManager: performed modification");
123 } catch (DatabaseException e) {
132 private void executeOnce(WriteGraph graph, final Resource trigger) throws DatabaseException {
133 getRequest(trigger).perform(graph);
134 // graph.syncRequest(getRequest(trigger));
137 private void execute(final ReadGraph graph, final Resource trigger) {
138 graph.asyncRequest(getRequest(trigger));
142 public void deactivate() {
147 public boolean isDisposed() {
148 return disposed || session == null;
153 public ActivationManager(Session session) {
154 this.session = session;
158 public IActivation activate(Resource r) {
161 throw new IllegalStateException("ActivationManager is disposed");
162 Activation activation = new Activation(r);
164 activation.execute(session);
165 } catch (DatabaseException e) {
166 Logger.defaultLogError(e);
172 public IActivation activate(WriteGraph graph, Resource r) throws DatabaseException {
175 throw new IllegalStateException("ActivationManager is disposed");
176 Activation activation = new Activation(r);
177 activation.execute(graph);
182 public void activateOnce(Resource resource) {
183 activate(resource).runOnceAndDeactivate();
187 public void activateOnce(WriteGraph graph, Resource resource) throws DatabaseException {
191 throw new IllegalStateException("ActivationManager is disposed");
193 Layer0X L0X = Layer0X.getInstance(graph);
194 for(Resource r : graph.getObjects(resource, L0X.HasTrigger)) {
195 new Activation(resource).executeOnce(graph, r);
202 public void dispose() {