IDEMPIERE-5567 Support of UUID as Key (FHCA-4195) (#1976)

- Fix 2Pack to work with UUID based tables
- Implement ability for PackOut/PackIn multi ID columns
This commit is contained in:
Carlos Ruiz 2023-08-26 03:49:39 +02:00 committed by GitHub
parent c1d8a50b12
commit 954b3b2fec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 391 additions and 140 deletions

View File

@ -1152,7 +1152,7 @@ public class GridField
} }
if (allValid) if (allValid)
return true; return true;
} else if (getDisplayType() == DisplayType.ChosenMultipleSelectionTable || getDisplayType() == DisplayType.ChosenMultipleSelectionSearch) { } else if (DisplayType.isMultiID(getDisplayType())) {
boolean allValid = true; boolean allValid = true;
for (String vals : ((String)m_value).split(",")) { for (String vals : ((String)m_value).split(",")) {
Integer vali = Integer.valueOf(vals); Integer vali = Integer.valueOf(vals);

View File

@ -792,7 +792,9 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
if (foreignTableMulti != null) if (foreignTableMulti != null)
return foreignTableMulti; return foreignTableMulti;
int refid = getAD_Reference_ID(); int refid = getAD_Reference_ID();
if (DisplayType.ChosenMultipleSelectionTable == refid || DisplayType.ChosenMultipleSelectionSearch == refid) { if (DisplayType.ChosenMultipleSelectionList == refid) {
foreignTableMulti = "AD_Ref_List";
} else if (DisplayType.ChosenMultipleSelectionTable == refid || DisplayType.ChosenMultipleSelectionSearch == refid) {
foreignTableMulti = DB.getSQLValueStringEx(get_TrxName(), sqlTableNameReference, getAD_Column_ID()); foreignTableMulti = DB.getSQLValueStringEx(get_TrxName(), sqlTableNameReference, getAD_Column_ID());
} else if (DisplayType.SingleSelectionGrid == refid || DisplayType.MultipleSelectionGrid == refid) { } else if (DisplayType.SingleSelectionGrid == refid || DisplayType.MultipleSelectionGrid == refid) {
foreignTableMulti = DB.getSQLValueStringEx(get_TrxName(), sqlTableNameSelectionGrid, getAD_Column_ID()); foreignTableMulti = DB.getSQLValueStringEx(get_TrxName(), sqlTableNameSelectionGrid, getAD_Column_ID());

View File

@ -548,7 +548,9 @@ public final class DisplayType
|| displayType == RadiogroupList || displayType == RadiogroupList
|| displayType == ChosenMultipleSelectionTable || displayType == ChosenMultipleSelectionTable
|| displayType == ChosenMultipleSelectionSearch || displayType == ChosenMultipleSelectionSearch
|| displayType == ChosenMultipleSelectionList) || displayType == ChosenMultipleSelectionList
|| displayType == SingleSelectionGrid
|| displayType == MultipleSelectionGrid)
return true; return true;
//not custom type, don't have to check factory //not custom type, don't have to check factory
@ -638,11 +640,22 @@ public final class DisplayType
*/ */
public static boolean isChosenMultipleSelection(int displayType) public static boolean isChosenMultipleSelection(int displayType)
{ {
if (displayType == ChosenMultipleSelectionList || displayType == ChosenMultipleSelectionSearch return ( displayType == ChosenMultipleSelectionList
|| displayType == ChosenMultipleSelectionTable) || displayType == ChosenMultipleSelectionSearch
return true; || displayType == ChosenMultipleSelectionTable);
else }
return false;
/**
*
* @param displayType
* @return true if displayType is a multi ID string separated by commas
*/
public static boolean isMultiID(int displayType)
{
return ( displayType == ChosenMultipleSelectionSearch
|| displayType == ChosenMultipleSelectionTable
|| displayType == SingleSelectionGrid
|| displayType == MultipleSelectionGrid);
} }
/************************************************************************** /**************************************************************************

View File

@ -907,10 +907,7 @@ public class MoveClient extends SvrProcess {
String convertTable = column.getReferenceTableName(); String convertTable = column.getReferenceTableName();
if ((tableName + "_ID").equalsIgnoreCase(columnName)) { if ((tableName + "_ID").equalsIgnoreCase(columnName)) {
convertTable = tableName; convertTable = tableName;
} else if ( column.getAD_Reference_ID() == DisplayType.ChosenMultipleSelectionTable } else if (DisplayType.isMultiID(column.getAD_Reference_ID())) {
|| column.getAD_Reference_ID() == DisplayType.ChosenMultipleSelectionSearch
|| column.getAD_Reference_ID() == DisplayType.SingleSelectionGrid
|| column.getAD_Reference_ID() == DisplayType.MultipleSelectionGrid) {
convertTable = column.getMultiReferenceTableName(); convertTable = column.getMultiReferenceTableName();
} else if (convertTable != null } else if (convertTable != null
&& ("AD_Ref_List".equalsIgnoreCase(convertTable) && ("AD_Ref_List".equalsIgnoreCase(convertTable)

View File

@ -173,7 +173,7 @@ public class GenericPOElementHandler extends AbstractElementHandler {
if (createElement) { if (createElement) {
// //
if (po.get_KeyColumns() != null && po.get_KeyColumns().length == 1 && po.get_ID() > 0 if (po.get_KeyColumns() != null && po.get_KeyColumns().length == 1 && (po.get_ID() > 0 || po.get_UUID() != null)
&& ! IHandlerRegistry.TABLE_GENERIC_SINGLE_HANDLER.equals(ctx.packOut.getCurrentPackoutItem().getType())) { && ! IHandlerRegistry.TABLE_GENERIC_SINGLE_HANDLER.equals(ctx.packOut.getCurrentPackoutItem().getType())) {
ElementHandler handler = ctx.packOut.getHandler(po.get_TableName()); ElementHandler handler = ctx.packOut.getHandler(po.get_TableName());
if (handler != null && !handler.getClass().equals(this.getClass()) ) { if (handler != null && !handler.getClass().equals(this.getClass()) ) {
@ -220,13 +220,22 @@ public class GenericPOElementHandler extends AbstractElementHandler {
private void exportDetail(PIPOContext ctx, TransformerHandler document, GenericPO parent, String[] tables) { private void exportDetail(PIPOContext ctx, TransformerHandler document, GenericPO parent, String[] tables) {
String mainTable = tables[0]; String mainTable = tables[0];
AttributesImpl atts = new AttributesImpl(); AttributesImpl atts = new AttributesImpl();
String sql = "SELECT * FROM " + mainTable + " WHERE " + parent.get_TableName() + "_ID = ?"; String keyColumn;
MTable table = MTable.get(ctx.ctx, parent.get_TableName());
if (table.isUUIDKeyTable())
keyColumn = PO.getUUIDColumnName(parent.get_TableName());
else
keyColumn = parent.get_TableName() + "_ID";
String sql = "SELECT * FROM " + mainTable + " WHERE " + keyColumn + " = ?";
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
sql = MRole.getDefault().addAccessSQL(sql, mainTable, true, true); sql = MRole.getDefault().addAccessSQL(sql, mainTable, true, true);
pstmt = DB.prepareStatement(sql, null); pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, parent.get_ID()); if (table.isUUIDKeyTable())
pstmt.setString(1, parent.get_UUID());
else
pstmt.setInt(1, parent.get_ID());
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
while (rs.next()) { while (rs.next()) {
GenericPO po = new GenericPO(mainTable, ctx.ctx, rs, getTrxName(ctx)); GenericPO po = new GenericPO(mainTable, ctx.ctx, rs, getTrxName(ctx));

View File

@ -58,7 +58,7 @@ public class IndexColumnElementHandler extends AbstractElementHandler {
parentId = getParentId(element, MTableIndex.Table_Name); parentId = getParentId(element, MTableIndex.Table_Name);
} else { } else {
Element pfElement = element.properties.get(MIndexColumn.COLUMNNAME_AD_TableIndex_ID); Element pfElement = element.properties.get(MIndexColumn.COLUMNNAME_AD_TableIndex_ID);
parentId = ReferenceUtils.resolveReference(ctx.ctx, pfElement, getTrxName(ctx)); parentId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, pfElement, getTrxName(ctx));
} }
if (parentId <= 0) { if (parentId <= 0) {
element.defer = true; element.defer = true;
@ -80,7 +80,7 @@ public class IndexColumnElementHandler extends AbstractElementHandler {
int columnId = 0; int columnId = 0;
Element columnElement = element.properties.get("AD_Column_ID"); Element columnElement = element.properties.get("AD_Column_ID");
if (ReferenceUtils.isIDLookup(columnElement) || ReferenceUtils.isUUIDLookup(columnElement)) { if (ReferenceUtils.isIDLookup(columnElement) || ReferenceUtils.isUUIDLookup(columnElement)) {
columnId = ReferenceUtils.resolveReference(ctx.ctx, columnElement, getTrxName(ctx)); columnId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, columnElement, getTrxName(ctx));
} }
if (columnId > 0) if (columnId > 0)
mIndexColumn.setAD_Column_ID(columnId); mIndexColumn.setAD_Column_ID(columnId);

View File

@ -103,7 +103,7 @@ public class MenuElementHandler extends AbstractElementHandler {
Element parentElement = element.properties.get("Parent_ID"); Element parentElement = element.properties.get("Parent_ID");
int parentId = 0; int parentId = 0;
if (parentElement != null) { if (parentElement != null) {
parentId = ReferenceUtils.resolveReference(ctx.ctx, parentElement, getTrxName(ctx)); parentId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, parentElement, getTrxName(ctx));
} }
String strSeqNo = getStringValue(element, "SeqNo"); String strSeqNo = getStringValue(element, "SeqNo");

View File

@ -65,12 +65,12 @@ public class ReferenceTableElementHandler extends AbstractElementHandler {
return; return;
} }
Element displayElement = element.properties.get("AD_Display"); Element displayElement = element.properties.get("AD_Display");
int displayColumnId = ReferenceUtils.resolveReference(ctx.ctx, displayElement, getTrxName(ctx)); int displayColumnId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, displayElement, getTrxName(ctx));
refTable.setAD_Display(displayColumnId); refTable.setAD_Display(displayColumnId);
Element keyElement = element.properties.get("AD_Key"); Element keyElement = element.properties.get("AD_Key");
int keyColumnId = ReferenceUtils.resolveReference(ctx.ctx, keyElement, getTrxName(ctx)); int keyColumnId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, keyElement, getTrxName(ctx));
refTable.setAD_Key(keyColumnId); refTable.setAD_Key(keyColumnId);
if (refTable.is_new() || refTable.is_Changed()) { if (refTable.is_new() || refTable.is_Changed()) {

View File

@ -58,7 +58,7 @@ public class ViewColumnElementHandler extends AbstractElementHandler {
parentId = getParentId(element, MViewComponent.Table_Name); parentId = getParentId(element, MViewComponent.Table_Name);
} else { } else {
Element pfElement = element.properties.get(MViewColumn.COLUMNNAME_AD_ViewComponent_ID); Element pfElement = element.properties.get(MViewColumn.COLUMNNAME_AD_ViewComponent_ID);
parentId = ReferenceUtils.resolveReference(ctx.ctx, pfElement, getTrxName(ctx)); parentId = ReferenceUtils.resolveReferenceAsInt(ctx.ctx, pfElement, getTrxName(ctx));
} }
if (parentId <= 0) { if (parentId <= 0) {
element.defer = true; element.defer = true;

View File

@ -116,7 +116,7 @@ public class WorkflowElementHandler extends AbstractElementHandler {
if (value != null && value.trim().length() > 0) { if (value != null && value.trim().length() > 0) {
MWorkflow m_Workflow = new MWorkflow(ctx.ctx, element.recordId, getTrxName(ctx)); MWorkflow m_Workflow = new MWorkflow(ctx.ctx, element.recordId, getTrxName(ctx));
PoFiller filler = new PoFiller(ctx, m_Workflow, element, this); PoFiller filler = new PoFiller(ctx, m_Workflow, element, this);
int id = filler.setTableReference("AD_WF_Node_ID"); int id = ((Number)filler.setTableReference("AD_WF_Node_ID")).intValue();
if (id <= 0) { if (id <= 0) {
log.warning("Failed to resolve start node reference for workflow element. Workflow=" log.warning("Failed to resolve start node reference for workflow element. Workflow="
+ m_Workflow.getName() + " StartNode=" + value); + m_Workflow.getName() + " StartNode=" + value);

View File

@ -141,7 +141,7 @@ public abstract class AbstractElementHandler implements ElementHandler {
public void backupRecord(PIPOContext ctx, int AD_Package_Imp_Detail_ID, String tableName,PO from){ public void backupRecord(PIPOContext ctx, int AD_Package_Imp_Detail_ID, String tableName,PO from){
// Create new record // Create new record
MTable mTable = MTable.get(ctx.ctx, tableName); MTable mTable = MTable.get(ctx.ctx, tableName, getTrxName(ctx));
int tableID = mTable.getAD_Table_ID(); int tableID = mTable.getAD_Table_ID();
POInfo poInfo = POInfo.getPOInfo(ctx.ctx, tableID); POInfo poInfo = POInfo.getPOInfo(ctx.ctx, tableID);

View File

@ -32,6 +32,7 @@ import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.compiere.model.MColumn; import org.compiere.model.MColumn;
import org.compiere.model.MTable; import org.compiere.model.MTable;
import org.compiere.model.PO;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
@ -46,7 +47,7 @@ public class IDFinder {
private static final CLogger log = CLogger.getCLogger(IDFinder.class); private static final CLogger log = CLogger.getCLogger(IDFinder.class);
private static Map<String, Integer>idCache = new ConcurrentHashMap<String, Integer>(); private static Map<String, Object>idCache = new ConcurrentHashMap<String, Object>();
/** /**
* Get ID from column value for a table. * Get ID from column value for a table.
@ -58,11 +59,9 @@ public class IDFinder {
* @param trxName * @param trxName
* @return * @return
*/ */
public static int findIdByColumn (String tableName, String columnName, Object value, int AD_Client_ID, boolean ignorecase, String trxName) { public static Object findIdByColumn (String tableName, String columnName, Object value, int AD_Client_ID, boolean ignorecase, String trxName) {
if (value == null) if (value == null)
return 0; return null;
int id = -1;
//construct cache key //construct cache key
StringBuilder key = new StringBuilder(); StringBuilder key = new StringBuilder();
@ -77,9 +76,18 @@ public class IDFinder {
if (idCache.containsKey(key.toString())) if (idCache.containsKey(key.toString()))
return idCache.get(key.toString()); return idCache.get(key.toString());
Object id = null;
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
String keycol;
if (table.isUUIDKeyTable())
keycol = PO.getUUIDColumnName(tableName);
else
keycol = tableName + "_ID";
StringBuilder sqlB = new StringBuilder ("SELECT ") StringBuilder sqlB = new StringBuilder ("SELECT ")
.append(tableName) .append(keycol)
.append("_ID FROM ") .append(" FROM ")
.append(tableName) .append(tableName)
.append(" WHERE ") .append(" WHERE ")
.append(" AD_Client_ID IN (0, ?) AND "); .append(" AD_Client_ID IN (0, ?) AND ");
@ -124,11 +132,9 @@ public class IDFinder {
columns = new String[]{columnName}; columns = new String[]{columnName};
} }
sqlB.append(" Order By AD_Client_ID Desc, ") sqlB.append(" ORDER BY AD_Client_ID DESC, ")
.append(tableName) .append(keycol);
.append("_ID");
MTable table = MTable.get(Env.getCtx(), tableName);
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
@ -159,8 +165,12 @@ public class IDFinder {
} }
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next()) {
id = rs.getInt(1); if (table.isUUIDKeyTable())
id = rs.getString(1);
else
id = rs.getInt(1);
}
} }
catch (Exception e) { catch (Exception e) {
throw new DatabaseAccessException(e); throw new DatabaseAccessException(e);
@ -169,13 +179,13 @@ public class IDFinder {
} }
//update cache //update cache
if (id >= 0) if (id != null)
idCache.put(key.toString(), id); idCache.put(key.toString(), id);
return id; return id;
} }
public static int findIdByColumn(String tableName, String columnName, Object value, int clientId, String trxName) { public static Object findIdByColumn(String tableName, String columnName, Object value, int clientId, String trxName) {
return findIdByColumn(tableName, columnName, value, clientId, false, trxName); return findIdByColumn(tableName, columnName, value, clientId, false, trxName);
} }
@ -188,8 +198,7 @@ public class IDFinder {
* @param nameMaster * @param nameMaster
* @param trxName * @param trxName
*/ */
public static int findIdByNameAndParentName (String tableName, String name, String tableNameMaster, String nameMaster, int AD_Client_ID, String trxName) { public static Object findIdByNameAndParentName (String tableName, String name, String tableNameMaster, String nameMaster, int AD_Client_ID, String trxName) {
int id = 0;
//construct cache key //construct cache key
StringBuilder key = new StringBuilder(); StringBuilder key = new StringBuilder();
key.append(tableName) key.append(tableName)
@ -204,22 +213,35 @@ public class IDFinder {
if (idCache.containsKey(key.toString())) if (idCache.containsKey(key.toString()))
return idCache.get(key.toString()); return idCache.get(key.toString());
Object id = null;
MTable tableMaster = MTable.get(Env.getCtx(), tableNameMaster, trxName);
String keycolMaster;
if (tableMaster.isUUIDKeyTable())
keycolMaster = PO.getUUIDColumnName(tableNameMaster);
else
keycolMaster = tableNameMaster + "_ID";
StringBuilder parentSql = new StringBuilder("SELECT ") StringBuilder parentSql = new StringBuilder("SELECT ")
.append(tableNameMaster) .append(keycolMaster)
.append("_ID FROM ") .append(" FROM ")
.append(tableNameMaster) .append(tableNameMaster)
.append(" WHERE Name = ? AND AD_Client_ID IN (0, ?) ") .append(" WHERE Name = ? AND AD_Client_ID IN (0, ?) ")
.append("ORDER BY AD_Client_ID Desc"); .append("ORDER BY AD_Client_ID Desc");
int parentId = DB.getSQLValue(trxName, parentSql.toString(), name, Env.getAD_Client_ID(Env.getCtx())); Object parentId = DB.getSQLValueEx(trxName, parentSql.toString(), name, Env.getAD_Client_ID(Env.getCtx()));
if (parentId > 0) { if (parentId != null) {
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
String keycol;
if (table.isUUIDKeyTable())
keycol = PO.getUUIDColumnName(tableName);
else
keycol = tableNameMaster + "_ID";
StringBuilder sqlB = new StringBuilder ("SELECT ") StringBuilder sqlB = new StringBuilder ("SELECT ")
.append(tableName) .append(keycol)
.append("_ID FROM ") .append(" FROM ")
.append(tableName) .append(tableName)
.append(" WHERE Name = ? AND ") .append(" WHERE Name = ? AND ")
.append(tableNameMaster) .append(keycol)
.append("_ID = ?"); .append(" = ?");
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
@ -227,7 +249,10 @@ public class IDFinder {
pstmt = DB.prepareStatement(sqlB.toString(), trxName); pstmt = DB.prepareStatement(sqlB.toString(), trxName);
pstmt.setString(1, name); pstmt.setString(1, name);
pstmt.setString(2, nameMaster); pstmt.setString(2, nameMaster);
pstmt.setInt(3, parentId); if (table.isUUIDKeyTable())
pstmt.setString(3, (String)parentId);
else
pstmt.setInt(3, ((Number)parentId).intValue());
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
id = rs.getInt(1); id = rs.getInt(1);
@ -239,7 +264,7 @@ public class IDFinder {
} }
//update cache //update cache
if (id > 0) if (id != null)
idCache.put(key.toString(), id); idCache.put(key.toString(), id);
return id; return id;
@ -257,7 +282,7 @@ public class IDFinder {
* @param trxName * @param trxName
* @return * @return
*/ */
public static int findIdByColumnAndParentId (String tableName, String columnName, String name, String tableNameMaster, int masterID, int AD_Client_ID, String trxName) { public static Object findIdByColumnAndParentId (String tableName, String columnName, String name, String tableNameMaster, Object masterID, int AD_Client_ID, String trxName) {
return findIdByColumnAndParentId(tableName, columnName, name, tableNameMaster, masterID, AD_Client_ID, false, trxName); return findIdByColumnAndParentId(tableName, columnName, name, tableNameMaster, masterID, AD_Client_ID, false, trxName);
} }
@ -271,29 +296,41 @@ public class IDFinder {
* @param trxName * @param trxName
*/ */
public static int findIdByColumnAndParentId (String tableName, String columnName, String name, String tableNameMaster, int masterID, int AD_Client_ID, boolean ignoreCase, String trxName) { public static Object findIdByColumnAndParentId (String tableName, String columnName, String name, String tableNameMaster, Object masterID, int AD_Client_ID, boolean ignoreCase, String trxName) {
int id = 0;
//check cache //check cache
String key = tableName + "." + columnName + "=" + name + tableNameMaster + "=" + masterID; String key = tableName + "." + columnName + "=" + name + tableNameMaster + "=" + masterID;
if (idCache.containsKey(key)) if (idCache.containsKey(key))
return idCache.get(key); return idCache.get(key);
Object id = null;
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
String keycol;
if (table.isUUIDKeyTable())
keycol = PO.getUUIDColumnName(tableName);
else
keycol = tableName + "_ID";
MTable tableMaster = MTable.get(Env.getCtx(), tableNameMaster, trxName);
String keycolMaster;
if (tableMaster.isUUIDKeyTable())
keycolMaster = PO.getUUIDColumnName(tableNameMaster);
else
keycolMaster = tableNameMaster + "_ID";
StringBuilder sqlB = new StringBuilder ("SELECT ") StringBuilder sqlB = new StringBuilder ("SELECT ")
.append(tableName) .append(keycol)
.append("_ID FROM ") .append(" FROM ")
.append(tableName) .append(tableName)
.append(" WHERE "); .append(" WHERE ");
if (ignoreCase) { if (ignoreCase) {
sqlB.append("Upper(") sqlB.append("UPPER(")
.append(columnName) .append(columnName)
.append(") = ? and "); .append(") = ? AND ");
} else { } else {
sqlB.append(columnName) sqlB.append(columnName)
.append(" = ? and "); .append(" = ? AND ");
} }
sqlB.append(tableNameMaster+"_ID = ? AND AD_Client_ID IN (0, ?) ") sqlB.append(keycolMaster+" = ? AND AD_Client_ID IN (0, ?) ")
.append("ORDER BY AD_Client_ID Desc "); .append("ORDER BY AD_Client_ID Desc ");
if (log.isLoggable(Level.INFO)) log.info(sqlB.toString()); if (log.isLoggable(Level.INFO)) log.info(sqlB.toString());
@ -308,12 +345,15 @@ public class IDFinder {
} else { } else {
pstmt.setString(1, name); pstmt.setString(1, name);
} }
pstmt.setInt(2, masterID); if (tableMaster.isUUIDKeyTable())
pstmt.setString(2, (String)masterID);
else
pstmt.setInt(2, ((Number)masterID).intValue());
pstmt.setInt(3, AD_Client_ID); pstmt.setInt(3, AD_Client_ID);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
{ {
id = rs.getInt(1); id = rs.getObject(1);
} }
} }
catch (Exception e) { catch (Exception e) {
@ -323,7 +363,7 @@ public class IDFinder {
} }
//update cache //update cache
if (id > 0) if (id != null)
idCache.put(key, id); idCache.put(key, id);
return id; return id;
@ -338,9 +378,7 @@ public class IDFinder {
* @param masterID * @param masterID
* @param trxName * @param trxName
*/ */
public static int findIdByNameAndParentId (String tableName, String name, String tableNameMaster, int masterID, int AD_Client_ID, String trxName) { public static Object findIdByNameAndParentId (String tableName, String name, String tableNameMaster, Object masterID, int AD_Client_ID, String trxName) {
int id = 0;
//construct cache key //construct cache key
StringBuilder key = new StringBuilder(); StringBuilder key = new StringBuilder();
key.append(tableName) key.append(tableName)
@ -357,25 +395,41 @@ public class IDFinder {
if (idCache.containsKey(key.toString())) if (idCache.containsKey(key.toString()))
return idCache.get(key.toString()); return idCache.get(key.toString());
Object id = null;
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
String keycol;
if (table.isUUIDKeyTable())
keycol = PO.getUUIDColumnName(tableName);
else
keycol = tableName + "_ID";
MTable tableMaster = MTable.get(Env.getCtx(), tableNameMaster, trxName);
String keycolMaster;
if (tableMaster.isUUIDKeyTable())
keycolMaster = PO.getUUIDColumnName(tableNameMaster);
else
keycolMaster = tableNameMaster + "_ID";
StringBuilder sqlB = new StringBuilder ("SELECT ") StringBuilder sqlB = new StringBuilder ("SELECT ")
.append(tableName) .append(keycol)
.append("_ID FROM ") .append(" FROM ")
.append(tableName) .append(tableName)
.append(" WHERE Name=? AND ") .append(" WHERE Name=? AND ")
.append(tableNameMaster) .append(keycolMaster)
.append("_ID=? AND AD_Client_ID IN (0, ?) ") .append("=? AND AD_Client_ID IN (0, ?) ")
.append("ORDER BY AD_Client_ID Desc"); .append("ORDER BY AD_Client_ID DESC");
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
pstmt = DB.prepareStatement(sqlB.toString(), trxName); pstmt = DB.prepareStatement(sqlB.toString(), trxName);
pstmt.setString(1, name); pstmt.setString(1, name);
pstmt.setInt(2, masterID); if (tableMaster.isUUIDKeyTable())
pstmt.setString(2, (String)masterID);
else
pstmt.setInt(2, ((Number)masterID).intValue());
pstmt.setInt(3, AD_Client_ID); pstmt.setInt(3, AD_Client_ID);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
id = rs.getInt(1); id = rs.getObject(1);
} }
catch (Exception e) { catch (Exception e) {
throw new DatabaseAccessException(e); throw new DatabaseAccessException(e);
@ -384,7 +438,7 @@ public class IDFinder {
} }
//update cache //update cache
if (id > 0) if (id != null)
idCache.put(key.toString(), id); idCache.put(key.toString(), id);
return id; return id;
@ -398,9 +452,7 @@ public class IDFinder {
* @param AD_Client_ID * @param AD_Client_ID
* @param trxName * @param trxName
*/ */
public static int findIdByName (String tableName, String name, int AD_Client_ID, String trxName) { public static Object findIdByName (String tableName, String name, int AD_Client_ID, String trxName) {
int id = 0;
//construct cache key //construct cache key
StringBuilder key = new StringBuilder(); StringBuilder key = new StringBuilder();
key.append(tableName) key.append(tableName)
@ -413,13 +465,19 @@ public class IDFinder {
if (idCache.containsKey(key.toString())) if (idCache.containsKey(key.toString()))
return idCache.get(key.toString()); return idCache.get(key.toString());
Object id = null;
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
String keycol;
if (table.isUUIDKeyTable())
keycol = PO.getUUIDColumnName(tableName);
else
keycol = tableName + "_ID";
StringBuilder sql = new StringBuilder("SELECT ") StringBuilder sql = new StringBuilder("SELECT ")
.append(keycol)
.append(" FROM ")
.append(tableName) .append(tableName)
.append("_ID ") .append(" WHERE Name=? ")
.append("FROM ")
.append(tableName)
.append(" ")
.append("WHERE Name=? ")
.append(" AND AD_Client_ID IN (0, ?) ") .append(" AND AD_Client_ID IN (0, ?) ")
.append(" ORDER BY AD_Client_ID Desc"); .append(" ORDER BY AD_Client_ID Desc");
@ -431,7 +489,7 @@ public class IDFinder {
pstmt.setInt(2, AD_Client_ID); pstmt.setInt(2, AD_Client_ID);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
id = rs.getInt(1); id = rs.getObject(1);
} }
catch (Exception e) { catch (Exception e) {
throw new DatabaseAccessException(e); throw new DatabaseAccessException(e);
@ -440,7 +498,7 @@ public class IDFinder {
} }
//update cache //update cache
if (id > 0) if (id != null)
idCache.put(key.toString(), id); idCache.put(key.toString(), id);
return id; return id;

View File

@ -47,7 +47,7 @@ public class POFinder {
int AD_Client_ID = Env.getAD_Client_ID(ctx); int AD_Client_ID = Env.getAD_Client_ID(ctx);
if (AD_Client_ID==0) if (AD_Client_ID==0)
return uuid; return uuid;
MTable table = MTable.get(ctx, tableName); MTable table = MTable.get(ctx, tableName, trxName);
if (table == null) { if (table == null) {
throw new IllegalStateException("getTargetUUID couldn't find table named " + tableName); throw new IllegalStateException("getTargetUUID couldn't find table named " + tableName);
} }
@ -64,7 +64,7 @@ public class POFinder {
*/ */
public static void updateUUIDMap(PIPOContext ctx, String tableName, String uuid, String targetUUID) { public static void updateUUIDMap(PIPOContext ctx, String tableName, String uuid, String targetUUID) {
X_AD_Package_UUID_Map map = new X_AD_Package_UUID_Map(ctx.ctx, 0, ctx.trx.getTrxName()); X_AD_Package_UUID_Map map = new X_AD_Package_UUID_Map(ctx.ctx, 0, ctx.trx.getTrxName());
MTable table = MTable.get(ctx.ctx, tableName); MTable table = MTable.get(ctx.ctx, tableName, ctx.trx.getTrxName());
map.setAD_Table_ID(table.getAD_Table_ID()); map.setAD_Table_ID(table.getAD_Table_ID());
map.setSource_UUID(uuid); map.setSource_UUID(uuid);
map.setTarget_UUID(targetUUID); map.setTarget_UUID(targetUUID);

View File

@ -137,7 +137,7 @@ public class PackRollProcess extends SvrProcess {
DB.close(rs, pstmt); DB.close(rs, pstmt);
} }
// Get Table value // Get Table value
tableName = MTable.getTableName(getCtx(), backup.getAD_Table_ID()); tableName = MTable.get(getCtx(), backup.getAD_Table_ID(), get_TrxName()).getTableName();
// Get Column Name // Get Column Name
// Adjust for Column reference table // Adjust for Column reference table

View File

@ -173,15 +173,40 @@ public class PoExporter {
} }
public void addTableReference(String columnName, String tableName, AttributesImpl atts) { public void addTableReference(String columnName, String tableName, AttributesImpl atts) {
int id = po.get_Value(columnName) != null ? (Integer)po.get_Value(columnName) : -1; if (tableName != null) {
addTableReference(columnName, tableName, id, atts); MTable table = MTable.get(po.getCtx(), tableName, po.get_TrxName());
if (table.isUUIDKeyTable()) {
String uuid = (String)po.get_Value(columnName);
addTableReferenceUUID(columnName, tableName, uuid, atts);
} else {
int id = po.get_Value(columnName) != null ? (Integer)po.get_Value(columnName) : -1;
addTableReference(columnName, tableName, id, atts);
}
}
}
public void addTableReferenceMulti(String columnName, String tableName, AttributesImpl atts) {
if (tableName != null) {
String values = (String)po.get_Value(columnName);
addTableReferenceMulti(columnName, tableName, values, atts);
}
} }
public void addTableReference(String columnName, String tableName, int id, AttributesImpl atts) { public void addTableReference(String columnName, String tableName, int id, AttributesImpl atts) {
String value = ReferenceUtils.getTableReference(tableName, id, atts); String value = ReferenceUtils.getTableReference(tableName, id, atts, po.get_TrxName());
addString(columnName, value, atts); addString(columnName, value, atts);
} }
public void addTableReferenceUUID(String columnName, String tableName, String uuid, AttributesImpl atts) {
String value = ReferenceUtils.getTableReferenceUUID(tableName, uuid, atts);
addString(columnName, value, atts);
}
public void addTableReferenceMulti(String columnName, String tableName, String values, AttributesImpl atts) {
String target_values = ReferenceUtils.getTableReferenceMulti(tableName, values, atts, po.get_TrxName());
addString(columnName, target_values, atts);
}
public void export(List<String> excludes) { public void export(List<String> excludes) {
export(excludes, false); export(excludes, false);
} }
@ -249,10 +274,10 @@ public class PoExporter {
add(columnName, false, new AttributesImpl()); add(columnName, false, new AttributesImpl());
} else if (DisplayType.TableDir == displayType || DisplayType.ID == displayType) { } else if (DisplayType.TableDir == displayType || DisplayType.ID == displayType) {
String tableName = null; String tableName = null;
if ("Record_ID".equalsIgnoreCase(columnName) && po.get_ColumnIndex("AD_Table_ID") >= 0) { if (("Record_ID".equalsIgnoreCase(columnName) || "Record_UU".equalsIgnoreCase(columnName)) && po.get_ColumnIndex("AD_Table_ID") >= 0) {
int AD_Table_ID = po.get_Value(po.get_ColumnIndex("AD_Table_ID")) != null int AD_Table_ID = po.get_ValueAsInt("AD_Table_ID");
? (Integer)po.get_Value(po.get_ColumnIndex("AD_Table_ID")) : 0; if (AD_Table_ID > 0)
tableName = MTable.getTableName(ctx.ctx, AD_Table_ID); tableName = MTable.get(ctx.ctx, AD_Table_ID, ctx.trx.getTrxName()).getTableName();
} else if (po.get_TableName().equals("AD_TreeNode") && columnName.equals("Parent_ID")) { } else if (po.get_TableName().equals("AD_TreeNode") && columnName.equals("Parent_ID")) {
int AD_Tree_ID = po.get_ValueAsInt("AD_Tree_ID"); int AD_Tree_ID = po.get_ValueAsInt("AD_Tree_ID");
MTree tree = new MTree(ctx.ctx, AD_Tree_ID, ctx.trx.getTrxName()); MTree tree = new MTree(ctx.ctx, AD_Tree_ID, ctx.trx.getTrxName());
@ -269,15 +294,20 @@ public class PoExporter {
add(columnName, "", new AttributesImpl()); add(columnName, "", new AttributesImpl());
} else if (DisplayType.isLookup(displayType)) { } else if (DisplayType.isLookup(displayType)) {
String tableName = null; String tableName = null;
if ("Record_ID".equalsIgnoreCase(columnName) && po.get_ColumnIndex("AD_Table_ID") >= 0) { if (("Record_ID".equalsIgnoreCase(columnName) || "Record_UU".equalsIgnoreCase(columnName)) && po.get_ColumnIndex("AD_Table_ID") >= 0) {
int AD_Table_ID = po.get_Value(po.get_ColumnIndex("AD_Table_ID")) != null int AD_Table_ID = po.get_ValueAsInt("AD_Table_ID");
? (Integer)po.get_Value(po.get_ColumnIndex("AD_Table_ID")) : 0; if (AD_Table_ID > 0)
tableName = MTable.getTableName(ctx.ctx, AD_Table_ID); tableName = MTable.get(ctx.ctx, AD_Table_ID, ctx.trx.getTrxName()).getTableName();
} else if (info.getColumnLookup(i) != null){ } else if (info.getColumnLookup(i) != null){
String lookupColumn = info.getColumnLookup(i).getColumnName(); String lookupColumn = info.getColumnLookup(i).getColumnName();
tableName = lookupColumn.substring(0, lookupColumn.indexOf(".")); tableName = lookupColumn.substring(0, lookupColumn.indexOf("."));
} }
addTableReference(columnName, tableName, new AttributesImpl()); if ( info.getColumnDisplayType(i) == DisplayType.ChosenMultipleSelectionList
|| DisplayType.isMultiID(info.getColumnDisplayType(i))) {
addTableReferenceMulti(columnName, tableName, new AttributesImpl());
} else {
addTableReference(columnName, tableName, new AttributesImpl());
}
} else if (DisplayType.Account == displayType) { } else if (DisplayType.Account == displayType) {
String tableName = "C_ValidCombination"; String tableName = "C_ValidCombination";
addTableReference(columnName, tableName, new AttributesImpl()); addTableReference(columnName, tableName, new AttributesImpl());

View File

@ -173,7 +173,7 @@ public class PoFiller{
* *
* @param qName * @param qName
*/ */
public int setTableReference(String qName) { public Object setTableReference(String qName) {
Element e = element.properties.get(qName); Element e = element.properties.get(qName);
if (e == null) if (e == null)
return 0; return 0;
@ -181,26 +181,35 @@ public class PoFiller{
String value = e.contents.toString(); String value = e.contents.toString();
String columnName = qName; String columnName = qName;
if (value != null && value.trim().length() > 0) { if (value != null && value.trim().length() > 0) {
int id = ReferenceUtils.resolveReference(ctx.ctx, e, po.get_TrxName()); MColumn col = MColumn.get(ctx.ctx, po.get_TableName(), columnName, po.get_TrxName());
if (columnName.equals("AD_Client_ID") && id > 0) { if (col == null) {
if (id != Env.getAD_Client_ID(ctx.ctx)) { POInfo poInfo = POInfo.getPOInfo(ctx.ctx, po.get_Table_ID(), po.get_TrxName());
col = new MColumn(ctx.ctx, poInfo.getAD_Column_ID(columnName), po.get_TrxName());
if (col.get_ID() == 0)
return -1;
}
boolean isMulti = DisplayType.isMultiID(col.getAD_Reference_ID());
Object id;
if (isMulti)
id = ReferenceUtils.resolveReferenceMulti(ctx.ctx, e, po.get_TrxName());
else
id = ReferenceUtils.resolveReference(ctx.ctx, e, po.get_TrxName());
if (columnName.equals("AD_Client_ID") && ((Number)id).intValue() > 0) {
if (((Number)id).intValue() != Env.getAD_Client_ID(ctx.ctx)) {
return -1; return -1;
} }
} }
if (po.get_ColumnIndex(columnName) >= 0) { if (po.get_ColumnIndex(columnName) >= 0) {
MColumn col = MColumn.get(ctx.ctx, po.get_TableName(), columnName, po.get_TrxName());
if (col == null) {
POInfo poInfo = POInfo.getPOInfo(ctx.ctx, po.get_Table_ID(), po.get_TrxName());
col = new MColumn(ctx.ctx, poInfo.getAD_Column_ID(columnName), po.get_TrxName());
if (col.get_ID() == 0)
return -1;
}
MTable foreignTable = null; MTable foreignTable = null;
String refTableName = col.getReferenceTableName(); String refTableName;
if (isMulti)
refTableName = col.getMultiReferenceTableName();
else
refTableName = col.getReferenceTableName();
if (refTableName != null) { if (refTableName != null) {
foreignTable = MTable.get(Env.getCtx(), refTableName, po.get_TrxName()); foreignTable = MTable.get(Env.getCtx(), refTableName, po.get_TrxName());
} else { } else {
if ("Record_ID".equalsIgnoreCase(columnName)) { if ("Record_ID".equalsIgnoreCase(columnName) || "Record_UU".equalsIgnoreCase(columnName)) {
// special case - get the foreign table using AD_Table_ID // special case - get the foreign table using AD_Table_ID
int tableID = 0; int tableID = 0;
try { try {
@ -220,31 +229,30 @@ public class PoFiller{
} }
} }
} }
if (id > 0 && refTableName != null) { if (id != null && refTableName != null) {
if (foreignTable != null) { if (foreignTable != null) {
/* Allow to read here from another tenant, cross tenant control is implemented later in a safe way */ if (isMulti) {
PO subPo = null; for (String idstring : id.toString().split(",")) {
try { if (!isValidTenant(foreignTable, idstring, isMulti))
PO.setCrossTenantSafe(); return -1;
subPo = foreignTable.getPO(id, po.get_TrxName()); }
} finally { } else {
PO.clearCrossTenantSafe(); if (!isValidTenant(foreignTable, id, isMulti))
}
if (subPo != null && subPo.getAD_Client_ID() != Env.getAD_Client_ID(ctx.ctx)) {
String accessLevel = foreignTable.getAccessLevel();
if ((MTable.ACCESSLEVEL_All.equals(accessLevel)
|| MTable.ACCESSLEVEL_SystemOnly.equals(accessLevel)
|| MTable.ACCESSLEVEL_SystemPlusClient.equals(accessLevel)) &&
subPo.getAD_Client_ID() != 0)
return -1; return -1;
} }
} }
if (po.get_ValueAsInt(columnName) != id) { if (id instanceof String) {
po.set_ValueNoCheck(columnName, id); if (!((String)id).equals(po.get_ValueAsString(columnName))) {
} po.set_ValueNoCheck(columnName, id);
}
} else {
if (po.get_ValueAsInt(columnName) != ((Number)id).intValue()) {
po.set_ValueNoCheck(columnName, id);
}
}
return id; return id;
} else if (id == 0) { } else if (id instanceof Number && ((Number)id).intValue() == 0) {
if (refTableName != null && MTable.isZeroIDTable(refTableName)) { if (refTableName != null && MTable.isZeroIDTable(refTableName)) {
po.set_ValueNoCheck(columnName, id); po.set_ValueNoCheck(columnName, id);
return id; return id;
@ -260,6 +268,38 @@ public class PoFiller{
} }
} }
private boolean isValidTenant(MTable foreignTable, Object id, boolean isMulti) {
/* Allow to read here from another tenant, cross tenant control is implemented later in a safe way */
PO subPo = null;
try {
PO.setCrossTenantSafe();
if (id instanceof String) {
if (isMulti) {
subPo = foreignTable.getPO(Integer.valueOf(id.toString()), po.get_TrxName());
} else {
subPo = foreignTable.getPOByUU((String)id, po.get_TrxName());
}
} else {
if (((Number)id).intValue() == 0 && MTable.isZeroIDTable(foreignTable.getTableName()))
return true;
subPo = foreignTable.getPO(((Number)id).intValue(), po.get_TrxName());
}
} finally {
PO.clearCrossTenantSafe();
}
if (subPo != null && subPo.getAD_Client_ID() != Env.getAD_Client_ID(ctx.ctx)) {
String accessLevel = foreignTable.getAccessLevel();
if ((MTable.ACCESSLEVEL_All.equals(accessLevel)
|| MTable.ACCESSLEVEL_SystemOnly.equals(accessLevel)
|| MTable.ACCESSLEVEL_SystemPlusClient.equals(accessLevel)) &&
subPo.getAD_Client_ID() != 0)
return false;
}
if (subPo.is_new())
return false;
return true;
}
/** /**
* process all attributes * process all attributes
* @param excludes list of attribute to exclude * @param excludes list of attribute to exclude
@ -289,7 +329,7 @@ public class PoFiller{
} else if (sAD_Org_ID != null && sAD_Org_ID.equals("@AD_Org_ID@")) { } else if (sAD_Org_ID != null && sAD_Org_ID.equals("@AD_Org_ID@")) {
po.setAD_Org_ID(Env.getAD_Org_ID(ctx.ctx)); po.setAD_Org_ID(Env.getAD_Org_ID(ctx.ctx));
} else { } else {
if (setTableReference("AD_Client_ID") >= 0) if (((Number)setTableReference("AD_Client_ID")).intValue() >= 0)
setTableReference("AD_Org_ID"); setTableReference("AD_Org_ID");
} }
} }
@ -310,8 +350,8 @@ public class PoFiller{
} }
Element e = element.properties.get(qName); Element e = element.properties.get(qName);
if (ReferenceUtils.isLookup(e)) { if (ReferenceUtils.isLookup(e)) {
int id = setTableReference(qName); Object id = setTableReference(qName);
if (id < 0) { if (id == null || (id instanceof Number && ((Number)id).intValue() < 0)) {
notFounds.add(qName); notFounds.add(qName);
} }
} else { } else {

View File

@ -7,6 +7,7 @@ import org.compiere.model.PO;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Util;
import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.AttributesImpl;
public class ReferenceUtils { public class ReferenceUtils {
@ -21,7 +22,22 @@ public class ReferenceUtils {
* @param trxName * @param trxName
* @return positive id if found * @return positive id if found
*/ */
public static int resolveReference(Properties ctx, Element e, String trxName) public static int resolveReferenceAsInt(Properties ctx, Element e, String trxName)
{
Object id = resolveReference(ctx, e, trxName);
if (id instanceof Number)
return ((Number)id).intValue();
return -1;
}
/**
*
* @param ctx
* @param e
* @param trxName
* @return positive id if found
*/
public static Object resolveReference(Properties ctx, Element e, String trxName)
{ {
String value = e.contents.toString(); String value = e.contents.toString();
String referenceKey = e.attributes.getValue("reference-key"); String referenceKey = e.attributes.getValue("reference-key");
@ -36,7 +52,7 @@ public class ReferenceUtils {
{ {
String uuid = value.trim(); String uuid = value.trim();
String target = Env.getAD_Client_ID(ctx) > 0 ? POFinder.getTargetUUID(ctx, referenceKey, uuid, trxName) : uuid; String target = Env.getAD_Client_ID(ctx) > 0 ? POFinder.getTargetUUID(ctx, referenceKey, uuid, trxName) : uuid;
int id = IDFinder.findIdByColumn(referenceKey, PO.getUUIDColumnName(referenceKey), target, Env.getAD_Client_ID(ctx), trxName); Object id = IDFinder.findIdByColumn(referenceKey, PO.getUUIDColumnName(referenceKey), target, Env.getAD_Client_ID(ctx), trxName);
return id; return id;
} }
else else
@ -50,6 +66,36 @@ public class ReferenceUtils {
} }
} }
/**
*
* @param ctx
* @param e
* @param trxName
* @return list of IDs or UUIDs if found
*/
public static Object resolveReferenceMulti(Properties ctx, Element e, String trxName)
{
String values = e.contents.toString();
String referenceKey = e.attributes.getValue("reference-key");
if (values != null && values.trim().length() > 0) {
String target_values = null;
for (String uuid : values.split(",")) {
// multi is always UUID, even for official IDs
String target = Env.getAD_Client_ID(ctx) > 0 ? POFinder.getTargetUUID(ctx, referenceKey, uuid, trxName) : uuid;
Object id = IDFinder.findIdByColumn(referenceKey, PO.getUUIDColumnName(referenceKey), target, Env.getAD_Client_ID(ctx), trxName);
if (id == null) // one of the multi UUID was not found, invalidate the complete string
return -1;
if (target_values == null)
target_values = id.toString();
else
target_values += "," + id.toString();
}
return target_values;
} else {
return 0;
}
}
public static boolean isLookup(Element element) public static boolean isLookup(Element element)
{ {
if (isIDLookup(element) || isUUIDLookup(element)) if (isIDLookup(element) || isUUIDLookup(element))
@ -68,7 +114,7 @@ public class ReferenceUtils {
return "uuid".equals(element.attributes.getValue("reference")); return "uuid".equals(element.attributes.getValue("reference"));
} }
public static String getTableReference(String tableName, int id, AttributesImpl atts) public static String getTableReference(String tableName, int id, AttributesImpl atts, String trxName)
{ {
String keyColumn = tableName + "_ID"; String keyColumn = tableName + "_ID";
if ( (id > 0 && id <= PackOut.MAX_OFFICIAL_ID) if ( (id > 0 && id <= PackOut.MAX_OFFICIAL_ID)
@ -87,7 +133,7 @@ public class ReferenceUtils {
} }
else else
{ {
MTable table = MTable.get(Env.getCtx(), tableName); MTable table = MTable.get(Env.getCtx(), tableName, trxName);
if (table == null) if (table == null)
throw new RuntimeException("Table Not Found. TableName="+tableName); throw new RuntimeException("Table Not Found. TableName="+tableName);
String uuidColumnName = PO.getUUIDColumnName(tableName); String uuidColumnName = PO.getUUIDColumnName(tableName);
@ -110,6 +156,62 @@ public class ReferenceUtils {
atts.addAttribute("", "", "reference", "CDATA", "id"); atts.addAttribute("", "", "reference", "CDATA", "id");
return ""; return "";
} }
}
public static String getTableReferenceUUID(String tableName, String uuid, AttributesImpl atts)
{
if (Util.isEmpty(uuid))
{
//no uuid
atts.addAttribute("", "", "reference", "CDATA", "uuid");
return "";
}
else
{
//uuid
atts.addAttribute("", "", "reference", "CDATA", "uuid");
atts.addAttribute("", "", "reference-key", "CDATA", tableName);
return uuid.trim();
}
}
public static String getTableReferenceMulti(String tableName, String values, AttributesImpl atts, String trxName)
{
atts.addAttribute("", "", "reference", "CDATA", "uuid");
if (Util.isEmpty(values)) {
return "";
}
MTable table = MTable.get(Env.getCtx(), tableName, trxName);
if (table == null)
throw new RuntimeException("Table Not Found. TableName="+tableName);
if (table.isUUIDKeyTable()) {
//uuid
atts.addAttribute("", "", "reference-key", "CDATA", tableName);
return values.trim();
}
// convert multi-IDs to multi-UUIDs
String target_values = "";
String keyColumn = tableName + "_ID";
String uuidColumnName = PO.getUUIDColumnName(tableName);
for (String value : values.split(",")) {
int id = Integer.valueOf(value);
// Translate always IDs to UUIDs, even for official IDs,
// because it would be more complex to manage a combination of official IDs and UUIDs
if (table.getColumn(uuidColumnName) != null) {
//uuid
String sql = "SELECT " + uuidColumnName + " FROM "
+ tableName + " WHERE " + keyColumn + " = ?";
String valuePartial = DB.getSQLValueString(null, sql, id);
if (!Util.isEmpty(valuePartial, true)) {
if (target_values.length() == 0)
target_values = valuePartial;
else
target_values += "," + valuePartial;
}
}
}
atts.addAttribute("", "", "reference-key", "CDATA", tableName);
return target_values;
}
}