]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetGraphUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetGraphUtils.java
1 package org.simantics.spreadsheet.graph;\r
2 \r
3 import java.io.File;\r
4 import java.io.FileNotFoundException;\r
5 import java.io.FileOutputStream;\r
6 import java.io.IOException;\r
7 import java.io.ObjectOutputStream;\r
8 import java.util.ArrayList;\r
9 import java.util.Collection;\r
10 import java.util.HashMap;\r
11 import java.util.Iterator;\r
12 import java.util.List;\r
13 import java.util.Map;\r
14 \r
15 import org.simantics.Simantics;\r
16 import org.simantics.databoard.Bindings;\r
17 import org.simantics.databoard.binding.mutable.Variant;\r
18 import org.simantics.databoard.util.binary.RandomAccessBinary;\r
19 import org.simantics.datatypes.DatatypeResource;\r
20 import org.simantics.datatypes.literal.Font;\r
21 import org.simantics.datatypes.literal.RGB;\r
22 import org.simantics.datatypes.utils.BTree;\r
23 import org.simantics.db.ReadGraph;\r
24 import org.simantics.db.Resource;\r
25 import org.simantics.db.WriteGraph;\r
26 import org.simantics.db.common.request.ObjectsWithType;\r
27 import org.simantics.db.common.utils.LiteralFileUtil;\r
28 import org.simantics.db.exception.DatabaseException;\r
29 import org.simantics.db.exception.ServiceException;\r
30 import org.simantics.db.layer0.StandardRealm;\r
31 import org.simantics.db.layer0.util.Layer0Utils;\r
32 import org.simantics.db.layer0.variable.Variable;\r
33 import org.simantics.db.layer0.variable.Variables;\r
34 import org.simantics.db.service.ClusteringSupport;\r
35 import org.simantics.layer0.Layer0;\r
36 import org.simantics.scl.runtime.tuple.Tuple2;\r
37 import org.simantics.spreadsheet.Range;\r
38 import org.simantics.spreadsheet.graph.synchronization.SpreadsheetSynchronizationEventHandler;\r
39 import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
40 import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
41 import org.simantics.structural.synchronization.Synchronizer;\r
42 \r
43 import gnu.trove.iterator.TObjectIntIterator;\r
44 import gnu.trove.map.hash.TObjectIntHashMap;\r
45 \r
46 public class SpreadsheetGraphUtils {\r
47 \r
48     public static File extractInitialCondition(ReadGraph graph, Resource ic) throws DatabaseException, IOException {\r
49 \r
50         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
51 \r
52         File temp = Simantics.getTempfile("excel","ic");\r
53 \r
54         LiteralFileUtil.copyRandomAccessBinaryToFile(graph, ic, SR.InitialCondition_bytes, temp);\r
55         if (temp.length() == 0)\r
56             throw new FileNotFoundException("Snapshot file does not exist.\nThis seems to be a database bug that manifests as total loss of state file data.\nThis error prevents the program from crashing.");\r
57 \r
58         return temp;\r
59         \r
60     }\r
61         \r
62     public static RandomAccessBinary getOrCreateRandomAccessBinary(WriteGraph graph, Resource initialCondition) throws DatabaseException, IOException {\r
63 \r
64         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
65         \r
66         // We put snapshot literals in their own clusters for now just to be safe\r
67         Resource literal = graph.getPossibleObject(initialCondition, SR.InitialCondition_bytes);\r
68         if (literal != null) {\r
69             RandomAccessBinary rab = graph.getRandomAccessBinary(literal);\r
70             rab.position(0);\r
71             rab.removeBytes(rab.length(), RandomAccessBinary.ByteSide.Right);\r
72             return rab;\r
73         } else {\r
74             Layer0 L0 = Layer0.getInstance(graph);\r
75             ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
76             literal = graph.newResource(cs.createCluster());\r
77             graph.claim(literal, L0.InstanceOf, null, L0.ByteArray);\r
78             graph.claim(initialCondition, SR.InitialCondition_bytes, SR.InitialCondition_bytes_Inverse, literal);\r
79             return graph.createRandomAccessBinary(literal, Bindings.BYTE_ARRAY.type(), null);\r
80         }\r
81     }\r
82 \r
83     public static Resource saveInitialCondition(WriteGraph graph, Variable run, Resource container, String name) throws DatabaseException {\r
84 \r
85                 String sessionName = run.getParent(graph).getURI(graph);\r
86 \r
87                 Resource bookResource = run.getRepresents(graph);\r
88                 \r
89         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
90         SpreadsheetBook book = realm.getEngine();\r
91 \r
92         try {\r
93         \r
94                 File temp = Simantics.getTempfile("excel", "ic");\r
95                 System.err.println("Saving initial condition to " + temp.getAbsolutePath());\r
96                 \r
97                         FileOutputStream fileOut = new FileOutputStream(temp);\r
98                         ObjectOutputStream out = new ObjectOutputStream(fileOut);\r
99                         out.writeObject(book);\r
100                         out.close();\r
101                         fileOut.close();\r
102                         \r
103                         Layer0 L0 = Layer0.getInstance(graph);\r
104                 SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
105                         Resource ic = graph.newResource();\r
106                         graph.claim(ic, L0.InstanceOf, SR.InitialCondition);\r
107                         graph.addLiteral(ic, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
108                 \r
109                 RandomAccessBinary rab = getOrCreateRandomAccessBinary(graph, ic);\r
110                 LiteralFileUtil.copyRandomAccessBinaryFromFile(temp, rab);\r
111                 \r
112                         graph.claim(container, L0.ConsistsOf, L0.PartOf, ic);\r
113                         \r
114                         graph.deny(bookResource, SR.HasInitialCondition);\r
115                         graph.claim(bookResource, SR.HasInitialCondition, ic);\r
116                         graph.claim(ic, SR.InitialCondition_ConditionOf, bookResource);\r
117                         \r
118                         setDefaultInitialConditionForBook(graph, bookResource, ic);\r
119 \r
120                 return ic;\r
121                 \r
122         } catch (IOException e) {\r
123                 \r
124                 throw new DatabaseException(e);\r
125                 \r
126         }\r
127     }\r
128     \r
129     public static void setDefaultInitialConditionForBook(WriteGraph graph, Resource book, Resource ic) throws ServiceException {\r
130         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
131         graph.deny(book, SR.Book_HasDefaultInitialCondition);\r
132         graph.claim(ic, SR.InitialCondition_DefaultConditionOf, book);\r
133     }\r
134 \r
135     public static void evaluateAll(ReadGraph graph, Variable run) throws DatabaseException {\r
136 \r
137                 String sessionName = run.getParent(graph).getURI(graph);\r
138         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
139         SpreadsheetBook book = realm.getEngine();\r
140         book.accept(new EvaluateAll(book));\r
141         \r
142     }\r
143 \r
144     public static void invalidateAll(ReadGraph graph, Variable run) throws DatabaseException {\r
145 \r
146                 String sessionName = run.getParent(graph).getURI(graph);\r
147         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
148         SpreadsheetBook book = realm.getEngine();\r
149         book.accept(new InvalidateAll());\r
150         realm.getNodeManager().refreshVariables();\r
151         \r
152     }\r
153     \r
154     public static boolean fullSynchronization(ReadGraph graph, Variable run) throws DatabaseException {\r
155         return partialSynchronization(graph, run, null);\r
156     }\r
157 \r
158     public static boolean partialSynchronization(ReadGraph graph, Variable run, TObjectIntHashMap<Variable> changeFlags) throws DatabaseException {\r
159 \r
160         Synchronizer synchronizer = new Synchronizer(graph);\r
161                 String sessionName = run.getParent(graph).getURI(graph);\r
162                 \r
163         Resource bookResource = run.getRepresents(graph);\r
164         Variable configuration = Variables.getVariable(graph, bookResource);\r
165         \r
166         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
167         SpreadsheetBook book = realm.getEngine();\r
168                         \r
169         SpreadsheetSynchronizationEventHandler handler = new SpreadsheetSynchronizationEventHandler(graph, book);\r
170         \r
171 //        System.err.println("sessionName : " + sessionName);\r
172 //        System.err.println("bookResource : " + graph.getURI(bookResource));\r
173 //        System.err.println("configuration : " + configuration.getURI(graph));\r
174 //        System.err.println("realm : " + realm);\r
175 //        System.err.println("book : " + book);\r
176         \r
177         if (changeFlags == null) {\r
178             synchronizer.fullSynchronization(configuration, handler);\r
179         } else {\r
180             \r
181             TObjectIntIterator<Variable> iter = changeFlags.iterator();\r
182             iter.advance();\r
183             Variable row = iter.key();\r
184             \r
185             Variable rowParent = row.getParent(graph);\r
186             while (!rowParent.equals(configuration)) {\r
187                 changeFlags.put(rowParent, 1);\r
188                 rowParent = rowParent.getParent(graph);\r
189             }\r
190             \r
191             changeFlags.put(configuration, 1);\r
192             \r
193             synchronizer.partialSynchronization(configuration, handler, changeFlags);\r
194         }\r
195         \r
196 //        book.accept(new InvalidateAll());\r
197 //        realm.getNodeManager().refreshVariables();\r
198 //        mapping.currentRevision = synchronizer.getHeadRevisionId();\r
199 //        mapping.setTrustUids(true);\r
200         // Clean up queries\r
201 //        QueryControl qc = g.getService(QueryControl.class);\r
202 //        qc.flush(g);\r
203 //        TimeLogger.log("Finished full synchronization");\r
204         realm.getNodeManager().fireNodeListeners();\r
205         return handler.getDidChanges();\r
206         \r
207     }\r
208 \r
209     public static Variable findCell(ReadGraph graph, Variable run, String reference) throws DatabaseException {\r
210 \r
211         int pos = reference.indexOf("!");\r
212         String sheetName = reference.substring(0, pos);\r
213         String cellName = reference.substring(pos+1);\r
214 \r
215                 String sessionName = run.getParent(graph).getURI(graph);\r
216         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
217         SpreadsheetBook book = realm.getEngine();\r
218         SpreadsheetEngine engine = book.getEngine(sheetName);\r
219         if(engine == null) return null;\r
220         \r
221         Range r = SpreadsheetUtils.decodeCellAbsolute(cellName);\r
222         SpreadsheetLine line = engine.getLine(r.startRow);\r
223         if(line == null) return null;\r
224         \r
225         String path = line.getPath();\r
226         if(path == null) return null;\r
227         \r
228         Variable lineVariable = run.browse(graph, path);\r
229         if(lineVariable==null) return null;\r
230         \r
231         return lineVariable.getChild(graph, cellName);\r
232         \r
233     }\r
234 \r
235     \r
236     public static boolean asBoolean(Object object) {\r
237         if(object instanceof Boolean) return (Boolean)object;\r
238         else if(object instanceof Number) return ((Number)object).doubleValue() != 0;\r
239         else if(object instanceof Variant) return asBoolean(((Variant)object).getValue());\r
240         else if(object instanceof String) {\r
241                 Double d = asDoubleWhereEmptyStringIsZero((String)object);\r
242                 if(d==null) return false;\r
243                 else return d != 0;\r
244         }\r
245         return false;\r
246     }\r
247     \r
248     public static String asString(Object object) {\r
249         if(object == null) return "";\r
250         if(object instanceof String) return (String)object;\r
251         if(object instanceof Number) {\r
252                 double dVal = ((Number)object).doubleValue();\r
253                 if(dVal == Math.floor(dVal)){\r
254                         return ""+((Number)object).intValue();\r
255                 } else {\r
256                         return object.toString();\r
257                 }\r
258         }\r
259         else if(object instanceof Variant) {\r
260                 Object o = ((Variant) object).getValue();\r
261                 if(o instanceof String) return (String)o;\r
262                 else if(o instanceof Number) asString((Number)o);\r
263                 else return o.toString();\r
264         }\r
265         return object.toString();\r
266     }\r
267     \r
268     public static Double asDoubleWhereEmptyStringIsZero(Object object){\r
269         if(object instanceof Number)\r
270                 return ((Number)object).doubleValue();\r
271         else if(object instanceof String) {\r
272                 try {\r
273                         if(((String)object).isEmpty())\r
274                                 return 0.0;\r
275                         return Double.parseDouble((String)object);\r
276                         } catch (NumberFormatException e) {\r
277                                 return null;\r
278                         }\r
279         } else if(object instanceof Variant) {\r
280                 Object o = ((Variant) object).getValue();\r
281                 return asDoubleWhereEmptyStringIsZero(o);\r
282         } else if (SpreadsheetCell.EMPTY == object) {\r
283                 return null;\r
284         }\r
285         return null;\r
286     }\r
287     \r
288     public static double asNumber(Object object) {\r
289         if(object instanceof Number) {\r
290                 return ((Number)object).doubleValue();\r
291         } else if(object instanceof String) {\r
292                 try {\r
293                         String str = (String)object;\r
294                         if(str.isEmpty()) return 0;\r
295                         return Double.parseDouble((String)object);\r
296                         } catch (NumberFormatException e) {\r
297                         return 0;\r
298                         }\r
299         } else if(object instanceof Variant) {\r
300                 Object o = ((Variant) object).getValue();\r
301                 return asNumber(o);\r
302         } else if (SpreadsheetCell.EMPTY == object) {\r
303                 return 0.0;\r
304         }\r
305                 \r
306         return 0.0;\r
307         \r
308     }\r
309     \r
310     public static Number asValidNumber(Object object) {\r
311         if(object instanceof Number) {\r
312                 return (Number)object;\r
313         } else if(object instanceof String) {\r
314                 try {\r
315                         return Double.parseDouble((String)object);\r
316                         } catch (NumberFormatException e) {\r
317                         return null;\r
318                         }\r
319         } else if(object instanceof Variant) {\r
320                 Object o = ((Variant) object).getValue();\r
321                 return asNumber(o);\r
322         } else if (SpreadsheetCell.EMPTY == object) {\r
323                 return null;\r
324         }\r
325                 \r
326         return null;\r
327         \r
328     }\r
329     \r
330     public static boolean matchCriteria(Object value, Object criteria) {\r
331         if(value==null || criteria==null) return false;\r
332         \r
333         if(value instanceof Variant){\r
334                 Double dVal = asDoubleWhereEmptyStringIsZero(value);\r
335                 if(dVal==null) value = ((Variant)value).getValue();\r
336                 else value = dVal;\r
337         }\r
338         if(criteria instanceof Variant){\r
339                 Double dVal = asDoubleWhereEmptyStringIsZero(criteria);\r
340                 if(dVal==null) criteria = ((Variant)criteria).getValue();\r
341                 else criteria = dVal;\r
342         }\r
343         \r
344         if(criteria instanceof Number && value instanceof Number) {\r
345                 Number nc = (asNumber(criteria));\r
346                 Number nv = (asNumber(value));\r
347                 return nc.equals(nv);\r
348         }\r
349         if(criteria instanceof String){\r
350                 boolean nums = false;\r
351                 Object valueObj = null;\r
352                         if(value instanceof Number){\r
353                                 valueObj = ((Number)value).doubleValue();\r
354                                 nums = true;\r
355                         }\r
356                         else valueObj = value.toString();\r
357                         \r
358                 String sc = criteria.toString();\r
359                         if(sc.length() >= 3){\r
360                                 String oper = sc.substring(0, 2);\r
361                                 String criteriaStr = sc.substring(2);\r
362                                 Double criteriaNum = null;\r
363                                 try {\r
364                                         criteriaNum = Double.parseDouble(criteriaStr);\r
365                                         if(oper.equals("<>")){\r
366                                                 if(!nums) return true;\r
367                                         }\r
368                                         else if(!nums) return false;\r
369                                         nums = true;\r
370                                 } catch (NumberFormatException e){\r
371                                         if(oper.equals("<>")){\r
372                                                 if(nums) return true;\r
373                                         }\r
374                                         else if(nums) return false;\r
375                                         nums = false;\r
376                                 }\r
377                                 \r
378                                 if(oper.equals(">=")){\r
379                                         if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) >= 0 ;\r
380                                         else return ((Number)valueObj).doubleValue() >= criteriaNum;\r
381                                 } else if(oper.equals("<=")){\r
382                                         if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) <= 0 ;\r
383                                         else return ((Number)valueObj).doubleValue() <= criteriaNum;\r
384                                 } else if(oper.equals("<>")){\r
385                                         if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) != 0 ;\r
386                                         else return ((Number)valueObj).doubleValue() != criteriaNum;\r
387                                 }\r
388                         }\r
389                 if(sc.length() >= 2){\r
390                         String oper = sc.substring(0, 1);\r
391                         String criteriaStr = sc.substring(1);\r
392                         Double criteriaNum = null;\r
393                         \r
394                         try {\r
395                                         criteriaNum = Double.parseDouble(criteriaStr);\r
396                                         if(!nums) return false;\r
397                                         nums = true;\r
398                                 } catch (NumberFormatException e){\r
399                                         if(nums) return false;\r
400                                         nums = false;\r
401                                 }\r
402                         if(oper.equals("<")){\r
403                                 if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) < 0;\r
404                                 else return ((Number)valueObj).doubleValue() < criteriaNum;\r
405                         } else if(oper.equals(">")){\r
406                                 if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) > 0;\r
407                                 else return ((Number)valueObj).doubleValue() > criteriaNum;\r
408                         } else if(oper.equals("=")){\r
409                                 if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) == 0;\r
410                                 else return ((Number)valueObj).doubleValue() == criteriaNum;\r
411                         }\r
412                 }\r
413                 return sc.equals(valueObj);\r
414         }\r
415         else if (criteria instanceof Number){\r
416                 return false;\r
417         }\r
418         throw new IllegalStateException();\r
419     }\r
420 \r
421     public static boolean excelEquals(Object left, Object right) {\r
422         if(left instanceof String) {\r
423                 if(right instanceof String) {\r
424                         return ((String) left).toLowerCase().equals(((String) right).toLowerCase());\r
425                 }\r
426         }\r
427         return left.equals(right);\r
428     }\r
429     \r
430 \r
431     public static List<Variable> possibleConfigurationCellVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {\r
432         List<Variable> rowVariables = possibleConfigurationLineVariables(graph, sheet, range);\r
433         List<Variable> result = new ArrayList<>();\r
434         for (Variable variable : rowVariables) {\r
435             Collection<Variable> children = variable.getChildren(graph);\r
436             for (Variable child : children) {\r
437                 if (variableInRange(graph, child, range)) {\r
438                     result.add(child);\r
439                 }\r
440             }\r
441         }\r
442         return result;\r
443     }\r
444     \r
445     public static Map<Integer, Resource> possibleConfigurationLineResources(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {\r
446         Variable lines = sheet.getPossibleChild(graph, "Lines");\r
447         if (lines == null)\r
448             throw new DatabaseException("Invalid input variable " + sheet.getURI(graph));\r
449         Resource linesR = lines.getRepresents(graph);\r
450         BTree bt = new BTree(graph, linesR);\r
451         List<Tuple2> tuples = bt.searchRangeBTree(graph, Variant.ofInstance(range.startRow), Variant.ofInstance(range.endRow));\r
452         Map<Integer, Resource> result = new HashMap<>(tuples.size());\r
453         for (Tuple2 tuple : tuples) {\r
454             Integer lineNumber = (Integer)((Variant)tuple.c0).getValue();\r
455             Resource resource = (Resource)tuple.c1;\r
456             result.put(lineNumber, resource);\r
457         }\r
458         return result; \r
459     }\r
460     \r
461     public static List<Variable> possibleConfigurationLineVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {\r
462         Map<Integer, Resource> rows = possibleConfigurationLineResources(graph, sheet, range);\r
463         List<Variable> result = new ArrayList<>(rows.size());\r
464         for (Resource row: rows.values()) {\r
465             Variable lineVar = Variables.getPossibleVariable(graph, row);\r
466             if (lineVar != null)\r
467                 result.add(lineVar);\r
468         }\r
469         return result;\r
470     }\r
471     \r
472     public static List<Variable> possibleRunLineVariables(ReadGraph graph, Variable sheetRun, Range range) throws DatabaseException {\r
473         \r
474         Variable run = sheetRun.getParent(graph);\r
475         \r
476         String sheetName = sheetRun.getName(graph);\r
477         String sessionName = run.getParent(graph).getURI(graph);\r
478         \r
479         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
480         SpreadsheetBook book = realm.getEngine();\r
481         \r
482         SpreadsheetEngine engine = book.getEngine(sheetName);\r
483         if(engine == null) return null;\r
484         \r
485         List<Variable> result = new ArrayList<>();\r
486         \r
487         int end = range.endRow < engine.lines.getMaxRow() ? range.endRow : engine.lines.getMaxRow();\r
488         for (int i = range.startRow; i <= end; i++) {\r
489                 SpreadsheetLine line = engine.getLine(i);\r
490                 if(line == null)\r
491                         continue;\r
492                 \r
493                 String path = line.getPath();\r
494                 path = line.getPath();\r
495                 if(path == null)\r
496                         continue;\r
497                 \r
498                 Variable lineVariable = run.browse(graph, path);\r
499                 if(lineVariable==null)\r
500                         continue;\r
501                 result.add(lineVariable);\r
502         }\r
503     \r
504         return result;\r
505     }\r
506     \r
507     public static List<Variable> possibleRunCellVariables(ReadGraph graph, Variable sheetRun, Range range) throws DatabaseException {\r
508         List<Variable> runLineVariable = possibleRunLineVariables(graph, sheetRun, range);\r
509         List<Variable> result = new ArrayList<>();\r
510         for (Variable variable : runLineVariable) {\r
511 //              System.out.println("line: " + variable.getURI(graph));\r
512             for (Variable child : variable.getChildren(graph)) {\r
513 //              System.out.print("cell : " + child.getURI(graph));\r
514                 if (variableInRange(graph, child, range)) {\r
515                     result.add(child);\r
516                 }\r
517             }\r
518         }\r
519         return result;\r
520     }\r
521     \r
522     private static boolean variableInRange(ReadGraph graph, Variable child, Range range) throws DatabaseException {\r
523         String name = child.getName(graph);\r
524         Range childRange = SpreadsheetUtils.decodeCellAbsolute(name);\r
525 //        System.out.print(" and range " + childRange);\r
526         if (childRange != null && range.contains(childRange)) {\r
527 //              System.out.println(" => range.contains(childRange) = true");\r
528             return true;\r
529         }\r
530 //        System.out.println();\r
531         return false;\r
532     }\r
533     \r
534     public static Map<Integer, Resource> createConfigurationLineResources(WriteGraph graph, Variable sheet, Range range) throws DatabaseException {\r
535         Layer0 L0 = Layer0.getInstance(graph);\r
536         SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
537         \r
538         Variable lines = sheet.getPossibleChild(graph, "Lines");\r
539         if (lines == null)\r
540             throw new DatabaseException("Invalid input variable " + sheet.getURI(graph));\r
541         Resource linesR = lines.getRepresents(graph);\r
542         BTree bt = new BTree(graph, linesR);\r
543         \r
544         Map<Integer, Resource> result = new HashMap<>();\r
545         for (int lineNumber = range.startRow; lineNumber <= range.endRow; lineNumber++) {\r
546             Resource line = graph.newResource();\r
547             graph.claim(line, L0.InstanceOf, null, SHEET.Line);\r
548             graph.claimLiteral(line, L0.HasName, L0.NameOf, L0.String, "Row" + lineNumber, Bindings.STRING);\r
549             bt.insertBTree(graph, Variant.ofInstance(lineNumber), line);\r
550             result.put(lineNumber, line);\r
551         }\r
552         return result;\r
553     }\r
554 \r
555     public static List<Variable> getOrCreateConfigurationCellVariables(WriteGraph graph, Variable sheet, Range range) throws DatabaseException {\r
556         \r
557         List<Variable> rows = possibleConfigurationLineVariables(graph, sheet, range);\r
558         if (rows.isEmpty()) {\r
559             createConfigurationLineResources(graph, sheet, range);\r
560             rows = possibleConfigurationLineVariables(graph, sheet, range);\r
561         }\r
562         \r
563         List<Variable> cells = possibleConfigurationCellVariables(graph, sheet, range);\r
564         if (cells.isEmpty()) {\r
565             Iterator<Variable> rowIterator = rows.iterator();\r
566             for (int rowNumber = range.startRow; rowNumber <= range.endRow; rowNumber++) {\r
567                 Variable row = rowIterator.next();\r
568                 for (int colNumber = range.startColumn; colNumber <= range.endColumn; colNumber++) {\r
569                     String location = SpreadsheetUtils.cellName(rowNumber, colNumber);\r
570                     defaultCreateCell(graph, row, location, new Variant(Bindings.STRING, ""));\r
571                 }\r
572             }\r
573         }\r
574         \r
575         cells = possibleConfigurationCellVariables(graph, sheet, range);\r
576         if(cells.isEmpty())\r
577             throw new DatabaseException("Unexpected problem while creating spreadsheet cell at '" + range + "'");\r
578         \r
579         return cells;\r
580     }\r
581     \r
582     private static void defaultCreateCell(WriteGraph graph, Variable parent, String location, Variant value) throws DatabaseException {\r
583 \r
584         Layer0 L0 = Layer0.getInstance(graph);\r
585         SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
586         Resource container = parent.getRepresents(graph);\r
587         \r
588         Resource cell = graph.newResource();\r
589         graph.claim(cell, L0.InstanceOf, null, SHEET.TextCell);\r
590         graph.addLiteral(cell, L0.HasName, L0.NameOf, L0.String, location, Bindings.STRING);\r
591         graph.addLiteral(cell, SHEET.Cell_content, SHEET.Cell_content_Inverse, L0.Variant, value, Bindings.VARIANT);\r
592         graph.claim(cell, L0.PartOf, container);\r
593         \r
594         Resource book = Variables.getContext(graph, parent).getRepresents(graph);\r
595         \r
596         \r
597         Collection<Resource> objects = graph.sync(new ObjectsWithType(book, L0.ConsistsOf, SHEET.Style));\r
598         \r
599         int styleId = SpreadsheetStyle.empty().getStyleId();\r
600         Resource style = null;\r
601         for (Resource possibleStyle : objects) {\r
602             int possibleStyleId = graph.getRelatedValue2(possibleStyle, SHEET.Style_id, Bindings.INTEGER);\r
603             if (possibleStyleId == styleId) {\r
604                 style = possibleStyle;\r
605                 break;\r
606             }\r
607         }\r
608         \r
609         if (style == null) {\r
610             style = graph.newResource();\r
611             graph.claim(style, L0.InstanceOf, null, SHEET.Style);\r
612             graph.claim(style, L0.PartOf, book);\r
613             \r
614             int id = objects.size();\r
615             graph.claimLiteral(style, L0.HasName, "Style_" + id);\r
616             graph.claimLiteral(style, SHEET.Style_id, styleId, Bindings.INTEGER);\r
617         }\r
618         graph.claim(cell, SHEET.Cell_HasStyle, style);\r
619         Layer0Utils.addCommentMetadata(graph, "Created cell on location " + location + " with value " + value.toString());\r
620     }\r
621 \r
622     public static Resource createStyle(WriteGraph graph, Resource book, SpreadsheetStyle sstyle) throws DatabaseException {\r
623         Layer0 L0 = Layer0.getInstance(graph);\r
624         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
625         Resource style = graph.newResource();\r
626         graph.claim(style, L0.InstanceOf, null, SR.Style);\r
627         graph.claim(style, L0.PartOf, book);\r
628         \r
629         int styleId = sstyle.getStyleId();\r
630         String styleName = sstyle.name;\r
631         \r
632         graph.claimLiteral(style, L0.HasName, styleName);\r
633         //System.err.println("CREATING STYLE " + styleName + " WITH ID: " + styleId);\r
634         graph.claimLiteral(style, SR.Style_id, styleId, Bindings.INTEGER);\r
635         \r
636         DatatypeResource DATATYPES = DatatypeResource.getInstance(graph);\r
637         if (sstyle.foreground != null)\r
638             graph.claimLiteral(style, SR.Cell_foreground, DATATYPES.RGB_Integer, sstyle.foreground, RGB.Integer.BINDING);\r
639         if (sstyle.background != null)\r
640             graph.claimLiteral(style, SR.Cell_background, DATATYPES.RGB_Integer, sstyle.background, RGB.Integer.BINDING);\r
641         if (sstyle.align != -1)\r
642             graph.claimLiteral(style, SR.Cell_align, sstyle.align, Bindings.INTEGER);\r
643         if (sstyle.font != null)\r
644             graph.claimLiteral(style, SR.Cell_font, DATATYPES.Font, sstyle.font, Font.BINDING);\r
645         if (sstyle.border != -1)\r
646             graph.claimLiteral(style, SR.Cell_border, sstyle.border);\r
647         if (sstyle.formatString != null && !sstyle.formatString.isEmpty())\r
648             graph.claimLiteral(style, SR.Cell_formatString, sstyle.formatString, Bindings.STRING);\r
649         if (sstyle.formatIndex != -1)\r
650             graph.claimLiteral(style, SR.Cell_formatIndex, sstyle.formatIndex, Bindings.INTEGER);\r
651         \r
652         return style;\r
653     }\r
654     \r
655     public static Resource createBook(WriteGraph graph, Resource parent, String name) throws DatabaseException {\r
656         Layer0 L0 = Layer0.getInstance(graph);\r
657         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
658         Resource book = graph.newResource();\r
659         graph.claim(book, L0.InstanceOf, SR.Book);\r
660         graph.claimLiteral(book, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
661         graph.claim(parent, L0.ConsistsOf, book);\r
662         \r
663         return book;\r
664     }\r
665     \r
666     public static Variable constructAndInitializeRunVariable(WriteGraph graph, Resource root) throws DatabaseException {\r
667         Variable run = SpreadsheetUtils.getBookVariable(graph, root);\r
668         SpreadsheetGraphUtils.fullSynchronization(graph, run);\r
669         SpreadsheetGraphUtils.evaluateAll(graph, run);\r
670         SpreadsheetGraphUtils.saveInitialCondition(graph, run, root, "Initial");\r
671         return run;\r
672     }\r
673 \r
674 }\r