
com.aggrepoint.utils.linkedtable.LinkedTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aputils Show documentation
Show all versions of aputils Show documentation
Common utilities used by both Dao and Winlet project
The newest version!
package com.aggrepoint.utils.linkedtable;
import java.util.Hashtable;
import java.util.Vector;
import com.aggrepoint.utils.TypeCast;
/**
* @param
* Type of column key
* @param
* Type of row key
* @param
* Table content type
*/
public class LinkedTable extends PropObject {
ColumnHead m_colHead;
ColumnHead m_colTail;
RowHead m_rowHead;
RowHead m_rowTail;
public TValue[][] toArray(TValue[][] arr) {
if (m_rowHead == null || m_colHead == null)
return null;
int rc = getRowCount();
int cc = getColumnCount();
boolean bCreate = true;
if (arr.length != rc)
bCreate = true;
else
for (int i = 0; i < arr.length; i++)
if (arr[i].length != cc) {
bCreate = true;
break;
}
if (bCreate)
arr = TypeCast.cast(java.lang.reflect.Array.newInstance(arr
.getClass().getComponentType().getComponentType(), rc, cc));
RowHead row = m_rowHead;
for (int r = 0; r < rc; r++) {
Node node = row.m_firstNode;
int c = 0;
while (node != null) {
arr[r][c++] = node.m_value;
node = node.m_nextInRow;
}
row = row.m_nextHead;
}
return arr;
}
RowHead getRow(TRow row, boolean createIfNotExists) {
if (m_rowHead == null) {
if (!createIfNotExists)
return null;
// This is the first row
// Create the row
m_rowHead = m_rowTail = new RowHead(row);
// { create nodes in the row
ColumnHead col = m_colHead;
Node nodePrev = null;
while (col != null) {
Node node = new Node(
col, m_rowHead, null);
col.m_firstNode = col.m_lastNode = node;
if (nodePrev == null)
m_rowHead.m_firstNode = node;
else
nodePrev.m_nextInRow = node;
nodePrev = node;
col = col.m_nextHead;
}
m_rowHead.m_lastNode = nodePrev;
// }
return m_rowHead;
}
RowHead r = m_rowHead.find(row);
if (r != null)
return r;
if (!createIfNotExists)
return null;
// append a row
r = new RowHead(row);
m_rowTail.m_nextHead = r;
m_rowTail = r;
// { create nodes in the row
ColumnHead col = m_colHead;
Node nodePrev = null;
while (col != null) {
Node node = new Node(
col, r, null);
col.m_lastNode.m_nextInColumn = node;
col.m_lastNode = node;
if (nodePrev == null)
r.m_firstNode = node;
else
nodePrev.m_nextInRow = node;
nodePrev = node;
col = col.m_nextHead;
}
r.m_lastNode = nodePrev;
// }
return r;
}
ColumnHead getColumn(TColumn column,
boolean createIfNotExists) {
if (m_colHead == null) {
if (!createIfNotExists)
return null;
// This is the first column
// Create the column
m_colHead = m_colTail = new ColumnHead(
column);
// { create nodes in the column
RowHead row = m_rowHead;
Node nodePrev = null;
while (row != null) {
Node node = new Node(
m_colHead, row, null);
row.m_firstNode = row.m_lastNode = node;
if (nodePrev == null)
m_colHead.m_firstNode = node;
else
nodePrev.m_nextInColumn = node;
nodePrev = node;
row = row.m_nextHead;
}
m_colHead.m_lastNode = nodePrev;
// }
return m_colHead;
}
ColumnHead col = m_colHead.find(column);
if (col != null)
return col;
if (!createIfNotExists)
return null;
// append a column
col = new ColumnHead(column);
m_colTail.m_nextHead = col;
m_colTail = col;
// { create nodes in the column
RowHead row = m_rowHead;
Node nodePrev = null;
while (row != null) {
Node node = new Node(
col, row, null);
row.m_lastNode.m_nextInRow = node;
row.m_lastNode = node;
if (nodePrev == null)
col.m_firstNode = node;
else
nodePrev.m_nextInColumn = node;
nodePrev = node;
row = row.m_nextHead;
}
col.m_lastNode = nodePrev;
// }
return col;
}
public ColumnHead addColumn(TColumn col) {
return getColumn(col, true);
}
public RowHead addRow(TRow row) {
return getRow(row, true);
}
public void insertColumn(TColumn col, int posi) {
ColumnHead newCol = new ColumnHead(
col);
if (posi == 0) {
newCol.m_nextHead = m_colHead;
m_colHead = newCol;
if (m_colTail == null)
m_colTail = newCol;
// create nodes in the column
RowHead row = m_rowHead;
Node nodePrev = null;
while (row != null) {
Node node = new Node(
newCol, row, null);
node.m_nextInRow = row.m_firstNode;
row.m_firstNode = node;
if (row.m_lastNode == null)
row.m_lastNode = node;
if (nodePrev == null)
newCol.m_firstNode = node;
else
nodePrev.m_nextInColumn = node;
nodePrev = node;
row = row.m_nextHead;
}
newCol.m_lastNode = nodePrev;
return;
}
ColumnHead prev = m_colHead;
for (int i = 0; i < posi - 1 && prev != null; i++)
prev = prev.m_nextHead;
if (prev == null)
return;
newCol.m_nextHead = prev.m_nextHead;
prev.m_nextHead = newCol;
if (newCol.m_nextHead == null)
m_colTail = newCol;
// create nodes in the column
RowHead row = m_rowHead;
Node nodePrev = null;
while (row != null) {
Node pn = row.m_firstNode;
for (int i = 0; i < posi - 1 && pn != null; i++)
pn = pn.m_nextInRow;
Node node = new Node(
newCol, row, null);
node.m_nextInRow = pn.m_nextInRow;
pn.m_nextInRow = node;
if (node.m_nextInRow == null)
row.m_lastNode = node;
if (nodePrev == null)
newCol.m_firstNode = node;
else
nodePrev.m_nextInColumn = node;
nodePrev = node;
row = row.m_nextHead;
}
newCol.m_lastNode = nodePrev;
}
public void set(TColumn column, TRow row, TValue value) {
ColumnHead col = getColumn(column, true);
RowHead r = getRow(row, true);
Node node = col.m_firstNode;
while (node != null) {
if (node.m_row == r) {
node.m_value = value;
return;
}
node = node.m_nextInColumn;
}
}
Object add(TValue a, TValue b) {
if (a instanceof Double)
return ((Double) a).doubleValue() + ((Double) b).doubleValue();
else if (a instanceof Float)
return ((Float) a).doubleValue() + ((Float) b).doubleValue();
else if (a instanceof Long)
return ((Long) a).doubleValue() + ((Long) b).doubleValue();
else if (a instanceof Integer)
return ((Integer) a).doubleValue() + ((Integer) b).doubleValue();
else if (a instanceof Short)
return ((Short) a).doubleValue() + ((Short) b).doubleValue();
return b;
}
@SuppressWarnings("unchecked")
public void add(TColumn column, TRow row, TValue value) {
ColumnHead col = getColumn(column, true);
RowHead r = getRow(row, true);
Node node = col.m_firstNode;
while (node != null) {
if (node.m_row == r) {
node.m_value = (TValue) add(node.m_value, value);
return;
}
node = node.m_nextInColumn;
}
}
public TValue get(TColumn column, TRow row) {
if (m_colHead == null || m_rowHead == null)
return null;
ColumnHead col = m_colHead.find(column);
RowHead r = m_rowHead.find(row);
if (col == null || r == null)
return null;
Node node = col.m_firstNode;
while (node != null) {
if (node.m_row == r) {
return node.m_value;
}
node = node.m_nextInColumn;
}
return null;
}
public TColumn getFirstColumn() {
if (m_colHead == null)
return null;
return m_colHead.m_value;
}
public TRow getFirstRow() {
if (m_rowHead == null)
return null;
return m_rowHead.m_value;
}
public Vector getColumns() {
if (m_colHead == null)
return null;
ColumnHead col = m_colHead;
while (col != null) {
col = col.m_nextHead;
}
Vector cols = new Vector();
col = m_colHead;
while (col != null) {
cols.add(col.m_value);
col = col.m_nextHead;
}
return cols;
}
public Vector> getColumnProps() {
if (m_colHead == null)
return null;
ColumnHead col = m_colHead;
while (col != null) {
col = col.m_nextHead;
}
Vector> cols = new Vector>();
col = m_colHead;
while (col != null) {
cols.add(col.getProps());
col = col.m_nextHead;
}
return cols;
}
public Vector getRows() {
if (m_rowHead == null)
return null;
RowHead row = m_rowHead;
while (row != null) {
row = row.m_nextHead;
}
Vector rows = new Vector();
row = m_rowHead;
while (row != null) {
rows.add(row.m_value);
row = row.m_nextHead;
}
return rows;
}
public Vector> getRowProps() {
if (m_rowHead == null)
return null;
RowHead row = m_rowHead;
while (row != null) {
row = row.m_nextHead;
}
Vector> rows = new Vector>();
row = m_rowHead;
while (row != null) {
rows.add(row.getProps());
row = row.m_nextHead;
}
return rows;
}
public int getColumnCount() {
if (m_colHead == null)
return 0;
int c = 0;
ColumnHead col = m_colHead;
while (col != null) {
c++;
col = col.m_nextHead;
}
return c;
}
public int getRowCount() {
if (m_rowHead == null)
return 0;
int c = 0;
RowHead row = m_rowHead;
while (row != null) {
c++;
row = row.m_nextHead;
}
return c;
}
int findRowPosi(TRow row) {
if (row == null)
return -1;
RowHead r = m_rowHead;
int posi = 0;
while (r != null) {
if (r.m_value.equals(row))
return posi;
posi++;
r = r.m_nextHead;
}
return -1;
}
RowHead getRowHead(int posi) {
if (posi < 0)
return null;
RowHead r = m_rowHead;
while (r != null) {
if (posi == 0)
return r;
posi--;
r = r.m_nextHead;
}
return null;
}
public TRow getRow(int posi) {
RowHead head = getRowHead(posi);
if (head == null)
return null;
return head.m_value;
}
int findColumnPosi(TColumn column) {
if (column == null)
return -1;
ColumnHead col = m_colHead;
int posi = 0;
while (col != null) {
if (col.m_value.equals(column))
return posi;
posi++;
col = col.m_nextHead;
}
return -1;
}
ColumnHead getColumnHead(int posi) {
if (posi < 0)
return null;
ColumnHead col = m_colHead;
while (col != null) {
if (posi == 0)
return col;
posi--;
col = col.m_nextHead;
}
return null;
}
public TColumn getColumn(int posi) {
ColumnHead head = getColumnHead(posi);
if (head == null)
return null;
return head.m_value;
}
public void deleteColumn(TColumn column) {
int posi = findColumnPosi(column);
if (posi == -1)
return;
if (posi == 0) {
if (m_colTail == m_colHead)
m_colHead = m_colTail = null;
else
m_colHead = m_colHead.m_nextHead;
RowHead row = m_rowHead;
while (row != null) {
if (m_colHead == null)
row.m_firstNode = row.m_lastNode = null;
else
row.m_firstNode = row.m_firstNode.m_nextInRow;
row = row.m_nextHead;
}
} else {
ColumnHead col = m_colHead;
posi--;
for (int i = 0; i < posi; i++)
col = col.m_nextHead;
if (m_colTail == col.m_nextHead)
m_colTail = col;
col.m_nextHead = col.m_nextHead.m_nextHead;
RowHead row = m_rowHead;
while (row != null) {
Node node = row.m_firstNode;
for (int i = 0; i < posi; i++)
node = node.m_nextInRow;
if (row.m_lastNode == node.m_nextInRow)
row.m_lastNode = node;
node.m_nextInRow = node.m_nextInRow.m_nextInRow;
row = row.m_nextHead;
}
}
}
public void deleteRow(TRow row) {
int posi = findRowPosi(row);
if (posi == -1)
return;
if (posi == 0) {
if (m_rowTail == m_rowHead)
m_rowHead = m_rowTail = null;
else
m_rowHead = m_rowHead.m_nextHead;
ColumnHead col = m_colHead;
while (col != null) {
if (m_rowHead == null)
col.m_firstNode = col.m_lastNode = null;
else
col.m_firstNode = col.m_firstNode.m_nextInColumn;
col = col.m_nextHead;
}
} else {
RowHead r = m_rowHead;
posi--;
for (int i = 0; i < posi; i++)
r = r.m_nextHead;
if (m_rowTail == r.m_nextHead)
m_rowTail = r;
r.m_nextHead = r.m_nextHead.m_nextHead;
ColumnHead col = m_colHead;
while (col != null) {
Node node = col.m_firstNode;
for (int i = 0; i < posi; i++)
node = node.m_nextInColumn;
if (col.m_lastNode == node.m_nextInColumn)
col.m_lastNode = node;
node.m_nextInColumn = node.m_nextInColumn.m_nextInColumn;
col = col.m_nextHead;
}
}
}
TValue[] getValuesInColumn(ColumnHead col,
TValue[] vals) {
if (col == null)
return null;
int count = getRowCount();
if (vals.length != count)
vals = TypeCast.cast(java.lang.reflect.Array.newInstance(vals
.getClass().getComponentType(), count));
Node node = col.m_firstNode;
int c = 0;
while (node != null) {
vals[c++] = node.m_value;
node = node.m_nextInColumn;
}
return vals;
}
public TValue[] getValuesInColumn(TColumn column, TValue[] vals) {
return getValuesInColumn(getColumn(column, false), vals);
}
public TValue[] getValuesInColumn(int posi, TValue[] vals) {
return getValuesInColumn(getColumnHead(posi), vals);
}
TValue[] getValuesInRow(RowHead r, TValue[] vals) {
if (r == null)
return null;
int count = getColumnCount();
if (vals.length != count)
vals = TypeCast.cast(java.lang.reflect.Array.newInstance(vals
.getClass().getComponentType(), count));
Node node = r.m_firstNode;
int c = 0;
while (node != null) {
vals[c++] = node.m_value;
node = node.m_nextInRow;
}
return vals;
}
public TValue[] getValuesInRow(TRow row, TValue[] vals) {
return getValuesInRow(getRow(row, false), vals);
}
public TValue[] getValuesInRow(int posi, TValue[] vals) {
return getValuesInRow(getRowHead(posi), vals);
}
@SuppressWarnings("unchecked")
public void sortColumns(TColumn[] order) {
if (order == null || m_colHead == null)
return;
// { calculate the order by position id
int[] orders = new int[getColumnCount()];
TColumn[] cols = TypeCast.cast(new Object[orders.length]);
int i = 0;
ColumnHead col = m_colHead;
while (col != null) {
cols[i++] = col.m_value;
col = col.m_nextHead;
}
i = 0;
for (TColumn c : order) {
for (int j = 0; j < cols.length; j++) {
if (cols[j] == null)
continue;
if (cols[j].equals(c)) {
orders[i++] = j;
cols[j] = null;
continue;
}
}
}
for (int j = 0; j < cols.length; j++)
if (cols[j] != null)
orders[i++] = j;
// }
// {sort header
Object[] heads = new Object[orders.length];
Object[] newHeads = new Object[orders.length];
i = 0;
col = m_colHead;
while (col != null) {
heads[i++] = col;
col = col.m_nextHead;
}
for (int j = 0; j < orders.length; j++)
newHeads[j] = heads[orders[j]];
m_colHead = (ColumnHead) newHeads[0];
m_colTail = (ColumnHead) newHeads[orders.length - 1];
m_colTail.m_nextHead = null;
for (int j = 0; j < orders.length - 1; j++)
((ColumnHead) newHeads[j]).m_nextHead = TypeCast
.cast(newHeads[j + 1]);
// }
// { sort data
Object[] nodes = new Object[orders.length];
Object[] newNodes = new Object[orders.length];
RowHead row = m_rowHead;
while (row != null) {
Node node = row.m_firstNode;
i = 0;
while (node != null) {
nodes[i++] = node;
node = node.m_nextInRow;
}
for (int j = 0; j < orders.length; j++)
newNodes[j] = nodes[orders[j]];
row.m_firstNode = (Node) newNodes[0];
row.m_lastNode = (Node) newNodes[orders.length - 1];
row.m_lastNode.m_nextInRow = null;
for (int j = 0; j < orders.length - 1; j++)
((Node) newNodes[j]).m_nextInRow = (Node) newNodes[j + 1];
row = row.m_nextHead;
}
// }
}
@SuppressWarnings("unchecked")
public void sortRows(TRow[] order) {
if (order == null || m_rowHead == null)
return;
// { calculate the order by position id
int[] orders = new int[getRowCount()];
TRow[] rows = TypeCast.cast(new Object[orders.length]);
int i = 0;
RowHead row = m_rowHead;
while (row != null) {
rows[i++] = row.m_value;
row = row.m_nextHead;
}
i = 0;
for (TRow r : order) {
for (int j = 0; j < rows.length; j++) {
if (rows[j] == null)
continue;
if (rows[j].equals(r)) {
orders[i++] = j;
rows[j] = null;
continue;
}
}
}
for (int j = 0; j < rows.length; j++)
if (rows[j] != null)
orders[i++] = j;
// }
// {sort header
Object[] heads = new Object[orders.length];
Object[] newHeads = new Object[orders.length];
i = 0;
row = m_rowHead;
while (row != null) {
heads[i++] = row;
row = row.m_nextHead;
}
for (int j = 0; j < orders.length; j++)
newHeads[j] = heads[orders[j]];
m_rowHead = (RowHead) newHeads[0];
m_rowTail = (RowHead) newHeads[orders.length - 1];
m_rowTail.m_nextHead = null;
for (int j = 0; j < orders.length - 1; j++)
((RowHead) newHeads[j]).m_nextHead = TypeCast
.cast(newHeads[j + 1]);
// }
// { sort data
Object[] nodes = new Object[orders.length];
Object[] newNodes = new Object[orders.length];
ColumnHead col = m_colHead;
while (col != null) {
Node node = col.m_firstNode;
i = 0;
while (node != null) {
nodes[i++] = node;
node = node.m_nextInColumn;
}
for (int j = 0; j < orders.length; j++)
newNodes[j] = nodes[orders[j]];
col.m_firstNode = (Node) newNodes[0];
col.m_lastNode = (Node) newNodes[orders.length - 1];
col.m_lastNode.m_nextInColumn = null;
for (int j = 0; j < orders.length - 1; j++)
((Node) newNodes[j]).m_nextInColumn = (Node) newNodes[j + 1];
col = col.m_nextHead;
}
// }
}
public void mergeColumn(TColumn from, TColumn to, INodeMerger merger) {
if (m_colHead == null)
return;
ColumnHead colFrom = m_colHead.find(from);
ColumnHead colTo = m_colHead.find(to);
if (colFrom == null)
return;
if (colTo == null) {
colFrom.m_value = to;
return;
}
Node ndFrom = colFrom.m_firstNode;
Node ndTo = colTo.m_firstNode;
while (ndFrom != null && ndTo != null) {
ndTo.m_value = merger.merge(ndFrom.m_value, ndTo.m_value);
ndFrom = ndFrom.m_nextInColumn;
ndTo = ndTo.m_nextInColumn;
}
deleteColumn(from);
}
public void mergeColumn(TColumn[] froms, TColumn to, INodeMerger merger) {
if (m_colHead == null)
return;
for (int i = 0; i < froms.length; i++)
mergeColumn(froms[i], to, merger);
}
public void mergeRow(TRow from, TRow to, INodeMerger merger) {
if (m_rowHead == null)
return;
RowHead rowFrom = m_rowHead.find(from);
RowHead rowTo = m_rowHead.find(to);
if (rowFrom == rowTo)
return;
if (rowFrom == null)
return;
if (rowTo == null) {
rowFrom.m_value = to;
return;
}
Node ndFrom = rowFrom.m_firstNode;
Node ndTo = rowTo.m_firstNode;
while (ndFrom != null && ndTo != null) {
ndTo.m_value = merger.merge(ndFrom.m_value, ndTo.m_value);
ndFrom = ndFrom.m_nextInRow;
ndTo = ndTo.m_nextInRow;
}
deleteRow(from);
}
public void mergeRow(TRow[] froms, TRow to, INodeMerger merger) {
if (m_rowHead == null)
return;
for (int i = 0; i < froms.length; i++)
mergeRow(froms[i], to, merger);
}
public void updateColumns(Hashtable map) {
if (m_colHead == null)
return;
ColumnHead col = m_colHead;
while (col != null) {
TColumn c = map.get(col.m_value);
if (c != null)
col.m_value = c;
col = col.m_nextHead;
}
}
public void updateRows(Hashtable map) {
if (m_rowHead == null)
return;
RowHead row = m_rowHead;
while (row != null) {
TRow r = map.get(row.m_value);
if (r != null)
row.m_value = r;
row = row.m_nextHead;
}
}
public boolean setColumnProp(TColumn col, String name, Object value) {
ColumnHead head = getColumn(col, false);
if (head == null)
return false;
head.setProp(name, value);
return true;
}
public boolean setColumnProp(int col, String name, Object value) {
ColumnHead head = getColumnHead(col);
if (head == null)
return false;
head.setProp(name, value);
return true;
}
public void copyColumnToProp(String name) {
ColumnHead col = m_colHead;
while (col != null) {
col.setProp(name, col.m_value);
col = col.m_nextHead;
}
}
public Object getColumnProp(TColumn col, String name) {
ColumnHead c = getColumn(col, false);
if (c == null)
return null;
if (name == null)
return c.getProps();
else
return c.getProp(name);
}
public Object getColumnProp(int posi, String name) {
ColumnHead c = getColumnHead(posi);
if (c == null)
return null;
if (name == null)
return c.getProps();
else
return c.getProp(name);
}
public boolean setRowProp(TRow row, String name, Object value) {
RowHead head = getRow(row, false);
if (head == null)
return false;
head.setProp(name, value);
return true;
}
public boolean setRowProp(int row, String name, Object value) {
RowHead head = getRowHead(row);
if (head == null)
return false;
head.setProp(name, value);
return true;
}
public void copyRowToProp(String name) {
RowHead r = m_rowHead;
while (r != null) {
r.setProp(name, r.m_value);
r = r.m_nextHead;
}
}
public Object getRowProp(TRow row, String name) {
RowHead head = getRow(row, false);
if (head == null)
return false;
if (name == null)
return head.getProps();
else
return head.getProp(name);
}
public Object getRowProp(int posi, String name) {
RowHead head = getRowHead(posi);
if (head == null)
return false;
if (name == null)
return head.getProps();
else
return head.getProp(name);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy