/*
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2002-2005 Julian Hyde
// Copyright (C) 2005-2011 Pentaho and others
// Copyright (C) 2006-2007 Cincom Systems, Inc.
// All Rights Reserved.
*/
package mondrian.gui;
import org.apache.log4j.Logger;
import java.lang.reflect.Field;
import java.util.List;
/**
* @author sean
*/
public class PropertyTableModel extends javax.swing.table.AbstractTableModel {
private static final Logger LOGGER =
Logger.getLogger(PropertyTableModel.class);
private Object parentTarget; // parent of target
private String factTable; // selected fact table
private String factTableSchema; // selected fact table schema
// List of names for this object's siblings already existing in parent'
private List<String> names;
private String errorMsg = null;
// error msg when property value could not be set.
String[] propertyNames;
Object target;
Workbench workbench;
public PropertyTableModel(Workbench wb, Object t, String[] pNames) {
super();
workbench = wb;
propertyNames = pNames;
target = t;
}
public String getColumnName(int i) {
if (i == 0) {
return workbench.getResourceConverter().getString(
"propertyTableModel.attribute", "Attribute");
} else if (i == 1) {
return workbench.getResourceConverter().getString(
"propertyTableModel.value", "Value");
}
return workbench.getResourceConverter().getString(
"propertyTableModel.unknown", "?");
}
// get property name for given row no.
public String getRowName(int i) {
String pName = propertyNames[i];
int j = -1;
if ((j = pName.indexOf('|')) != -1) { //"|"
return pName.substring(0, j).trim();
} else {
return propertyNames[i];
}
}
public boolean isCellEditable(int row, int col) {
if (col == 1) {
Object cellObj = getValueAt(row, col);
if (cellObj instanceof MondrianGuiDef.Join) {
return false;
} else {
return true;
}
}
return false;
}
/**
* Returns the number of columns in the model. A
* <code>JTable</code> uses this method to determine how many columns it
* should create and display by default.
*
* @return the number of columns in the model
* @see #getRowCount
*/
public int getColumnCount() {
return 2; //that's 'Property' and 'Value'
}
/**
* Returns the number of rows in the model. A
* <code>JTable</code> uses this method to determine how many rows it
* should display. This method should be quick, as it
* is called frequently during rendering.
*
* @return the number of rows in the model
* @see #getColumnCount
*/
public int getRowCount() {
return propertyNames.length;
}
/**
* Returns the value for the cell at <code>columnIndex</code> and
* <code>rowIndex</code>.
*
* @param rowIndex the row whose value is to be queried
* @param columnIndex the column whose value is to be queried
* @return the value Object at the specified cell
*/
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) {
return propertyNames[rowIndex];
} else {
try {
String pName = propertyNames[rowIndex];
if ((pName.indexOf('|')) != -1) {
//"formula | formulaElement.cdata" This is for special cases
// where more than one field refers to the same value. For
// eg. calculated memeber's formula and formulaelement.cdata
// refers to the same formula string. These cases arise to
// handle xml standards where an attribute can also appear
// as an xml tag.
Object obj = null;
// split field names on | to form an array of property names
// strings that are optional.
String[] pNames = pName.split(
"\\|",
0);
for (int j = 0; j < pNames.length; j++) {
if ((pNames[j].indexOf('.')) != -1) {
// Split string on . to form an array of property
// name within the property name.
String[] pNamesField = pNames[j].trim().split(
"\\.",
0);
if (pNamesField.length > 1) {
Field f =
target.getClass().getField(
pNamesField[0].trim());
obj = f.get(target);
if (obj != null) {
Field f2 = obj.getClass().getField(
pNamesField[1].trim());
Object obj2 = f2.get(obj);
return obj2;
}
}
return null;
} else {
Field f =
target.getClass().getField(pNames[j].trim());
obj = f.get(target);
if (obj != null) {
return obj;
}
}
}
return obj;
} else {
// default case where one field refers to one value.
Field f =
target.getClass().getField(propertyNames[rowIndex]);
Object obj = f.get(target);
return obj;
}
} catch (Exception ex) {
LOGGER.error("getValueAt(row, index)", ex);
return "#ERROR";
}
}
}
public void setValueAt(Object value, int rowIndex, int columnIndex) {
setErrorMsg(null);
try {
String pName = propertyNames[rowIndex];
int i = -1;
if ((i = pName.indexOf('|')) != -1) {
//"formula | formulaElement.cdata"
// save value in the first field name
Field f =
target.getClass().getField(
propertyNames[rowIndex].substring(0, i).trim());
f.set(target, value);
// Delete the value from second and remaining field names. split
// field names on | to form an array of property names strings
// that are optional.
String[] pNames =
pName.split(
"\\|",
0);
for (int j = 1; j < pNames.length; j++) {
// Split string on . to form an array of property name
// within the property name.
String[] pNamesField =
pNames[j].trim().split(
"\\.",
0);
Field f2 =
target.getClass().getField(pNamesField[0].trim());
f2.set(target, null);
}
// } else if ((target instanceof MondrianGuiDef.UserDefinedFunction)
// && (pName.equals("script")))
// {
// ((MondrianGuiDef.UserDefinedFunction) target).script =
// (MondrianGuiDef.Script) value;
// } else if ((target instanceof MondrianGuiDef.MemberFormatter)
// && (pName.equals("script")))
// {
// ((MondrianGuiDef.MemberFormatter) target).script =
// (MondrianGuiDef.Script) value;
// } else if ((target instanceof MondrianGuiDef.CellFormatter)
// && (pName.equals("script")))
// {
// ((MondrianGuiDef.CellFormatter) target).script =
// (MondrianGuiDef.Script) value;
// } else if ((target instanceof MondrianGuiDef.PropertyFormatter)
// && (pName.equals("script")))
// {
// ((MondrianGuiDef.PropertyFormatter) target).script =
// (MondrianGuiDef.Script) value;
} else if ((target instanceof MondrianGuiDef.Level)
&& (pName.equals("ordinalExp")))
{
((MondrianGuiDef.Level) target).ordinalExp.expressions[0] =
(MondrianGuiDef.SQL) value;
} else if ((target instanceof MondrianGuiDef.Level)
&& (pName.equals("captionExp")))
{
((MondrianGuiDef.Level) target).captionExp.expressions[0] =
(MondrianGuiDef.SQL) value;
} else if ((target instanceof MondrianGuiDef.Table
&& pName.equals("name"))
|| (target instanceof MondrianGuiDef.Hierarchy
&& pName.equals("primaryKeyTable"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("table")))
{
// updating all table values
if (value != null) {
// split and save only if value exists
String[] aValues =
((String) value).split(JdbcMetaData.LEVEL_SEPARATOR);
if (aValues.length == 2) {
if (target instanceof MondrianGuiDef.Table) {
((MondrianGuiDef.Table) target).name = aValues[1];
((MondrianGuiDef.Table) target).schema = aValues[0];
// to refresh the value in schema field also
// alongwith table name
fireTableDataChanged();
} else {
Field f =
target.getClass().getField(
propertyNames[rowIndex]);
f.set(target, aValues[1]);
}
} else {
// Avoids table="" to be set on schema
Field f =
target.getClass().getField(propertyNames[rowIndex]);
setFieldValue(f, value);
}
}
} else if ((target instanceof MondrianGuiDef.Dimension
&& pName.equals("foreignKey"))
|| (target instanceof MondrianGuiDef.DimensionUsage
&& pName.equals("foreignKey"))
|| (target instanceof MondrianGuiDef.Measure
&& pName.equals("column"))
|| (target instanceof MondrianGuiDef.Hierarchy
&& pName.equals("primaryKey"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("column"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("nameColumn"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("ordinalColumn"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("parentColumn"))
|| (target instanceof MondrianGuiDef.Level
&& pName.equals("captionColumn"))
|| (target instanceof MondrianGuiDef.Closure
&& pName.equals("parentColumn"))
|| (target instanceof MondrianGuiDef.Closure
&& pName.equals("childColumn"))
|| (target instanceof MondrianGuiDef.Property
&& pName.equals("column")))
{
// updating all column values
if (value != null) {
// split and save only if value exists
String[] aValues =
((String) value).split(JdbcMetaData.LEVEL_SEPARATOR);
Field f =
target.getClass().getField(propertyNames[rowIndex]);
// Avoids *Column="" to be set on schema. Also remove
// column data type with the final split on a dash.
value = aValues[aValues.length - 1].split(" - ")[0];
setFieldValue(f, value);
}
} else {
if (propertyNames[rowIndex].equals("name")
&& (!(target instanceof MondrianGuiDef.Table))
&& (!value.equals(
target.getClass().getField(
propertyNames[rowIndex]).get(target)))
&& duplicateName(value))
{
setErrorMsg(
workbench.getResourceConverter().getFormattedString(
"propertyTableModel.duplicateValue.error",
"Error setting name property. {0} already exists",
value.toString()));
} else {
Field f =
target.getClass().getField(propertyNames[rowIndex]);
// Avoids property to be set on schema with an empty value.
setFieldValue(f, value);
}
}
} catch (Exception ex) {
LOGGER.error("setValueAt(aValue, row, index)", ex);
}
}
private void setFieldValue(Field aField, Object aValue)
throws IllegalAccessException
{
if (aValue != null && aValue.toString().trim().length() == 0) {
aField.set(target, null);
} else {
aField.set(target, aValue);
}
}
public Object getValue() {
return target;
}
public Object getParentTarget() {
return parentTarget;
}
public void setParentTarget(Object parentTarget) {
this.parentTarget = parentTarget;
}
public String getFactTable() {
return factTable;
}
public void setFactTable(String factTable) {
this.factTable = factTable;
}
public String getFactTableSchema() {
return factTableSchema;
}
public void setFactTableSchema(String factTableSchema) {
this.factTableSchema = factTableSchema;
}
private boolean duplicateName(Object aValue) {
return (names != null && names.contains(aValue));
}
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
// End PropertyTableModel.java