Some fixes for resource cleaning spreadsheets in simupedia
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetSessionManager.java
1 package org.simantics.spreadsheet.graph;
2
3 import java.io.BufferedInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.ObjectInputStream;
9 import java.io.ObjectStreamClass;
10 import java.util.Collection;
11 import java.util.HashSet;
12 import java.util.Set;
13
14 import org.simantics.db.ReadGraph;
15 import org.simantics.db.Resource;
16 import org.simantics.db.WriteGraph;
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.layer0.StandardRealm;
19 import org.simantics.db.layer0.StandardSessionManager;
20 import org.simantics.db.layer0.variable.ProxyVariables;
21 import org.simantics.db.layer0.variable.Variable;
22 import org.simantics.db.layer0.variable.Variables;
23 import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment;
24 import org.simantics.spreadsheet.graph.synchronization.SpreadsheetSynchronizationEventHandler;
25 import org.simantics.spreadsheet.resource.SpreadsheetResource;
26 import org.simantics.structural.synchronization.Synchronizer;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 public class SpreadsheetSessionManager extends StandardSessionManager<SheetNode, SpreadsheetBook> {
31
32     private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetSessionManager.class);
33     
34         private static SpreadsheetSessionManager INSTANCE;
35         
36         public static SpreadsheetSessionManager getInstance() {
37                 if(INSTANCE == null) {
38                         INSTANCE = new SpreadsheetSessionManager();
39                 }
40                 return INSTANCE;
41         }
42         
43         public class ClassLoaderObjectInputStream extends ObjectInputStream{
44
45              private ClassLoader classLoader;
46
47              public ClassLoaderObjectInputStream(ClassLoader classLoader, InputStream in) throws IOException {
48                   super(in);
49                   this.classLoader = classLoader;
50              }
51              
52              @Override
53              protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException{
54              
55                   try{
56                        String name = desc.getName();
57                        return Class.forName(name, false, classLoader);
58                   }
59                   catch(ClassNotFoundException e){
60                        return super.resolveClass(desc);
61                   }
62              }
63         }
64         
65     private SpreadsheetBook getPossibleInitialCondition(ReadGraph graph, Resource context, Resource book) throws DatabaseException {
66         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
67         Collection<Resource> ics = graph.getObjects(context, SR.HasInitialCondition);
68         
69         Resource found = null;
70         Set<Resource> founds = new HashSet<>();
71         Set<Resource> foundDefaults = new HashSet<>();
72
73         for (Resource initialCondition : ics) {
74             if (graph.hasStatement(book, SR.Book_HasDefaultInitialCondition, initialCondition)) {
75                 foundDefaults.add(initialCondition);
76             }
77             if (graph.hasStatement(initialCondition, SR.InitialCondition_ConditionOf, book)) {
78                 founds.add(initialCondition);
79             }
80         }
81         if (foundDefaults.size() == 1) {
82             found = foundDefaults.iterator().next();
83         } else if (foundDefaults.size() == 0 && founds.size() == 1) {
84             found = founds.iterator().next();
85         } else {
86             System.err.println("Could not find IC for SpreadsheetBook " + graph.getPossibleURI(book));
87             System.err.println("foundDefaults : " + foundDefaults.size());
88             if (!foundDefaults.isEmpty()) {
89                 for (Resource foundDefault : foundDefaults) {
90                     System.err.println(graph.getPossibleURI(foundDefault));
91                 }
92             }
93             System.err.println("founds : " + founds.size());
94             if (!founds.isEmpty()) {
95                 for (Resource foun : founds) {
96                     System.err.println(graph.getPossibleURI(foun));
97                 }
98             }
99         }
100
101         if (found != null) {
102             try {
103                 File tmp = SpreadsheetGraphUtils.extractInitialCondition(graph, found);
104                 System.err.println("Extracting IC from " + tmp.getAbsolutePath());
105                 InputStream fileIn = new BufferedInputStream(new FileInputStream(tmp));
106                 ObjectInputStream in = new ClassLoaderObjectInputStream(getClass().getClassLoader(), fileIn);
107                 SpreadsheetBook srBook = (SpreadsheetBook) in.readObject();
108                 in.close();
109                 return srBook;
110             } catch (IOException e) {
111                 throw new DatabaseException(e);
112             } catch (ClassNotFoundException e) {
113                 throw new DatabaseException(e);
114             }
115         }
116         return null;
117     }
118         
119     @Override
120     protected SpreadsheetBook createEngine(ReadGraph graph, String id) throws DatabaseException {
121
122         Variable run = Variables.getVariable(graph, id);
123         Variable context = ProxyVariables.proxyVariableInput(graph, run);
124         if (context != null) {
125             Variable base = ProxyVariables.proxyVariableBase(graph, run);
126             Resource bookResource = base.getRepresents(graph);
127             Resource contextResource = context.getRepresents(graph);
128             if (contextResource != null) {
129                 SpreadsheetBook ic = getPossibleInitialCondition(graph, contextResource, bookResource);
130                 if (ic != null)
131                     return ic;
132             }
133
134             SpreadsheetBook ic = getPossibleInitialCondition(graph, bookResource, bookResource);
135             if (ic != null)
136                 return ic;
137         }
138
139         SpreadsheetBook book = new SpreadsheetBook();
140         
141         Variable base = ProxyVariables.proxyVariableBase(graph, run);
142         Resource bookResource = base.getRepresents(graph);
143         Variable configuration = Variables.getVariable(graph, bookResource);
144         
145         SpreadsheetSynchronizationEventHandler handler = new SpreadsheetSynchronizationEventHandler(graph, book);
146         Synchronizer synchronizer = new Synchronizer(graph);
147         synchronizer.fullSynchronization(configuration, handler);
148         
149         return book;
150
151     }
152
153         @Override
154         protected StandardRealm<SheetNode, SpreadsheetBook> createRealm(SpreadsheetBook engine, String id) {
155                 return new SpreadsheetRealm(engine, id);
156         }
157
158         @Override
159         public void removeRealm(WriteGraph graph, String id) throws DatabaseException {
160         StandardRealm<SheetNode, SpreadsheetBook> realm = getOrCreateRealm(graph, id);
161         SpreadsheetEvaluationEnvironment.removeInstance(realm.getEngine());
162         super.removeRealm(graph, id);
163     }
164     
165     // Utility function for SCL, this should maybe be replaced with something better in the future
166     public static void removeSpreadsheetSession(WriteGraph graph, Variable runVariable) throws DatabaseException {
167         String uri = runVariable.getParent(graph).getURI(graph);
168         getInstance().removeRealm(graph, uri);
169     }
170 }
171