/**
   * Return Where clause for Record Access
   *
   * @param AD_Table_ID table
   * @param keyColumnName (fully qualified) key column name
   * @param rw true if read write
   * @return where clause or ""
   */
  public StringBuilder getRecordWhere(
      final int AD_Table_ID, final String keyColumnName, final boolean rw) {
    // loadRecordAccess(false);
    //
    final StringBuilder sbInclude = new StringBuilder();
    final StringBuilder sbExclude = new StringBuilder();
    // Role Access
    for (final TableRecordPermission recordAccess : getPermissionsList()) {
      if (recordAccess.getAD_Table_ID() == AD_Table_ID) {
        // NOT IN (x)
        if (recordAccess.isExclude()) {
          if (sbExclude.length() == 0) {
            sbExclude.append(keyColumnName).append(" NOT IN (");
          } else {
            sbExclude.append(",");
          }
          sbExclude.append(recordAccess.getRecord_ID());
        }
        // IN (x)
        else if (!rw || !recordAccess.isReadOnly()) // include
        {
          if (sbInclude.length() == 0) {
            sbInclude.append(keyColumnName).append(" IN (");
          } else {
            sbInclude.append(",");
          }
          sbInclude.append(recordAccess.getRecord_ID());
        }
      }
    } // for all Table Access

    final StringBuilder sb = new StringBuilder();
    if (sbExclude.length() > 0) {
      sb.append(sbExclude).append(")");
    }
    if (sbInclude.length() > 0) {
      if (sb.length() > 0) {
        sb.append(" AND ");
      }
      sb.append(sbInclude).append(")");
    }

    return sb;
  } // getRecordWhere
  /**
   * Access to Record (no check of table)
   *
   * @param AD_Table_ID table
   * @param Record_ID record
   * @param ro read only
   * @return boolean
   */
  public boolean isRecordAccess(final int AD_Table_ID, final int Record_ID, final boolean ro) {
    boolean negativeList = true;
    for (final TableRecordPermission ra : getPermissionsList()) {
      if (ra.getAD_Table_ID() != AD_Table_ID) {
        continue;
      }

      if (ra.isExclude()) // Exclude
      // If you Exclude Access to a column and select Read Only,
      // you can only read data (otherwise no access).
      {
        if (ra.getRecord_ID() == Record_ID) {
          if (ro) {
            return ra.isReadOnly();
          } else {
            return false;
          }
        }
      } else
      // Include
      // If you Include Access to a column and select Read Only,
      // you can only read data (otherwise full access).
      {
        negativeList = false; // has to be defined
        if (ra.getRecord_ID() == Record_ID) {
          if (!ro) {
            return !ra.isReadOnly();
          } else {
            // ro
            return true;
          }
        }
      }
    } // for all Table Access
    return negativeList;
  } // isRecordAccess
  public void addRecordDependentAccessSql(
      final StringBuilder retSQL,
      final AccessSqlParser asp,
      final String tableName,
      final boolean rw) {
    final String mainSql = asp.getMainSql();

    int AD_Table_ID = 0;
    String whereColumnName = null;
    final List<Integer> includes = new ArrayList<Integer>();
    final List<Integer> excludes = new ArrayList<Integer>();
    for (final TableRecordPermission recordDependentAccess : getDependentRecordPermissionsList()) {
      final String columnName =
          recordDependentAccess.getKeyColumnName(asp.getTableInfo(asp.getMainSqlIndex()));
      if (columnName == null) {
        continue; // no key column
      }

      if (mainSql.toUpperCase().startsWith("SELECT COUNT(*) FROM ")) {
        // globalqss - Carlos Ruiz - [ 1965744 ] Dependent entities access problem
        // this is the count select, it doesn't have the column but needs to be filtered

        if (!TablesAccessInfo.instance.isPhysicalColumn(tableName, columnName)) {
          continue;
        }
      } else {
        final int posColumn = mainSql.indexOf(columnName);
        if (posColumn == -1) {
          continue;
        }
        // we found the column name - make sure it's a column name
        char charCheck = mainSql.charAt(posColumn - 1); // before
        if (!(charCheck == ',' || charCheck == '.' || charCheck == ' ' || charCheck == '(')) {
          continue;
        }
        charCheck = mainSql.charAt(posColumn + columnName.length()); // after
        if (!(charCheck == ',' || charCheck == ' ' || charCheck == ')')) {
          continue;
        }
      }

      if (AD_Table_ID != 0 && AD_Table_ID != recordDependentAccess.getAD_Table_ID()) {
        retSQL.append(getDependentAccess(whereColumnName, includes, excludes));
      }

      AD_Table_ID = recordDependentAccess.getAD_Table_ID();
      // *** we found the column in the main query
      if (recordDependentAccess.isExclude()) {
        excludes.add(recordDependentAccess.getRecord_ID());
        logger.fine("Exclude " + columnName + " - " + recordDependentAccess);
      } else if (!rw || !recordDependentAccess.isReadOnly()) {
        includes.add(recordDependentAccess.getRecord_ID());
        logger.fine("Include " + columnName + " - " + recordDependentAccess);
      }
      whereColumnName = getDependentRecordWhereColumn(mainSql, columnName);
    } // for all dependent records
    retSQL.append(getDependentAccess(whereColumnName, includes, excludes));

    // //
    // retSQL.append(orderBy);
    // logger.finest(retSQL.toString());
    // return retSQL.toString();
  } // addAccessSQL