package com.plexobject.rbac.repository.bdb;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.plexobject.rbac.repository.PermissionRepository;
import com.plexobject.rbac.repository.PersistenceException;
import com.plexobject.rbac.repository.RoleRepository;
import com.plexobject.rbac.domain.Permission;
import com.plexobject.rbac.domain.Role;
import com.plexobject.rbac.metric.Metric;
import com.plexobject.rbac.metric.Timing;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.persist.EntityCursor;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.SecondaryIndex;
public class PermissionRepositoryImpl extends
BaseRepositoryImpl<Permission, Integer> implements PermissionRepository {
private RoleRepository roleRepository;
private SecondaryIndex<String, Integer, Permission> rolenameIndex;
public PermissionRepositoryImpl(final EntityStore entityStore) {
super(entityStore);
this.roleRepository = new RoleRepositoryImpl(entityStore);
try {
rolenameIndex = entityStore.getSecondaryIndex(primaryIndex,
String.class, "roleIds");
} catch (DatabaseException e) {
throw new PersistenceException(e);
}
}
@Override
public Set<Permission> getPermissionsForRoles(Collection<Role> roles) {
final Timing timer = Metric.newTiming(getClass().getName()
+ ".getPermissionsForRole");
Set<Permission> permissions = new HashSet<Permission>();
try {
for (Role role : roles) {
loadPermissionsForRole(role, permissions);
}
return permissions;
} catch (DatabaseException e) {
throw new PersistenceException(e);
} finally {
timer.stop();
}
}
private void loadPermissionsForRole(Role role,
Collection<Permission> permissions) throws DatabaseException {
EntityCursor<Permission> cursor = null;
try {
cursor = rolenameIndex.subIndex(role.getId()).entities();
Iterator<Permission> it = cursor.iterator();
while (it.hasNext()) {
Permission next = it.next();
permissions.add(next);
}
if (role.hasParentIds()) {
for (String parentId : role.getParentIds()) {
Role parent = roleRepository.findById(parentId);
if (!role.equals(parent)) {
loadPermissionsForRole(parent, permissions);
}
}
}
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (DatabaseException e) {
LOGGER.error("failed to close cursor", e);
}
}
}
}
}