2010-02-03 03:29:47 +01:00
|
|
|
package com.metaweb.gridworks.model;
|
2010-01-24 22:09:50 +01:00
|
|
|
|
2010-01-27 02:48:42 +01:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.ObjectInputStream;
|
2010-01-25 23:51:25 +01:00
|
|
|
import java.io.Serializable;
|
2010-01-24 22:09:50 +01:00
|
|
|
import java.util.ArrayList;
|
2010-02-06 00:05:00 +01:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Comparator;
|
2010-01-24 22:09:50 +01:00
|
|
|
import java.util.List;
|
|
|
|
|
2010-02-06 00:05:00 +01:00
|
|
|
import com.metaweb.gridworks.expr.ExpressionUtils;
|
2010-02-03 03:29:47 +01:00
|
|
|
import com.metaweb.gridworks.history.History;
|
|
|
|
import com.metaweb.gridworks.process.ProcessManager;
|
2010-01-27 02:48:42 +01:00
|
|
|
|
2010-01-25 23:51:25 +01:00
|
|
|
public class Project implements Serializable {
|
|
|
|
private static final long serialVersionUID = -5089046824819472570L;
|
|
|
|
|
2010-02-03 22:57:38 +01:00
|
|
|
final public long id;
|
2010-01-27 02:48:42 +01:00
|
|
|
|
2010-02-03 22:57:38 +01:00
|
|
|
final public ColumnModel columnModel = new ColumnModel();
|
|
|
|
final public List<Row> rows = new ArrayList<Row>();
|
|
|
|
final public History history;
|
2010-01-27 02:48:42 +01:00
|
|
|
|
|
|
|
transient public ProcessManager processManager;
|
2010-01-24 22:09:50 +01:00
|
|
|
|
|
|
|
public Project() {
|
|
|
|
id = Math.round(Math.random() * 1000000) + System.currentTimeMillis();
|
2010-01-27 02:48:42 +01:00
|
|
|
history = new History(this);
|
|
|
|
|
|
|
|
internalInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
|
|
|
in.defaultReadObject();
|
|
|
|
internalInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void internalInitialize() {
|
|
|
|
processManager = new ProcessManager();
|
2010-02-03 21:55:48 +01:00
|
|
|
|
2010-02-06 00:05:00 +01:00
|
|
|
recomputeRowContextDependencies();
|
2010-02-03 21:55:48 +01:00
|
|
|
}
|
|
|
|
|
2010-02-06 00:05:00 +01:00
|
|
|
static protected class Group {
|
|
|
|
int[] cellIndices;
|
|
|
|
int keyCellIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void recomputeRowContextDependencies() {
|
|
|
|
List<Group> keyedGroups = new ArrayList<Group>();
|
|
|
|
|
2010-02-06 00:32:29 +01:00
|
|
|
addRootKeyedGroup(keyedGroups);
|
|
|
|
|
2010-02-06 00:05:00 +01:00
|
|
|
for (ColumnGroup group : columnModel.columnGroups) {
|
|
|
|
if (group.keyColumnIndex >= 0) {
|
|
|
|
Group keyedGroup = new Group();
|
|
|
|
keyedGroup.keyCellIndex = columnModel.columns.get(group.keyColumnIndex).getCellIndex();
|
|
|
|
keyedGroup.cellIndices = new int[group.columnSpan - 1];
|
|
|
|
|
|
|
|
int c = 0;
|
|
|
|
for (int i = 0; i < group.columnSpan; i++) {
|
|
|
|
int columnIndex = group.startColumnIndex + i;
|
|
|
|
if (columnIndex != group.keyColumnIndex) {
|
|
|
|
int cellIndex = columnModel.columns.get(columnIndex).getCellIndex();
|
|
|
|
keyedGroup.cellIndices[c++] = cellIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
keyedGroups.add(keyedGroup);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Collections.sort(keyedGroups, new Comparator<Group>() {
|
|
|
|
public int compare(Group o1, Group o2) {
|
|
|
|
return o2.cellIndices.length - o1.cellIndices.length; // larger groups first
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
int[] lastNonBlankRowsByGroup = new int[keyedGroups.size()];
|
|
|
|
for (int i = 0; i < lastNonBlankRowsByGroup.length; i++) {
|
|
|
|
lastNonBlankRowsByGroup[i] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int r = 0; r < rows.size(); r++) {
|
|
|
|
Row row = rows.get(r);
|
|
|
|
row.contextRowSlots = null;
|
|
|
|
row.contextCellSlots = null;
|
|
|
|
|
|
|
|
for (int g = 0; g < keyedGroups.size(); g++) {
|
|
|
|
Group group = keyedGroups.get(g);
|
|
|
|
|
|
|
|
if (ExpressionUtils.isBlank(row.getCellValue(group.keyCellIndex))) {
|
|
|
|
int contextRowIndex = lastNonBlankRowsByGroup[g];
|
|
|
|
if (contextRowIndex >= 0) {
|
|
|
|
for (int dependentCellIndex : group.cellIndices) {
|
|
|
|
if (!ExpressionUtils.isBlank(row.getCellValue(dependentCellIndex))) {
|
|
|
|
setRowDependency(
|
|
|
|
row,
|
|
|
|
dependentCellIndex,
|
|
|
|
contextRowIndex,
|
|
|
|
group.keyCellIndex
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lastNonBlankRowsByGroup[g] = r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row.contextRowSlots != null) {
|
|
|
|
row.contextRows = new ArrayList<Integer>();
|
|
|
|
for (int index : row.contextRowSlots) {
|
|
|
|
if (index >= 0) {
|
|
|
|
row.contextRows.add(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Collections.sort(row.contextRows);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-06 00:32:29 +01:00
|
|
|
protected void addRootKeyedGroup(List<Group> keyedGroups) {
|
|
|
|
int count = columnModel.getMaxCellIndex() + 1;
|
|
|
|
if (count > 0 && columnModel.getKeyColumnIndex() < columnModel.columns.size()) {
|
|
|
|
Group rootKeyedGroup = new Group();
|
|
|
|
|
|
|
|
rootKeyedGroup.cellIndices = new int[count - 1];
|
|
|
|
rootKeyedGroup.keyCellIndex = columnModel.columns.get(columnModel.getKeyColumnIndex()).getCellIndex();
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
if (i < rootKeyedGroup.keyCellIndex) {
|
|
|
|
rootKeyedGroup.cellIndices[i] = i;
|
|
|
|
} else if (i > rootKeyedGroup.keyCellIndex) {
|
|
|
|
rootKeyedGroup.cellIndices[i - 1] = i;
|
|
|
|
}
|
2010-02-06 00:05:00 +01:00
|
|
|
}
|
2010-02-06 00:32:29 +01:00
|
|
|
keyedGroups.add(rootKeyedGroup);
|
2010-02-06 00:05:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setRowDependency(Row row, int cellIndex, int contextRowIndex, int contextCellIndex) {
|
|
|
|
int count = columnModel.getMaxCellIndex() + 1;
|
|
|
|
if (row.contextRowSlots == null || row.contextCellSlots == null) {
|
|
|
|
row.contextRowSlots = new int[count];
|
|
|
|
row.contextCellSlots = new int[count];
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
row.contextRowSlots[i] = -1;
|
|
|
|
row.contextCellSlots[i] = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
row.contextRowSlots[cellIndex] = contextRowIndex;
|
|
|
|
row.contextCellSlots[cellIndex] = contextCellIndex;
|
2010-01-24 22:09:50 +01:00
|
|
|
}
|
|
|
|
}
|