package org.pentaho.platform.plugin.services.security.userrole; import org.pentaho.platform.api.engine.ICacheManager; import org.pentaho.platform.api.engine.IUserRoleListService; import org.pentaho.platform.api.mt.ITenant; import org.pentaho.platform.engine.core.system.PentahoSystem; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Caching Decorator for an IUserRoleListService. It will use the configured ICacheManager in the PentahoSystem to cache * all calls being made to the decorated instance. * <p/> * Created by nbaker on 5/20/14. */ public class CachingUserRoleListServiceDecorator implements IUserRoleListService { private IUserRoleListService delegate; private ICacheManager cacheManager = PentahoSystem.getCacheManager( null ); private static final String REGION = "userRoleListCache"; private static final String ALL_USERS = "all users"; private static final String ALL_ROLES = "all roles"; private static final String SYSTEM_ROLES = "system roles"; private static final String ROLES_BY_USER = "roles by user"; private static interface DelegateOperation { List<String> perform(); } private final DelegateOperation ALL_ROLES_OPERATION = new DelegateOperation() { @Override public List<String> perform() { return delegate.getAllRoles(); } }; private final DelegateOperation SYSTEM_ROLES_OPERATION = new DelegateOperation() { @Override public List<String> perform() { return delegate.getSystemRoles(); } }; private final DelegateOperation ALL_USERS_OPERATION = new DelegateOperation() { @Override public List<String> perform() { return delegate.getAllUsers(); } }; public CachingUserRoleListServiceDecorator( IUserRoleListService delegate ) { if ( delegate == null ) { throw new IllegalArgumentException( "Decorated IUserRoleListService cannot be null" ); } this.delegate = delegate; if ( !this.cacheManager.cacheEnabled( REGION ) ) { this.cacheManager.addCacheRegion( REGION ); } } @SuppressWarnings( "unchecked" ) private List<String> performOperation( String cacheEntry, DelegateOperation operation ) { List<String> results = null; Object fromRegionCache = cacheManager.getFromRegionCache( REGION, cacheEntry ); if (fromRegionCache instanceof List ) { results = (List<String>) fromRegionCache; }else{ results = operation.perform(); cacheManager.putInRegionCache( REGION, cacheEntry, results ); } return new ArrayList<String>(results); } @Override public List<String> getAllRoles() { return performOperation( ALL_ROLES, ALL_ROLES_OPERATION ); } @Override public List<String> getSystemRoles() { return performOperation( SYSTEM_ROLES, SYSTEM_ROLES_OPERATION ); } @Override public List<String> getRolesForUser( final ITenant tenant, final String username ) { return performOperation( ROLES_BY_USER + getTenantKey( tenant ) + username, new DelegateOperation() { @Override public List<String> perform() { return delegate.getRolesForUser( tenant, username ); } } ); } private String getTenantKey( ITenant tenant ) { return ( ( tenant != null ) ? tenant.getId() : "_" ); } @Override public List<String> getAllUsers( final ITenant tenant ) { return performOperation( ALL_USERS + getTenantKey( tenant ), new DelegateOperation() { @Override public List<String> perform() { return delegate.getAllUsers( tenant ); } } ); } @Override public List<String> getAllRoles( final ITenant tenant ) { return performOperation( ALL_ROLES + getTenantKey( tenant ), new DelegateOperation() { @Override public List<String> perform() { return delegate.getAllRoles( tenant ); } } ); } @Override public List<String> getUsersInRole( final ITenant tenant, final String role ) { return performOperation( ALL_USERS + getTenantKey( tenant ) + role, new DelegateOperation() { @Override public List<String> perform() { return delegate.getUsersInRole( tenant, role ); } } ); } @Override public List<String> getAllUsers() { return performOperation( ALL_USERS, ALL_USERS_OPERATION ); } }