1 14 package org.compiere.model; 15 16 import javax.swing.table.*; 17 import javax.swing.event.*; 18 19 import java.sql.*; 20 import java.util.*; 21 import java.math.*; 22 import java.beans.*; 23 import java.io.Serializable ; 24 25 import org.compiere.util.*; 26 27 48 public final class MTable extends AbstractTableModel 49 implements Serializable 50 { 51 60 public MTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo, 61 boolean withAccessControl) 62 { 63 super(); 64 log.info(TableName); 65 m_ctx = ctx; 66 m_AD_Table_ID = AD_Table_ID; 67 setTableName(TableName); 68 m_WindowNo = WindowNo; 69 m_TabNo = TabNo; 70 m_withAccessControl = withAccessControl; 71 } 73 private Logger log = Logger.getCLogger(getClass()); 74 private Properties m_ctx; 75 private int m_AD_Table_ID; 76 private String m_tableName = ""; 77 private int m_WindowNo; 78 private int m_TabNo; 79 private boolean m_withAccessControl; 80 private boolean m_readOnly = true; 81 private boolean m_deleteable = true; 82 84 85 private int m_rowCount = 0; 86 87 private boolean m_changed = false; 88 89 private int m_rowChanged = -1; 90 91 private boolean m_inserting = false; 92 93 private int m_newRow = -1; 94 95 private boolean m_open = false; 96 97 private boolean m_compareDB = true; 99 private volatile ArrayList m_buffer = new ArrayList(100); 101 private volatile ArrayList m_sort = new ArrayList(100); 102 103 private Object [] m_rowData = null; 104 105 private Object [] m_oldValue = null; 106 private Loader m_loader = null; 108 109 110 private ArrayList m_fields = new ArrayList(30); 111 private ArrayList m_parameterSELECT = new ArrayList(5); 112 private ArrayList m_parameterWHERE = new ArrayList(5); 113 114 115 private String m_SQL; 116 117 private String m_SQL_Count; 118 119 private String m_SQL_Select; 120 121 private String m_whereClause = ""; 122 123 private boolean m_onlyCurrentRows = false; 124 125 private int m_onlyCurrentDays = 1; 126 127 private String m_orderClause = ""; 128 129 130 private int m_indexKeyColumn = -1; 131 132 private int m_indexRowIDColumn = -1; 133 134 private int m_indexColorColumn = -1; 135 136 private int m_indexProcessedColumn = -1; 137 138 private int m_indexActiveColumn = -1; 139 140 private int m_indexClientColumn = -1; 141 142 private int m_indexOrgColumn = -1; 143 144 145 private Vector m_dataStatusListeners; 146 147 private VetoableChangeSupport m_vetoableChangeSupport = new VetoableChangeSupport(this); 148 149 public static final String PROPERTY = "MTable-RowSave"; 150 151 155 public void setTableName(String newTableName) 156 { 157 if (m_open) 158 { 159 log.error("setTableName - Table already open - ignored"); 160 return; 161 } 162 if (newTableName == null || newTableName.length() == 0) 163 return; 164 m_tableName = newTableName; 165 } 167 171 public String getTableName() 172 { 173 return m_tableName; 174 } 176 183 public boolean setWhereClause(String newWhereClause, boolean onlyCurrentRows, int onlyCurrentDays) 184 { 185 if (m_open) 186 { 187 log.error("setWhereClause - Table already open - ignored"); 188 return false; 189 } 190 m_whereClause = newWhereClause; 192 m_onlyCurrentRows = onlyCurrentRows; 193 m_onlyCurrentDays = onlyCurrentDays; 194 if (m_whereClause == null) 195 m_whereClause = ""; 196 return true; 197 } 199 203 public String getWhereClause() 204 { 205 return m_whereClause; 206 } 208 212 public boolean isOnlyCurrentRowsDisplayed() 213 { 214 return !m_onlyCurrentRows; 215 } 217 221 public void setOrderClause(String newOrderClause) 222 { 223 m_orderClause = newOrderClause; 224 if (m_orderClause == null) 225 m_orderClause = ""; 226 } 228 232 public String getOrderClause() 233 { 234 return m_orderClause; 235 } 237 242 private String createSelectSql() 243 { 244 if (m_fields.size() == 0 || m_tableName == null || m_tableName.equals("")) 245 return ""; 246 247 StringBuffer select = new StringBuffer ("SELECT "); 249 for (int i = 0; i < m_fields.size(); i++) 250 { 251 if (i > 0) 252 select.append(","); 253 MField field = (MField)m_fields.get(i); 254 select.append(field.getColumnName()); 255 } 256 select.append(" FROM ").append(m_tableName); 258 m_SQL_Select = select.toString(); 259 m_SQL_Count = "SELECT COUNT(*) FROM " + m_tableName; 260 262 StringBuffer where = new StringBuffer (""); 263 if (m_whereClause.length() > 0) 265 { 266 where.append(" WHERE "); 267 if (m_whereClause.indexOf("@") == -1) 268 where.append(m_whereClause); 269 else where.append(Env.parseContext(m_ctx, m_WindowNo, m_whereClause, false)); 271 } 272 if (m_onlyCurrentRows) 273 { 274 if (where.toString().indexOf(" WHERE ") == -1) 275 where.append(" WHERE "); 276 else 277 where.append(" AND "); 278 where.append("(Processed='N' OR Updated>SysDate-").append(m_onlyCurrentDays).append(")"); 280 } 281 282 m_SQL = m_SQL_Select + where.toString(); 284 m_SQL_Count += where.toString(); 285 if (m_withAccessControl) 286 { 287 boolean ro = MRole.SQL_RO; 288 m_SQL = MRole.getDefault(m_ctx, false).addAccessSQL(m_SQL, 291 m_tableName, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); 292 m_SQL_Count = MRole.getDefault(m_ctx, false).addAccessSQL(m_SQL_Count, 293 m_tableName, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); 294 } 295 296 if (!m_orderClause.equals("")) 298 m_SQL += " ORDER BY " + m_orderClause; 299 log.debug("createSelectSql - " + m_SQL_Count); 301 Env.setContext(m_ctx, m_WindowNo, m_TabNo, "SQL", m_SQL); 302 return m_SQL; 303 } 305 309 public void addField (MField field) 310 { 311 log.debug ("addField (" + m_tableName + ") - " + field.getColumnName()); 312 if (m_open) 313 { 314 log.error("addField - Table already open - ignored: " + field.getColumnName()); 315 return; 316 } 317 if (!MRole.getDefault(m_ctx, false).isColumnAccess (m_AD_Table_ID, field.getAD_Column_ID(), true)) 318 { 319 log.debug ("addField - No Column Access " + field.getColumnName()); 320 return; 321 } 322 if (field.getDisplayType() == DisplayType.RowID) 324 m_indexRowIDColumn = m_fields.size(); 325 if (field.isKey()) 327 m_indexKeyColumn = m_fields.size(); 328 else if (field.getColumnName().equals("IsActive")) 329 m_indexActiveColumn = m_fields.size(); 330 else if (field.getColumnName().equals("Processed")) 331 m_indexProcessedColumn = m_fields.size(); 332 else if (field.getColumnName().equals("AD_Client_ID")) 333 m_indexClientColumn = m_fields.size(); 334 else if (field.getColumnName().equals("AD_Org_ID")) 335 m_indexOrgColumn = m_fields.size(); 336 m_fields.add(field); 338 } 340 346 public String getColumnName (int index) 347 { 348 if (index < 0 || index > m_fields.size()) 349 { 350 log.error("getColumnName - invalid index=" + index); 351 return ""; 352 } 353 MField field = (MField)m_fields.get(index); 355 return field.getColumnName(); 356 } 358 364 public int findColumn (String columnName) 365 { 366 for (int i = 0; i < m_fields.size(); i++) 367 { 368 MField field = (MField)m_fields.get(i); 369 if (columnName.equals(field.getColumnName())) 370 return i; 371 } 372 return -1; 373 } 375 381 public Class getColumnClass (int index) 382 { 383 if (index < 0 || index >= m_fields.size()) 384 { 385 log.error("getColumnClass - invalid index=" + index); 386 return null; 387 } 388 MField field = (MField)m_fields.get(index); 389 return DisplayType.getClass(field.getDisplayType(), false); 390 } 392 398 public void setParameterSELECT (int index, Object parameter) 399 { 400 if (index >= m_parameterSELECT.size()) 401 m_parameterSELECT.add(parameter); 402 else 403 m_parameterSELECT.set(index, parameter); 404 } 406 412 public void setParameterWHERE (int index, Object parameter) 413 { 414 if (index >= m_parameterWHERE.size()) 415 m_parameterWHERE.add(parameter); 416 else 417 m_parameterWHERE.set(index, parameter); 418 } 420 421 426 protected MField getField (int index) 427 { 428 if (index < 0 || index >= m_fields.size()) 429 return null; 430 return (MField)m_fields.get(index); 431 } 433 438 protected MField getField (String identifier) 439 { 440 if (identifier == null || identifier.length() == 0) 441 return null; 442 int cols = m_fields.size(); 443 for (int i = 0; i < cols; i++) 444 { 445 MField field = (MField)m_fields.get(i); 446 if (identifier.equalsIgnoreCase(field.getColumnName())) 447 return field; 448 } 449 return null; 451 } 453 454 455 456 462 public boolean open () 463 { 464 log.info("open"); 465 if (m_open) 466 { 467 log.debug("open - already open"); 468 dataRefreshAll(); 469 return true; 470 } 471 472 createSelectSql(); 474 if (m_SQL == null || m_SQL.equals("")) 475 { 476 log.error("open - No SQL"); 477 return false; 478 } 479 480 m_loader = new Loader(); 482 m_rowCount = m_loader.open(); 483 m_buffer = new ArrayList(m_rowCount+10); 484 m_sort = new ArrayList(m_rowCount+10); 485 if (m_rowCount > 0) 486 m_loader.start(); 487 else 488 m_loader.close(); 489 m_open = true; 490 m_changed = false; 492 m_rowChanged = -1; 493 return true; 494 } 496 500 public void loadComplete() 501 { 502 if (m_loader != null) 504 { 505 if (m_loader.isAlive()) 506 { 507 try 508 { 509 m_loader.join(); 510 } 511 catch (InterruptedException ie) 512 { 513 log.error("loadComplete - join interrupted", ie); 514 } 515 } 516 } 517 for (int i = 0; i < m_fields.size(); i++) 519 { 520 MField field = (MField)m_fields.get(i); 521 field.lookupLoadComplete(); 522 } 523 } 525 529 public boolean isLoading() 530 { 531 if (m_loader != null && m_loader.isAlive()) 532 return true; 533 return false; 534 } 536 540 public boolean isOpen() 541 { 542 return m_open; 543 } 545 549 public void close (boolean finalCall) 550 { 551 if (!m_open) 552 return; 553 log.debug("close - final=" + finalCall); 554 555 if (finalCall) 557 { 558 m_dataStatusListeners.clear(); 559 EventListener evl[] = listenerList.getListeners(TableModelListener.class); 560 for (int i = 0; i < evl.length; i++) 561 listenerList.remove(TableModelListener.class, evl[i]); 562 VetoableChangeListener vcl[] = m_vetoableChangeSupport.getVetoableChangeListeners(); 563 for (int i = 0; i < vcl.length; i++) 564 m_vetoableChangeSupport.removeVetoableChangeListener(vcl[i]); 565 } 566 567 while (m_loader != null && m_loader.isAlive()) 569 { 570 log.debug("close - interrupting Loader"); 571 m_loader.interrupt(); 572 try 573 { 574 Thread.sleep(200); } 576 catch (InterruptedException ie) 577 {} 578 } 579 580 if (!m_inserting) 581 dataSave(true); 582 583 if (m_buffer != null) 584 m_buffer.clear(); 585 m_buffer = null; 586 if (m_sort != null) 587 m_sort.clear(); 588 m_sort = null; 589 590 if (finalCall) 591 dispose(); 592 593 log.debug("close - complete"); 595 m_open = false; 596 } 598 602 private void dispose() 603 { 604 for (int i = 0; i < m_fields.size(); i++) 606 ((MField)m_fields.get(i)).dispose(); 607 m_fields.clear(); 608 m_fields = null; 609 m_dataStatusListeners = null; 611 m_vetoableChangeSupport = null; 612 m_parameterSELECT.clear(); 614 m_parameterSELECT = null; 615 m_parameterWHERE.clear(); 616 m_parameterWHERE = null; 617 m_buffer = null; 619 m_sort = null; 620 m_rowData = null; 621 m_oldValue = null; 622 m_loader = null; 623 } 625 629 public int getColumnCount() 630 { 631 return m_fields.size(); 632 } 634 638 public int getFieldCount() 639 { 640 return m_fields.size(); 641 } 643 647 public int getRowCount() 648 { 649 return m_rowCount; 650 } 652 656 public void setColorColumn (String columnName) 657 { 658 m_indexColorColumn = findColumn(columnName); 659 } 661 673 public int getColorCode (int row) 674 { 675 if (m_indexColorColumn == -1) 676 return 0; 677 Object data = getValueAt(row, m_indexColorColumn); 678 if (data == null || !(data instanceof BigDecimal)) 680 return 0; 681 int cmp = Env.ZERO.compareTo(data); 682 if (cmp > 0) 683 return -1; 684 if (cmp < 0) 685 return 1; 686 return 0; 687 } 689 690 698 public void sort (int col, boolean ascending) 699 { 700 log.info("sort #" + col + " " + ascending); 701 if (getRowCount() == 0) 702 return; 703 MField field = getField (col); 704 if (field.getDisplayType() == DisplayType.RowID) 706 return; 707 boolean isLookup = DisplayType.isLookup(field.getDisplayType()); 708 709 for (int i = 0; i < m_sort.size(); i++) 711 { 712 MSort sort = (MSort)m_sort.get(i); 713 Object [] rowData = (Object [])m_buffer.get(sort.index); 714 if (isLookup) 715 sort.data = field.getLookup().getDisplay(rowData[col]); else 717 sort.data = rowData[col]; } 719 720 MSort sort = new MSort(0, null); 722 sort.setSortAsc(ascending); 723 Collections.sort(m_sort, sort); 724 fireTableDataChanged(); 726 fireDataStatusIEvent("Sorted"); 728 } 730 735 public int getKeyID (int row) 736 { 737 if (m_indexKeyColumn != -1) 739 { 740 try 741 { 742 Integer ii = (Integer )getValueAt(row, m_indexKeyColumn); 743 if (ii == null) 744 return -1; 745 return ii.intValue(); 746 } 747 catch (Exception e) { 749 return -1; 750 } 751 } 752 return -1; 753 } 755 759 public String getKeyColumnName() 760 { 761 if (m_indexKeyColumn != -1) 762 return getColumnName(m_indexKeyColumn); 763 return ""; 764 } 766 771 public Object getRowID (int row) 772 { 773 Object [] rid = getRID(row); 774 if (rid == null) 775 return null; 776 return rid[0]; 777 } 779 786 public Object [] getRID (int row) 787 { 788 if (m_indexRowIDColumn == -1 || row < 0 || row >= getRowCount()) 789 return null; 790 return (Object [])getValueAt(row, m_indexRowIDColumn); 791 } 793 798 public int getRow (Object RowID) 799 { 800 if (RowID == null) 801 return 0; 802 803 String find = RowID.toString(); 805 806 if (m_loader != null && m_loader.isAlive()) 808 { 809 try 810 { 811 Thread.sleep(250); } 813 catch (InterruptedException ie) 814 {} 815 } 816 817 int size = m_sort.size(); ArrayList search = new ArrayList(size); 820 for (int i = 0; i < size; i++) 821 { 822 Object [] r = (Object [])getValueAt(i, 0); 823 String s = r[0].toString(); 824 MSort so = new MSort(i, s); 825 search.add(so); 826 } 827 828 MSort sort = new MSort(0, null); 830 Collections.sort(search, sort); 831 832 int index = Collections.binarySearch(search, find, sort); 834 if (index < 0) { 836 search.clear(); 837 return 0; 838 } 839 MSort result = (MSort)search.get(index); 841 search.clear(); 843 return result.index; 844 } 846 847 848 849 855 public Object getValueAt (int row, int col) 856 { 857 if (!m_open || row < 0 || col < 0 || row >= m_rowCount) 859 { 860 return null; 862 } 863 864 int loops = 0; 866 while (row >= m_buffer.size() && m_loader.isAlive() && loops < 15) 867 { 868 log.debug("getValueAt - waiting for loader row=" + row + ", size=" + m_buffer.size()); 869 try 870 { 871 Thread.sleep(500); } 873 catch (InterruptedException ie) 874 {} 875 loops++; 876 } 877 878 if (row >= m_buffer.size()) 880 { 881 return null; 883 } 884 885 MSort sort = (MSort)m_sort.get(row); 887 Object [] rowData = (Object [])m_buffer.get(sort.index); 888 if (rowData == null || col > rowData.length) 890 { 891 return null; 893 } 894 return rowData[col]; 895 } 897 901 public void setChanged (boolean changed) 902 { 903 if (!m_open || m_readOnly) 905 return; 906 907 m_changed = changed; 909 if (!changed) 910 m_rowChanged = -1; 911 fireDataStatusIEvent(""); 912 } 914 922 public final void setValueAt (Object value, int row, int col) 923 { 924 setValueAt (value, row, col, false); 925 } 927 936 public final void setValueAt (Object value, int row, int col, boolean force) 937 { 938 if (!m_open || m_readOnly || row < 0 || col < 0 || col == 0 || m_rowCount == 0) return; 944 945 dataSave(row, false); 946 947 Object oldValue = getValueAt(row, col); 949 if (!force && ( 950 (oldValue == null && value == null) 951 || (oldValue != null && oldValue.equals(value)) 952 || (oldValue != null && value != null && oldValue.toString().equals(value.toString())) 953 )) 954 return; 955 956 log.debug("setValueAt r=" + row + " c=" + col + " = " + value + " (" + oldValue + ")"); 957 958 m_oldValue = new Object [3]; 960 m_oldValue[0] = new Integer (row); 961 m_oldValue[1] = new Integer (col); 962 m_oldValue[2] = oldValue; 963 964 MSort sort = (MSort)m_sort.get(row); 966 Object [] rowData = (Object [])m_buffer.get(sort.index); 967 m_rowChanged = row; 968 969 if (col == 0) 971 { 972 rowData[col] = value; 973 m_buffer.set(sort.index, rowData); 974 return; 975 } 976 977 if (m_rowData == null) 979 { 980 int size = m_fields.size(); 981 m_rowData = new Object [size]; 982 for (int i = 0; i < size; i++) 983 m_rowData[i] = rowData[i]; 984 } 985 986 rowData[col] = value; 988 m_buffer.set(sort.index, rowData); 989 fireTableCellUpdated(row, col); 991 MField field = getField(col); 993 field.setValue(value, m_inserting); 994 DataStatusEvent evt = createDSE(); 996 evt.setChangedColumn(col); 997 fireDataStatusChanged(evt); 998 } 1000 1006 public Object getOldValue (int row, int col) 1007 { 1008 if (m_oldValue == null) 1009 return null; 1010 if (((Integer )m_oldValue[0]).intValue() == row 1011 && ((Integer )m_oldValue[1]).intValue() == col) 1012 return m_oldValue[2]; 1013 return null; 1014 } 1016 1022 public boolean needSave(boolean onlyRealChange) 1023 { 1024 return needSave(m_rowChanged, onlyRealChange); 1025 } 1027 1032 public boolean needSave() 1033 { 1034 return needSave(m_rowChanged, false); 1035 } 1037 1044 public boolean needSave(int newRow) 1045 { 1046 return needSave(newRow, false); 1047 } 1049 1058 public boolean needSave(int newRow, boolean onlyRealChange) 1059 { 1060 log.debug("needSave - Row=" + newRow + 1061 ", Changed=" + m_rowChanged + "/" + m_changed); if (!m_changed && m_rowChanged == -1) 1064 return false; 1065 if (m_changed && m_rowChanged == -1 && onlyRealChange) 1067 return false; 1068 if (newRow == m_rowChanged) 1070 return false; 1071 1072 return true; 1073 } 1075 1076 1077 public static final char SAVE_OK = 'O'; public static final char SAVE_ERROR = 'E'; 1079 public static final char SAVE_ACCESS = 'A'; 1080 public static final char SAVE_MANDATORY = 'M'; 1081 public static final char SAVE_ABORT = 'U'; 1082 1083 1089 public boolean dataSave (int newRow, boolean manualCmd) 1090 { 1091 log.debug("dataSave - Row=" + newRow + 1092 ", Changed=" + m_rowChanged + "/" + m_changed); if (!m_changed && m_rowChanged == -1) 1095 return true; 1096 if (newRow == m_rowChanged) 1098 return true; 1099 1100 return (dataSave(manualCmd) == SAVE_OK); 1101 } 1103 1110 public char dataSave (boolean manualCmd) 1111 { 1112 if (!m_open) 1114 { 1115 log.warn ("dataSave - Error - Open=" + m_open); 1116 return SAVE_ERROR; 1117 } 1118 if (m_rowChanged == -1) 1120 { 1121 log.info("dataSave - NoNeed - Changed=" + m_changed + ", Row=" + m_rowChanged); 1122 if (!manualCmd) 1124 return SAVE_OK; 1125 } 1126 if (m_rowData == null) 1128 { 1129 log.warn ("dataSave - Error - DataNull=" + (m_rowData == null)); 1130 return SAVE_ERROR; 1131 } 1132 1133 if (m_readOnly) 1134 1135 { 1137 log.warn("dataSave - IsReadOnly - ignored"); 1138 dataIgnore(); 1139 return SAVE_ACCESS; 1140 } 1141 1142 if (m_rowChanged == -1) 1144 { 1145 if (m_newRow != -1) m_rowChanged = m_newRow; 1147 else 1148 { 1149 fireDataStatusEEvent("SaveErrorNoChange", ""); 1150 return SAVE_ERROR; 1151 } 1152 } 1153 1154 int[] co = getClientOrg(m_rowChanged); 1156 int AD_Client_ID = co[0]; 1157 int AD_Org_ID = co[1]; 1158 if (!MRole.getDefault(m_ctx, false).canUpdate(AD_Client_ID, AD_Org_ID, m_AD_Table_ID, true)) 1159 { 1160 fireDataStatusEEvent(Log.retrieveError()); 1161 dataIgnore(); 1162 return SAVE_ACCESS; 1163 } 1164 1165 log.info("dataSave - Saving row " + m_rowChanged); 1166 1167 try 1169 { 1170 if (!manualCmd) 1171 m_vetoableChangeSupport.fireVetoableChange(PROPERTY, 0, m_rowChanged); 1172 } 1173 catch (PropertyVetoException pve) 1174 { 1175 log.warn("dataSave - " + pve.getMessage()); 1176 dataIgnore(); 1177 return SAVE_ABORT; 1178 } 1179 1180 MSort sort = (MSort)m_sort.get(m_rowChanged); 1182 Object [] rowData = (Object [])m_buffer.get(sort.index); 1183 1184 String missingColumns = getMandatory(rowData); 1186 if (missingColumns.length() != 0) 1187 { 1188 fireDataStatusEEvent("FillMandatory", missingColumns); 1189 return SAVE_MANDATORY; 1190 } 1191 1192 1195 boolean error = false; 1196 String is = null; 1198 final String ERROR = "ERROR: "; 1199 final String INFO = "Info: "; 1200 1201 String SQL = m_SQL_Select; 1203 StringBuffer refreshSQL = new StringBuffer (SQL).append(" WHERE "); StringBuffer singleRowWHERE = new StringBuffer (); 1205 StringBuffer multiRowWHERE = new StringBuffer (); 1206 Object rowID = null; 1208 if (m_inserting) 1209 { 1210 SQL += " WHERE 1=2"; 1211 } 1212 else 1213 { 1214 SQL += " WHERE ROWID=?"; 1216 rowID = getRowID (m_rowChanged); 1217 } 1218 PreparedStatement pstmt = null; 1219 try 1220 { 1221 pstmt = DB.prepareStatement (SQL, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); 1222 if (!m_inserting) 1223 DB.getDatabase().setRowID(pstmt, 1, rowID); 1224 ResultSet rs = pstmt.executeQuery(); 1225 if (!(m_inserting || rs.next())) 1227 { 1228 rs.close(); 1229 pstmt.close(); 1230 fireDataStatusEEvent("SaveErrorRowNotFound", ""); 1231 dataRefresh(m_rowChanged); 1232 return SAVE_ERROR; 1233 } 1234 1235 Object [] rowDataDB = null; 1236 boolean manualUpdate = ResultSet.CONCUR_READ_ONLY == rs.getConcurrency(); 1238 if (manualUpdate) 1239 createUpdateSqlReset(); 1240 if (m_inserting) 1241 { 1242 if (manualUpdate) 1243 log.debug("dataSave - prepare inserting ... manual"); 1244 else 1245 { 1246 log.debug ("dataSave - prepare inserting ... RowSet"); 1247 rs.moveToInsertRow (); 1248 } 1249 } 1250 else 1251 { 1252 log.debug("dataSave - prepare updating ... manual=" + manualUpdate); 1253 rowDataDB = readData (rs); 1255 } 1256 1257 1266 1267 Timestamp now = new Timestamp(System.currentTimeMillis()); 1269 int user = Env.getContextAsInt(m_ctx, "#AD_User_ID"); 1270 1271 1274 int size = m_fields.size(); 1275 for (int col = 0; col < size; col++) 1276 { 1277 MField field = (MField)m_fields.get (col); 1278 String columnName = field.getColumnName (); 1279 1281 if (field.getDisplayType () == DisplayType.RowID) 1283 ; 1285 else if (field.isKey () && m_inserting) 1287 { 1288 if (columnName.endsWith ("_ID")) 1289 { 1290 int insertID = DB.getKeyNextNo (m_ctx, m_WindowNo, m_tableName); 1291 if (manualUpdate) 1292 createUpdateSql (columnName, String.valueOf (insertID)); 1293 else 1294 rs.updateInt (col + 1, insertID); singleRowWHERE.append (columnName).append ("=").append (insertID); 1296 is = INFO + columnName + " -> " + insertID + " (Key)"; 1298 } 1299 else { 1301 String str = rowData[col].toString (); 1302 if (manualUpdate) 1303 createUpdateSql (columnName, DB.TO_STRING (str)); 1304 else 1305 rs.updateString (col + 1, str); singleRowWHERE.append (columnName).append ("=").append (DB.TO_STRING(str)); 1307 is = INFO + columnName + " -> " + str + " (StringKey)"; 1309 } 1310 log.debug ("dataSave - " + is); 1311 } 1313 else if (columnName.equals ("DocumentNo")) 1315 { 1316 boolean newDocNo = false; 1317 String docNo = (String )rowData[col]; 1318 if (docNo == null || docNo.length () == 0) 1320 newDocNo = true; 1321 else if (docNo.startsWith ("<") && docNo.endsWith (">")) 1323 newDocNo = true; 1324 1325 if (newDocNo || m_inserting) 1326 { 1327 String insertDoc = null; 1328 if (m_inserting) 1330 insertDoc = DB.getDocumentNo (m_ctx, m_WindowNo, m_tableName, true); 1331 log.debug ("dataSave - DocumentNo entered=" + docNo + ", DocTypeInsert=" + insertDoc + ", newDocNo=" + newDocNo); 1332 if (insertDoc == null || insertDoc.length () == 0) 1334 { 1335 if (!newDocNo && docNo != null && docNo.length () > 0) 1336 insertDoc = docNo; 1337 else insertDoc = DB.getDocumentNo (m_ctx, m_WindowNo, m_tableName, false); 1339 } 1340 if (insertDoc == null || insertDoc.length () == 0) 1342 { 1343 if (docNo != null && docNo.length () != 0) 1345 insertDoc = (String )rowData[col]; 1346 else 1347 { 1348 error = true; 1349 is = ERROR + field.getColumnName () + "= " + rowData[col] + " NO DocumentNo"; 1350 log.debug ("dataSave - " + is); 1351 break; 1352 } 1353 } 1354 if (manualUpdate) 1356 createUpdateSql (columnName, DB.TO_STRING (insertDoc)); 1357 else 1358 rs.updateString (col + 1, insertDoc); is = INFO + columnName + " -> " + insertDoc + " (DocNo)"; 1361 log.debug ("dataSave - " + is); 1362 } 1363 } 1365 else if (columnName.equals ("Value") && m_inserting) 1367 { 1368 String value = (String )rowData[col]; 1369 if (value == null || value.length () == 0) 1371 { 1372 value = DB.getDocumentNo (m_ctx, m_WindowNo, m_tableName, false); 1373 if (value == null || value.length () == 0) 1375 { 1376 error = true; 1377 is = ERROR + field.getColumnName () + "= " + rowData[col] 1378 + " No DocumentNo"; 1379 log.debug ("dataSave - " + is); 1380 break; 1381 } 1382 } 1383 if (manualUpdate) 1384 createUpdateSql (columnName, DB.TO_STRING (value)); 1385 else 1386 rs.updateString (col + 1, value); is = INFO + columnName + " -> " + value + " (Value)"; 1389 log.debug ("dataSave - " + is); 1390 } 1392 else if (columnName.equals ("Updated")) 1394 { 1395 if (m_compareDB && !m_inserting && !m_rowData[col].equals (rowDataDB[col])) { 1397 error = true; 1398 is = ERROR + field.getColumnName () + "= " + m_rowData[col] 1399 + " != DB: " + rowDataDB[col]; 1400 log.debug ("dataSave - " + is); 1401 break; 1402 } 1403 if (manualUpdate) 1404 createUpdateSql (columnName, DB.TO_DATE (now, false)); 1405 else 1406 rs.updateTimestamp (col + 1, now); is = INFO + "Updated/By -> " + now + " - " + user; 1409 log.debug ("dataSave - " + is); 1410 } 1412 else if (columnName.equals ("UpdatedBy")) 1414 { 1415 if (manualUpdate) 1416 createUpdateSql (columnName, String.valueOf (user)); 1417 else 1418 rs.updateInt (col + 1, user); } 1421 else if (m_inserting && columnName.equals ("Created")) 1423 { 1424 if (manualUpdate) 1425 createUpdateSql (columnName, DB.TO_DATE (now, false)); 1426 else 1427 rs.updateTimestamp (col + 1, now); } 1430 else if (m_inserting && columnName.equals ("CreatedBy")) 1432 { 1433 if (manualUpdate) 1434 createUpdateSql (columnName, String.valueOf (user)); 1435 else 1436 rs.updateInt (col + 1, user); } 1439 else if (m_rowData[col] == null && rowData[col] == null) 1441 { 1442 if (m_inserting) 1443 { 1444 if (manualUpdate) 1445 createUpdateSql (columnName, "NULL"); 1446 else 1447 rs.updateNull (col + 1); is = INFO + columnName + "= NULL"; 1449 log.debug ("dataSave - " + is); 1450 } 1451 } 1452 1453 else if (m_inserting 1455 || (m_rowData[col] == null && rowData[col] != null) 1456 || (m_rowData[col] != null && rowData[col] == null) 1457 || !m_rowData[col].equals (rowData[col])) { 1459 if (m_inserting || !m_compareDB 1461 || (m_rowData[col] == null && rowDataDB[col] == null) 1462 || (m_rowData[col] != null && m_rowData[col].equals (rowDataDB[col]))) 1463 { 1464 String type = "String"; 1465 if (rowData[col] == null) 1466 { 1467 if (manualUpdate) 1468 createUpdateSql (columnName, "NULL"); 1469 else 1470 rs.updateNull (col + 1); } 1472 else if (DisplayType.isNumeric (field.getDisplayType ())) 1474 { 1475 if (manualUpdate) 1476 createUpdateSql (columnName, rowData[col].toString ()); 1477 else 1478 rs.updateBigDecimal (col + 1, (BigDecimal)rowData[col]); type = "Number"; 1480 } 1481 else if (DisplayType.isID (field.getDisplayType ())) 1483 { 1484 int number = 0; 1485 try 1486 { 1487 number = Integer.parseInt (rowData[col].toString ()); 1488 if (manualUpdate) 1489 createUpdateSql (columnName, String.valueOf (number)); 1490 else 1491 rs.updateInt (col + 1, number); } 1493 catch (Exception e) { 1495 if (manualUpdate) 1496 createUpdateSql (columnName, DB.TO_STRING (rowData[col].toString ())); 1497 else 1498 rs.updateString (col + 1, rowData[col].toString ()); } 1500 type = "ID"; 1501 } 1502 else if (DisplayType.isDate (field.getDisplayType ())) 1504 { 1505 if (manualUpdate) 1506 createUpdateSql (columnName, DB.TO_DATE ((Timestamp)rowData[col], false)); 1507 else 1508 rs.updateTimestamp (col + 1, (Timestamp)rowData[col]); type = "Date"; 1510 } 1511 else if (field.getDisplayType() == DisplayType.TextLong) 1513 { 1514 if (manualUpdate) 1515 createUpdateSql (columnName, "empty_clob()"); 1516 type = "CLOB"; 1519 } 1520 else 1522 { 1523 if (manualUpdate) 1524 createUpdateSql (columnName, DB.TO_STRING (rowData[col].toString ())); 1525 else 1526 rs.updateString (col + 1, rowData[col].toString ()); } 1528 is = INFO + columnName + "= " + m_rowData[col] 1530 + " -> " + rowData[col] + " (" + type + ")"; 1531 log.debug ("dataSave - " + is); 1532 } 1533 else 1535 { 1536 error = true; 1537 is = ERROR + field.getColumnName () + "= " + m_rowData[col] 1538 + " != DB: " + rowDataDB[col] + " -> " + rowData[col]; 1539 log.debug ("dataSave - " + is); 1540 } 1541 } 1543 if (field.isKey() && !m_inserting) 1545 { 1546 if (rowData[col] == null) 1547 throw new RuntimeException ("dataSave - Key " + columnName + " is NULL"); 1548 if (columnName.endsWith ("_ID")) 1549 singleRowWHERE.append (columnName).append ("=").append (rowData[col]); 1550 else 1551 singleRowWHERE.append (columnName).append ("=").append (DB.TO_STRING(rowData[col].toString())); 1552 } 1553 if (field.isParent()) 1555 { 1556 if (rowData[col] == null) 1557 throw new RuntimeException ("dataSave - MultiKey Parent " + columnName + " is NULL"); 1558 if (multiRowWHERE.length() != 0) 1559 multiRowWHERE.append(" AND "); 1560 if (columnName.endsWith ("_ID")) 1561 multiRowWHERE.append (columnName).append ("=").append (rowData[col]); 1562 else 1563 multiRowWHERE.append (columnName).append ("=").append (DB.TO_STRING(rowData[col].toString())); 1564 } 1565 } 1567 if (error) 1568 { 1569 if (manualUpdate) 1570 createUpdateSqlReset(); 1571 else 1572 rs.cancelRowUpdates(); 1573 rs.close(); 1574 pstmt.close(); 1575 fireDataStatusEEvent("SaveErrorDataChanged", ""); 1576 dataRefresh(m_rowChanged); 1577 return SAVE_ERROR; 1578 } 1579 1580 1583 String whereClause = singleRowWHERE.toString(); 1584 if (whereClause.length() == 0) 1585 whereClause = multiRowWHERE.toString(); 1586 if (m_inserting) 1588 { 1589 log.debug("dataSave - inserting ..."); 1590 if (manualUpdate) 1591 { 1592 String sql = createUpdateSql(true, null); 1593 int no = DB.executeUpdateEx(sql); 1594 if (no != 1) 1595 log.error("dataSave - insert #=" + no + " - " + sql); 1596 } 1597 else 1598 rs.insertRow(); 1599 } 1600 else 1601 { 1602 log.debug("dataSave - updating ... " + whereClause); 1603 if (manualUpdate) 1604 { 1605 String sql = createUpdateSql(false, whereClause); 1606 int no = DB.executeUpdateEx(sql); 1607 if (no != 1) 1608 log.error("dataSave - update #=" + no + " - " + sql); 1609 } 1610 else 1611 rs.updateRow(); 1612 } 1613 1614 log.debug("dataSave - committing ..."); 1615 DB.commit(true); 1616 if (m_inserting || manualUpdate) 1618 { 1619 rs.close(); 1620 pstmt.close(); 1621 log.debug("dataSave - reading ... " + whereClause); 1623 refreshSQL.append(whereClause); 1624 pstmt = DB.prepareStatement(refreshSQL.toString()); 1625 rs = pstmt.executeQuery(); 1626 if (rs.next()) 1627 { 1628 rowDataDB = readData(rs); 1629 m_buffer.set(sort.index, rowDataDB); 1631 fireTableRowsUpdated(m_rowChanged, m_rowChanged); 1632 } 1633 else 1634 log.error("dataSave - inserted row not found"); 1635 } 1636 else 1637 { 1638 log.debug("dataSave - refreshing ..."); 1639 rs.refreshRow(); rowDataDB = readData(rs); 1641 m_buffer.set(sort.index, rowDataDB); 1643 fireTableRowsUpdated(m_rowChanged, m_rowChanged); 1644 } 1645 rs.close(); 1647 pstmt.close(); 1648 pstmt = null; 1649 } 1650 catch (SQLException e) 1651 { 1652 try 1653 { 1654 if (pstmt != null) 1655 pstmt.close (); 1656 pstmt = null; 1657 } 1658 catch (Exception ex) 1659 { 1660 } 1661 1662 String msg = "SaveError"; 1663 if (e.getErrorCode() == 1) { 1665 log.error ("dataSave - Key Not Unique", e); 1666 msg = "SaveErrorNotUnique"; 1667 } 1668 else 1669 log.error ("dataSave\nSQL= " + SQL, e); 1670 fireDataStatusEEvent(msg, e.getLocalizedMessage()); 1671 return SAVE_ERROR; 1672 } 1673 1674 m_rowData = null; 1676 m_changed = false; 1677 m_compareDB = true; 1678 m_rowChanged = -1; 1679 m_newRow = -1; 1680 m_inserting = false; 1681 fireDataStatusIEvent("Saved"); 1682 log.info("dataSave - fini"); 1684 return SAVE_OK; 1685 } 1687 private ArrayList m_createSqlColumn = new ArrayList(); 1688 private ArrayList m_createSqlValue = new ArrayList(); 1689 1690 1695 private void createUpdateSql (String columnName, String value) 1696 { 1697 m_createSqlColumn.add(columnName); 1698 m_createSqlValue.add(value); 1699 if (Log.isTraceLevel(10)) 1700 log.debug("createUpdateSql #" + m_createSqlColumn.size() 1701 + " - " + columnName + "=" + value); 1702 } 1704 1710 private String createUpdateSql (boolean insert, String whereClause) 1711 { 1712 StringBuffer sb = new StringBuffer (); 1713 if (insert) 1714 { 1715 sb.append("INSERT INTO ").append(m_tableName).append(" ("); 1716 for (int i = 0; i < m_createSqlColumn.size(); i++) 1717 { 1718 if (i != 0) 1719 sb.append(","); 1720 sb.append(m_createSqlColumn.get(i)); 1721 } 1722 sb.append(") VALUES ( "); 1723 for (int i = 0; i < m_createSqlValue.size(); i++) 1724 { 1725 if (i != 0) 1726 sb.append(","); 1727 sb.append(m_createSqlValue.get(i)); 1728 } 1729 sb.append(")"); 1730 } 1731 else 1732 { 1733 sb.append("UPDATE ").append(m_tableName).append(" SET "); 1734 for (int i = 0; i < m_createSqlColumn.size(); i++) 1735 { 1736 if (i != 0) 1737 sb.append(","); 1738 sb.append(m_createSqlColumn.get(i)).append("=").append(m_createSqlValue.get(i)); 1739 } 1740 sb.append(" WHERE ").append(whereClause); 1741 } 1742 log.debug("createUpdateSql=" + sb.toString()); 1743 createUpdateSqlReset(); 1745 return sb.toString(); 1746 } 1748 1751 private void createUpdateSqlReset() 1752 { 1753 m_createSqlColumn = new ArrayList(); 1754 m_createSqlValue = new ArrayList(); 1755 } 1757 1762 private String getMandatory(Object [] rowData) 1763 { 1764 StringBuffer sb = new StringBuffer (); 1766 1767 int size = m_fields.size(); 1769 for (int i = 0; i < size; i++) 1770 { 1771 MField field = (MField)m_fields.get(i); 1772 if (field.isMandatory(true)) { 1774 if (rowData[i] == null || rowData[i].toString().length() == 0) 1775 { 1776 field.setInserting (true); field.setError(true); 1778 if (sb.length() > 0) 1779 sb.append(", "); 1780 sb.append(field.getHeader()); 1781 } 1782 else 1783 field.setError(false); 1784 } 1785 } 1786 1787 if (sb.length() == 0) 1788 return ""; 1789 return sb.toString(); 1790 } 1792 1793 1794 1801 public boolean dataNew (int currentRow, boolean copyCurrent) 1802 { 1803 log.info("dataNew - Current=" + currentRow + ", Copy=" + copyCurrent); 1804 dataSave(-2, false); 1806 1807 if (m_readOnly) 1809 { 1810 fireDataStatusEEvent("AccessCannotInsert", ""); 1811 return false; 1812 } 1813 1814 1817 m_inserting = true; 1818 int size = m_fields.size(); 1820 m_rowData = new Object [size]; Object [] rowData = new Object [size]; 1822 if (copyCurrent) 1824 { 1825 MSort sort = (MSort) m_sort.get(currentRow); 1826 Object [] origData = (Object [])m_buffer.get(sort.index); 1827 for (int i = 0; i < size; i++) 1828 rowData[i] = origData[i]; 1829 } 1830 else { 1832 for (int i = 0; i < size; i++) 1833 { 1834 MField field = (MField)m_fields.get(i); 1835 rowData[i] = field.getDefault(); 1836 field.setValue(rowData[i], m_inserting); 1837 } 1838 } 1839 m_changed = true; 1840 m_compareDB = true; 1841 m_rowChanged = -1; m_newRow = currentRow + 1; 1843 if (m_buffer.size() < m_newRow) 1845 m_newRow = m_buffer.size(); 1846 1847 MSort sort = new MSort(m_buffer.size(), null); m_buffer.add(rowData); 1850 m_sort.add(m_newRow, sort); 1852 m_rowCount++; 1853 1854 log.debug("dataNew - Current=" + currentRow + ", New=" + m_newRow); 1856 fireTableRowsInserted(m_newRow, m_newRow); 1857 fireDataStatusIEvent(copyCurrent ? "UpdateCopied" : "Inserted"); 1858 log.debug("dataNew - Current=" + currentRow + ", New=" + m_newRow + " - complete"); 1859 return true; 1860 } 1862 1863 1864 1865 1872 public boolean dataDelete (int row) 1873 { 1874 log.info("dataDelete - " + row); 1875 if (row < 0) 1876 return false; 1877 Object rowID = getRowID(row); 1878 if (rowID == null) 1879 return false; 1880 1881 if (m_readOnly) 1883 { 1884 fireDataStatusEEvent("AccessCannotDelete", ""); 1885 return false; 1886 } 1887 1888 if (!m_deleteable 1890 || (m_indexProcessedColumn > 0 && "Y".equals(getValueAt(row, m_indexProcessedColumn)) && !m_tableName.startsWith("I_") )) { 1894 fireDataStatusEEvent("AccessNotDeleteable", ""); 1895 return false; 1896 } 1897 1898 1900 1901 StringBuffer SQL = new StringBuffer ("DELETE "); 1903 SQL.append(m_tableName).append(" WHERE ROWID=?"); 1904 int no = 0; 1905 try 1906 { 1907 PreparedStatement pstmt = DB.prepareStatement(SQL.toString()); 1908 DB.getDatabase().setRowID(pstmt, 1, rowID); 1909 no = pstmt.executeUpdate(); 1910 pstmt.close(); 1911 } 1912 catch (SQLException e) 1913 { 1914 log.error ("dataDelete", e); 1915 String msg = "DeleteError"; 1916 if (e.getErrorCode() == 2292) msg = "DeleteErrorDependent"; 1918 fireDataStatusEEvent(msg, e.getLocalizedMessage()); 1919 return false; 1920 } 1921 if (no != 1) 1923 { 1924 log.error("dataDelete - Number of deleted rows = " + no); 1925 return false; 1926 } 1927 1928 MSort sort = (MSort)m_sort.get(row); 1930 int bufferRow = sort.index; 1931 1932 m_buffer.remove(bufferRow); 1934 m_rowCount--; 1935 1936 m_sort.remove(row); 1938 for (int i = 0; i < m_sort.size(); i++) 1940 { 1941 MSort ptr = (MSort)m_sort.get(i); 1942 if (ptr.index > bufferRow) 1943 ptr.index--; } 1945 1946 m_changed = false; 1948 m_rowChanged = -1; 1949 fireTableRowsDeleted(row, row); 1950 fireDataStatusIEvent("Deleted"); 1951 log.debug("dataDelete - " + row + " complete"); 1952 return true; 1953 } 1955 1956 1957 1960 public void dataIgnore() 1961 { 1962 log.info("dataIgnore - Inserting=" + m_inserting); 1963 if (!m_inserting && !m_changed && m_rowChanged < 0) 1964 { 1965 log.debug("dataIgnore - Nothing to ignore"); 1966 return; 1967 } 1968 1969 if (m_inserting) 1971 { 1972 MSort sort = (MSort)m_sort.get(m_newRow); 1974 int bufferRow = sort.index; 1975 m_buffer.remove(bufferRow); 1977 m_rowCount--; 1978 m_sort.remove(m_newRow); m_changed = false; 1982 m_rowData = null; 1983 m_rowChanged = -1; 1984 m_inserting = false; 1985 fireTableRowsDeleted(m_newRow, m_newRow); 1987 } 1988 else 1989 { 1990 if (m_rowData != null) 1992 { 1993 MSort sort = (MSort)m_sort.get(m_rowChanged); 1994 m_buffer.set(sort.index, m_rowData); 1995 } 1996 m_changed = false; 1997 m_rowData = null; 1998 m_rowChanged = -1; 1999 m_inserting = false; 2000 } 2003 m_newRow = -1; 2004 fireDataStatusIEvent("Ignored"); 2005 } 2007 2008 2012 public void dataRefresh (int row) 2013 { 2014 log.info("dataRefresh " + row); 2015 2016 if (row < 0) 2017 return; 2018 Object rowID = getRowID(row); 2019 if (rowID == null) 2020 return; 2021 2022 dataIgnore(); 2024 2025 String SQL = m_SQL_Select + " WHERE ROWID=?"; 2027 MSort sort = (MSort)m_sort.get(row); 2028 Object [] rowDataDB = null; 2029 try 2030 { 2031 PreparedStatement pstmt = DB.prepareStatement(SQL); 2032 DB.getDatabase().setRowID(pstmt, 1, rowID); 2033 ResultSet rs = pstmt.executeQuery(); 2034 if (rs.next()) 2036 rowDataDB = readData(rs); 2037 rs.close(); 2038 pstmt.close(); 2039 } 2040 catch (SQLException e) 2041 { 2042 log.error ("dataRefresh\nSQL=" + SQL, e); 2043 fireTableRowsUpdated(row, row); 2044 fireDataStatusEEvent("RefreshError", ""); 2045 return; 2046 } 2047 2048 m_buffer.set(sort.index, rowDataDB); 2050 m_rowData = null; 2052 m_changed = false; 2053 m_rowChanged = -1; 2054 m_inserting = false; 2055 fireTableRowsUpdated(row, row); 2056 fireDataStatusIEvent("Refreshed"); 2057 } 2059 2060 2063 public void dataRefreshAll() 2064 { 2065 log.info("dataRefreshAll"); 2066 dataIgnore(); 2067 close(false); 2068 open(); 2069 m_rowData = null; 2071 m_changed = false; 2072 m_rowChanged = -1; 2073 m_inserting = false; 2074 fireTableDataChanged(); 2075 fireDataStatusIEvent("Refreshed"); 2076 } 2078 2079 2086 public boolean dataRequery (String whereClause, boolean onlyCurrentRows, int onlyCurrentDays) 2087 { 2088 log.info("dataRequery - " + whereClause + "; OnlyCurrent=" + onlyCurrentRows); 2089 close(false); 2090 m_onlyCurrentDays = onlyCurrentDays; 2091 setWhereClause(whereClause, onlyCurrentRows, m_onlyCurrentDays); 2092 open(); 2093 m_rowData = null; 2095 m_changed = false; 2096 m_rowChanged = -1; 2097 m_inserting = false; 2098 fireTableDataChanged(); 2099 fireDataStatusIEvent("Refreshed"); 2100 return true; 2101 } 2103 2104 2105 2106 2113 public boolean isCellEditable (int row, int col) 2114 { 2115 if (col == 0) 2118 return true; 2119 2120 if (m_readOnly) 2122 return false; 2123 if (col == m_indexRowIDColumn || col == m_indexKeyColumn) 2125 return false; 2126 2127 2128 if (col < 0 && col >= m_fields.size()) 2130 return false; 2131 if (!isRowEditable(row)) 2133 return false; 2134 if (col == m_indexActiveColumn && m_indexProcessedColumn == -1) 2136 return true; 2137 2138 return ((MField)m_fields.get(col)).isEditable(false); 2140 } 2142 2143 2148 public boolean isRowEditable (int row) 2149 { 2150 if (m_readOnly || row < 0) 2153 return false; 2154 if (m_indexActiveColumn > 0 && "N".equals(getValueAt(row, m_indexActiveColumn))) return false; 2157 if (m_indexProcessedColumn > 0 && "Y".equals(getValueAt(row, m_indexProcessedColumn))) return false; 2160 int[] co = getClientOrg(row); 2162 int AD_Client_ID = co[0]; 2163 int AD_Org_ID = co[1]; 2164 return MRole.getDefault(m_ctx, false).canUpdate(AD_Client_ID, AD_Org_ID, m_AD_Table_ID, false); 2165 } 2167 2172 private int[] getClientOrg (int row) 2173 { 2174 int AD_Client_ID = -1; 2175 if (m_indexClientColumn != -1) 2176 { 2177 Integer ii = (Integer )getValueAt(row, m_indexClientColumn); 2178 if (ii != null) 2179 AD_Client_ID = ii.intValue(); 2180 } 2181 int AD_Org_ID = 0; 2182 if (m_indexOrgColumn != -1) 2183 { 2184 Integer ii = (Integer )getValueAt(row, m_indexOrgColumn); 2185 if (ii != null) 2186 AD_Org_ID = ii.intValue(); 2187 } 2188 return new int[] {AD_Client_ID, AD_Org_ID}; 2189 } 2191 2195 public void setReadOnly (boolean value) 2196 { 2197 log.debug("setReadOnly " + value); 2198 m_readOnly = value; 2199 } 2201 2205 public boolean isReadOnly() 2206 { 2207 return m_readOnly; 2208 } 2210 2214 public boolean isInserting() 2215 { 2216 return m_inserting; 2217 } 2219 2225 public void setCompareDB (boolean compareDB) 2226 { 2227 m_compareDB = compareDB; 2228 } 2230 2235 public boolean getCompareDB () 2236 { 2237 return m_compareDB; 2238 } 2240 2241 2245 public void setDeleteable (boolean value) 2246 { 2247 log.debug("setDeleteable " + value); 2248 m_deleteable = value; 2249 } 2251 2252 2253 2258 private Object [] readData (ResultSet rs) 2259 { 2260 int size = m_fields.size(); 2261 Object [] rowData = new Object [size]; 2262 String columnName = null; 2263 int displayType = 0; 2264 2265 try 2266 { 2267 for (int j = 0; j < size; j++) 2269 { 2270 MField field = (MField)m_fields.get(j); 2272 columnName = field.getColumnName(); 2273 displayType = field.getDisplayType(); 2274 if (DisplayType.isNumeric(displayType)) 2276 rowData[j] = rs.getBigDecimal(j+1); else if (DisplayType.isID(displayType) && (columnName.endsWith("_ID")) || columnName.endsWith("edBy")) 2279 { 2280 rowData[j] = new Integer (rs.getInt(j+1)); if (rs.wasNull()) 2282 rowData[j] = null; 2283 } 2284 else if (DisplayType.isDate(displayType)) 2286 rowData[j] = rs.getTimestamp(j+1); else if (displayType == DisplayType.RowID) 2289 { 2290 Object [] rid = new Object [3]; 2291 if (columnName.equals("ROWID")) 2292 rid[0] = DB.getDatabase().getRowID(rs, j+1); 2293 else 2294 rid[2] = new Integer (rs.getInt(j+1)); 2295 rid[1] = new Boolean (false); 2296 rowData[j] = rid; 2297 } 2298 else if (displayType == DisplayType.TextLong) 2300 { 2301 Object value = rs.getObject(j+1); 2302 if (rs.wasNull()) 2303 rowData[j] = null; 2304 else if (value instanceof Clob) 2305 { 2306 Clob lob = (Clob)value; 2307 long length = lob.length(); 2308 rowData[j] = lob.getSubString(1, (int)length); 2309 } 2310 } 2311 else 2313 rowData[j] = rs.getString(j+1); } 2315 } 2316 catch (SQLException e) 2317 { 2318 log.error("readData - " + columnName + ", DT=" + displayType, e); 2319 } 2320 return rowData; 2321 } 2323 2324 2325 2329 public synchronized void removeDataStatusListener(DataStatusListener l) 2330 { 2331 if (m_dataStatusListeners != null && m_dataStatusListeners.contains(l)) 2332 { 2333 Vector v = (Vector) m_dataStatusListeners.clone(); 2334 v.removeElement(l); 2335 m_dataStatusListeners = v; 2336 } 2337 } 2339 2343 public synchronized void addDataStatusListener(DataStatusListener l) 2344 { 2345 Vector v = m_dataStatusListeners == null ? new Vector(2) : (Vector) m_dataStatusListeners.clone(); 2346 if (!v.contains(l)) 2347 { 2348 v.addElement(l); 2349 m_dataStatusListeners = v; 2350 } 2351 } 2353 2357 private void fireDataStatusChanged (DataStatusEvent e) 2358 { 2359 if (m_dataStatusListeners != null) 2360 { 2361 Vector listeners = m_dataStatusListeners; 2362 int count = listeners.size(); 2363 for (int i = 0; i < count; i++) 2364 ((DataStatusListener) listeners.elementAt(i)).dataStatusChanged(e); 2365 } 2366 } 2368 2372 private DataStatusEvent createDSE() 2373 { 2374 boolean changed = m_changed; 2375 if (m_rowChanged != -1) 2376 changed = true; 2377 DataStatusEvent dse = new DataStatusEvent(this, m_rowCount, changed, 2378 Env.isAutoCommit(m_ctx, m_WindowNo), m_inserting); 2379 return dse; 2380 } 2382 2386 protected void fireDataStatusIEvent (String AD_Message) 2387 { 2388 DataStatusEvent e = createDSE(); 2389 e.setInfo(AD_Message, "", false); 2390 fireDataStatusChanged (e); 2391 } 2393 2398 protected void fireDataStatusEEvent (String AD_Message, String info) 2399 { 2400 DataStatusEvent e = createDSE(); 2403 e.setInfo(AD_Message, info, true); 2404 Log.saveError(AD_Message, info); 2405 fireDataStatusChanged (e); 2406 } 2408 2412 protected void fireDataStatusEEvent (ValueNamePair errorLog) 2413 { 2414 if (errorLog != null) 2415 fireDataStatusEEvent (errorLog.getValue(), errorLog.getName()); 2416 } 2418 2419 2420 2424 public synchronized void removeVetoableChangeListener(VetoableChangeListener l) 2425 { 2426 m_vetoableChangeSupport.removeVetoableChangeListener(l); 2427 } 2429 2433 public synchronized void addVetoableChangeListener(VetoableChangeListener l) 2434 { 2435 m_vetoableChangeSupport.addVetoableChangeListener(l); 2436 } 2438 2443 protected void fireVetoableChange(PropertyChangeEvent e) throws java.beans.PropertyVetoException 2444 { 2445 m_vetoableChangeSupport.fireVetoableChange(e); 2446 } 2448 2452 public String toString() 2453 { 2454 return new StringBuffer ("MTable[").append(m_tableName) 2455 .append(",WindowNo=").append(m_WindowNo) 2456 .append(",Tab=").append(m_TabNo).append("]").toString(); 2457 } 2459 2460 2461 2462 2465 class Loader extends Thread implements Serializable 2466 { 2467 2470 public Loader() 2471 { 2472 super("TLoader"); 2473 } 2475 private PreparedStatement m_pstmt = null; 2476 private ResultSet m_rs = null; 2477 2478 2482 private int open() 2483 { 2484 int rows = 0; 2487 try 2488 { 2489 PreparedStatement pstmt = DB.prepareStatement(m_SQL_Count); 2490 setParameter (pstmt, true); 2491 ResultSet rs = pstmt.executeQuery(); 2492 if (rs.next()) 2493 rows = rs.getInt(1); 2494 rs.close(); 2495 pstmt.close(); 2496 } 2497 catch (SQLException e0) 2498 { 2499 if (e0.getErrorCode() == 904) log.warn("Loader.open Count - " + e0.getLocalizedMessage() + "\nSQL=" + m_SQL_Count); 2502 else 2503 log.error ("Loader.open Count SQL=" + m_SQL_Count, e0); 2504 return 0; 2505 } 2506 2507 try 2509 { 2510 m_pstmt = DB.prepareStatement(m_SQL); 2511 setParameter (m_pstmt, false); 2513 m_rs = m_pstmt.executeQuery(); 2514 } 2515 catch (SQLException e) 2516 { 2517 log.error ("Loader.open\nFull SQL=" + m_SQL, e); 2518 return 0; 2519 } 2520 StringBuffer info = new StringBuffer ("Rows="); 2521 info.append(rows); 2522 if (rows == 0) 2523 info.append(" - ").append(m_SQL_Count); 2524 log.debug("Loader.open - " + info.toString()); 2525 return rows; 2526 } 2528 2531 private void close() 2532 { 2533 try 2535 { 2536 if (m_rs != null) 2537 m_rs.close(); 2538 if (m_pstmt != null) 2539 m_pstmt.close(); 2540 } 2541 catch (SQLException e) 2542 { 2543 log.error ("Loader.closeRS", e); 2544 } 2545 m_rs = null; 2546 m_pstmt = null; 2547 } 2549 2552 public void run() 2553 { 2554 log.info("Loader.run"); 2555 if (m_rs == null) 2556 return; 2557 2558 try 2559 { 2560 while(m_rs.next()) 2561 { 2562 if (this.isInterrupted()) 2563 { 2564 log.debug("Loader interrupted"); 2565 close(); 2566 return; 2567 } 2568 Object [] rowData = readData(m_rs); 2570 MSort sort = new MSort(m_buffer.size(), null); m_buffer.add(rowData); 2573 m_sort.add(sort); 2574 2575 if (m_buffer.size() % 250 == 0) 2577 { 2578 try 2580 { 2581 yield(); 2582 sleep(10); } 2584 catch (InterruptedException ie) 2585 { 2586 log.debug("Loader interrupted while sleeping"); 2587 close(); 2588 return; 2589 } 2590 DataStatusEvent evt = createDSE(); 2591 evt.setLoading(m_buffer.size()); 2592 fireDataStatusChanged(evt); 2593 } 2594 } } 2596 catch (SQLException e) 2597 { 2598 log.error ("Loader.run", e); 2599 } 2600 close(); 2601 fireDataStatusIEvent(""); 2602 } 2604 2610 private void setParameter (PreparedStatement pstmt, boolean countSQL) 2611 { 2612 if (m_parameterSELECT.size() == 0 && m_parameterWHERE.size() == 0) 2613 return; 2614 try 2615 { 2616 int pos = 1; for (int i = 0; !countSQL && i < m_parameterSELECT.size(); i++) 2619 { 2620 Object para = m_parameterSELECT.get(i); 2621 if (para != null) 2622 log.debug("setParameter Select " + i + "=" + para); 2623 if (para == null) 2625 ; 2626 else if (para instanceof Integer ) 2627 { 2628 Integer ii = (Integer )para; 2629 pstmt.setInt (pos++, ii.intValue()); 2630 } 2631 else if (para instanceof BigDecimal) 2632 pstmt.setBigDecimal (pos++, (BigDecimal)para); 2633 else 2634 pstmt.setString(pos++, para.toString()); 2635 } 2636 for (int i = 0; i < m_parameterWHERE.size(); i++) 2638 { 2639 Object para = m_parameterWHERE.get(i); 2640 if (para != null) 2641 log.debug("setParameter Where " + i + "=" + para); 2642 if (para == null) 2644 ; 2645 else if (para instanceof Integer ) 2646 { 2647 Integer ii = (Integer )para; 2648 pstmt.setInt (pos++, ii.intValue()); 2649 } 2650 else if (para instanceof BigDecimal) 2651 pstmt.setBigDecimal (pos++, (BigDecimal)para); 2652 else 2653 pstmt.setString(pos++, para.toString()); 2654 } 2655 } 2656 catch (SQLException e) 2657 { 2658 log.error("Loader.setParameter", e); 2659 } 2660 } 2662 } 2664} | Popular Tags |