1 package org.simantics.spreadsheet.solver;
3 import java.util.Collection;
4 import java.util.Collections;
6 import java.util.Optional;
8 import org.simantics.spreadsheet.SpreadsheetVisitor;
9 import org.simantics.spreadsheet.Spreadsheets;
11 import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap;
13 @SuppressWarnings("rawtypes")
14 public class SpreadsheetLines implements SpreadsheetElement<SpreadsheetLine, SpreadsheetEngine>, SheetNode {
16 private static final long serialVersionUID = -3615335969248723486L;
19 private SpreadsheetEngine parent;
21 public Int2ObjectAVLTreeMap<SpreadsheetLines> nodes = new Int2ObjectAVLTreeMap<SpreadsheetLines>();
22 public Int2ObjectAVLTreeMap<SpreadsheetLine> lines = new Int2ObjectAVLTreeMap<SpreadsheetLine>();
25 public SpreadsheetLines(SpreadsheetEngine parent, String name) {
28 id = getEngine().getBook().getNewId(this);
31 public SpreadsheetEngine getEngine() {
40 public String getName() {
44 @SuppressWarnings({ "unchecked" })
46 public Map getChildren() {
47 Int2ObjectAVLTreeMap result = new Int2ObjectAVLTreeMap();
54 public Map getProperties() {
55 return Collections.singletonMap("typeURI", new SpreadsheetTypeNode(Spreadsheets.LINES_TYPE_URI));
58 Object resolve(String[] parts, int index) {
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);
65 if(index == parts.length-1) return line;
66 else return line.resolve(parts, index+1);
69 int indx = Integer.parseInt(part);
70 SpreadsheetLines node = nodes.get(indx);
72 if(index == parts.length-1) return node;
73 else return node.resolve(parts, index+1);
81 public Object ensureSubprocess(String[] path, int index) {
83 String name = path[index];
85 int i = Integer.parseInt(name);
86 SpreadsheetLines line = nodes.get(i);
88 line = new SpreadsheetLines(parent, "" + i);
92 if(index == path.length - 1) {
95 return line.ensureSubprocess(path, index+1);
100 public void setKeys(int[] keys) {
105 public void accept(SpreadsheetVisitor v) {
109 public String getPath() {
110 return "/" + parent.getName() + "/" + parent.lines.getName() + "/" + getName();
113 private int getKey(int index) {
114 return keys[2*index+1];
117 private int getChild(int index) {
118 return keys[2*index];
122 * [(child,key),...,key)
125 public SpreadsheetLine getLine(int k) {
128 int n = (keys.length - 1) / 2;
130 while(i <= n && k > getKey(i-1)) i++;
132 if(i <= n && k == getKey(i-1)) {
133 return lines.get(-k);
136 int nodeName = getChild(i-1);
137 SpreadsheetLines node = nodes.get(nodeName);
138 if(node == null) return null;
139 return node.getLine(k);
143 public int getMaxRow() {
144 // if keys == null then this is the root of BTree which has only one child
147 for (SpreadsheetLines node : nodes.values()) {
148 int row = node.getMaxRow();
154 int largestChild = keys[keys.length-1];
155 if(largestChild > 0) {
156 SpreadsheetLines child = nodes.get(largestChild);
157 return child.getMaxRow();
159 return keys[keys.length-2];
164 public Optional<SpreadsheetEngine> getParent() {
165 return Optional.of(parent);
169 public Collection<SpreadsheetLine> getSpreadsheetChildren() {
170 return lines.values();
174 public void remove(SpreadsheetLine child) {
175 lines.remove(-child.row);
179 public int hashCode() {
180 final int prime = 31;
182 result = prime * result + ((name == null) ? 0 : name.hashCode());
183 result = prime * result + ((parent == null) ? 0 : parent.hashCode());
188 public boolean equals(Object obj) {
193 if (getClass() != obj.getClass())
195 SpreadsheetLines other = (SpreadsheetLines) obj;
197 if (other.name != null)
199 } else if (!name.equals(other.name))
201 if (parent == null) {
202 if (other.parent != null)
204 } else if (!parent.equals(other.parent))