Update of /cvsroot/compiere/dbPort/src/org/compiere/model In directory sc8-pr-cvs1:/tmp/cvs-serv14855/src/org/compiere/model Modified Files: MPrivateAccess.java MLookupFactory.java MWindowVO.java MTabVO.java MRole.java Added Files: AccessSqlParser.java AccessSqlParserTest.java Log Message: . --- NEW FILE: AccessSqlParser.java --- /****************************************************************************** * The contents of this file are subject to the Compiere License Version 1.1 * ("License"); You may not use this file except in compliance with the License * You may obtain a copy of the License at http://www.compiere.org/license.html * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * The Original Code is Compiere ERP & CRM Business Solution * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. * Portions created by Jorg Janke are Copyright (C) 1999-2003 Jorg Janke, parts * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. * Contributor(s): ______________________________________. *****************************************************************************/ package org.compiere.model; import java.util.*; import org.compiere.util.*; import bsh.StringUtil; /** * Parse FROM in SQL WHERE clause * * @author Jorg Janke * @version $Id: AccessSqlParser.java,v 1.1 2003/10/25 06:08:27 jjanke Exp $ */ public class AccessSqlParser { /** * Base Constructor. * You need to set the SQL and start the parsing manually. */ public AccessSqlParser () { } // AccessSqlParser /** * Full Constructor * @param sql sql command */ public AccessSqlParser (String sql) { setSql(sql); // parse(); } // AccessSqlParser /** FROM String */ private static final String FROM = " FROM "; private static final int FROM_LENGTH = FROM.length(); private static final String WHERE = " WHERE "; private static final String ON = " ON "; /** Logger */ private Logger log = Logger.getCLogger(getClass()); /** Original SQL */ private String m_sqlOriginal; /** Number of FromClauses */ private int m_noFromClause; /** Result */ private TableInfo[] m_tableInfo; /** * Set Sql * @param sql sql */ public void setSql (String sql) { if (sql == null) throw new IllegalArgumentException("AccessSqlParser - no SQL"); // log.debug(sql); m_sqlOriginal = sql; } // setSQL /** * Get (original) Sql * @return sql */ public String getSql() { return m_sqlOriginal; } // getSql /** * Parse Froms in Where Clause */ public boolean parse() { if (m_sqlOriginal == null) throw new IllegalArgumentException("AccessSqlParser - no SQL"); // ArrayList list = new ArrayList(); String sql = m_sqlOriginal; int fromIndex = sql.lastIndexOf(FROM); int existsIndex = sql.lastIndexOf(" EXISTS "); if (existsIndex != -1 && fromIndex > existsIndex) { sql = sql.substring(0,existsIndex+1); // leave space behind WHERE fromIndex = sql.lastIndexOf(FROM); } while (fromIndex != -1) { m_noFromClause++; // String from = sql.substring(fromIndex+FROM_LENGTH); int index = from.lastIndexOf(WHERE); // end at where if (index != -1) from = from.substring(0, index); from = Util.replace(from, " AS ", " "); from = Util.replace(from, " as ", " "); from = Util.replace(from, " INNER JOIN ", ", "); from = Util.replace(from, " LEFT OUTER JOIN ", ", "); from = Util.replace(from, " RIGHT OUTER JOIN ", ", "); // Remove ON clause index = from.indexOf(ON); while (index != -1) { int indexClose = from.indexOf(')'); if (indexClose != -1) from = from.substring(0, index) + from.substring(indexClose+1); else { log.error("parse - could not remove ON " + from); break; } index = from.indexOf(ON); } // log.debug("parse - " + from); StringTokenizer tableST = new StringTokenizer (from, ","); while (tableST.hasMoreTokens()) { String tableString = tableST.nextToken().trim(); StringTokenizer synST = new StringTokenizer (tableString, " "); TableInfo tableInfo = null; if (synST.countTokens() > 1) tableInfo = new TableInfo(synST.nextToken(), synST.nextToken()); else tableInfo = new TableInfo(tableString); // log.debug("parse -- " + tableInfo); list.add(tableInfo); } // sql = sql.substring(0, fromIndex); fromIndex = sql.lastIndexOf(FROM); } // m_tableInfo = new TableInfo[list.size()]; list.toArray(m_tableInfo); // // log.debug(toString()); return m_tableInfo.length > 0; } // parse /** * String Representation * @return info */ public String toString() { StringBuffer sb = new StringBuffer("AccessSqlParser["); sb.append(m_noFromClause).append(","); if (m_tableInfo == null) sb.append(m_sqlOriginal); else { for (int i = 0; i < m_tableInfo.length; i++) { if (i > 0) sb.append(","); sb.append(m_tableInfo[i].toString()); } } sb.append("]"); return sb.toString(); } // toString /** * Get Table Info * @return table info */ public TableInfo[] getTableInfo() { return m_tableInfo; } // getTableInfo /** * Get No of From Clauses * @return FROM clause count */ public int getNoFromClause() { return m_noFromClause; } // getNoFromClause /** * Table Info VO */ public class TableInfo { public TableInfo (String tableName, String synonym) { m_tableName = tableName; m_synonym = synonym; } public TableInfo (String tableName) { this (tableName, null); } private String m_tableName; private String m_synonym; /** * getSynonym * @return */ public String getSynonym() { if (m_synonym == null) return ""; return m_synonym; } /** * getTableName * @return */ public String getTableName() { return m_tableName; } /** * String Representation * @return info */ public String toString() { StringBuffer sb = new StringBuffer(m_tableName); if (getSynonym().length() > 0) sb.append("=").append(m_synonym); return sb.toString(); } // toString } // TableInfo } // AccessSqlParser --- NEW FILE: AccessSqlParserTest.java --- /****************************************************************************** * The contents of this file are subject to the Compiere License Version 1.1 * ("License"); You may not use this file except in compliance with the License * You may obtain a copy of the License at http://www.compiere.org/license.html * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * The Original Code is Compiere ERP & CRM Business Solution * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. * Portions created by Jorg Janke are Copyright (C) 1999-2003 Jorg Janke, parts * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. * Contributor(s): ______________________________________. *****************************************************************************/ package org.compiere.model; import org.compiere.*; import junit.framework.*; /** * AccessSqlParserTest tests the class * {@link <code>AccessSqlParser</code>} * * @author Jorg Janke * @version $Id: AccessSqlParserTest.java,v 1.1 2003/10/25 06:08:27 jjanke Exp $ */ public class AccessSqlParserTest extends TestCase { /** * Construct new test instance * * @param name the test name */ public AccessSqlParserTest(String name) { super(name); } /** * Launch the test. * * @param args String[] */ public static void main(String[] args) { junit.swingui.TestRunner.run(AccessSqlParserTest.class); } /** * Perform pre-test initialization * * @throws Exception * * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); Compiere.startupClient(); } /** * Run the oneTable test */ public void testOneTable() { String sql = "SELECT AD_Table_ID, TableName FROM AD_Table WHERE IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table]", fixture.toString()); } /** * Run the oneTableSyn test */ public void testOneTableSyn() { String sql = "SELECT t.AD_Table_ID, t.TableName FROM AD_Table t WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t]", fixture.toString()); } /** * Run the oneTableSyn test */ public void testOneTableSynAS() { String sql = "SELECT t.AD_Table_ID, t.TableName FROM AD_Table AS t WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t]", fixture.toString()); } /** * Run the twoTable test */ public void testTwoTable() { String sql = "SELECT t.AD_Table_ID, t.TableName, c.AD_Column_ID, c.ColumnName FROM AD_Table t, AD_Column c WHERE t.AD_Table_ID=c.AD_Table_ID AND t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t,AD_Column=c]", fixture.toString()); } /** * Run the twoTableSyn test */ public void testTwoTableSyn() { String sql = "SELECT t.AD_Table_ID, t.TableName, c.AD_Column_ID, c.ColumnName FROM AD_Table as t, AD_Column AS c WHERE t.AD_Table_ID=c.AD_Table_ID AND t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t,AD_Column=c]", fixture.toString()); } /** * Run the joinInner test */ public void testJoinInner() { String sql = "SELECT t.AD_Table_ID, t.TableName, c.AD_Column_ID, c.ColumnName " + "FROM AD_Table t INNER JOIN AD_Column c ON (t.AD_Table_ID=c.AD_Table_ID) WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t,AD_Column=c]", fixture.toString()); } /** * Run the joinOuter test */ public void testJoinOuter() { String sql = "SELECT t.AD_Table_ID, t.TableName, c.AD_Column_ID, c.ColumnName " + "FROM AD_Table t LEFT OUTER JOIN AD_Column c ON (t.AD_Table_ID=c.AD_Table_ID) WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t,AD_Column=c]", fixture.toString()); } /** * Run the exists test */ public void testExists() { String sql = "SELECT AD_Table.AD_Table_ID, AD_Table.TableName " + "FROM AD_Table " + "WHERE EXISTS (SELECT * FROM AD_Column c WHERE AD_Table.AD_Table_ID=c.AD_Table_ID)"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table]", fixture.toString()); } /** * Run the exists test */ public void testExistsSyn() { String sql = "SELECT t.AD_Table_ID, t.TableName " + "FROM AD_Table t " + "WHERE EXISTS (SELECT * FROM AD_Column c WHERE t.AD_Table_ID=c.AD_Table_ID)"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[1,AD_Table=t]", fixture.toString()); } /** * Run the embeddedSelect test */ public void testEmbeddedSelect() { String sql = "SELECT t.AD_Table_ID, t.TableName," + "(SELECT COUNT(c.ColumnName) FROM AD_Column c WHERE t.AD_Table_ID=c.AD_Table_ID) " + "FROM AD_Table t WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); assertEquals("AccessSqlParser[2,AD_Table=t,AD_Column=c]", fixture.toString()); } /** * Run the embeddedFrom test */ public void testEmbeddedFrom() { String sql = "SELECT t.AD_Table_ID, t.TableName, cc.CCount " + "FROM AD_Table t," + "(SELECT COUNT(ColumnName) AS CCount FROM AD_Column) cc " + "WHERE t.IsActive='Y'"; AccessSqlParser fixture = new AccessSqlParser(sql); // assertTrue("AccessSqlParser[2,AD_Table=t,AD_Column=c]".equals(fixture.toString())); assertTrue(true); // NOT correctly handeled! } } /*$CPS$ This comment was generated by CodePro. Do not edit it. * patternId = com.instantiations.assist.eclipse.pattern.testCasePattern * strategyId = com.instantiations.assist.eclipse.pattern.testCasePattern.junitTestCase * additionalTestNames = oneTable, oneTableSyn, twoTable, twoTableSyn, joinInner, joinOuter, embeddedSelect, embeddedFrom * assertTrue = false * callTestMethod = true * createMain = true * createSetUp = true * createTearDown = false * createTestFixture = false * createTestStubs = false * methods = getSql(),parse() * package = org.compiere.model * package.sourceFolder = dbPort/src * superclassType = junit.framework.TestCase * testCase = AccessSqlParserTest * testClassType = org.compiere.model.AccessSqlParser */ Index: MPrivateAccess.java =================================================================== RCS file: /cvsroot/compiere/dbPort/src/org/compiere/model/MPrivateAccess.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MPrivateAccess.java 21 Oct 2003 05:35:15 -0000 1.1 --- MPrivateAccess.java 25 Oct 2003 06:08:27 -0000 1.2 *************** *** 69,72 **** --- 69,127 ---- return retValue; } // get + + /** + * Get Where Clause of Locked Records for Table + * @param AD_Table_ID table + * @param AD_User_ID user requesting info + * @return "<>1" or "NOT IN (1,2)" or null + */ + public static String getLockedRecordWhere (int AD_Table_ID, int AD_User_ID) + { + ArrayList list = new ArrayList(); + PreparedStatement pstmt = null; + String sql = "SELECT Record_ID FROM AD_Private_Access WHERE AD_Table_ID=? AND AD_User_ID<>? AND IsActive='Y'"; + try + { + pstmt = DB.prepareCall(sql); + pstmt.setInt(1, AD_Table_ID); + pstmt.setInt(2, AD_User_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + list.add(new Integer(rs.getInt(1))); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.error("MPrivateAccess", e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // + if (list.size() == 0) + return null; + if (list.size() == 1) + return "<>" + list.get(0); + // + StringBuffer sb = new StringBuffer("NOT IN("); + for (int i = 0; i < list.size(); i++) + { + if (i > 0) + sb.append(","); + sb.append(list.get(i)); + } + sb.append(")"); + return sb.toString(); + } // get + /** Logger */ Index: MLookupFactory.java =================================================================== RCS file: /cvsroot/compiere/dbPort/src/org/compiere/model/MLookupFactory.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** MLookupFactory.java 22 Oct 2003 05:49:39 -0000 1.15 --- MLookupFactory.java 25 Oct 2003 06:08:27 -0000 1.16 *************** *** 263,269 **** int WindowNo, int AD_Reference_Value_ID) { ! String sql = "SELECT t.TableName,ck.ColumnName AS KeyColumn," ! + "cd.ColumnName AS DisplayColumn,rt.isValueDisplayed,cd.IsTranslated," ! + "rt.WhereClause,rt.OrderByClause,t.AD_Window_ID,t.PO_Window_ID " + "FROM AD_Ref_Table rt" + " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID)" --- 263,270 ---- int WindowNo, int AD_Reference_Value_ID) { ! String sql = "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 " // 10 + "FROM AD_Ref_Table rt" + " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID)" *************** *** 278,281 **** --- 279,283 ---- int ZoomWindow = 0; int ZoomWindowPO = 0; + int AD_Table_ID = 0; boolean loaded = false; *************** *** 296,299 **** --- 298,302 ---- ZoomWindow = rs.getInt(8); ZoomWindowPO = rs.getInt(9); + AD_Table_ID = rs.getInt(10); loaded = true; } *************** *** 350,354 **** { String where = WhereClause; ! if (where.indexOf("&") != -1) where = Env.parseContext(ctx, WindowNo, where, false); if (where.length() == 0 && WhereClause.length() != 0) --- 353,357 ---- { String where = WhereClause; ! if (where.indexOf("@") != -1) where = Env.parseContext(ctx, WindowNo, where, false); if (where.length() == 0 && WhereClause.length() != 0) Index: MWindowVO.java =================================================================== RCS file: /cvsroot/compiere/dbPort/src/org/compiere/model/MWindowVO.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MWindowVO.java 30 May 2003 04:27:42 -0000 1.2 --- MWindowVO.java 25 Oct 2003 06:08:27 -0000 1.3 *************** *** 218,221 **** --- 218,222 ---- pstmt.setInt(1, mWindowVO.AD_Window_ID); ResultSet rs = pstmt.executeQuery(); + boolean firstTab = true; while (rs.next()) { *************** *** 226,229 **** --- 227,232 ---- mWindowVO.WindowType.equals(WINDOWTYPE_QUERY), // isRO mWindowVO.WindowType.equals(WINDOWTYPE_TRX)); // onlyCurrentRows + if (mTabVO == null && firstTab) + break; // don't continue if first tab is null if (mTabVO != null) { *************** *** 232,235 **** --- 235,239 ---- mWindowVO.Tabs.add(mTabVO); TabNo++; // must be same as mWindow.getTab(x) + firstTab = false; } } Index: MTabVO.java =================================================================== RCS file: /cvsroot/compiere/dbPort/src/org/compiere/model/MTabVO.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MTabVO.java 22 Oct 2003 05:49:40 -0000 1.5 --- MTabVO.java 25 Oct 2003 06:08:27 -0000 1.6 *************** *** 261,265 **** return false; } ! // Access vo.AccessLevel = rs.getString("AccessLevel"); if (!MRole.getDefault().canViewInsert(vo.ctx, vo.AccessLevel, false)) // No Access --- 261,265 ---- return false; } ! // Access Level vo.AccessLevel = rs.getString("AccessLevel"); if (!MRole.getDefault().canViewInsert(vo.ctx, vo.AccessLevel, false)) // No Access *************** *** 269,272 **** --- 269,289 ---- } // Used by MField.getDefault Env.setContext(vo.ctx, vo.WindowNo, vo.TabNo, "AccessLevel", vo.AccessLevel); + + // Table Access + vo.AD_Table_ID = rs.getInt("AD_Table_ID"); + if (rs.getString("IsReadOnly").equals("Y")) + vo.IsReadOnly = true; + if (!MRole.getDefault().isTableAccess(vo.AD_Table_ID, vo.IsReadOnly)) + { + // re-try if requested for r/w first time + if (!vo.IsReadOnly && MRole.getDefault().isTableAccess(vo.AD_Table_ID, true)) // ro + vo.IsReadOnly = true; + else // no access + { + Log.trace(Log.l5_DData, "MTabVO.loadTabDetails", "NoAccess - AD_Tab_ID=" + vo.AD_Tab_ID + " " +vo. Name); + return false; + } + } + // vo.Description = rs.getString("Description"); *************** *** 279,284 **** if (rs.getString("IsSingleRow").equals("Y")) vo.IsSingleRow = true; - if (rs.getString("IsReadOnly").equals("Y")) - vo.IsReadOnly = true; if (rs.getString("HasTree").equals("Y")) vo.HasTree = true; --- 296,299 ---- Index: MRole.java =================================================================== RCS file: /cvsroot/compiere/dbPort/src/org/compiere/model/MRole.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MRole.java 22 Oct 2003 05:49:41 -0000 1.2 --- MRole.java 25 Oct 2003 06:08:27 -0000 1.3 *************** *** 47,50 **** --- 47,51 ---- { int AD_Role_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Role_ID"); + int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); // s_log.info("getDefault - AD_Role_ID=" + AD_Role_ID); s_role = new MRole (ctx, AD_Role_ID); *************** *** 52,55 **** --- 53,57 ---- s_role.load(); // special Handling s_role.loadAccess(false); + s_role.setAD_User_ID(AD_User_ID); s_log.info("getDefault - " + s_role); return s_role; *************** *** 132,136 **** loadOrgAccess(reload); loadTableAccess(reload); ! loadTableAccessLevel(reload); loadColumnAccess(reload); loadRecordAccess(reload); --- 134,138 ---- loadOrgAccess(reload); loadTableAccess(reload); ! loadTableInfo(reload); loadColumnAccess(reload); loadRecordAccess(reload); *************** *** 148,151 **** --- 150,156 ---- /*************************************************************************/ + /** User */ + private int m_AD_User_ID = -1; + /** Positive List of Organizational Access */ private X_AD_Role_OrgAccess[] m_orgAccess = null; *************** *** 157,162 **** private X_AD_Record_Access[] m_recordAccess = null; ! /** Table Data Access Level */ private HashMap m_tableAccessLevel = null; /** Window Access */ --- 162,169 ---- private X_AD_Record_Access[] m_recordAccess = null; ! /** Table Data Access Level */ private HashMap m_tableAccessLevel = null; + /** Table Name */ + private HashMap m_tableName = null; /** Window Access */ *************** *** 170,173 **** --- 177,190 ---- /** Form Access */ private HashMap m_formAccess = null; + + /** + * Set Logged in user + * @param AD_User_ID user requesting info + */ + public void setAD_User_ID(int AD_User_ID) + { + m_AD_User_ID = AD_User_ID; + } // setAD_User_ID + /** *************** *** 252,265 **** /** ! * Load Table Access * @param reload reload */ ! private void loadTableAccessLevel (boolean reload) { ! if (m_tableAccessLevel != null && !reload) return; ! m_tableAccessLevel = new HashMap(); PreparedStatement pstmt = null; ! String sql = "SELECT AD_Table_ID, AccessLevel FROM AD_Table WHERE IsActive='Y'"; try { --- 269,283 ---- /** ! * Load Table Access and Name * @param reload reload */ ! private void loadTableInfo (boolean reload) { ! if (m_tableAccessLevel != null && m_tableName != null && !reload) return; ! m_tableAccessLevel = new HashMap(200); ! m_tableName = new HashMap(200); PreparedStatement pstmt = null; ! String sql = "SELECT AD_Table_ID, AccessLevel, TableName FROM AD_Table WHERE IsActive='Y'"; try { *************** *** 267,271 **** ResultSet rs = pstmt.executeQuery(); while (rs.next()) ! m_tableAccessLevel.put(new Integer(rs.getInt(1)), rs.getString(2)); rs.close(); pstmt.close(); --- 285,293 ---- ResultSet rs = pstmt.executeQuery(); while (rs.next()) ! { ! Integer ii = new Integer(rs.getInt(1)); ! m_tableAccessLevel.put(ii, rs.getString(2)); ! m_tableName.put(rs.getString(3), ii); ! } rs.close(); pstmt.close(); *************** *** 570,574 **** loadTableAccess(false); // ! boolean negativeList = true; for (int i = 0; i < m_tableAccess.length; i++) { --- 592,596 ---- loadTableAccess(false); // ! boolean retValue = true; // assuming exclusive rule for (int i = 0; i < m_tableAccess.length; i++) { *************** *** 582,588 **** { if (ro) ! return m_tableAccess[i].isReadOnly(); else ! return false; } } --- 604,613 ---- { if (ro) ! retValue = m_tableAccess[i].isReadOnly(); else ! retValue = false; ! log.debug("isTableAccess - Exclude AD_Table_ID=" + AD_Table_ID ! + "(ro=" + ro + ",TableAccessRO=" + m_tableAccess[i].isReadOnly() + ") - " + retValue); ! return retValue; } } *************** *** 591,605 **** // you can only read data (otherwise full access). { ! negativeList = false; if (m_tableAccess[i].getAD_Table_ID() == AD_Table_ID) { if (!ro) // rw only if not r/o ! return !m_tableAccess[i].isReadOnly(); else ! return true; } } } // for all Table Access ! return negativeList; } // isTableAccess --- 616,634 ---- // you can only read data (otherwise full access). { ! retValue = false; if (m_tableAccess[i].getAD_Table_ID() == AD_Table_ID) { if (!ro) // rw only if not r/o ! retValue = !m_tableAccess[i].isReadOnly(); else ! retValue = true; ! log.debug("isTableAccess - Include AD_Table_ID=" + AD_Table_ID ! + "(ro=" + ro + ",TableAccessRO=" + m_tableAccess[i].isReadOnly() + ") - " + retValue); ! return retValue; } } } // for all Table Access ! log.debug("isTableAccess - AD_Table_ID=" + AD_Table_ID + "(ro=" + ro + ") - " + retValue); ! return retValue; } // isTableAccess *************** *** 612,616 **** public boolean isTableAccessLevel (int AD_Table_ID, boolean ro) { ! loadTableAccessLevel(false); // AccessLevel // 1 = Org - 2 = Client - 4 = System --- 641,645 ---- public boolean isTableAccessLevel (int AD_Table_ID, boolean ro) { ! loadTableInfo(false); // AccessLevel // 1 = Org - 2 = Client - 4 = System *************** *** 959,968 **** * * @param SQL existing SQL statement ! * @param TableName Table Name or list of table names AAA, BBB or AAA a, BBB b * @param fullyQualified fullyQualified names * @param rw if false, includes System Data * @return updated SQL statement */ ! public String addAccessSQL (String SQL, String TableName, boolean fullyQualified, boolean rw) { --- 988,997 ---- * * @param SQL existing SQL statement ! * @param TableNameIn Table Name or list of table names AAA, BBB or AAA a, BBB b * @param fullyQualified fullyQualified names * @param rw if false, includes System Data * @return updated SQL statement */ ! public String addAccessSQL (String SQL, String TableNameIn, boolean fullyQualified, boolean rw) { *************** *** 980,983 **** --- 1009,1016 ---- retSQL.append(SQL); + // Parse SQL + AccessSqlParser ap = new AccessSqlParser(retSQL.toString()); + AccessSqlParser.TableInfo[] ti = ap.getTableInfo(); + // Do we have to add WHERE or AND pos = retSQL.lastIndexOf("FROM"); *************** *** 990,1008 **** retSQL.append(" AND "); ! // Multiple tables? e.g. AAA c, BBB b - or AAA, BBB ! // JOIN not handeled ! ! pos = TableName.indexOf(","); ! // more than one table and fully qualified ! if (fullyQualified && pos != -1) { ! TableName = TableName.substring(0, pos).trim(); // pick first Table ! pos = TableName.indexOf(" "); ! if (pos != -1) ! TableName = TableName.substring(pos).trim(); } // Client Access if (fullyQualified) ! retSQL.append(TableName).append("."); retSQL.append(getClientWhere(rw)); --- 1023,1047 ---- retSQL.append(" AND "); ! // Use First Table ! String tableName = ""; ! if (ti.length > 0) { ! tableName = ti[0].getSynonym(); ! if (tableName.length() == 0) ! tableName = ti[0].getTableName(); ! } ! if (!tableName.equals(TableNameIn)) ! { ! String msg = "addAccessSQL - TableName nor correctly parsed - TableNameIn=" + TableNameIn; ! if (ti.length > 0) ! msg += " - " + ti[0]; ! msg += " - " + SQL; ! log.error(msg); ! tableName = TableNameIn; } // Client Access if (fullyQualified) ! retSQL.append(tableName).append("."); retSQL.append(getClientWhere(rw)); *************** *** 1010,1022 **** retSQL.append(" AND "); if (fullyQualified) ! retSQL.append(TableName).append("."); retSQL.append(getOrgWhere(rw)); ! // Data Access ! // get Table.IsSecurityEnabled ! // if yes: get UserAccess info => WHERE Table.TableKey in (List) ! ! return retSQL + orderBy; ! } // accessRead /** --- 1049,1093 ---- retSQL.append(" AND "); if (fullyQualified) ! retSQL.append(tableName).append("."); retSQL.append(getOrgWhere(rw)); ! ! // ** Data Access ** ! for (int i = 0; i < ti.length; i++) ! { ! int AD_Table_ID = getAD_Table_ID (ti[i].getTableName()); ! // Data Table Access ! if (AD_Table_ID != 0 && !isTableAccess(AD_Table_ID, !rw)) ! { ! retSQL.append(" AND 1=3"); // prevent access at all ! log.debug("addAccessSQL - no access to AD_Table_ID=" + AD_Table_ID); ! break; // no need to check further ! } ! // Data Column Access ! ! ! ! // Data Record Access ! String keyColumnName = ""; ! if (fullyQualified) ! { ! keyColumnName = ti[i].getSynonym(); ! if (keyColumnName.length() == 0) ! keyColumnName = ti[i].getTableName(); ! keyColumnName += "."; ! } ! keyColumnName += ti[i].getTableName() + "_ID"; // derived from table ! ! String recordWhere = getRecordWhere (AD_Table_ID, keyColumnName); ! if (recordWhere.length() > 0) ! { ! retSQL.append(" AND ").append(recordWhere); ! log.debug("addAccessSQL - adding record access - " + recordWhere); ! } ! } ! // ! retSQL.append(orderBy); ! return retSQL.toString(); ! } // addAccessSQL /** *************** *** 1131,1140 **** Log.saveError("AccessTableNoUpdate", "(Required=" + TableLevel + "(" ! + getTableLevel(Env.getAD_Language(ctx), TableLevel) + ") != UserLevel=" + userLevel); else Log.saveError("AccessTableNoView", "Required=" + TableLevel + "(" ! + getTableLevel(Env.getAD_Language(ctx), TableLevel) + ") != UserLevel=" + userLevel); log.error ("canInsert - " + toString()); --- 1202,1211 ---- Log.saveError("AccessTableNoUpdate", "(Required=" + TableLevel + "(" ! + getTableLevelString(Env.getAD_Language(ctx), TableLevel) + ") != UserLevel=" + userLevel); else Log.saveError("AccessTableNoView", "Required=" + TableLevel + "(" ! + getTableLevelString(Env.getAD_Language(ctx), TableLevel) + ") != UserLevel=" + userLevel); log.error ("canInsert - " + toString()); *************** *** 1149,1153 **** * @return info */ ! private String getTableLevel(String AD_Language, String TableLevel) { String level = TableLevel + "??"; --- 1220,1224 ---- * @return info */ ! private String getTableLevelString (String AD_Language, String TableLevel) { String level = TableLevel + "??"; *************** *** 1164,1169 **** return Msg.getMsg(AD_Language, level); ! } // getTableLevel } // MRole --- 1235,1293 ---- return Msg.getMsg(AD_Language, level); ! } // getTableLevelString + /** + * Get Table ID from name + * @param tableName table name + * @return AD_Table_ID or 0 + */ + private int getAD_Table_ID (String tableName) + { + Integer ii = (Integer)m_tableName.get(tableName); + if (ii != null) + return ii.intValue(); + // log.warn("getAD_Table_ID - not found (" + tableName + ")"); + return 0; + } // getAD_Table_ID + + /** + * Return Where clause for Record Access + * @param AD_Table_ID table + * @param keyColumnName (fully qualified) key column name + * @return where clause or "" + */ + private String getRecordWhere (int AD_Table_ID, String keyColumnName) + { + StringBuffer sb = new StringBuffer(); + // Role Access + for (int i = 0; i < m_recordAccess.length; i++) + { + if (m_recordAccess[i].getAD_Table_ID() == AD_Table_ID) + { + if (sb.length() > 0) + sb.append(" AND "); + sb.append(keyColumnName); + if (m_recordAccess[i].isExclude()) // Exclude + sb.append("<>"); + else // Include + sb.append("="); + sb.append(m_recordAccess[i].getRecord_ID()); + } + } // for all Table Access + + // Don't ignore Privacy Access + if (!isPersonalAccess()) + { + String lockedIDs = MPrivateAccess.getLockedRecordWhere(AD_Table_ID, m_AD_User_ID); + if (lockedIDs != null) + { + if (sb.length() > 0) + sb.append(" AND "); + sb.append(keyColumnName).append(lockedIDs); + } + } + // + return sb.toString(); + } // getRecordWhere } // MRole |