001 /* 002 // $Id: //open/mondrian/src/main/mondrian/gui/PropertyTableModel.java#14 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2002-2008 Julian Hyde and others 007 // Copyright (C) 2006-2007 Cincom Systems, Inc. 008 // All Rights Reserved. 009 // You must accept the terms of that agreement to use this software. 010 */ 011 package mondrian.gui; 012 013 import java.lang.reflect.Field; 014 import java.util.*; 015 016 import org.apache.log4j.Logger; 017 018 /** 019 * 020 * @author sean 021 * @version $Id: //open/mondrian/src/main/mondrian/gui/PropertyTableModel.java#14 $ 022 */ 023 public class PropertyTableModel extends javax.swing.table.AbstractTableModel { 024 025 private static final Logger LOGGER = Logger.getLogger(PropertyTableModel.class); 026 027 private Object parentTarget; // parent of target 028 private String factTable; // selected fact table 029 private String factTableSchema; // selected fact table schema 030 private ArrayList names; // List of names for this object's siblings already existing in parent' 031 private String errorMsg = null; // error msg when property value could not be set. 032 033 String[] propertyNames; 034 Object target; 035 Workbench workbench; 036 037 public PropertyTableModel(Workbench wb, Object t, String[] pNames) { 038 super(); 039 workbench = wb; 040 propertyNames = pNames; 041 target = t; 042 } 043 044 public String getColumnName(int i) { 045 if (i == 0) { 046 return workbench.getResourceConverter().getString("propertyTableModel.attribute","Attribute"); 047 } else if (i == 1) { 048 return workbench.getResourceConverter().getString("propertyTableModel.value","Value"); 049 } 050 051 return workbench.getResourceConverter().getString("propertyTableModel.unknown","?"); 052 } 053 054 // get property name for given row no. 055 public String getRowName(int i) { 056 String pName = propertyNames[i]; 057 int j=-1; 058 if ((j = pName.indexOf('|')) != -1) { //"|" 059 return pName.substring(0,j).trim(); 060 } else { 061 return propertyNames[i]; } 062 } 063 064 public boolean isCellEditable(int row, int col) { 065 if (col == 1) { 066 Object cellObj = getValueAt(row, col); 067 if (cellObj instanceof MondrianGuiDef.Join) { 068 return false; 069 } else { 070 return true; 071 } 072 } 073 074 return false; 075 } 076 077 /** Returns the number of columns in the model. A 078 * <code>JTable</code> uses this method to determine how many columns it 079 * should create and display by default. 080 * 081 * @return the number of columns in the model 082 * @see #getRowCount 083 * 084 */ 085 public int getColumnCount() { 086 return 2; //that's 'Property' and 'Value' 087 } 088 089 /** Returns the number of rows in the model. A 090 * <code>JTable</code> uses this method to determine how many rows it 091 * should display. This method should be quick, as it 092 * is called frequently during rendering. 093 * 094 * @return the number of rows in the model 095 * @see #getColumnCount 096 * 097 */ 098 public int getRowCount() { 099 return propertyNames.length; 100 } 101 102 /** Returns the value for the cell at <code>columnIndex</code> and 103 * <code>rowIndex</code>. 104 * 105 * @param rowIndex the row whose value is to be queried 106 * @param columnIndex the column whose value is to be queried 107 * @return the value Object at the specified cell 108 * 109 */ 110 public Object getValueAt(int rowIndex, int columnIndex) { 111 if (columnIndex == 0) { 112 return propertyNames[rowIndex]; 113 } else { 114 try { 115 String pName = propertyNames[rowIndex]; 116 if ((pName.indexOf('|')) != -1) { //"formula | formulaElement.cdata" 117 /* This is for special cases where more than one field refers to the same value. 118 * For eg. calculated memeber's formula and formulaelement.cdata refers to the same formula string. 119 * These cases arise to handle xml standards where an attribute can also appear as an xml tag. 120 */ 121 Object obj = null; 122 String[] pNames = pName.split("\\|",0); // split field names on | to form an array of property names strings that are optional. 123 for (int j = 0; j < pNames.length; j++) { 124 if ((pNames[j].indexOf('.')) != -1) { 125 String[] pNamesField = pNames[j].trim().split("\\.",0); // split string on . to form an array of property name within the property name. 126 if (pNamesField.length > 1) { 127 Field f = target.getClass().getField(pNamesField[0].trim()); 128 obj = f.get(target); 129 if (obj != null) { 130 Field f2 = obj.getClass().getField(pNamesField[1].trim()); 131 Object obj2 = f2.get(obj); 132 return obj2; 133 } 134 } 135 return null; 136 } else { 137 Field f = target.getClass().getField(pNames[j].trim()); 138 obj = f.get(target); 139 if (obj != null) { 140 return obj; 141 } 142 } 143 } 144 return obj; 145 } else { 146 // default case where one field refers to one value. 147 Field f = target.getClass().getField(propertyNames[rowIndex]); 148 149 Object obj = f.get(target); 150 return obj; 151 } 152 } catch (Exception ex) { 153 LOGGER.error("getValueAt(row, index)", ex); 154 return "#ERROR"; 155 } 156 } 157 } 158 159 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 160 setErrorMsg(null); 161 try { 162 String pName = propertyNames[rowIndex]; 163 int i=-1; 164 if ((i = pName.indexOf('|')) != -1) { //"formula | formulaElement.cdata" 165 Field f = target.getClass().getField(propertyNames[rowIndex].substring(0,i).trim()); // save value in the first field name 166 f.set(target,aValue); 167 // delete the value from second and remaining field names 168 String[] pNames = pName.split("\\|",0); // split field names on | to form an array of property names strings that are optional. 169 for (int j = 1; j < pNames.length; j++) { 170 String[] pNamesField = pNames[j].trim().split("\\.",0); // split string on . to form an array of property name within the property name. 171 Field f2 = target.getClass().getField(pNamesField[0].trim()); 172 f2.set(target,null); 173 } 174 175 } else if ((target instanceof MondrianGuiDef.Level) && (pName.equals("ordinalExp"))) { 176 ((MondrianGuiDef.Level) target).ordinalExp.expressions[0] = (MondrianGuiDef.SQL) aValue; 177 /* 178 Field f = target.getClass().getField(propertyNames[rowIndex]); 179 f.set(((MondrianGuiDef.Level) target).ordinalExp.expressions[0], aValue); 180 */ 181 } else if ((target instanceof MondrianGuiDef.Table && pName.equals("name")) || 182 (target instanceof MondrianGuiDef.Hierarchy && pName.equals("primaryKeyTable")) || 183 (target instanceof MondrianGuiDef.Level && pName.equals("table"))) { 184 // updating all table values 185 if (aValue != null) { // split and save only if value exists 186 String[] aValues = ((String) aValue).split("->"); 187 if (aValues.length == 2) { 188 if (target instanceof MondrianGuiDef.Table) { 189 ((MondrianGuiDef.Table) target).name = aValues[1]; 190 ((MondrianGuiDef.Table) target).schema = aValues[0]; 191 fireTableDataChanged(); // to refresh the value in schema field also alongwith table name 192 } else { 193 Field f = target.getClass().getField(propertyNames[rowIndex]); 194 f.set(target,aValues[1]); 195 } 196 } else { 197 Field f = target.getClass().getField(propertyNames[rowIndex]); 198 f.set(target,aValue); 199 } 200 } 201 202 } else if ((target instanceof MondrianGuiDef.Dimension && pName.equals("foreignKey")) || 203 (target instanceof MondrianGuiDef.DimensionUsage && pName.equals("foreignKey")) || 204 (target instanceof MondrianGuiDef.Measure && pName.equals("column")) || 205 (target instanceof MondrianGuiDef.Hierarchy && pName.equals("primaryKey")) || 206 (target instanceof MondrianGuiDef.Level && pName.equals("column")) || 207 (target instanceof MondrianGuiDef.Level && pName.equals("nameColumn")) || 208 (target instanceof MondrianGuiDef.Level && pName.equals("ordinalColumn")) || 209 (target instanceof MondrianGuiDef.Level && pName.equals("parentColumn")) || 210 (target instanceof MondrianGuiDef.Level && pName.equals("captionColumn")) || 211 (target instanceof MondrianGuiDef.Closure && pName.equals("parentColumn")) || 212 (target instanceof MondrianGuiDef.Closure && pName.equals("childColumn")) || 213 (target instanceof MondrianGuiDef.Property && pName.equals("column"))) { 214 // updating all column values 215 if (aValue != null) { // split and save only if value exists 216 String[] aValues = ((String) aValue).split("->"); 217 Field f = target.getClass().getField(propertyNames[rowIndex]); 218 f.set(target, aValues[aValues.length - 1]); // save the last value in the array from split 219 } 220 221 } else { 222 if (propertyNames[rowIndex].equals("name") 223 && (! (target instanceof MondrianGuiDef.Table)) 224 && (! aValue.equals(target.getClass().getField(propertyNames[rowIndex]).get(target))) 225 && duplicateName(aValue)) { 226 setErrorMsg(workbench.getResourceConverter().getFormattedString("propertyTableModel.duplicateValue.error", 227 "Error setting name property. {0} already exists", 228 new String[] { aValue.toString() })); 229 } else { 230 Field f = target.getClass().getField(propertyNames[rowIndex]); 231 f.set(target,aValue); 232 } 233 } 234 } catch (Exception ex) { 235 LOGGER.error("setValueAt(aValue, row, index)", ex); 236 } 237 } 238 239 public Object getValue() { 240 return target; 241 } 242 243 public Object getParentTarget() { 244 return parentTarget; 245 } 246 247 public void setParentTarget(Object parentTarget) { 248 this.parentTarget = parentTarget; 249 } 250 251 public String getFactTable() { 252 return factTable; 253 } 254 255 public void setFactTable(String factTable) { 256 this.factTable = factTable; 257 } 258 259 public String getFactTableSchema() { 260 return factTableSchema; 261 } 262 263 public void setFactTableSchema(String factTableSchema) { 264 this.factTableSchema = factTableSchema; 265 } 266 267 private boolean duplicateName(Object aValue) { 268 return (names != null && names.contains(aValue)); 269 } 270 271 public ArrayList getNames() { 272 return names; 273 } 274 275 public void setNames(ArrayList names) { 276 this.names = names; 277 } 278 279 public String getErrorMsg() { 280 return errorMsg; 281 } 282 283 public void setErrorMsg(String errorMsg) { 284 this.errorMsg = errorMsg; 285 } 286 } 287 288 // End PropertyTableModel.java