class SecurityService {

    public Boolean hasUserPermissionToObject(final User user, final PermissionName permissionName, final SecurableModel securableModel) {
        if (user == null) {
            throw new IllegalArgumentException("User can not be null.");
        }
        if (permissionName == null) {
            throw new IllegalArgumentException("Permission Name can not be null.");
        }
        if (securableModel == null) {
            throw new IllegalArgumentException("SecurableModel can not be null.");
        }

        if (hasUserPermissionToClass(user, permissionName, securableModel.getClass().getCanonicalName())) {
            return true;
        }

        final List<Long> userRoleIds = new ArrayList<>();
        for (Role role : user.getRoles()) {
            userRoleIds.add(role.getId());
        }
        final List<AclEntry> rolesAclEntries = aclEntryService.findAll(permissionName, AclSidType.ROLE, userRoleIds, AclClassName.getByName(securableModel.getClass().getCanonicalName()), securableModel.getId());

        if (rolesAclEntries.size() > 0) {
            if (log.isDebugEnabled()) {
                log.debug("User " + user.getUsername() + " has permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "] based on the ACL security settings.");
            }
            return true;
        }

        if (securableModel.getCreatedBy() != null && securableModel.getCreatedBy().getId().equals(user.getId())) {
            List<AclEntry> ownerAclEntries = aclEntryService.findAll(permissionName, AclSidType.OWNER, 0L, AclClassName.getByName(securableModel.getClass().getCanonicalName()), securableModel.getId());
            if (ownerAclEntries.size() > 0) {
                if (log.isDebugEnabled()) {
                    log.debug("User " + user.getUsername() + " has permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "] based on that he is the owner.");
                }
                return true;
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("User " + user.getUsername() + " has not permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "].");
        }
        return false;
    }

}

class SecurityServiceTest {

    @Resource
    private UserRepository userRepository;
    @Resource
    private PageRepository pageRepository;
    @Resource
    private ModuleRepository moduleRepository;
    @Autowired
    private SecurityService securityService;

    @Ignore
    @Test
    public void userAdminHasPermissionToAddModule() {

        log.debug("userAdminHasPermissionToAddModule()");
        User admin = userRepository.findOne(1L);
        Module module = moduleRepository.findOne(2L);
        Boolean hasPermission = securityService.hasUserPermissionToObject(admin, PermissionName.MODULE_ADD, module);
        assertTrue(hasPermission);
    }

}