Pergunta

I have a list of the following objects:

class ResourcePermissionDTO {
  PermissionType permissionType;
  ... 
}

where PermissionType is the following enum:

public enum PermissionType {
   DENY, READ_ONLY, READ_WRITE;
}

So, the list looks like:

List<ResourcePermissionDTO> myResourcePermissions = ...

What I want is to return the first ResourcePermissionDTO found in myResourcePermissions with the most restrictive permission. Currently I have the following, but it is a bit messy and I though there might be a better way to do it using Google Guava/functional idioms?

private ResourcePermissionDTO returnTheFirstMostRestrictivePermissionFoundIn(final List<ResourcePermissionDTO> resourcePermissionDTOs) {
    if (resourcePermissionDTOs.isEmpty()) {
      return null;
    }

    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfDeny = Lists.newArrayList();
    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfReadOnly = Lists.newArrayList();
    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfReadWrite = Lists.newArrayList();

    for (final ResourcePermissionDTO resourcePermissionDTO : resourcePermissionDTOs) {
      switch (resourcePermissionDTO.getPermissionType()) {
      case DENY:
        resourcePermissionDTOsWithReadWritePermissionOfDeny.add(resourcePermissionDTO);
        break;
      case READ_ONLY:
        resourcePermissionDTOsWithReadWritePermissionOfReadOnly.add(resourcePermissionDTO);
        break;
      case READ_WRITE:
        resourcePermissionDTOsWithReadWritePermissionOfReadWrite.add(resourcePermissionDTO);
        break;
      default:
        break;
      }
    }

    if (!resourcePermissionDTOsWithReadWritePermissionOfDeny.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfDeny.get(0);
    } else if (!resourcePermissionDTOsWithReadWritePermissionOfReadOnly.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfReadOnly.get(0);
    } else if (!resourcePermissionDTOsWithReadWritePermissionOfReadWrite.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfReadWrite.get(0);
    } else {
      return null;
    }
  }
Foi útil?

Solução

Even in imperative style it can be simplified as follows:

List<ResourcePermissionDTO> permissions = ...;
ResourcePermissionDTO result = null;

for (ResourcePermissionDTO p: permissions) {
    if (result == null || isStronger(p.getPermissionType(), result.getPermissionType())) {
        result = p;
        if (result.getPermissionType() == PermissionType.DENY) break; // (1)
    }
}

return result;

If you prefer functional style, you can reproduce exactly the same (though without short-circuit optimization at (1)) using reduce(). Guava doesn't support reduce(), therefore the following example is in Java 8:

return permissions.stream().reduce((result, p) -> {
    return isStronger(p.getPermissionType(), result.getPermissionType()) ? p : result;
}).orElse(null);

Outras dicas

How I would do it

  1. Make ResourcePermissionDTO implement Comparable<ResourcePermissionDTO>
 class ResourcePermissionDTO implements Comparable<ResourcePermissionDTO> {
      PermissionType permissionType;
      @Override
      public int compareTo(ResourcePermissionDTO that) {
          return this.permissionType.compareTo(that.permissionType);
      }
    }
  1. Add all DTO's to a single list

    List<ResourcePermissionDTO> myResourcePermissions =

  2. Use Guava's Ordering to get first item from List

    ResourcePermissionDTO leastRestrictive = Ordering.natural().max(myResourcePermissions);

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top