@Override
  public boolean revoke(TAccessControlEntity info) throws IOError, TException {
    Permission.Action[] actions = ThriftUtilities.permissionActionsFromString(info.actions);
    try {
      if (info.scope == TPermissionScope.NAMESPACE) {
        AccessControlClient.revoke(connectionCache.getAdmin().getConnection(), info.getNsName(),
          info.getUsername(), actions);
      } else if (info.scope == TPermissionScope.TABLE) {
        TableName tableName = TableName.valueOf(info.getTableName());
        AccessControlClient.revoke(connectionCache.getAdmin().getConnection(), tableName,
          info.getUsername(), null, null, actions);
      }
    } catch (Throwable t) {
      if (t instanceof IOException) {
        throw getIOError(t);
      } else {
        throw getIOError(new DoNotRetryIOException(t.getMessage()));
      }
    }
    return true;
  }
Note: this internal interface is slightly different from public APIs in regard to handling of
the qualifier. Here we differ from the public Java API in that null != byte[0]. Rather, we
respect qual == null as a request for the entire column family. The caller (
{@link #getVerTs(ByteBuffer, ByteBuffer, ByteBuffer, long, int, Map)}) interface IS consistent
in that the column is parse like normal.
hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftHBaseServiceHandler.java