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