On 24.4.2012 11:17, Boleslaw Dawidowicz wrote:
On Apr 24, 2012, at 10:56 AM, Marek Posolda wrote:
3) Another potentially missing thing is pagination. I assume that we can have 
thousands of users in DB and thousands of resource objects, which in next turn 
means that you can have millions of permissions. In large environments, 
invoking of PermissionManager.listPermissions(Object resource, String 
operation) could return like 10.000 records. So counting with this case and 
provide additional methods for pagination support may be good IMO. Something 
like:

List<Permission>  listPermissions(Object resource, Identity String operation, 
int offset, int pageSize);

For pagination I propose using something like Range object

https://github.com/bdaw/DeltaSpikeMirror/blob/fc7752409f289b6dfbd577292b70a786a4fb62f4/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/idm/Range.java

List<Permission>  listPermissions(Object resource, Identity String operation, 
Range range);

with usage like:

listPermissions(customerRecord, READ, Range.of(10,20));

or

Range page = new Range(0, 10);
x.listPermissions(customerRecord, READ, page.next());
yes, slightly better and more flexible than using only "int offset, int pageSize".

Maybe instead of providing more overloaded "listPermissions" methods with different signatures, we can think about using query API and create concept of PermissionQuery?
So on PermissionManager having single method:

List<Permission> listPermissions(PermissionQuery query);



and having

public interface PermissionQuery
{
   private final IdentityType;
   private final String operation;
   private final Object resource;
   private final ResourceIdentifier resourceIdentifier;

   private Range range;
   private int countOfObjects = -1;

public PermissionQuery(IdentityType idType, String operation, Object resource, ResourceIdentifier resourceIdentifier, Range range)
   {
       // snipet
   }

   public void setRange()
   {
       this.range = range;
   }

   public void nextPage()
   {
       range.next();
   }

   public boolean hasAvailableResultsOnCurrentPage()
   {
      if (countOfObjects == -1)
      {
          // compute total count of poermission objects from DB
      }

       return range.getLimit() < countOfObjects;
   }

   // getters

}



Now I want to obtain all available actions of user John for resource object "maryCustomer":

PermissionQuery permissionQuery = new PermissionQuery(new User("john"), null, maryCustomer,null, Range.of(0,10));

while (permissionQuery.hasAvailableResultsOnCurrentPage())
{
List<Permission> currentPage = permissionManager.listPermissions(permissionQuery);

     // Do something with results
     permissionQuery.nextPage();
}




I am not sure if methods related to pagination should be covered directly in PermissionQuery as it won't be immutable then and method hasAvailableResultsOnCurrentPage() will need to access DB to compute total number of available results. Maybe we can have two separate methods on PermissionManager. One for case without pagination and second with pagination. And for pagination case, we will probably need to count total number of results:

List<Permission> listPermissions(PermissionQuery query);
List<Permission> listPermissions(PermissionQuery query, Range page);
int getPermissionsCount(PermissionQuery);

WDYT?

Marek

Bolek





Reply via email to