]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet/src/org/simantics/spreadsheet/solver/SpreadsheetLines.java
e53d7cb61624109dd53b87f119604c1fd6c982c5
[simantics/platform.git] / bundles / org.simantics.spreadsheet / src / org / simantics / spreadsheet / solver / SpreadsheetLines.java
1 package org.simantics.spreadsheet.solver;
2
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.Map;
6 import java.util.Optional;
7
8 import org.simantics.spreadsheet.SpreadsheetVisitor;
9 import org.simantics.spreadsheet.Spreadsheets;
10
11 import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap;
12
13 @SuppressWarnings("rawtypes")
14 public class SpreadsheetLines implements SpreadsheetElement<SpreadsheetLine, SpreadsheetEngine>, SheetNode {
15
16     private static final long serialVersionUID = -3615335969248723486L;
17
18     private final int id;
19     private SpreadsheetEngine parent;
20     private String name;
21     public Int2ObjectAVLTreeMap<SpreadsheetLines> nodes = new Int2ObjectAVLTreeMap<SpreadsheetLines>();
22     public Int2ObjectAVLTreeMap<SpreadsheetLine> lines = new Int2ObjectAVLTreeMap<SpreadsheetLine>();
23     public int[] keys;
24
25     public SpreadsheetLines(SpreadsheetEngine parent, String name) {
26         this.parent = parent;
27         this.name = name;
28         id = getEngine().getBook().getNewId(this);
29     }
30
31     public SpreadsheetEngine getEngine() {
32         return parent;
33     }
34
35     public int getId() {
36         return id;
37     }
38
39     @Override
40     public String getName() {
41         return name;
42     }
43
44     @SuppressWarnings({ "unchecked" })
45     @Override
46     public Map getChildren() {
47         Int2ObjectAVLTreeMap result = new Int2ObjectAVLTreeMap();
48         result.putAll(nodes);
49         result.putAll(lines);
50         return result;
51     }
52
53     @Override
54     public Map getProperties() {
55         return Collections.singletonMap("typeURI", new SpreadsheetTypeNode(Spreadsheets.LINES_TYPE_URI));
56     } 
57
58     Object resolve(String[] parts, int index) {
59
60         String part = parts[index];
61         if(part.charAt(0) == 'R') {
62             int indx = Integer.parseInt(part.substring(3));
63             SpreadsheetLine line = lines.get(-indx);
64             if(line != null) {
65                 if(index == parts.length-1) return line;
66                 else return line.resolve(parts, index+1);
67             }
68         } else {
69             int indx = Integer.parseInt(part);
70             SpreadsheetLines node = nodes.get(indx);
71             if(node != null) {
72                 if(index == parts.length-1) return node;
73                 else return node.resolve(parts, index+1);
74             }
75         }
76
77         return null;
78
79     }
80
81     public Object ensureSubprocess(String[] path, int index) {
82
83         String name = path[index];
84
85         int i = Integer.parseInt(name);
86         SpreadsheetLines line = nodes.get(i);
87         if(line == null) {
88             line = new SpreadsheetLines(parent, "" + i);
89             nodes.put(i, line);
90         }
91
92         if(index == path.length - 1) {
93             return line;
94         } else {
95             return line.ensureSubprocess(path, index+1);
96         }
97
98     }
99
100     public void setKeys(int[] keys) {
101         this.keys = keys;
102     }
103
104     @Override
105     public void accept(SpreadsheetVisitor v) {
106         v.visit(this);
107     }
108
109     public String getPath() {
110         return "/" + parent.getName() + "/" + parent.lines.getName() + "/" + getName();
111     }
112
113     private int getKey(int index) {
114         return keys[2*index+1];
115     }
116
117     private int getChild(int index) {
118         return keys[2*index];
119     }
120
121     /*
122      *  [(child,key),...,key)
123      * 
124      */
125     public SpreadsheetLine getLine(int k) {
126
127         int i=1;
128         int n = (keys.length - 1) / 2;
129
130         while(i <= n && k > getKey(i-1)) i++;
131
132         if(i <= n && k == getKey(i-1)) {
133             return lines.get(-k);
134         }
135
136         int nodeName = getChild(i-1);
137         SpreadsheetLines node = nodes.get(nodeName);
138         if(node == null) return null;
139         return node.getLine(k);
140
141     }
142
143     public int getMaxRow() {
144         // if keys == null then this is the root of BTree which has only one child 
145         if (keys == null) {
146             int maxRow = 0;
147             for (SpreadsheetLines node : nodes.values()) {
148                 int row = node.getMaxRow();
149                 if (row > maxRow)
150                     maxRow = row;
151             }
152             return maxRow;
153         }
154         int largestChild = keys[keys.length-1]; 
155         if(largestChild > 0) {
156             SpreadsheetLines child = nodes.get(largestChild);
157             return child.getMaxRow();
158         } else {
159             return keys[keys.length-2];
160         }
161     }
162
163     @Override
164     public Optional<SpreadsheetEngine> getParent() {
165         return Optional.of(parent);
166     }
167
168     @Override
169     public Collection<SpreadsheetLine> getSpreadsheetChildren() {
170         return lines.values();
171     }
172
173     @Override
174     public void remove(SpreadsheetLine child) {
175         lines.remove(-child.row);
176     }
177
178     @Override
179     public int hashCode() {
180         final int prime = 31;
181         int result = 1;
182         result = prime * result + ((name == null) ? 0 : name.hashCode());
183         result = prime * result + ((parent == null) ? 0 : parent.hashCode());
184         return result;
185     }
186
187     @Override
188     public boolean equals(Object obj) {
189         if (this == obj)
190             return true;
191         if (obj == null)
192             return false;
193         if (getClass() != obj.getClass())
194             return false;
195         SpreadsheetLines other = (SpreadsheetLines) obj;
196         if (name == null) {
197             if (other.name != null)
198                 return false;
199         } else if (!name.equals(other.name))
200             return false;
201         if (parent == null) {
202             if (other.parent != null)
203                 return false;
204         } else if (!parent.equals(other.parent))
205             return false;
206         return true;
207     }
208
209 }