Column.java [src/usda/weru/util/table] Revision: default Date:
/*
* Column.java
*
* Created on June 8, 2006, 10:54 AM
*
*/
package usda.weru.util.table;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import org.jdom.Element;
import usda.weru.util.ConversionCalculator;
import usda.weru.util.ConversionUnit;
import usda.weru.util.ConvertedValue;
/**
* Wrapper class for a Column object in a WepsTable.
* @author Joseph Levin
*/
public class Column implements ColumnGroupOrColumn, XmlObject{
// protected Label c_label;
protected WepsTableMeta c_meta;
protected ColumnGroup c_parentColumnGroup;
protected ColumnGroupOrColumn c_tempChild;
protected String c_id;
protected boolean c_anonymous;
protected boolean c_forDisplay = true;
protected boolean quickplot = false;
protected Column c_parent;
//Inhertable junk
protected String c_name;
protected int c_dataType = WepsTableEnum.NO_VALUE;
protected String c_dataKey;
protected ConversionUnit c_dataUnits;
protected Hashtable <String, ConversionUnit> c_dataDisplayUnits; //System to unit
protected Hashtable <String, Format> c_dataFormats; //System to format
protected Hashtable <String, DataLimit> c_dataLimits; //System to format
protected List <DataAdjustment> c_dataAdjustments;
protected int c_minWidth = WepsTableEnum.NO_VALUE;;
protected int c_width = WepsTableEnum.NO_VALUE;
protected int c_maxWidth = WepsTableEnum.NO_VALUE;
protected int c_hidden = WepsTableEnum.NO_VALUE;;
protected int c_visible = WepsTableEnum.NO_VALUE;;
// protected CellStyle c_cellStyle;
//
//
/**
* Create a Column object associated with the given WepsTableMeta.
* @param meta The WepsTableMeta to which this Column will be associated.
*/
public Column(WepsTableMeta meta) {
this(meta, true);
}
/**
* Create a Column object associated with the given WepsTableMeta and is either displayable or not.
* @param meta The WepsTableMeta to which this Column will be associated.
* @param forDisplay Whether or not the Column will be displayable.
*/
public Column(WepsTableMeta meta, boolean forDisplay) {
init();
c_meta = meta;
c_forDisplay = forDisplay;
}
/**
* Load configuration settings for this Column from a jdom Element.
* @param node An org.jdom.Element containing configuration information about this Column.
*/
public void fromXml(Element node){
loadId(node);
loadParent(node);
loadName(node);
loadVisibility(node);
// loadCellStyle(node);
loadData(node);
loadWidth(node);
// if (isForDisplay()){
// loadLabels(node);
// }
}
private void init(){
}
private boolean isForDisplay(){
return c_forDisplay;
}
/**
* Return whether or not this column is hidden. If a parent is specified it will check the parent to see if it is hidden.
* @return Whether or not the Column is hidden.
*/
public boolean isHidden(){
if (c_hidden == WepsTableEnum.NO_VALUE && c_parent != null){
return c_parent.isHidden();
}
else if (c_hidden == WepsTableEnum.NO_VALUE){
return false;
}
else{
return (c_hidden == 1);
}
}
/**
* Return whether or not this column is visible. If a parent is specified it will check the parent to see if it is visible.
* @return Whether or not the column is visible.
*/
public boolean isVisible(){
if (c_visible == WepsTableEnum.NO_VALUE && c_parent != null){
return c_parent.isVisible();
}
else if (c_visible == WepsTableEnum.NO_VALUE){
return true;
}
else{
return (c_visible == 1);
}
}
public void setQuickPlot(boolean quickplot){
this.quickplot = quickplot;
}
public boolean isQuickPlot(){
return quickplot;
}
// /**
// * Return the Label used for this Column.
// * @return The Label for this Column.
// */
// public Label getLabel(){
// return c_label;
// }
//
/**
* Return whether or not the Column is anonymous.
* @return <b>true</b> if the column is anonymous, <b>false</b> otherwise.
*/
public boolean isAnonymous(){
return c_anonymous;
}
/**
* Set the ColumnGroup this Column will be a part of.
* @param parent The ColumnGroup this Column will be a part of.
* @return
*/
public ColumnGroupOrColumn setParent(ColumnGroup parent){
if (c_tempChild == null){
c_parentColumnGroup = parent;
return this;
}
else{
c_tempChild.setParent(parent);
return c_tempChild;
}
}
/**
* Return the ColumnGroup this Column is a part of.
* @return The ColumnGroup this Column is a part of.
*/
public ColumnGroup getParentGroup(){
return c_parentColumnGroup;
}
/**
* Set the parent Column this Column will inherit configuration settings from.
* @param parent The parent Column this Column will inherit configuration settings from.
*/
public void setParent(Column parent){
c_parent = parent;
}
/**
* Return the depth in the header that this Columns Label will appear.
* @return The depth in the header.
*/
public int depthInHeader(){
int depth = 0;
// if (getLabel() != null && getLabel().getSpanRows() > 1){
// depth = depth + getLabel().getSpanRows() - 1;
// }
if (getParentGroup() != null){
depth++;
depth = depth + getParentGroup().depthInHeader();
}
return depth;
}
/**
* Returns the number of Columns under this Column (inclusive).
* @return 1
*/
public int bottomBreadth(){
return 1;
}
/**
* Not implemented.
* @param child
* @return <b>false</b>
*/
public boolean isFirstChild(ColumnGroupOrColumn child){
return false;
}
private void loadId(Element node){
//Get Id
String id = node.getAttributeValue(WepsTableEnum.XML_id);
if (id != null){
c_id = id;
}
else{
//Get Id from counter
c_id = c_meta.getAnonymousId();
c_anonymous = true;
}
}
private void loadParent(Element node){
//Set Parent Column
String parentId = node.getAttributeValue(WepsTableEnum.XML_parent);
if (parentId != null){
Column parentColumn = c_meta.getColumn(parentId);
//Has the parent been loaded?
if(parentColumn != null) setParent(parentColumn);
}
}
private void loadName(Element node){
c_name = node.getChildTextTrim(WepsTableEnum.XML_name);
}
private void loadVisibility(Element node){
String visibleText = node.getChildTextTrim(WepsTableEnum.XML_visible);
String hiddenText = node.getChildTextTrim(WepsTableEnum.XML_hidden);
if (visibleText != null){
if (Helper.isTrue(visibleText)){
c_visible = 1;
}
else{
c_visible = 0;
}
}
if (hiddenText != null){
if (Helper.isTrue(hiddenText)){
c_hidden = 1;
}
else{
c_hidden = 0;
}
}
}
// private void loadCellStyle(Element node){
// Element styleNode = node.getChild(WepsTableEnum.XML_style);
// if (styleNode == null) return;
// String cellId = null;
// cellId = styleNode.getTextTrim();
//
// if (cellId != null && cellId.length() > 0){
// c_cellStyle = c_meta.getCellStyle(cellId);
// }
// else{
// c_cellStyle = new CellStyle(c_meta);
// c_cellStyle.fromXml(styleNode);
// }
// }
//
// private void loadLabel(Element node){
// c_label = new Label(c_meta);
// Element labelElement = node.getChild(WepsTableEnum.XML_label);
// c_label.fromXml(labelElement);
// }
//
// private void loadLabels(Element node){
// List <Element> labelNodes = (List <Element>) node.getChildren(WepsTableEnum.XML_label);
// c_label = new Label(c_meta);
//
// boolean first = true;
// boolean last = false;
// ColumnGroup parent = null;
// ColumnGroupOrColumn tempChild = null;
// for (Element child : labelNodes){
// last = labelNodes.indexOf(child) == labelNodes.size() - 1; //Is the child the last element?
// if (last){
// c_label.fromXml(child);
// if (parent != null){
// parent.add(this);
// c_tempChild = tempChild;
// }
// }
// else{
// //We have more labels which we will create unique ColumnGroup objects for.
// ColumnGroup tempColumns = new ColumnGroup(c_meta);
// if(parent != null){
// parent.add(tempColumns);
// }
//
// if (first){
// first = false;
// tempChild = tempColumns;
// }
// Label tempLabel = new Label(c_meta);
// tempLabel.fromXml(child);
// tempColumns.setLabel(tempLabel);
// parent = tempColumns;
// }
// }
// }
//
private void loadData(Element node){
Element data = node.getChild(WepsTableEnum.XML_data);
if (data == null) return;
String typeText = data.getAttributeValue(WepsTableEnum.XML_type);
int type = WepsTableEnum.getEnumFromTag(typeText);
if (type > 0 ) c_dataType = type;
loadFormats(data);
switch(getDataType()){
case WepsTableEnum.DATA_numeric:
loadUnits(data);
loadDisplayUnits(data);
loadAdjustments(data);
loadLimits(data);
break;
case WepsTableEnum.DATA_list:
loadChoiceList(data);
break;
}
}
private void loadUnits(Element node){
try{
String unitsTag = node.getChildTextTrim(WepsTableEnum.XML_units);
//No tag, stop
if (unitsTag == null) return;
c_dataUnits = ConversionCalculator.getUnitFromTag(unitsTag);
}
catch(Exception e){}
}
private void loadDisplayUnits(Element node){
if (getUnits() == null) return; //We don't need display units if we don't have units to convert from.
List <Element> displayUnits = (List <Element>) node.getChildren(WepsTableEnum.XML_displayunits);
//Load display units linked to a measurement system (SI, or US, etc...)
boolean loadedDefault = false;
for (Element unitElement : displayUnits){
String system = unitElement.getAttributeValue(WepsTableEnum.XML_system);
if (system == null || system.length() == 0){
if (loadedDefault) continue;
system = WepsTableEnum.NO_UNITS_SYSTEM;
loadedDefault = true;
}
if (unitElement.getText().length() > 0){
try{
ConversionUnit unit = ConversionCalculator.getUnitFromTag(unitElement.getText());
if (system != null && system.length() > 0 && unit != null){
if (c_dataDisplayUnits == null){
c_dataDisplayUnits = new Hashtable <String, ConversionUnit> ();
}
c_dataDisplayUnits.put(system, unit);
}
}
catch(Exception e){
//TODO:Notify of conversion unit lookup failure.
}
}
}
}
private void loadFormats(Element node){
List <Element> formatNodeList = (List <Element>) node.getChildren(WepsTableEnum.XML_format);
//Load formats linked to a measurement system (SI, or US, etc...)
boolean loadedDefault = false;
for (Element formatNode : formatNodeList){
String system = formatNode.getAttributeValue(WepsTableEnum.XML_system);
if (system == null || system.length() == 0){
if (loadedDefault) continue;
system = WepsTableEnum.NO_UNITS_SYSTEM;
loadedDefault = true;
}
String pattern = formatNode.getText();
if (pattern != null && pattern.length() > 0){
Format format = null;
switch(getDataType()){
case WepsTableEnum.DATA_numeric:
format = new DecimalFormat(pattern);
break;
case WepsTableEnum.DATA_date:
format = new SimpleDateFormat(pattern);
}
if (format != null){
if (c_dataFormats == null){
c_dataFormats = new Hashtable <String, Format> ();
}
c_dataFormats.put(system, format);
}
}
}
}
/**
* Return the format used for the unit system this Column uses or the parents format if none is declared.
* @param unitsSystem The unit system for the format required.
* @return The format used by this Column for the unit system specified.
*/
public Format getFormat(String unitsSystem){
if (c_dataFormats == null && c_parent != null){
return c_parent.getFormat(unitsSystem);
}
else{
if (c_dataFormats == null) return null;
return c_dataFormats.get(unitsSystem);
}
}
private void loadAdjustments(Element node){
List <Element> adjustmentNodes = node.getChildren(WepsTableEnum.XML_adjust);
for (Element adjustNode : adjustmentNodes){
if (c_dataAdjustments == null){
c_dataAdjustments = new Vector <DataAdjustment> ();
}
DataAdjustment adjust = new DataAdjustment();
adjust.fromXml(adjustNode);
c_dataAdjustments.add(adjust);
}
}
/**
* Return a List of adjustments applied to the Columns data or a List from the parent if there is none specified.
* @return The List of adjustments to be applied to the Columns data.
*/
public List <DataAdjustment> getAdjustmentList(){
if (c_dataAdjustments == null && c_parent != null){
return c_parent.getAdjustmentList();
}
else{
return c_dataAdjustments;
}
}
private void loadLimits(Element node){
List <Element> limitNodes = node.getChildren(WepsTableEnum.XML_limit);
for (Element limitNode : limitNodes){
DataLimit limit = new DataLimit();
limit.fromXml(limitNode);
if (c_dataLimits == null){
c_dataLimits = new Hashtable <String, DataLimit> ();
}
c_dataLimits.put(limit.getSystem(), limit);
}
}
/**
* Return the DataLimit to be applied to this Column in the unit system specified.
* @param unitsSystem The unit system to be used.
* @return The DataLimit to be applied.
*/
public DataLimit getLimit(String unitsSystem){
if (c_dataLimits == null && c_parent != null){
return c_parent.getLimit(unitsSystem);
}
else{
if (c_dataLimits == null) return null;
return c_dataLimits.get(unitsSystem);
}
}
private void loadChoiceList(Element node){
}
private void loadWidth(Element node){
Element widthNode = node.getChild(WepsTableEnum.XML_width);
if (widthNode == null) return;
String widthText = widthNode.getValue();
String minText = widthNode.getAttributeValue(WepsTableEnum.XML_min);
String maxText = widthNode.getAttributeValue(WepsTableEnum.XML_max);
int width = WepsTableEnum.getEnumFromTag(widthText);
if (width != WepsTableEnum.NOT_FOUND){
c_width = width;
}
else{
try{
c_width = Integer.parseInt(widthText);
}
catch(NumberFormatException nfe){
return;
}
}
try{
c_minWidth = Integer.parseInt(minText);
}
catch(NumberFormatException nfe){}
try{
c_maxWidth = Integer.parseInt(maxText);
}
catch(NumberFormatException nfe){}
}
/**
* Return the ID of this Column.
* @return The ID for this Column.
*/
public String getId(){
return c_id;
}
/**
* Return the name of the Column or the name of the parent Column if none is specified.
* @return The name of the Column.
*/
public String getName(){
if (c_name == null && c_parent != null){
return c_parent.getName();
}
else if (c_name == null){
return getId();
}
else{
return c_name;
}
}
/**
* Return the data key used by this Column.
* @return The data key used by this Column.
*/
public String getDataKey(){
if (c_dataKey != null){
return c_dataKey;
}
else{
if (isAnonymous() && c_parent != null){
return c_parent.getDataKey();
}
else{
return getId();
}
}
}
// /**
// * Return the CellStyle used by this Column, or the CellStyle used by the parent.
// * @return The CellStyle used by this Column.
// */
// public CellStyle getCellStyle(){
// if (c_cellStyle == null && c_parent != null){
// return c_parent.getCellStyle();
// }
// else{
// return c_cellStyle;
// }
// }
//
//
//
/**
* Return a the Columns ID.
* @return The Columns ID.
*/
public String toString(){
return getId();
}
// /**
// * ParseEvent handler.
// * @param event The ParseEvent to be handled.
// */
// public void parse(ParseEvent event){
// String field = event.getField();
// WepsTable table = event.getTable();
// String unitsSystem = table.getUnitsSystem();
// int rowIndex = event.getRowIndex();
//
// if (field == null) return;
// field = field.toLowerCase().trim();
//
// if (field.equals(WepsTableEnum.PARSE_units)){
// if (getUnits() != null){
// event.setParsedExpression(getUnits().getName());
// }
// }
// else if (field.equals(WepsTableEnum.PARSE_displayunits)){
// ConversionUnit displayUnits = getDisplayUnits(unitsSystem);
// if (displayUnits != null){
// event.setParsedExpression(displayUnits.getName());
// }
// }
// else if (field.equals(WepsTableEnum.PARSE_displayunitsabbreviation)){
// ConversionUnit displayUnits = getDisplayUnits(unitsSystem);
// if (displayUnits != null){
// event.setParsedExpression(displayUnits.getAbbreviation());
// }
// }
// else if (field.equals(WepsTableEnum.PARSE_value)){
// event.setParsedExpression(table.getDataView().getObject(rowIndex, this));
// }
// else if (field.equals("quickplot")){
// event.setParsedExpression(true);
// }
// }
//
/**
* Returns the units used by this Column or the units of the parent column if none are specified.
* @return The units being used by this Column.
*/
public ConversionUnit getUnits(){
if (c_dataUnits == null && c_parent != null){
return c_parent.getUnits();
}
else{
return c_dataUnits;
}
}
/**
* Returns the display units used by this Column given the system provided.
* @param system The system of units being used.
* @return The Columns units converted to the units of the system.
*/
public ConversionUnit getDisplayUnits(String system){
if (system == null) return null;
if (c_dataDisplayUnits == null && c_parent != null){
return c_parent.getDisplayUnits(system);
}
else{
if (c_dataDisplayUnits == null) return null;
return c_dataDisplayUnits.get(system);
}
}
/**
* Apply all available adjustments to the Object supplied.
* @param o The Object to be adjusted.
* @param unitsSystem Not used.
* @return The adjusted Object.
*/
public Object applyAdjustments(Object o, String unitsSystem){
//Adjust the data
List <DataAdjustment> adjustments = getAdjustmentList();
if (adjustments != null){
for (DataAdjustment adjust : adjustments){
o = adjust.adjust(o);
}
}
return o;
}
/**
* Convert this Columns data to use a different unit system for display.
* @param o The Object to be converted.
* @param unitsSystem The unit System to convert to.
* @return The converted value.
*/
public Object applyDisplayUnits(Object o, String unitsSystem){
if (o == null){
return null;
}
try{
double d = Double.parseDouble(o.toString());
ConversionUnit displayUnits = getDisplayUnits(unitsSystem);
ConversionUnit units = getUnits();
if (displayUnits != null && units != null){
ConvertedValue cValue = new ConvertedValue();
cValue.setBaseUnits(units);
cValue.setDisplayUnits(displayUnits);
cValue.setValue(d);
d = cValue.getDisplayValue();
return d;
}
else return o;
}
catch(NumberFormatException nfe){
return o;
}
catch(Exception e){
return "#ERR#";
}
}
/**
* Apply available limits to this Column.
* @param o The Object to apply the limits to.
* @param unitsSystem The unit system specifying the set of limits to be used.
* @return The adjusted value.
*/
public Object applyLimits(Object o, String unitsSystem){
//Limit the data
DataLimit limit = getLimit(unitsSystem);
if (limit != null){
return limit.limit(o);
}
else{
return o;
}
}
/**
* Apply formating to the Object passed.
* @param o The Object to be formatted.
* @param unitsSystem The unit system whos formatting will be used.
* @return The formatted Object.
*/
public Object applyFormat(Object o, String unitsSystem){
//Format the data
Format format = getFormat(unitsSystem);
if (format != null){
try{
return format.format(o);
}
catch(Exception e){
return o;
}
}
else{
return o;
}
}
/**
* Return the data type for this Column or the data type of the parent if there is none specified.
* @return The data type used by this Column.
*/
public int getDataType(){
if (c_dataType < 0 && c_parent != null){
return c_parent.getDataType();
}
else{
return c_dataType;
}
}
// /**
// * Return the width of this Column or the width of the parent if there is none specified.
// * @return The width of the Column or JCTableEnum.VARIABLE_ESTIMATE if there is no value available.
// */
// public int getWidth(){
// if (c_width == WepsTableEnum.NO_VALUE && c_parent != null){
// return c_parent.getWidth();
// }
// else{
// if (c_width == WepsTableEnum.NO_VALUE){
// return JCTableEnum.VARIABLE_ESTIMATE;
// }
// else{
// return c_width;
// }
// }
// }
//
/**
* Return the minimum width or the minimum width of the parent if no minimum width is specified.
* @return The minimum width of the Column.
*/
public int getMinWidth(){
if (c_minWidth == WepsTableEnum.NO_VALUE && c_parent != null){
return c_parent.getMinWidth();
}
else{
return c_minWidth;
}
}
/**
* Return the maximum width or the maximum width of the parent if no maximum width is specified.
* @return The maximum width of the Column.
*/
public int getMaxWidth(){
if (c_maxWidth == WepsTableEnum.NO_VALUE && c_parent != null){
return c_parent.getMaxWidth();
}
else{
return c_maxWidth;
}
}
}