📄 mtable.java
字号:
Object[] rowData = (Object[])m_buffer.get(sort.index);
m_rowChanged = row;
// Selection
if (col == 0)
{
rowData[col] = value;
m_buffer.set(sort.index, rowData);
return;
}
// save original value - deep copy
if (m_rowData == null)
{
int size = m_fields.size();
m_rowData = new Object[size];
for (int i = 0; i < size; i++)
m_rowData[i] = rowData[i];
}
// save & update
rowData[col] = value;
m_buffer.set(sort.index, rowData);
// update Table
fireTableCellUpdated(row, col);
// update MField
getField(col).setValue(value, m_inserting);
// inform
DataStatusEvent evt = createDSE();
evt.setChangedColumn(col);
fireDataStatusChanged(evt);
} // setValueAt
/**
* Get Old Value
* @param row row
* @param col col
* @return old value
*/
public Object getOldValue (int row, int col)
{
if (m_oldValue == null)
return null;
if (((Integer)m_oldValue[0]).intValue() == row
&& ((Integer)m_oldValue[1]).intValue() == col)
return m_oldValue[2];
return null;
} // getOldValue
/**
* Check if the current row needs to be saved.
* @param onlyRealChange if true the value of a field was actually changed
* (e.g. for new records, which have not been changed) - default false
* @return true it needs to be saved
*/
public boolean needSave(boolean onlyRealChange)
{
return needSave(m_rowChanged, onlyRealChange);
} // needSave
/**
* Check if the row needs to be saved.
* - only if nothing was changed
* @return true it needs to be saved
*/
public boolean needSave()
{
return needSave(m_rowChanged, false);
} // needSave
/**
* Check if the row needs to be saved.
* - only when row changed
* - only if nothing was changed
* @param newRow to check
* @return true it needs to be saved
*/
public boolean needSave(int newRow)
{
return needSave(newRow, false);
} // needSave
/**
* Check if the row needs to be saved.
* - only when row changed
* - only if nothing was changed
* @param newRow to check
* @param onlyRealChange if true the value of a field was actually changed
* (e.g. for new records, which have not been changed) - default false
* @return true it needs to be saved
*/
public boolean needSave(int newRow, boolean onlyRealChange)
{
Log.trace(Log.l4_Data, "MTable.needSave - Row=" + newRow,
"Changed=" + m_rowChanged + " " + m_changed); // m_rowChanged set in setValueAt
// nothing done
if (!m_changed && m_rowChanged == -1)
return false;
// E.g. New unchanged records
if (m_changed && m_rowChanged == -1 && onlyRealChange)
return false;
// same row
if (newRow == m_rowChanged)
return false;
return true;
} // dataSave
/*************************************************************************/
public static final char SAVE_OK = 'O'; // the only OK condition
public static final char SAVE_ERROR = 'E';
public static final char SAVE_ACCESS = 'A';
public static final char SAVE_MANDATORY = 'M';
public static final char SAVE_ABORT = 'U';
/**
* Check if it needs to be saved and save it.
* @param newRow row
* @param manualCmd manual command to save
* @return true if not needed to be saved or successful saved
*/
public boolean dataSave (int newRow, boolean manualCmd)
{
Log.trace(Log.l4_Data, "MTable.dataSave Row=" + newRow,
"Changed=" + m_rowChanged + " " + m_changed); // m_rowChanged set in setValueAt
// nothing done
if (!m_changed && m_rowChanged == -1)
return true;
// same row, don't save yet
if (newRow == m_rowChanged)
return true;
return (dataSave(manualCmd) == SAVE_OK);
} // dataSave
/**
* Save unconditional.
* @param manualCmd if true, no vetoable PropertyChange will be fired for save confirmation
* @return OK Or Error condition
* Error info (Access*, FillMandatory, SaveErrorNotUnique,
* SaveErrorRowNotFound, SaveErrorDataChanged) is saved in the log
*/
public char dataSave (boolean manualCmd)
{
// cannot save
if (!m_open)
{
Log.trace(Log.l4_Data, "MTable.dataSave Error", "Open=" + m_open);
return SAVE_ERROR;
}
// no need - not changed - row not positioned - no Value changed
if (m_rowChanged == -1)
{
Log.trace(Log.l4_Data, "MTable.dataSave NoNeed", "Changed=" + m_changed + ", Row=" + m_rowChanged);
// return SAVE_ERROR;
if (!manualCmd)
return SAVE_OK;
}
// Value not changed
if (m_rowData == null)
{
Log.trace(Log.l4_Data, "MTable.dataSave Error", "DataNull=" + (m_rowData == null));
return SAVE_ERROR;
}
Log.trace(Log.l4_Data, "MTable.dataSave", "Saving row " + m_rowChanged);
if (m_readOnly)
/** @todo save changes when processed */
// If Processed - not editable (Find always editable) -> ok for changing payment terms, etc.
{
Log.trace(Log.l4_Data, "IsReadOnly - ignored");
dataIgnore();
return SAVE_ACCESS;
}
// Can we change?
if (!Access.canUpdate(m_ctx, m_WindowNo))
{
fireDataStatusEEvent(Log.retrieveError());
dataIgnore();
return SAVE_ACCESS;
}
// row not positioned - no Value changed
if (m_rowChanged == -1)
{
if (m_newRow != -1) // new row and nothing changed - might be OK
m_rowChanged = m_newRow;
else
{
fireDataStatusEEvent("SaveErrorNoChange", "");
return SAVE_ERROR;
}
}
// inform about data save action, if not manually initiated
try
{
if (!manualCmd)
m_vetoableChangeSupport.fireVetoableChange(PROPERTY, 0, m_rowChanged);
}
catch (PropertyVetoException pve)
{
Log.trace(Log.l5_DData, pve.getMessage());
dataIgnore();
return SAVE_ABORT;
}
// get updated row data
MSort sort = (MSort)m_sort.get(m_rowChanged);
Object[] rowData = (Object[])m_buffer.get(sort.index);
// Check Mandatory
String missingColumns = getMandatory(rowData);
if (missingColumns.length() != 0)
{
fireDataStatusEEvent("FillMandatory", missingColumns);
return SAVE_MANDATORY;
}
/**
* Update row
*/
boolean error = false;
//
String is;
final String ERROR = "ERROR: ";
final String INFO = "Info: ";
// SQL with specific where clause
String SQL = m_SQL_Select;
StringBuffer refreshSQL = new StringBuffer(SQL).append(" WHERE "); // to be completed when key known
StringBuffer multiRowWHERE = new StringBuffer();
// Create SQL & RowID
Object rowID = null;
if (m_inserting)
SQL += " WHERE 1=2";
else
{
// FOR UPDATE causes - ORA-01002 fetch out of sequence
SQL += " WHERE ROWID=?";
rowID = getRowID (m_rowChanged);
}
try
{
PreparedStatement pstmt = DB.prepareStatement (SQL,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
if (!m_inserting)
DB.getDatabase().setRowID(pstmt, 1, rowID);
ResultSet rs = pstmt.executeQuery();
// only one row
if (!(m_inserting || rs.next()))
{
rs.close();
pstmt.close();
fireDataStatusEEvent("SaveErrorRowNotFound", "");
dataRefresh(m_rowChanged);
return SAVE_ERROR;
}
Object[] rowDataDB = null;
// Prepare
if (m_inserting)
{
Log.trace(Log.l4_Data, "start inserting ...");
rs.moveToInsertRow();
}
else
// get current Data in DB
rowDataDB = readData(rs);
/** Data:
* m_rowData = original Data
* rowData = updated Data
* rowDataDB = current Data in DB
* 1) Difference between original & updated Data? N:next
* 2) Difference between original & current Data? Y:don't update
* 3) Update current Data
* 4) Refresh to get last Data (changed by trigger, ...)
*/
// Constants for Created/Updated(By)
Timestamp now = new Timestamp(System.currentTimeMillis());
int user = Env.getContextAsInt(m_ctx, "#AD_User_ID");
/**
* for every column
*/
int size = m_fields.size();
for (int col = 0; col < size; col++)
{
MField field = (MField)m_fields.get(col);
// Log.trace(Log.l6_Database, field.getColumnName() + "= " + m_rowData[col] + " <> DB: " + rowDataDB[col] + " -> " + rowData[col]);
String columnName = field.getColumnName();
// RowID
if (field.getDisplayType() == DisplayType.RowID)
; // ignore
// New Key
else if (m_inserting && field.isKey())
{
if (columnName.endsWith("_ID"))
{
int insertID = DB.getKeyNextNo(m_ctx, m_WindowNo, m_tableName);
rs.updateInt(col+1, insertID); // ***
refreshSQL.append(columnName).append("=").append(insertID);
//
is = INFO + columnName + " -> " + insertID;
}
else // Key with String value
{
rs.updateString(col+1, rowData[col].toString()); // ***
refreshSQL.append(columnName).append("='").append(rowData[col]).append("'");
//
is = INFO + columnName + " -> " + rowData[col].toString();
}
Log.trace(Log.l5_DData, is);
} // New Key
// New DocumentNo
else if (columnName.equals("DocumentNo"))
{
boolean newDocNo = false;
String docNo = (String)rowData[col];
// we need to have a doc number
if (docNo == null || docNo.length() == 0)
newDocNo = true;
// Preliminary ID from CalloutSystem
else if (docNo.startsWith("<") && docNo.endsWith(">"))
newDocNo = true;
if (newDocNo || m_inserting)
{
String insertDoc = null;
// always overwrite if insering with mandatory DocType DocNo
if (m_inserting)
insertDoc = DB.getDocumentNo(m_ctx, m_WindowNo, m_tableName, true);
Log.trace(Log.l6_Database, "MTable.dataSave", "DocumentNo entered=" + docNo
+ ", DocTypeInsert=" + insertDoc + ", newDocNo=" + newDocNo);
// can we use entered DocNo?
if (insertDoc == null || insertDoc.length() == 0)
{
if (!newDocNo && docNo != null && docNo.length() > 0)
insertDoc = docNo;
else // get a number from DocType or Table
insertDoc = DB.getDocumentNo(m_ctx, m_WindowNo, m_tableName, false);
}
// There might not be an automatic document no for this document
if (insertDoc == null || insertDoc.length() == 0)
{
// in case DB function did not return a value
if (docNo != null && docNo.length() != 0)
insertDoc = (String)rowData[col];
else
{
error = true;
is = ERROR + field.getColumnName() + "= " + rowData[col]
+ " NO DocumentNo";
Log.trace(Log.l5_DData, is);
break;
}
}
//
rs.updateString(col+1, insertDoc); // ***
//
is = INFO + columnName + " -> " + insertDoc;
Log.trace(Log.l5_DData, is);
}
} // New DocumentNo
// New Value
else if (columnName.equals("Value") && m_inserting)
{
String value = (String)rowData[col];
// Get from Sequence, if not entered
if (value == null || value.length() == 0)
{
value = DB.getDocumentNo(m_ctx, m_WindowNo, m_tableName, false);
// No DocumentNo
if (value == null || value.length() == 0)
{
error = true;
is = ERROR + field.getColumnName() + "= " + rowData[col]
+ " No DocumentNo";
Log.trace(Log.l5_DData, is);
break;
}
}
rs.updateString(col+1, value); // ***
//
is = INFO + columnName + " -> " + value;
Log.trace(Log.l5_DData, is);
}
// Updated - check database
else if (columnName.equals("Updated"))
{
if (!m_inserting && !m_rowData[col].equals(rowDataDB[col])) // changed
{
error = true;
is = ERROR + field.getColumnName() + "= " + m_rowData[col]
+ " != DB: " + rowDataDB[col];
Log.trace(Log.l5_DData, is);
break;
}
rs.updateTimestamp(col+1, now); // ***
//
is = INFO + "Updated/By -> " + now + " " + user;
Log.trace(Log.l5_DData, is);
} // Updated
// UpdatedBy - update
else if (columnName.equals("UpdatedBy"))
{
rs.updateInt(col+1, user); // ***
} // UpdatedBy
// Created
else if (m_inserting && columnName.equals("Created"))
{
rs.updateTimestamp(col+1, now); // ***
} // Created
// CreatedBy
else if (m_inserting && columnName.equals("CreatedBy"))
{
rs.updateInt(col+1, user); // ***
} // CreatedBy
// Nothing changed & null
else if (m_rowData[col] == null && rowData[col] == null)
{
if (m_inserting)
{
rs.updateNull(col+1); // ***
is = INFO + columnName + "= NULL";
Log.trace(Log.l5_DData, is);
}
}
// Data changed
else if (m_inserting
|| (m_rowData[col] == null && rowData[col] != null)
|| (m_rowData[col] != null && rowData[col] == null)
|| !m_rowData[col].equals(rowData[col])) // changed
{
// Original == DB
if (m_inserting
|| (m_rowData[col] == null && rowDataDB[col] == null)
|| (m_rowData[col] != null && m_rowData[col].equals(rowDataDB[col])) )
{
String type = "String";
if (rowData[col] == null)
rs.updateNull(col+1); // ***
else
{
if (DisplayType.isNumeric(field.getDisplayType()))
{
rs.updateBigDecimal(col+1, (BigDecimal)rowData[col]); // ***
type = "Number";
}
else if (DisplayType.isID(field.getDisplayType()))
{
int number = 0;
try
{
number = Integer.parseInt(rowData[col].toString());
rs.updateInt(col+1, number);
}
catch (Exception e) // could also be a String (AD_Language, AD_Message)
{
rs.updateString(col+1, rowData[col].toString());
}
type = "ID";
}
else if (DisplayType.isDate(field.getDisplayType()))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -