]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/request/DependentInstances3.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / request / DependentInstances3.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.common.request;
13
14 import java.util.Set;
15
16 import org.simantics.db.ReadGraph;
17 import org.simantics.db.Resource;
18 import org.simantics.db.Statement;
19 import org.simantics.db.common.utils.NameUtils;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.service.CollectionSupport;
22 import org.simantics.layer0.Layer0;
23 import org.simantics.utils.Development;
24
25 import gnu.trove.map.hash.THashMap;
26
27 public class DependentInstances3 extends ResourceRead<ResourceSetGraph> {
28
29     private static final boolean DEBUG = false;
30
31     private static ThreadLocal<THashMap<DependentInstances3, ResourceSetGraph>> workArea = new ThreadLocal<THashMap<DependentInstances3, ResourceSetGraph>>() {
32         protected gnu.trove.map.hash.THashMap<DependentInstances3,ResourceSetGraph> initialValue() {
33             return new THashMap<>();
34         }
35     };
36
37         public DependentInstances3(Resource resource) {
38                 super(resource);
39         }
40
41         @Override
42         public ResourceSetGraph perform(ReadGraph graph) throws DatabaseException {
43                 
44                 if(resource.equals(graph.getRootLibrary())) return new ResourceSetGraph(graph, resource);
45         
46                 if(Development.DEVELOPMENT)
47                         if(graph.isImmutable(resource))
48                                 System.err.println("Immutable resource in DependentInstances3: " + NameUtils.getSafeName(graph, resource, true));
49                 
50         // This is a loop
51         THashMap<DependentInstances3, ResourceSetGraph> workingSet = workArea.get();
52         ResourceSetGraph result = workingSet.get(this);
53         if(result != null) return result;
54
55         result = new ResourceSetGraph(graph, resource);
56         
57         workingSet.put(this, result);
58         
59         CollectionSupport cs = graph.getService(CollectionSupport.class);
60         Set<Resource> objects = cs.createSet();
61         
62                 Layer0 L0 = Layer0.getInstance(graph);
63                 for(Statement dep : graph.getStatements(resource, L0.IsDependencyOf)) {
64                         if(graph.isSubrelationOf(dep.getPredicate(), L0.HasPrevious)) continue;
65                         Resource object = dep.getObject();
66                         if(graph.isImmutable(object)) continue;
67                         objects.add(object);
68                 }
69                 
70                 for(Resource object : objects ) {
71             if(DEBUG)
72                 System.err.println(NameUtils.getSafeName(graph, object, true) + " depends on " + NameUtils.getSafeName(graph, resource, true));
73                     DependentInstances3 query = new DependentInstances3(object);
74                     ResourceSetGraph instances = workingSet.get(query);
75                     if(instances == null) instances = graph.syncRequest(query);
76                         result.references.add(instances);
77                 }
78                 
79                 workingSet.remove(this);
80                 return result;
81                 
82         }
83
84 }