From a950ba9f008b52123e3e2027056fc15ed348f380 Mon Sep 17 00:00:00 2001 From: hengsin Date: Sun, 19 Dec 2021 22:01:25 +0800 Subject: [PATCH] IDEMPIERE-5113 MInfoWindow: column access doesn't work if From clause is created without synonym/alias (#1064) --- .../src/org/compiere/model/MInfoColumn.java | 16 +- .../src/org/compiere/model/MInfoWindow.java | 11 +- .../org/adempiere/webui/info/InfoWindow.java | 10 +- .../idempiere/test/model/MInfoWindowTest.java | 157 ++++++++++++++++++ 4 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 org.idempiere.test/src/org/idempiere/test/model/MInfoWindowTest.java diff --git a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java index 82147d4fc4..dafe37d533 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java @@ -104,14 +104,24 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn, Immutab */ public boolean isColumnAccess(TableInfo[] tableInfos) { + String synonym = null; + String column = null; int index = getSelectClause().indexOf("."); if (index == getSelectClause().lastIndexOf(".") && index >= 0) { - String synonym = getSelectClause().substring(0, index); - String column = getSelectClause().substring(index+1); + synonym = getSelectClause().substring(0, index); + column = getSelectClause().substring(index+1); + } + else if (tableInfos.length == 1) + { + synonym = Util.isEmpty(tableInfos[0].getSynonym(), true) ? tableInfos[0].getTableName() : tableInfos[0].getSynonym(); + column = getSelectClause(); + } + if (!Util.isEmpty(synonym, true) && !Util.isEmpty(column, true)) + { for(TableInfo tableInfo : tableInfos) { - if (tableInfo.getSynonym() != null && tableInfo.getSynonym().equals(synonym)) + if ((!Util.isEmpty(tableInfo.getSynonym(),true) && tableInfo.getSynonym().equals(synonym)) || (Util.isEmpty(tableInfo.getSynonym(),true) && tableInfo.getTableName().equals(synonym))) { String tableName = tableInfo.getTableName(); MTable mTable = MTable.get(Env.getCtx(), tableName); diff --git a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java index 506e149175..af62a138a5 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java @@ -518,5 +518,14 @@ public class MInfoWindow extends X_AD_InfoWindow implements ImmutablePOSupport @Override public I_AD_Table getAD_Table() throws RuntimeException { return MTable.get(Env.getCtx(), getAD_Table_ID(), get_TrxName()); - } + } + + /** + * + * @return array of {@link TableInfo} + */ + public TableInfo[] getTableInfos() { + AccessSqlParser sqlParser = new AccessSqlParser("SELECT * FROM " + getFromClause()); + return sqlParser.getTableInfo(0); + } } // MInfoWindow diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index 926040c902..a7487304bf 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -69,7 +69,6 @@ import org.adempiere.webui.window.FDialog; import org.compiere.minigrid.ColumnInfo; import org.compiere.minigrid.EmbedWinInfo; import org.compiere.minigrid.IDColumn; -import org.compiere.model.AccessSqlParser; import org.compiere.model.AccessSqlParser.TableInfo; import org.compiere.model.GridField; import org.compiere.model.GridFieldVO; @@ -606,8 +605,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL String tableName = null; tableName = MTable.getTableName(Env.getCtx(), infoWindow.getAD_Table_ID()); - AccessSqlParser sqlParser = new AccessSqlParser("SELECT * FROM " + infoWindow.getFromClause()); - tableInfos = sqlParser.getTableInfo(0); + tableInfos = infoWindow.getTableInfos(); if (tableInfos[0].getSynonym() != null && tableInfos[0].getSynonym().trim().length() > 0) { p_tableName = tableInfos[0].getSynonym().trim(); if (p_whereClause != null && p_whereClause.trim().length() > 0) { @@ -745,8 +743,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL MInfoWindow embedInfo = new MInfoWindow(Env.getCtx(), infoRelatedID, null); - AccessSqlParser sqlParser = new AccessSqlParser("SELECT * FROM " + embedInfo.getFromClause()); - TableInfo[] tableInfos = sqlParser.getTableInfo(0); + TableInfo[] tableInfos = embedInfo.getTableInfos(); if (tableInfos[0].getSynonym() != null && tableInfos[0].getSynonym().trim().length() > 0){ tableName = tableInfos[0].getSynonym().trim(); } @@ -2048,8 +2045,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL */ public ArrayList getInfoColumnslayout(MInfoWindow info){ - AccessSqlParser sqlParser = new AccessSqlParser("SELECT * FROM " + info.getFromClause()); - TableInfo[] tableInfos = sqlParser.getTableInfo(0); + TableInfo[] tableInfos = info.getTableInfos(); MInfoColumn[] p_infoColumns = info.getInfoColumns(tableInfos); InfoColumnVO[] infoColumns = InfoColumnVO.create(Env.getCtx(), p_infoColumns); diff --git a/org.idempiere.test/src/org/idempiere/test/model/MInfoWindowTest.java b/org.idempiere.test/src/org/idempiere/test/model/MInfoWindowTest.java new file mode 100644 index 0000000000..84e121e7c7 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/MInfoWindowTest.java @@ -0,0 +1,157 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.compiere.model.AccessSqlParser.TableInfo; +import org.compiere.model.MColumn; +import org.compiere.model.MColumnAccess; +import org.compiere.model.MInfoColumn; +import org.compiere.model.MInfoWindow; +import org.compiere.model.MRole; +import org.compiere.model.MTable; +import org.compiere.model.MTest; +import org.compiere.model.PO; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * + * @author hengsin + * + */ +public class MInfoWindowTest extends AbstractTestCase { + + public MInfoWindowTest() { + } + + @Test + public void testColumnAccess() { + MInfoWindow infoWindow = new MInfoWindow(Env.getCtx(), 0, getTrxName()); + MInfoColumn infoColumn1 = new MInfoColumn(Env.getCtx(), 0, getTrxName()); + MInfoColumn infoColumn2 = new MInfoColumn(Env.getCtx(), 0, getTrxName()); + try { + PO.setCrossTenantSafe(); + infoWindow.setAD_Table_ID(MTest.Table_ID); + infoWindow.setName("testColumnAccess"); + infoWindow.setFromClause("Test t"); + infoWindow.saveEx(); + + infoColumn1.setAD_InfoWindow_ID(infoWindow.get_ID()); + infoColumn1.setName(MTest.COLUMNNAME_T_Amount); + infoColumn1.setEntityType("U"); + infoColumn1.setSelectClause("t."+MTest.COLUMNNAME_T_Amount); + infoColumn1.setSeqNo(10); + infoColumn1.setAD_Reference_ID(DisplayType.Amount); + infoColumn1.setColumnName(MTest.COLUMNNAME_T_Amount); + infoColumn1.saveEx(); + + infoColumn2.setAD_InfoWindow_ID(infoWindow.get_ID()); + infoColumn2.setName(MTest.COLUMNNAME_T_DateTime); + infoColumn2.setEntityType("U"); + infoColumn2.setSelectClause("t."+MTest.COLUMNNAME_T_DateTime); + infoColumn2.setSeqNo(10); + infoColumn2.setAD_Reference_ID(DisplayType.DateTime); + infoColumn2.setColumnName(MTest.COLUMNNAME_T_DateTime); + infoColumn2.saveEx(); + } finally { + PO.clearCrossTenantSafe(); + } + + infoWindow.getInfoColumns(true, true); + TableInfo[] tableInfos = infoWindow.getTableInfos(); + MInfoColumn[] infoColumns = infoWindow.getInfoColumns(tableInfos); + assertNotNull(infoColumns); + assertEquals(2, infoColumns.length); + + MRole role = MRole.getDefault(); + MTable table = MTable.get(infoWindow.getAD_Table_ID()); + MColumn column = table.getColumn(infoColumn2.getColumnName()); + assertNotNull(column); + + MColumnAccess ca = new MColumnAccess(Env.getCtx(), 0, null); + ca.setAD_Role_ID(role.getAD_Role_ID()); + ca.setIsExclude(true); + ca.setAD_Table_ID(table.get_ID()); + ca.setAD_Column_ID(column.get_ID()); + ca.setIsReadOnly(false); + ca.saveEx(); + + try { + role.loadAccess(true); + infoColumns = infoWindow.getInfoColumns(tableInfos); + assertNotNull(infoColumns); + assertEquals(1, infoColumns.length); + + try { + PO.setCrossTenantSafe(); + infoColumn1.setSelectClause(MTest.Table_Name+"."+MTest.COLUMNNAME_T_Amount); + infoColumn1.saveEx(); + + infoColumn2.setSelectClause(MTest.Table_Name+"."+MTest.COLUMNNAME_T_DateTime); + infoColumn2.saveEx(); + + infoWindow.setFromClause("Test"); + infoWindow.getInfoColumns(true, true); + infoWindow.saveEx(); + } finally { + PO.clearCrossTenantSafe(); + } + + infoWindow.getInfoColumns(true, true); + tableInfos = infoWindow.getTableInfos(); + infoColumns = infoWindow.getInfoColumns(tableInfos); + assertNotNull(infoColumns); + assertEquals(1, infoColumns.length); + + try { + PO.setCrossTenantSafe(); + infoColumn1.setSelectClause(MTest.COLUMNNAME_T_Amount); + infoColumn1.saveEx(); + + infoColumn2.setSelectClause(MTest.COLUMNNAME_T_DateTime); + infoColumn2.saveEx(); + + infoWindow.setFromClause("Test"); + infoWindow.getInfoColumns(true, true); + infoWindow.saveEx(); + } finally { + PO.clearCrossTenantSafe(); + } + + infoWindow.getInfoColumns(true, true); + tableInfos = infoWindow.getTableInfos(); + infoColumns = infoWindow.getInfoColumns(tableInfos); + assertNotNull(infoColumns); + assertEquals(1, infoColumns.length); + } finally { + ca.deleteEx(true); + } + } +}