/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Language; /** * Factory to create MLookup instance. * * @author Jorg Janke * @version $Id: MLookupFactory.java,v 1.3 2006/07/30 00:58:04 jjanke Exp $ * * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1734394 ] MLookupFactory.getLookup_TableDirEmbed is not translated *
  • BF [ 1714261 ] MLookupFactory: TableDirEmbed -> TableEmbed not supported *
  • BF [ 1672820 ] Sorting should be language-sensitive *
  • BF [ 1739530 ] getLookup_TableDirEmbed error when BaseColumn is sql query *
  • BF [ 1739544 ] getLookup_TableEmbed error for self referencing references *
  • BF [ 1817768 ] Isolate hardcoded table direct columns * @author Teo Sarca *
  • BF [ 2933367 ] Virtual Column Identifiers are not working * https://sourceforge.net/p/adempiere/bugs/2291/ * @author Carlos Ruiz, GlobalQSS *
  • BF [ 2561593 ] Multi-tenant problem with webui */ public class MLookupFactory { /** Logging */ private static CLogger s_log = CLogger.getCLogger(MLookupFactory.class); /** Table Reference Cache */ private static CCache s_cacheRefTable = new CCache(I_AD_Ref_Table.Table_Name, 30, CCache.DEFAULT_EXPIRE_MINUTE); // 1h /** List Reference Cache */ private static CCache s_cacheRefList = new CCache(I_AD_Ref_List.Table_Name, 30, CCache.DEFAULT_EXPIRE_MINUTE); // 1h /** * Create MLookup * * @param ctx context for access * @param WindowNo window no * @param AD_Reference_ID lookup display type * @param Column_ID AD_Column_ID or AD_Process_Para_ID * @param language language * @param ColumnName key column name * @param AD_Reference_Value_ID AD_Reference (List - AD_Ref_List, Table - AD_Ref_Table) * @param IsParent parent (prevents query to directly access value) * @param ValidationCode optional SQL validation/filter * @throws Exception if Lookup could not be created * @return MLookup */ public static MLookup get (Properties ctx, int WindowNo, int Column_ID, int AD_Reference_ID, Language language, String ColumnName, int AD_Reference_Value_ID, boolean IsParent, String ValidationCode) throws Exception { MLookupInfo info = getLookupInfo (ctx, WindowNo, Column_ID, AD_Reference_ID, language, ColumnName, AD_Reference_Value_ID, IsParent, ValidationCode); if (info == null) throw new Exception ("MLookup.create - no LookupInfo"); return new MLookup(info, 0); } // create /** * @param ctx * @param WindowNo * @param Column_ID * @param AD_Reference_ID * @return MLookupInfo */ public static MLookupInfo getLookupInfo(Properties ctx, int WindowNo, int Column_ID, int AD_Reference_ID) { return getLookupInfo(ctx, WindowNo, 0, Column_ID, AD_Reference_ID); } /** * @param ctx * @param WindowNo * @param TabNo * @param Column_ID * @param AD_Reference_ID * @return MLookupInfo */ public static MLookupInfo getLookupInfo(Properties ctx, int WindowNo, int TabNo, int Column_ID, int AD_Reference_ID) { MColumn column = MColumn.get(ctx, Column_ID); if (column.get_ID() == 0) s_log.log(Level.SEVERE, "Column Not Found - AD_Column_ID=" + Column_ID); String ColumnName = column.getColumnName(); int AD_Reference_Value_ID = column.getAD_Reference_Value_ID(); boolean IsParent = column.isParent(); String ValidationCode = ""; if (column.getAD_Val_Rule_ID() > 0) { MValRule valRule = MValRule.get(ctx, column.getAD_Val_Rule_ID()); ValidationCode = valRule.getCode(); } // MLookupInfo info = getLookupInfo (ctx, WindowNo, TabNo, Column_ID, AD_Reference_ID, Env.getLanguage(ctx), ColumnName, AD_Reference_Value_ID, IsParent, ValidationCode); return info; } /** * Create MLookup * * @param ctx context for access * @param WindowNo window no * @param TabNo TabNo * @param Column_ID AD_Column_ID or AD_Process_Para_ID * @param AD_Reference_ID display type * @return MLookup */ public static MLookup get (Properties ctx, int WindowNo, int TabNo, int Column_ID, int AD_Reference_ID) { // MLookupInfo info = getLookupInfo (ctx, WindowNo, TabNo, Column_ID, AD_Reference_ID); return new MLookup(info, TabNo); } // get /** * Get Information for Lookups based on Column_ID for Table Columns or Process Parameters. * @param ctx context for access * @param language report language * @param WindowNo window no * @param Column_ID AD_Column_ID or AD_Process_Para_ID * @param ColumnName key column name * @param AD_Reference_ID display type * @param AD_Reference_Value_ID AD_Reference (List, Table) * @param IsParent parent (prevents query to directly access value) * @param ValidationCode optional SQL validation * @return lookup info structure */ static public MLookupInfo getLookupInfo (Properties ctx, int WindowNo, int Column_ID, int AD_Reference_ID, Language language, String ColumnName, int AD_Reference_Value_ID, boolean IsParent, String ValidationCode) { return getLookupInfo(ctx, WindowNo, 0, Column_ID, AD_Reference_ID, language, ColumnName, AD_Reference_Value_ID, IsParent, ValidationCode); } // getLookupInfo /** * Get Information for Lookups based on Column_ID for Table Columns or Process Parameters. * @param ctx context for access * @param language report language * @param WindowNo window no * @param tabNo tab no * @param Column_ID AD_Column_ID or AD_Process_Para_ID * @param ColumnName key column name * @param AD_Reference_ID display type * @param AD_Reference_Value_ID AD_Reference (List, Table) * @param IsParent parent (prevents query to directly access value) * @param ValidationCode optional SQL validation * @return lookup info structure */ static public MLookupInfo getLookupInfo (Properties ctx, int WindowNo, int tabNo, int Column_ID, int AD_Reference_ID, Language language, String ColumnName, int AD_Reference_Value_ID, boolean IsParent, String ValidationCode) { MLookupInfo info = null; boolean needToAddSecurity = true; // List if (DisplayType.isList(AD_Reference_ID)) // 17 { info = getLookup_List(language, AD_Reference_Value_ID); needToAddSecurity = false; } // Table or Search with Reference_Value else if ((AD_Reference_ID == DisplayType.Table || AD_Reference_ID == DisplayType.TableUU || AD_Reference_ID == DisplayType.Search || AD_Reference_ID == DisplayType.SearchUU || AD_Reference_ID == DisplayType.ChosenMultipleSelectionTable || AD_Reference_ID == DisplayType.ChosenMultipleSelectionSearch) && AD_Reference_Value_ID != 0) { info = getLookup_Table (ctx, language, WindowNo, AD_Reference_Value_ID); } // TableDir, Search, ID, ... else { info = getLookup_TableDir (ctx, language, WindowNo, ColumnName); } // do we have basic info? if (info == null) { s_log.severe ("No SQL - " + ColumnName); return null; } // remaining values info.ctx = ctx; info.WindowNo = WindowNo; info.tabNo = tabNo; info.Column_ID = Column_ID; info.DisplayType = AD_Reference_ID; info.AD_Reference_Value_ID = AD_Reference_Value_ID; info.IsParent = IsParent; info.ValidationCode = ValidationCode; if (info.ValidationCode == null) info.ValidationCode = ""; // Variables in SQL WHERE if (info.Query.indexOf('@') != -1) { String newSQL = Env.parseContext(ctx, 0, info.Query, false); // only global if (newSQL.length() == 0) { s_log.severe ("SQL parse error: " + info.Query); return null; } info.Query = newSQL; if (s_log.isLoggable(Level.FINE)) s_log.fine("getLookupInfo, newSQL ="+newSQL); //jz } // Direct Query - NO Validation/Security if (info.QueryDirect.indexOf('@') != -1) { String newSQL = Env.parseContext(ctx, 0, info.QueryDirect, false); // only global if (newSQL.length() == 0) { s_log.severe ("SQL parse error: " + info.QueryDirect); return null; } info.QueryDirect = newSQL; if (s_log.isLoggable(Level.FINE)) s_log.fine("getLookupInfo, newSQL ="+newSQL); //jz } // Validation //String local_validationCode = ""; if (info.ValidationCode.length() == 0) info.IsValidated = true; else { info.IsValidated = false; } // Add Security if (needToAddSecurity) info.Query = MRole.getDefault(ctx, false).addAccessSQL(info.Query, info.TableName, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); return info; } // getLookupInfo /** * Get Lookup Info for List display type * @param language language * @param AD_Reference_Value_ID list reference id (AD_Ref_List) * @return MLookupInfo */ static public MLookupInfo getLookup_List(Language language, int AD_Reference_Value_ID) { String lang; if (language == null) { lang = Env.getAD_Language(Env.getCtx()); } else { lang = language.getAD_Language(); } StringBuilder key = new StringBuilder() .append(Env.getAD_Client_ID(Env.getCtx())).append("|") .append(lang).append("|") .append(String.valueOf(AD_Reference_Value_ID)); MLookupInfo retValue = (MLookupInfo)s_cacheRefList.get(key.toString()); if (retValue != null) { if (s_log.isLoggable(Level.FINEST)) s_log.finest("Cache: " + retValue); return retValue.cloneIt(); } boolean orderByValue = MReference.get(AD_Reference_Value_ID).isOrderByValue(); StringBuilder realSQL = new StringBuilder ("SELECT NULL, AD_Ref_List.Value,"); MClient client = MClient.get(Env.getCtx()); StringBuilder AspFilter = new StringBuilder(); if ( client.isUseASP() ) { AspFilter.append(" AND AD_Ref_List.AD_Ref_List_ID NOT IN ( ") .append(" SELECT li.AD_Ref_List_ID") .append(" FROM ASP_Ref_List li") .append(" INNER JOIN ASP_Level l ON ( li.ASP_Level_ID = l.ASP_Level_ID)") .append(" INNER JOIN ASP_ClientLevel cl on (l.ASP_Level_ID = cl.ASP_Level_ID)") .append(" INNER JOIN AD_Client c on (cl.AD_Client_ID = c.AD_Client_ID)") .append(" WHERE li.AD_Reference_ID=").append(AD_Reference_Value_ID) .append(" AND li.IsActive='Y'") .append(" AND c.AD_Client_ID=").append(client.getAD_Client_ID()) .append(" AND li.ASP_Status='H')"); } if (Env.isBaseLanguage(language, "AD_Ref_List")) realSQL.append("AD_Ref_List.Name,AD_Ref_List.IsActive FROM AD_Ref_List "); else realSQL.append("trl.Name, AD_Ref_List.IsActive ") .append("FROM AD_Ref_List INNER JOIN AD_Ref_List_Trl trl ") .append(" ON (AD_Ref_List.AD_Ref_List_ID=trl.AD_Ref_List_ID AND trl.AD_Language='") .append(language.getAD_Language()).append("')"); realSQL.append(" WHERE AD_Ref_List.AD_Reference_ID=").append(AD_Reference_Value_ID); String directSql = realSQL.toString() + " AND AD_Ref_List.Value=?"; realSQL.append(AspFilter.toString()); if (orderByValue) realSQL.append(" ORDER BY 2"); else realSQL.append(" ORDER BY 3"); // sort by name/translated name - teo_sarca, [ 1672820 ] // MLookupInfo info = new MLookupInfo(realSQL.toString(), "AD_Ref_List", "AD_Ref_List.Value", 101,101, MQuery.getEqualQuery("AD_Reference_ID", AD_Reference_Value_ID)); // Zoom Window+Query info.QueryDirect = directSql; s_cacheRefList.put(key.toString(), info.cloneIt()); return info; } // getLookup_List /** * Get Lookup SQL for List (for use as embedded query in SELECT) * @param language Language * @param AD_Reference_Value_ID list reference id (AD_Ref_List) * @param linkColumnName link column name * @return SELECT Name FROM AD_Ref_List WHERE AD_Reference_ID=x AND Value=linkColumn */ static public String getLookup_ListEmbed(Language language, int AD_Reference_Value_ID, String linkColumnName) { StringBuilder realSQL = new StringBuilder ("SELECT "); if (Env.isBaseLanguage(language, "AD_Ref_List")) realSQL.append("AD_Ref_List.Name FROM AD_Ref_List "); else realSQL.append("trl.Name ") .append("FROM AD_Ref_List INNER JOIN AD_Ref_List_Trl trl ") .append(" ON (AD_Ref_List.AD_Ref_List_ID=trl.AD_Ref_List_ID AND trl.AD_Language='") .append(language.getAD_Language()).append("')"); realSQL.append(" WHERE AD_Ref_List.AD_Reference_ID=").append(AD_Reference_Value_ID) .append(" AND AD_Ref_List.Value=").append(linkColumnName); // return realSQL.toString(); } // getLookup_ListEmbed /** * Get Lookup Info for Table Lookup display type * @param ctx context for access and dynamic access * @param language report language * @param WindowNo window no * @param AD_Reference_Value_ID table reference id (AD_Ref_Table) * @return MLookupInfo */ static private MLookupInfo getLookup_Table (Properties ctx, Language language, int WindowNo, int AD_Reference_Value_ID) { String lang; if (language == null) { lang = Env.getAD_Language(Env.getCtx()); } else { lang = language.getAD_Language(); } StringBuilder key = new StringBuilder() .append(Env.getAD_Client_ID(ctx)).append("|") .append(Env.getAD_Role_ID(ctx)).append("|") .append(Env.getAD_User_ID(ctx)).append("|") .append(lang).append("|") .append(String.valueOf(AD_Reference_Value_ID)); MLookupInfo retValue = (MLookupInfo)s_cacheRefTable.get(key.toString()); if (retValue != null) { if (s_log.isLoggable(Level.FINEST)) s_log.finest("Cache: " + retValue); return retValue.cloneIt(); } // String sql0 = "SELECT t.TableName,ck.ColumnName AS KeyColumn," // 1..2 + "cd.ColumnName AS DisplayColumn,rt.IsValueDisplayed,cd.IsTranslated," // 3..5 + "rt.WhereClause,rt.OrderByClause,t.AD_Window_ID,t.PO_Window_ID, " // 6..9 + "t.AD_Table_ID, cd.ColumnSQL as DisplayColumnSQL, " // 10..11 + "rt.AD_Window_ID as RT_AD_Window_ID, rt.AD_InfoWindow_ID as AD_InfoWindow_ID " // 12..13 + "FROM AD_Ref_Table rt" + " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID)" + " INNER JOIN AD_Column ck ON (rt.AD_Key=ck.AD_Column_ID)" + " INNER JOIN AD_Column cd ON (rt.AD_Display=cd.AD_Column_ID) " + "WHERE rt.AD_Reference_ID=?" + " AND rt.IsActive='Y' AND t.IsActive='Y'"; // String KeyColumn = null, DisplayColumn = null, TableName = null, WhereClause = null, OrderByClause = null; String displayColumnSQL = null; boolean IsTranslated = false, isValueDisplayed = false; int ZoomWindow = 0; int ZoomWindowPO = 0; int overrideZoomWindow = 0; int infoWindowId = 0; boolean loaded = false; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql0, null); pstmt.setInt(1, AD_Reference_Value_ID); rs = pstmt.executeQuery(); if (rs.next()) { TableName = rs.getString(1); KeyColumn = rs.getString(2); DisplayColumn = rs.getString(3); isValueDisplayed = "Y".equals(rs.getString(4)); IsTranslated = "Y".equals(rs.getString(5)); WhereClause = rs.getString(6); OrderByClause = rs.getString(7); ZoomWindow = rs.getInt(8); ZoomWindowPO = rs.getInt(9); displayColumnSQL = rs.getString(11); if (displayColumnSQL != null && displayColumnSQL.length() > 0 && (displayColumnSQL.startsWith(MColumn.VIRTUAL_UI_COLUMN_PREFIX) || displayColumnSQL.startsWith(MColumn.VIRTUAL_SEARCH_COLUMN_PREFIX))) displayColumnSQL = "NULL"; if (displayColumnSQL != null && displayColumnSQL.contains("@")) displayColumnSQL = Env.parseContext(Env.getCtx(), -1, displayColumnSQL, false, true); overrideZoomWindow = rs.getInt(12); infoWindowId = rs.getInt(13); loaded = true; } } catch (SQLException e) { s_log.log(Level.SEVERE, sql0, e); return null; } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } if (!loaded) { s_log.log(Level.SEVERE, "No Table Reference Table ID=" + AD_Reference_Value_ID); return null; } StringBuilder realSQL = new StringBuilder("SELECT "); if (!KeyColumn.endsWith("_ID") && !KeyColumn.endsWith("_UU")) realSQL.append("NULL,"); boolean showID = DisplayColumn.equals(TableName+"_ID") || DisplayColumn.equals(PO.getUUIDColumnName(TableName)); ArrayList list = null; if (showID) { list = getListIdentifiers(TableName); // Do we have columns ? if (list == null || list.size() == 0) { if (s_log.isLoggable(Level.INFO)) { s_log.log(Level.INFO, "No Identifier records found: " + KeyColumn); } if (list == null) list = new ArrayList(); list.add(new LookupDisplayColumn(KeyColumn, null, false, DisplayType.ID, 0)); } // set isTranslated IsTranslated = false; for (LookupDisplayColumn ldc : list) { if (!IsTranslated && ldc.IsTranslated) { IsTranslated = true; break; } } } String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx())); String lookupDisplayColumn = null; // Translated if (IsTranslated && !Env.isBaseLanguage(language, TableName)) { realSQL.append(TableName).append(".").append(KeyColumn).append(","); if (KeyColumn.endsWith("_ID") || KeyColumn.endsWith("_UU")) realSQL.append("NULL,"); if (isValueDisplayed) realSQL.append("NVL(").append(TableName).append(".Value,'-1') || '").append(separator).append("' || "); if (displayColumnSQL != null && displayColumnSQL.trim().length() > 0) realSQL.append("NVL(").append(displayColumnSQL).append(",'-1')"); else { if (showID) { StringBuilder displayColumn = getDisplayColumn(language, TableName, list); lookupDisplayColumn = displayColumn.toString(); realSQL.append(displayColumn); } else { lookupDisplayColumn = DisplayColumn; realSQL.append("NVL(").append(TableName).append("_Trl.").append(DisplayColumn).append(",'-1')"); } } realSQL.append(",").append(TableName).append(".IsActive"); String realKeyColumn = KeyColumn.endsWith("_ID") || KeyColumn.endsWith("_UU") ? KeyColumn : (MTable.get(ctx, TableName).isUUIDKeyTable() ? PO.getUUIDColumnName(TableName) : TableName + "_ID"); realSQL.append(" FROM ").append(TableName) .append(" INNER JOIN ").append(TableName).append("_TRL ON (") .append(TableName).append(".").append(realKeyColumn) .append("=").append(TableName).append("_Trl.").append(realKeyColumn) .append(" AND ").append(TableName).append("_Trl.AD_Language='") .append(language.getAD_Language()).append("')"); } // Not Translated else { realSQL.append(TableName).append(".").append(KeyColumn).append(","); if (KeyColumn.endsWith("_ID") || KeyColumn.endsWith("_UU")) realSQL.append("NULL,"); if (isValueDisplayed) realSQL.append("NVL(").append(TableName).append(".Value,'-1') || '").append(separator).append("' || "); if (displayColumnSQL != null && displayColumnSQL.trim().length() > 0) realSQL.append("NVL(").append(displayColumnSQL).append(",'-1')"); else { if (showID) { StringBuilder displayColumn = getDisplayColumn(language, TableName, list); lookupDisplayColumn = displayColumn.toString(); realSQL.append(displayColumn); } else { lookupDisplayColumn = DisplayColumn; realSQL.append("NVL(").append(TableName).append(".").append(DisplayColumn).append(",'-1')"); } } realSQL.append(",").append(TableName).append(".IsActive"); realSQL.append(" FROM ").append(TableName); } String directQuery = realSQL.toString() + " WHERE " + TableName + "." + KeyColumn + "=?"; // add WHERE clause MQuery zoomQuery = null; if (WhereClause != null && WhereClause.length() > 0) { String where = WhereClause; if (where.indexOf('@') != -1) where = Env.parseContext(ctx, WindowNo, where, false); if (where.length() == 0 && WhereClause.length() != 0) s_log.severe ("Could not resolve: " + WhereClause); // We have no context if (where.length() != 0) { realSQL.append(" WHERE ").append(where); if (where.indexOf('.') == -1) s_log.log(Level.SEVERE, "getLookup_Table - " + TableName + ": WHERE should be fully qualified: " + WhereClause); zoomQuery = new MQuery (TableName); zoomQuery.addRestriction(where); } } // Order By qualified term or by Name if (OrderByClause != null && OrderByClause.length() > 0 ) { realSQL.append(" ORDER BY ").append(OrderByClause); if (OrderByClause.indexOf('.') == -1) s_log.log(Level.SEVERE, "getLookup_Table - " + TableName + ": ORDER BY must fully qualified: " + OrderByClause); } else realSQL.append(" ORDER BY 3"); if (s_log.isLoggable(Level.FINEST)) s_log.finest("AD_Reference_Value_ID=" + AD_Reference_Value_ID + " - " + realSQL); int zoomWinID = Env.getZoomWindowID(MTable.get(ctx, TableName).getAD_Table_ID(), 0, WindowNo); if (zoomWinID > 0) ZoomWindow = zoomWinID; if (overrideZoomWindow > 0) { ZoomWindow = overrideZoomWindow; ZoomWindowPO = 0; } StringBuilder msginf = new StringBuilder().append(TableName).append(".").append(KeyColumn); retValue = new MLookupInfo (realSQL.toString(), TableName, msginf.toString(), ZoomWindow, ZoomWindowPO, zoomQuery); retValue.DisplayColumn = lookupDisplayColumn; retValue.InfoWindowId = infoWindowId; retValue.QueryDirect = MRole.getDefault().addAccessSQL(directQuery, TableName, true, false); List lookupDisplayColumns = new ArrayList(); if (isValueDisplayed) lookupDisplayColumns.add("Value"); lookupDisplayColumns.add(lookupDisplayColumn != null ? lookupDisplayColumn : DisplayColumn); retValue.lookupDisplayColumns = lookupDisplayColumns; if(list != null) { retValue.lookupDisplayColumnNames = new ArrayList<>(); if (isValueDisplayed) retValue.lookupDisplayColumnNames.add("Value"); for (LookupDisplayColumn ldc : list) { retValue.lookupDisplayColumnNames.add(ldc.ColumnName); } } else { retValue.lookupDisplayColumnNames = new ArrayList<>(retValue.lookupDisplayColumns); } s_cacheRefTable.put(key.toString(), retValue.cloneIt()); return retValue; } // getLookup_Table /** * Get Embedded Lookup SQL for Table Lookup display type * @param language language * @param BaseColumn base column name * @param BaseTable base table name * @param AD_Reference_Value_ID table reference id (AD_Ref_Table) * @return SELECT Name FROM Table */ public static String getLookup_TableEmbed (Language language, String BaseColumn, String BaseTable, int AD_Reference_Value_ID) { String sql = "SELECT t.TableName,ck.ColumnName AS KeyColumn," + "cd.ColumnName AS DisplayColumn,rt.isValueDisplayed,cd.IsTranslated, cd.AD_Column_ID AS columnDisplay_ID " + "FROM AD_Ref_Table rt" + " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID)" + " INNER JOIN AD_Column ck ON (rt.AD_Key=ck.AD_Column_ID)" + " INNER JOIN AD_Column cd ON (rt.AD_Display=cd.AD_Column_ID) " + "WHERE rt.AD_Reference_ID=?" + " AND rt.IsActive='Y' AND t.IsActive='Y'"; // String KeyColumn, DisplayColumn, TableName, TableNameAlias; boolean IsTranslated, isValueDisplayed; Integer columnDisplay_ID = 0; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, AD_Reference_Value_ID); rs = pstmt.executeQuery(); if (!rs.next()) { s_log.log(Level.SEVERE, "Cannot find Reference Table, ID=" + AD_Reference_Value_ID + ", Base=" + BaseTable + "." + BaseColumn); return null; } TableName = rs.getString(1); KeyColumn = rs.getString(2); DisplayColumn = rs.getString(3); isValueDisplayed = rs.getString(4).equals("Y"); IsTranslated = rs.getString(5).equals("Y"); columnDisplay_ID = rs.getInt(6); } catch (SQLException e) { s_log.log(Level.SEVERE, sql, e); return null; } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } int Column_ID = MColumn.getColumn_ID(BaseTable, BaseColumn); MColumn column = MColumn.get(Env.getCtx(), Column_ID); boolean showID = DisplayColumn.equals(TableName+"_ID") || DisplayColumn.equals(PO.getUUIDColumnName(TableName)); if (showID) { if (column.isVirtualColumn()) return getLookup_TableDirEmbed(language, DisplayColumn, BaseTable, column.getColumnSQL()); else return getLookup_TableDirEmbed(language, DisplayColumn, BaseTable, BaseColumn); } // If it's self referencing then use other alias - teo_sarca [ 1739544 ] if (TableName.equals(BaseTable)) { TableNameAlias = TableName + "1"; } else { TableNameAlias = TableName; } StringBuilder embedSQL = new StringBuilder("SELECT "); if (isValueDisplayed) { String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx())); embedSQL.append(TableNameAlias).append(".Value||'").append(separator).append("'||"); } MColumn columnDisplay = MColumn.get(Env.getCtx(), columnDisplay_ID); if (columnDisplay.isVirtualUIColumn() || columnDisplay.isVirtualSearchColumn()) { s_log.warning("Virtual UI Column must not be used as display"); return null; } boolean translated = false; // Translated if (IsTranslated && !Env.isBaseLanguage(language, TableName)) { translated = true; if (columnDisplay.isVirtualColumn()) { s_log.warning("Column SQL should not be Translated"); return null; } else embedSQL.append(TableName).append("_Trl.").append(DisplayColumn); embedSQL.append(" FROM ").append(TableName).append(" ").append(TableNameAlias) .append(" INNER JOIN ").append(TableName).append("_TRL ON (") .append(TableNameAlias).append(".").append(KeyColumn) .append("=").append(TableName).append("_Trl.").append(KeyColumn) .append(" AND ").append(TableName).append("_Trl.AD_Language='") .append(language.getAD_Language()).append("')"); } // Not Translated else { if (columnDisplay.isVirtualColumn()) embedSQL.append(columnDisplay.getColumnSQL(true)).append(" AS ").append(KeyColumn); else embedSQL.append(TableNameAlias).append(".").append(DisplayColumn); embedSQL.append(" FROM ").append(TableName).append(" ").append(TableNameAlias); } embedSQL.append(" WHERE "); // If is not virtual column - teo_sarca [ 1739530 ] if (!column.isVirtualColumn()) { embedSQL.append(BaseTable).append(".").append(BaseColumn); embedSQL.append("=").append(TableNameAlias).append(".").append(KeyColumn); } else if (translated) { embedSQL.append(TableNameAlias).append(".").append(KeyColumn).append("=").append(column.getColumnSQL(true)); } else { embedSQL.append(TableNameAlias).append(".").append(KeyColumn).append("=").append(column.getColumnSQL(true)); } return embedSQL.toString(); } // getLookup_TableEmbed /** * Get Lookup Info for Table Direct lookup display type * @param ctx context for access * @param language language * @param ColumnName column name * @param WindowNo Window number * @return MLookupInfo */ static private MLookupInfo getLookup_TableDir (Properties ctx, Language language, int WindowNo, String ColumnName) { if (!ColumnName.endsWith("_ID") && !ColumnName.endsWith("_UU")) { String error = "Key does not end with '_ID' or '_UU': " + ColumnName; s_log.log(Level.SEVERE, error, new Exception(error)); return null; } String KeyColumn = MQuery.getZoomColumnName(ColumnName); String TableName = MQuery.getZoomTableName(ColumnName); int ZoomWindow = 0; int ZoomWindowPO = 0; //try cache StringBuilder cacheKey = new StringBuilder() .append(Env.getAD_Client_ID(ctx)).append("|") .append(Env.getAD_Role_ID(ctx)).append("|") .append(Env.getAD_User_ID(ctx)).append("|") .append(language.getAD_Language()).append("|") .append(TableName).append(".") .append(KeyColumn); if (s_cacheRefTable.containsKey(cacheKey.toString())) return s_cacheRefTable.get(cacheKey.toString()).cloneIt(); ArrayList list = getListIdentifiers(TableName); // Do we have columns ? if (list == null || list.size() == 0) { if (s_log.isLoggable(Level.INFO)) { s_log.log(Level.INFO, "No Identifier records found: " + ColumnName); } if (list == null) list = new ArrayList(); list.add(new LookupDisplayColumn(KeyColumn, null, false, DisplayType.ID, 0)); } // set isTranslated boolean isTranslated = false; for (LookupDisplayColumn ldc : list) { if (!isTranslated && ldc.IsTranslated) { isTranslated = true; break; } } MTable table = MTable.get(ctx, TableName); ZoomWindow = table.getAD_Window_ID(); ZoomWindowPO = table.getPO_Window_ID(); int zoomWinID = Env.getZoomWindowID(table.getAD_Table_ID(), 0, WindowNo); if (zoomWinID > 0) ZoomWindow = zoomWinID; StringBuilder realSQL = new StringBuilder("SELECT "); realSQL.append(TableName).append(".").append(KeyColumn).append(",NULL,"); StringBuilder displayColumn = getDisplayColumn(language, TableName, list); realSQL.append(displayColumn.toString()); realSQL.append(",").append(TableName).append(".IsActive"); // Translation if (isTranslated && !Env.isBaseLanguage(language, TableName)) { realSQL.append(" FROM ").append(TableName) .append(" INNER JOIN ").append(TableName).append("_TRL ON (") .append(TableName).append(".").append(KeyColumn) .append("=").append(TableName).append("_Trl.").append(KeyColumn) .append(" AND ").append(TableName).append("_Trl.AD_Language='") .append(language.getAD_Language()).append("')"); } else // no translation { realSQL.append(" FROM ").append(TableName); } String directQuery = realSQL.toString() + " WHERE " + TableName + "." + KeyColumn + "=?"; // Order by Display realSQL.append(" ORDER BY 3"); MQuery zoomQuery = null; // corrected in VLookup if (s_log.isLoggable(Level.FINE)) s_log.fine("ColumnName=" + ColumnName + " - " + realSQL); StringBuilder msginf = new StringBuilder().append(TableName).append(".").append(KeyColumn); MLookupInfo lInfo = new MLookupInfo(realSQL.toString(), TableName, msginf.toString(), ZoomWindow, ZoomWindowPO, zoomQuery); lInfo.DisplayColumn = displayColumn.toString(); lInfo.QueryDirect = MRole.getDefault().addAccessSQL(directQuery, TableName, true, false); List lookupDisplayColumns = new ArrayList(); for (LookupDisplayColumn ldc : list) { lookupDisplayColumns.add(ldc.ColumnName); } lInfo.lookupDisplayColumns = lookupDisplayColumns; if(list != null) { lInfo.lookupDisplayColumnNames = new ArrayList<>(); for (LookupDisplayColumn ldc : list) { lInfo.lookupDisplayColumnNames.add(ldc.ColumnName); } } s_cacheRefTable.put(cacheKey.toString(), lInfo.cloneIt()); return lInfo; } // getLookup_TableDir /** * @param language * @param tableName * @param list * @return display columns */ private static StringBuilder getDisplayColumn(Language language, String tableName, ArrayList list) { return getDisplayColumn(language, tableName, list, tableName); } /** * @param language * @param TableName * @param list * @param baseTable * @return display columns */ private static StringBuilder getDisplayColumn(Language language, String TableName, ArrayList list, String baseTable) { StringBuilder displayColumn = new StringBuilder(); int size = list.size(); // Get Display Column for (int i = 0; i < size; i++) { if (i > 0) { displayColumn.append(" ||'") .append(MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx()))) .append("'|| " ); } LookupDisplayColumn ldc = (LookupDisplayColumn)list.get(i); StringBuilder msg = new StringBuilder().append(TableName).append(".").append(ldc.ColumnName); String columnSQL = ldc.IsVirtual ? ldc.ColumnSQL : msg.toString(); displayColumn.append("NVL("); // translated if (ldc.IsTranslated && !Env.isBaseLanguage(language, TableName) && !ldc.IsVirtual && baseTable != null && !(TableName+"_Trl").equalsIgnoreCase(baseTable)) { displayColumn.append(TableName).append("_Trl.").append(ldc.ColumnName); } // date, number else if (DisplayType.isDate(ldc.DisplayType) || DisplayType.isNumeric(ldc.DisplayType)) { displayColumn.append(DB.TO_CHAR(columnSQL, ldc.DisplayType, language.getAD_Language())); } // Table else if ((ldc.DisplayType == DisplayType.Table || ldc.DisplayType == DisplayType.TableUU || ldc.DisplayType == DisplayType.Search || ldc.DisplayType == DisplayType.SearchUU) && ldc.AD_Reference_ID != 0) { String embeddedSQL; if (ldc.IsVirtual) embeddedSQL = getLookup_TableEmbed (language, ldc.ColumnSQL, TableName, ldc.AD_Reference_ID); else embeddedSQL = getLookup_TableEmbed (language, ldc.ColumnName, TableName, ldc.AD_Reference_ID); if (embeddedSQL != null) displayColumn.append("(").append(embeddedSQL).append(")"); } // TableDir else if ((ldc.DisplayType == DisplayType.TableDir || ldc.DisplayType == DisplayType.Search) && ldc.ColumnName.endsWith("_ID") || (ldc.DisplayType == DisplayType.TableDirUU || ldc.DisplayType == DisplayType.SearchUU) && ldc.ColumnName.endsWith("_UU")) { String embeddedSQL; if (ldc.IsVirtual) embeddedSQL = getLookup_TableDirEmbed(language, ldc.ColumnName, TableName, ldc.ColumnSQL); else embeddedSQL = getLookup_TableDirEmbed(language, ldc.ColumnName, TableName); if (embeddedSQL != null) displayColumn.append("(").append(embeddedSQL).append(")"); } // List else if (DisplayType.isList(ldc.DisplayType)) { if (ldc.DisplayType == DisplayType.ChosenMultipleSelectionList) { displayColumn.append(columnSQL); } else { String embeddedSQL = getLookup_ListEmbed(language, ldc.AD_Reference_ID, ldc.ColumnName); if (embeddedSQL != null) displayColumn.append("(").append(embeddedSQL).append(")"); } } // ID else if (DisplayType.isID(ldc.DisplayType)) { displayColumn.append(DB.TO_CHAR(columnSQL, ldc.DisplayType, language.getAD_Language())); } // String else { displayColumn.append(columnSQL); } displayColumn.append(",'-1')"); } return displayColumn; } /** * Get embedded SQL for TableDir Lookup display type * * @param language language * @param ColumnName column name * @param BaseTable base table * @return SELECT Column FROM TableName WHERE BaseTable.ColumnName=TableName.ColumnName * @see #getLookup_TableDirEmbed(Language, String, String, String) */ static public String getLookup_TableDirEmbed (Language language, String ColumnName, String BaseTable) { return getLookup_TableDirEmbed (language, ColumnName, BaseTable, ColumnName); } // getLookup_TableDirEmbed /** * Get embedded SQL for TableDir Lookup display type * * @param language language * @param ColumnName column name * @param BaseTable base table * @param BaseColumn base column * @return SELECT Column FROM TableName WHERE BaseTable.BaseColumn=TableName.ColumnName */ static public String getLookup_TableDirEmbed (Language language, String ColumnName, String BaseTable, String BaseColumn) { String KeyColumn = MQuery.getZoomColumnName(ColumnName); String TableName = MQuery.getZoomTableName(ColumnName); ArrayList list = getListIdentifiers(TableName); // Do we have columns ? if (list == null || list.size() == 0) { s_log.log(Level.SEVERE, "No Identifier records found: " + ColumnName); return ""; } // set isTranslated boolean isTranslated = false; for (LookupDisplayColumn ldc : list) { if (!isTranslated && ldc.IsTranslated) { isTranslated = true; break; } } // StringBuilder embedSQL = new StringBuilder("SELECT "); StringBuilder displayColumn = getDisplayColumn(language, TableName, list, BaseTable); embedSQL.append(displayColumn.toString()); embedSQL.append(" FROM ").append(TableName); // Translation if ( isTranslated && !Env.isBaseLanguage(language, TableName) && !(TableName+"_Trl").equalsIgnoreCase(BaseTable)) // IDEMPIERE-1070 { embedSQL.append(" INNER JOIN ").append(TableName).append("_TRL ON (") .append(TableName).append(".").append(KeyColumn) .append("=").append(TableName).append("_Trl.").append(KeyColumn) .append(" AND ").append(TableName).append("_Trl.AD_Language=") .append(DB.TO_STRING(language.getAD_Language())).append(")"); } embedSQL.append(" WHERE "); // If is not virtual column - teo_sarca [ 1739530 ] if (! BaseColumn.trim().startsWith("(")) { embedSQL.append(BaseTable).append(".").append(BaseColumn); } else { embedSQL.append(BaseColumn); } embedSQL.append("=").append(TableName).append(".").append(ColumnName); // return embedSQL.toString(); } // getLookup_TableDirEmbed /** * @param TableName * @return identifier list for a table */ private static ArrayList getListIdentifiers(String TableName) { ArrayList list = new ArrayList(); MTable table = MTable.get(Env.getCtx(), TableName); if (table == null) return null; for (String idColumnName : table.getIdentifierColumns()) { MColumn column = table.getColumn(idColumnName); LookupDisplayColumn ldc = new LookupDisplayColumn(column.getColumnName(), column.getColumnSQL(true), column.isTranslated(), column.getAD_Reference_ID(), column.getAD_Reference_Value_ID()); list.add (ldc); } return list; } } // MLookupFactory