WepsTableMeta.java [src/usda/weru/util/table] Revision: default Date:
/*
* WepsTableMeta.java
*
* Created on June 8, 2006, 12:16 PM
*
*/
package usda.weru.util.table;
import java.io.File;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import org.jdom.Element;
/**
* Contains configuration information for a WepsTable object.
* @author Joseph Levin
*/
public class WepsTableMeta implements XmlObject, Serializable {
private static int c_anonymousId = 100;
protected List<Column> c_columns;
// protected transient Label[][] c_labelMatrix;
protected WepsTableMeta c_parent; //Inheritable values.
// protected Hashtable<String, CellStyle> c_cellStyleMap;
protected Hashtable<String, Column> c_columnMap;
protected int c_frozenColumns = WepsTableEnum.NO_VALUE;
protected int c_frozenRows = WepsTableEnum.NO_VALUE;
protected int c_columnLabelDisplay = 1;
protected int c_rowLabelDisplay = WepsTableEnum.NO_VALUE;
// protected String c_defaultCellStyleId;
// protected String c_defaultLabelStyleId;
// protected CellStyle c_defaultCellStyle;
// protected CellStyle c_defaultLabelStyle;
/**
* Creates a new instance of WepsTableMeta
*/
public WepsTableMeta() {
init();
}
/**
* Initialize data structures that will hold information about the table.
*/
public void init() {
// c_cellStyleMap = new Hashtable<String, CellStyle>();
c_columnMap = new Hashtable<String, Column>();
c_columns = new Vector<Column>();
}
/**
* Load table configuration information from an org.jdom XML node.
* @param node An org.jdom.Element containing configuration information for the table.
*/
public void fromXml(Element node) {
init();
loadParent(node);
// loadCellStyles(node);
loadColumnStyles(node);
loadColumns(node);
// loadRowLabelDisplay(node);
// loadColumnLabelDisplay(node);
// loadFrozenRows(node);
// loadFrozenColumns(node);
}
// /**
// * Apply the current configuration settings to the specified WepsTable.
// * @param table The usda.weru.util.table.WepsTable to apply the current configuration to.
// */
// public void applyToTable(WepsTable table) {
// table.setRepaintEnabled(false);
// //Frozen rows/columns
// int frozenRows = getFrozenRows();
// if (frozenRows >= 0) {
// table.setFrozenRows(frozenRows);
// }
//
// int frozenColumns = getFrozenColumns();
// if (frozenColumns >= 0) {
// table.setFrozenColumns(frozenColumns);
// }
//
// //Label Display
// table.setRowLabelDisplay(isRowLabelDisplayed());
// table.setColumnLabelDisplay(isColumnLabelDisplayed());
//
// //Default styles
// CellStyle defaultCellStyle = getDefaultCellStyle();
// if (defaultCellStyle != null) {
// table.setDefaultCellStyle(defaultCellStyle);
// }
//
// CellStyle defaultLabelStyle = getDefaultLabelStyle();
// if (defaultLabelStyle != null) {
// table.setDefaultLabelStyle(defaultLabelStyle);
// }
//
//
// //Set column widths
// for (int c = 0; c < getColumnCount(); c++) {
// Column column = getColumn(c);
// table.setPixelWidth(c, column.getWidth());
//
// int min = column.getMinWidth();
// if (min != WepsTableEnum.NO_VALUE) {
// table.setMinWidth(c, min);
// }
//
// int max = column.getMaxWidth();
// if (max != WepsTableEnum.NO_VALUE) {
// table.setMaxWidth(c, max);
// }
//
// if (column.isHidden() || !column.isVisible()) {
// table.setColumnHidden(c, true);
// }
// }
//
// //Span columns for headers.
// table.clearSpannedRanges();
// if (isColumnLabelDisplayed()) {
// spanLabels(table);
// }
//
// //Lable Row Sizes.
// for (int r = -1; r < getLabelRowCount(); r++) {
// table.setPixelHeight(r, 20);
// }
// table.setRepaintEnabled(true);
//
// }
//
// /**
// * Returns the CellStyle of the given name. If there is no style by that name it will check the parent's list of styles. Returns <B>null</B> if it still can't be found.
// * @param id The id of the CellStyle.
// * @return The CellStyle that was found or <B>null</B> if one could not be found.
// */
// public CellStyle getCellStyle(String id) {
// if (id == null) {
// return null;
// //Inherit styles from the parent.
// }
// CellStyle style = c_cellStyleMap.get(id);
// if (style != null) {
// return style;
// } else if (c_parent != null) {
// return c_parent.getCellStyle(id);
// } else {
// return null;
// }
// }
//
// /**
// * Returns all CellStyles available.
// * @return A Collection of all available CellStyles.
// */
// public Collection<CellStyle> getCellStyles() {
// return c_cellStyleMap.values();
// }
//
// /**
// * Adds the given CellStyle to the list of available CellStyles.
// * @param style The style to be added to the list.
// */
// public void putCellStyle(CellStyle style) {
// if (style.isAnonymous()) {
// return; //No reason to store an anonymous cellstyle.
// }
// c_cellStyleMap.put(style.getId(), style);
// }
//
/**
* Returns the specified Column. Checks the parent if the column can't be found. Returns <B>null</B> if it still can't be found.
* @param id The name of the desired Column.
* @return The Column found or null if no column found.
*/
public Column getColumn(String id) {
if (id == null) {
return null;
//Inherit columns from the parent.
}
Column column = c_columnMap.get(id);
if (column != null) {
return column;
} else if (c_parent != null) {
return c_parent.getColumn(id);
} else {
return null;
}
}
/**
* Adds the given Column to the list of Columns
* @param column The Column to be added.
*/
public void putColumn(Column column) {
if (column.isAnonymous()) {
return; //No reason to store an anonymous column for lookup
}
c_columnMap.put(column.getId(), column);
}
/**
* Returns a unique ID.
* @return A unique ID.
*/
public String getAnonymousId() {
return Integer.toString(c_anonymousId++);
}
/**
* Load configuration settings from an XML file.
* @param file The file containing configuration settings for the table.
*/
public void fromFile(File file) {
Element root = Helper.getRootNode(file);
//TODO: Notify of fail.
if (root == null) {
return;
}
fromXml(root);
}
private void loadParent(Element node) {
String parentPath = node.getAttributeValue(WepsTableEnum.XML_parent);
if (parentPath == null) {
return;
}
File parentFile = new File(new File(parentPath).getAbsoluteFile().toString());
WepsTableMeta parent = new WepsTableMeta();
parent.fromFile(parentFile);
setParentMeta(parent);
}
private void setParentMeta(WepsTableMeta meta) {
c_parent = meta;
}
// @SuppressWarnings("unchecked")
// private void loadCellStyles(Element node) {
// //Load the defined cell styles
// Element stylesNode = node.getChild(WepsTableEnum.XML_cellstyles);
//
// if (stylesNode != null) //No cell styles to load.
// {
// for (Element element : (List<Element>) stylesNode.getChildren(WepsTableEnum.XML_style)) {
// CellStyle cellStyle = new CellStyle(this);
// cellStyle.fromXml(element);
// putCellStyle(cellStyle);
// }
// }
//
// //Load the default cell and label styles
// c_defaultCellStyleId = node.getChildText(WepsTableEnum.XML_defaultcellstyle);
// c_defaultCellStyle = getCellStyle(getDefaultCellStyleId());
//
// c_defaultLabelStyleId = node.getChildText(WepsTableEnum.XML_defaultlabelstyle);
// c_defaultLabelStyle = getCellStyle(getDefaultLabelStyleId());
//
// if (c_parent != null) {
// for (CellStyle style : c_parent.getCellStyles()) {
// style.setMeta(this);
// style.refreshParentStyle();
// }
// }
// }
//
// /**
// * Return the default CellStyle ID. If there is no default specified, it checks for the parents default CellStyle ID.
// * @return The ID of the default CellStyle.
// */
// public String getDefaultCellStyleId() {
// if (c_defaultCellStyleId == null && c_parent != null) {
// return c_parent.getDefaultCellStyleId();
// } else {
// return c_defaultCellStyleId;
// }
// }
//
// /**
// * Return the default CellStyle. If there is no default specified, it checks for the parents default CellStyle.
// * @return The default CellStyle.
// */
// public CellStyle getDefaultCellStyle() {
// if (c_defaultCellStyle == null && c_parent != null) {
// return c_parent.getDefaultCellStyle();
// } else {
// return c_defaultCellStyle;
// }
// }
//
// /**
// * Return the default label CellStyle ID. If there is no default specified, it checks for the parents default label CellStyle ID.
// * @return The default label CellStyle ID.
// */
// public String getDefaultLabelStyleId() {
// if (c_defaultLabelStyleId == null && c_parent != null) {
// return c_parent.getDefaultLabelStyleId();
// } else {
// return c_defaultLabelStyleId;
// }
// }
//
// /**
// * Return the default label CellStyle. If there is no default specified, it checks for the parents default label CellStyle.
// * @return The default label CellStyle.
// */
// public CellStyle getDefaultLabelStyle() {
// if (c_defaultLabelStyle == null && c_parent != null) {
// return c_parent.getDefaultLabelStyle();
// } else {
// return c_defaultLabelStyle;
// }
// }
//
private void loadColumnStyles(Element node) {
Element columnStylesNode = node.getChild(WepsTableEnum.XML_columnstyles);
if (columnStylesNode == null) {
return;
}
List<Element> children = columnStylesNode.getChildren(WepsTableEnum.XML_column);
for (Element columnNode : children) {
Column column = new Column(this, false);
column.fromXml(columnNode);
putColumn(column);
}
}
private void loadColumns(Element node) {
Element columnsNode = node.getChild(WepsTableEnum.XML_columns);
if (columnsNode != null) {
ColumnGroup columns = new ColumnGroup(this);
columns.fromXml(columnsNode);
// buildLabelMatrix();
}
}
// private void buildLabelMatrix() {
// int numberOfColumns = c_columns.size();
// int numberOfRows = 0;
// for (Column column : c_columns) {
// int depth = column.depthInHeader();
// if (depth > numberOfRows) {
// numberOfRows = depth;
// }
// }
//// numberOfRows = numberOfRows;
// c_labelMatrix = new Label[numberOfRows][numberOfColumns];
// for (int c = 0; c < numberOfColumns; c++) {
// addToLabelMatrix(getColumn(c), numberOfRows - 1, c);
// }
// }
//
// private void addToLabelMatrix(ColumnGroupOrColumn group, int rowIndex, int columnIndex) {
// //printLabelMatrix();
//
// int numberOfColumnsToSpan = group.getLabel().getSpanColumns();
// //Is the column spanning set on the label?
// if (numberOfColumnsToSpan <= 0) {
// //Determine the number of columns to span.
// //This is the number of columns at the bottom of the tree which share this parent.
// //Should always be one for a column, they have no children.
// numberOfColumnsToSpan = group.bottomBreadth();
// }
//
// int numberOfRowsToSpan = group.getLabel().getSpanRows();
// //Is the row spanning set on the label?
// if (numberOfRowsToSpan <= 0) {
// //Determine the number of rows to span.
// //span = rows - depthInHeader + 1
// int depth = group.depthInHeader() - 1; //We subtract 1 because the top level parent is a root container.
// numberOfRowsToSpan = rowIndex - depth + 1;
// }
//
// for (int c = 0; c < numberOfColumnsToSpan; c++) {
// for (int r = 0; r < numberOfRowsToSpan; r++) {
// if (c_labelMatrix[rowIndex - r][columnIndex + c] == null) {
// c_labelMatrix[rowIndex - r][columnIndex + c] = group.getLabel();
// }
// }
// }
//
// if (group.depthInHeader() > 1) { //Has a parent and grandparent.
// if (group.getParentGroup().isFirstChild(group)) {
// //This is the fist child, so it adds the parent.
// addToLabelMatrix(group.getParentGroup(), rowIndex - numberOfRowsToSpan, columnIndex);
// }
// }
//
// }
//
// /**
// *
// * @param table The WepsTable to be queried.
// * @param rowIndex The row index of the Cell to be queried.
// * @param columnIndex The column index of the cell to be queried.
// * @return
// */
// public Object getColumnLabel(WepsTable table, int rowIndex, int columnIndex) {
// if (rowIndex < 0 || columnIndex < 0) {
// return null;
// }
// Label label = getLabelMatrix()[rowIndex][columnIndex];
// if (label == null) {
// return null;
// }
// Object value = label.getObject(table, rowIndex, columnIndex);
// if (value instanceof String) {
// value = parse((String) value, table, rowIndex, columnIndex);
// }
// return value;
// }
//
// public void spanLabels(JCTable table) {
// //Num rows = 2 ---> freeze
// //TODO: Adjust frozen rows to the user's number of frozen rows. This will need to be handled by overiding setFrozenRows in WepsTable.
// boolean[][] used = null;
// try {
// used = new boolean[getLabelMatrix().length][getLabelMatrix()[0].length];
// } catch (ArrayIndexOutOfBoundsException aioobe) {
// //TODO: Notify of fail.
// return;
// }
//
// for (int r = 0; r < getLabelMatrix().length; r++) {
// for (int c = 0; c < getLabelMatrix()[r].length; c++) {
// if (!used[r][c]) {
// JCCellRange span = getSpan(r, c, used);
// if (span != null) {
// table.addSpannedRange(span);
// }
// }
// }
// }
// }
//
// private JCCellRange getSpan(int rowIndex, int columnIndex, boolean[][] used) {
// if (used[rowIndex][columnIndex]) {
// return null;
// }
// JCCellRange span = new JCCellRange();
// Label[][] labelMatrix = getLabelMatrix();
// Label label = labelMatrix[rowIndex][columnIndex];
//
// int endColumn = columnIndex;
// Label test = labelMatrix[rowIndex][endColumn];
//
// //How many columns are the same? Catch if the entire row has the same header.
// for (int cdx = columnIndex; cdx < used[rowIndex].length; cdx++) {
// test = labelMatrix[rowIndex][cdx];
// if (test != label) {
// break;
// }
// endColumn = cdx;
// }
//
// int endRow = 0;
// for (int rdx = rowIndex; rdx < used.length; rdx++) {
// test = labelMatrix[rdx][columnIndex];
// if (test != label) {
// break;
// }
// endRow = rdx;
// for (int cdx = columnIndex; cdx < endColumn; cdx++) {
// used[rdx][cdx] = false;
// }
// }
//
// span.start_column = columnIndex;
// span.start_row = rowIndex - 1;
// span.end_column = endColumn;
// span.end_row = endRow - 1;
//
// for (int ir = span.start_row + 1; ir <= span.end_row + 1; ir++) {
// for (int ic = span.start_column; ic <= span.end_column; ic++) {
// used[ir][ic] = true;
// }
// }
//
// return span;
// }
//
// /**
// *
// * @return
// */
// public Label[][] getLabelMatrix() {
// //TODO: Add more smarts to the tests, ie: is the number of columns correct...
// if (c_labelMatrix == null) {
// buildLabelMatrix();
// }
// return c_labelMatrix.clone();
// }
//
// private void loadRowLabelDisplay(Element node) {
// String rowLabelDisplayText = node.getChildTextTrim(WepsTableEnum.XML_rowlabeldisplay);
// if (rowLabelDisplayText == null) {
// return;
// }
// boolean rowLabelDisplay = Helper.isTrue(rowLabelDisplayText);
// if (rowLabelDisplay) {
// c_rowLabelDisplay = 1;
// }
// }
//
// /**
// *
// * @return
// */
// public boolean isRowLabelDisplayed() {
// if (c_rowLabelDisplay == WepsTableEnum.NO_VALUE && c_parent != null) {
// return c_parent.isRowLabelDisplayed();
// } else {
// return (c_rowLabelDisplay == 1);
// }
// }
//
// private void loadColumnLabelDisplay(Element node) {
// String columnLabelDisplayText = node.getChildTextTrim(WepsTableEnum.XML_columnlabeldisplay);
// if (columnLabelDisplayText == null) {
// return;
// }
// boolean columnLabelDisplay = Helper.isTrue(columnLabelDisplayText);
// if (columnLabelDisplay) {
// c_columnLabelDisplay = 1;
// }
// }
//
// /**
// *
// * @return
// */
// public boolean isColumnLabelDisplayed() {
// if (c_columnLabelDisplay == WepsTableEnum.NO_VALUE && c_parent != null) {
// return c_parent.isColumnLabelDisplayed();
// } else {
// return (c_columnLabelDisplay == 1);
// }
// }
//
// private void loadFrozenRows(Element node) {
// String frozenRowsText = node.getChildTextTrim(WepsTableEnum.XML_frozenrows);
// try {
// int frozenRows = Integer.parseInt(frozenRowsText);
// c_frozenRows = frozenRows;
// } catch (NumberFormatException nfe) {
// return;
// }
// }
//
// /**
// * Return the number of rows to be reserved as header rows.
// * @return The number of rows used as header rows.
// */
// public int getFrozenRows() {
// if (c_frozenRows == WepsTableEnum.NO_VALUE && c_parent != null) {
// return c_parent.getFrozenRows();
// } else if (c_frozenRows > 0) {
// return c_frozenRows;
// } else {
// return 0;
// }
// }
//
// private void loadFrozenColumns(Element node) {
// String frozenColumnsText = node.getChildTextTrim(WepsTableEnum.XML_frozencolumns);
// try {
// int frozenColumns = Integer.parseInt(frozenColumnsText);
// c_frozenColumns = frozenColumns;
// } catch (NumberFormatException nfe) {
// return;
// }
// }
//
// /**
// * Return the number of columns to be reserved as row headers.
// * @return The number of columns used as header rows.
// */
// public int getFrozenColumns() {
// if (c_frozenColumns == WepsTableEnum.NO_VALUE && c_parent != null) {
// return c_parent.getFrozenColumns();
// } else if (c_frozenColumns > 0) {
// return c_frozenColumns;
// } else {
// return 0;
// }
// }
//
/**
* Returns the list of Columns available to the table.
* @return The list of columns available to the table.
*/
public Column[] getColumns() {
Column[] temp = new Column[0];
return c_columns.toArray(temp);
}
/**
* Returns the number of Columns available to the table.
* @return The number of columns available to the table.
*/
public int getColumnCount() {
if (c_columns == null) {
return 0;
}
int count = c_columns.size();
return count;
}
/**
* Add the specified Column to the list of available Columns.
* @param column The Column to be added.
*/
public void addColumn(Column column) {
c_columns.add(column);
putColumn(column);
}
/**
* Return the Column at the specified index in the table.
* @param columnIndex The index of the desired Column.
* @return The Column at the specified index.
*/
public Column getColumn(int columnIndex) {
try {
return c_columns.get(columnIndex);
} catch (IndexOutOfBoundsException ioobe) {
return null;
}
}
// /**
// * Return the number of rows used as column headers.
// * @return The number or rows used as column headers.
// */
// public int getLabelRowCount() {
// if (isColumnLabelDisplayed() == false) {
// return 0;
// }
// int count = getLabelMatrix().length;
// return count;
// }
//
// /**
// * Evaluate the supplied boolean expression.
// * @param expression The expression to be evaluated.
// * @param table
// * @param rowIndex
// * @param columnIndex
// * @return The result of the expression.
// */
// public boolean evaluate(String expression, WepsTable table, int rowIndex, int columnIndex) {
// //Very very basic, only supports left of == equals right of == in a string comparison.
// int operatorIndex = expression.indexOf("==");
// if (operatorIndex < 0) {
// return false;
// }
// String left = expression.substring(0, operatorIndex);
// String right = expression.substring(operatorIndex + 2);
//
// if (left == null || right == null) {
// return false;
// }
// left = parse(left, table, rowIndex, columnIndex).toString();
// right = parse(right, table, rowIndex, columnIndex).toString();
//
// return left.equals(right);
// } //Regex = (?:\$\{([.[^\}]]*)\.([.[^\}]]*)\})|(?:\$\{([.[^\}]]*)\})
// //This will match ${name.field}, name is in group 1 and field is in group 2, group 3 is a field without a name, ${field}
// private static final String parsePatternString = "(?:\\$\\{([.[^\\}]]*)\\.([.[^\\}]]*)\\})|(?:\\$\\{([.[^\\}]]*)\\})";
// private static final Pattern parsePattern = Pattern.compile(parsePatternString); //Regex For Events = (?:\$X\{([.[^\}]]*)\.([.[^\}]]*)\})|(?:\$X\{([.[^\}]]*)\})
// private static final String parseXPatternString = "(?:\\$X\\{([.[^\\}]]*)\\.([.[^\\}]]*)\\})|(?:\\$X\\{([.[^\\}]]*)\\})";
// private static final Pattern parseXPattern = Pattern.compile(parseXPatternString);
//
// /**
// *
// * @param text
// * @param table
// * @param rowIndex
// * @param columnIndex
// * @return
// */
// public Object parse(String text, WepsTable table, int rowIndex, int columnIndex) {
// Object value;
// value = parseSpecial(text, table, rowIndex, columnIndex);
// value = parseExternal(value.toString(), table, rowIndex, columnIndex);
// value = parseInternal(value.toString(), table, rowIndex, columnIndex);
// return value;
// }
//
// private Object parseSpecial(String text, WepsTable table, int rowIndex, int columnIndex) {
// text = text.replace("${column.index}", String.valueOf(columnIndex));
// return text;
// }
//
// private Object parseExternal(String text, WepsTable table, int rowIndex, int columnIndex) {
// if (text == null) {
// return null;
// }
// Object value = text;
// if (text.indexOf("X") > 0) {
// int a = 0;
// }
// Matcher matcher = parseXPattern.matcher(text);
// while (matcher.find()) {
// String expression = matcher.group();
// String loneField = matcher.group(3);
// String field;
// String name;
// if (loneField != null && loneField.length() > 0) {
// name = null;
// field = loneField;
// } else {
// name = matcher.group(1);
// field = matcher.group(2);
// }
// ParseEvent event = new ParseEvent(text, table, rowIndex, columnIndex, expression, name, field);
// table.fireParseEvent(event);
// if (event.getParsed() != null) {
// text = text.replace(expression, event.getParsed().toString());
// }
//
// value = text;
// }
// return value;
// }
//
// private Object parseInternal(String text, WepsTable table, int rowIndex, int columnIndex) {
// if (text == null) {
// return null;
// }
// Matcher matcher = parsePattern.matcher(text);
// while (matcher.find()) {
// String expression = matcher.group();
// String loneField = matcher.group(3);
// Column column = null;
// String field;
// String name = null;
// if (loneField != null && loneField.length() > 0) {
// //Assume the current column.
// column = getColumn(columnIndex);
// field = loneField;
// } else {
// name = matcher.group(1);
// column = c_columnMap.get(name);
// field = matcher.group(2);
// }
//
//
// if (column != null) {
// ParseEvent event = new ParseEvent(text, table, rowIndex, columnIndex, expression, name, field);
// column.parse(event);
// Object value = event.getParsed();
// if (value == null) {
// value = "#N/A#";
// }
// text = text.replace(expression, value.toString());
// }
// }
// return text;
// }
}