// Path: src/main/java/act/aaa/util/LoginUserFinder.java
// public class LoginUserFinder extends ValueLoader.Base {
// 
//     public static final String KEY_USER_KEY = "key";
// 
//     private Dao dao;
//     private String querySpec;
//     private Class<?> userType;
//     private Class<?> userKeyType;
// 
//     @Override
//     public Object get() {
//         AAAContext aaaContext = AAA.context();
//         if (null != aaaContext) {
//             Principal principal = aaaContext.getCurrentPrincipal();
//             if (null != principal) {
//                 if (userType.isInstance(principal)) {
//                     return principal;
//                 }
//                 String querySpec = this.querySpec;
//                 AAAPlugin plugin = Act.getInstance(AAAPlugin.class);
//                 if (PROP_ID.equals(querySpec)) {
//                     String s = principal.getProperty(PROP_ID);
//                     E.unexpectedIf(S.isBlank(s), "Cannot determine id of principal");
//                     Object id = $.convert(s).to(dao.idType());
//                     String cacheKey = S.string(id);
//                     Object cached = plugin.cachedUser(cacheKey);
//                     if (null == cached) {
//                         cached = dao.findById(id);
//                         if (null != cached) {
//                             plugin.cacheUser(cacheKey, cached);
//                         }
//                     }
//                     return cached;
//                 }
//                 String name = principal.getName();
//                 int pos = name.indexOf(':');
//                 if (pos > 0) {
//                     querySpec = name.substring(0, pos);
//                     name = name.substring(pos + 1);
//                 }
//                 String cacheKey = S.concat(querySpec, "::", name);
//                 Object cached = plugin.cachedUser(cacheKey);
//                 if (null == cached) {
//                     Object val = userKeyType == String.class ? name : $.convert(name).to(userKeyType);
//                     cached = dao.findOneBy(querySpec, val);
//                     if (null != cached) {
//                         plugin.cacheUser(cacheKey, cached);
//                     }
//                 }
//                 return cached;
//             }
//         }
//         return null;
//     }
// 
//     @Override
//     protected void initialized() {
//         App app = App.instance();
// 
//         userType = spec.rawType();
//         userKeyType = $.fieldOf(userType, AAAConfig.user.key.get()).getType();
//         dao = app.dbServiceManager().dao(userType);
// 
//         querySpec = S.string(options.get(KEY_USER_KEY));
//         if (S.blank(querySpec)) {
//             querySpec = AAAConfig.user.key.get();
//         }
//     }
// 
//     public static String userKey(String userIdentifier) {
//         return S.concat(AAAConfig.user.key.get(), "::", userIdentifier);
//     }
// }


import act.Act;
import act.aaa.util.LoginUserFinder;
import act.app.ActionContext;
import act.app.ActionContext.PreFireSessionResolvedEvent;
import act.app.App;
import act.app.event.AppStop;
import act.app.event.SysEventId;
import act.event.*;
import act.util.LogSupportedDestroyableBase;
import org.osgl.$;
import org.osgl.aaa.*;
import org.osgl.aaa.impl.DumbAuditor;
import org.osgl.cache.CacheService;
import org.osgl.http.H;
import org.osgl.util.E;
import org.osgl.util.S;
import osgl.version.Version;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
            return "Permission";
        } else if (Privilege.class.isAssignableFrom(clz)) {
            return "Privilege";
        } else {
            return "Role";
        }
    }

    private String cacheKey(Class<? extends AAAObject> clz, String name) {
        return cacheKey(typeName(clz), name);
    }

    private String cacheKey(AAAObject object) {
        return cacheKey(typeName(object), object.getName());
    }

    private String cacheKey(String typeName, String name) {
        return S.concat(name, "-", typeName);
    }

    private void onLogin(String userIdentifier) {
        flushUserAndPrincipalCache(userIdentifier);
    }

    private void onLogout(String userIdentifier) {
        flushUserAndPrincipalCache(userIdentifier);
    }

    private void flushUserAndPrincipalCache(String userIdentifier) {
        evictUser(userIdentifier);
// Path: src/main/java/act/aaa/util/LoginUserFinder.java
// public class LoginUserFinder extends ValueLoader.Base {
// 
//     public static final String KEY_USER_KEY = "key";
// 
//     private Dao dao;
//     private String querySpec;
//     private Class<?> userType;
//     private Class<?> userKeyType;
// 
//     @Override
//     public Object get() {
//         AAAContext aaaContext = AAA.context();
//         if (null != aaaContext) {
//             Principal principal = aaaContext.getCurrentPrincipal();
//             if (null != principal) {
//                 if (userType.isInstance(principal)) {
//                     return principal;
//                 }
//                 String querySpec = this.querySpec;
//                 AAAPlugin plugin = Act.getInstance(AAAPlugin.class);
//                 if (PROP_ID.equals(querySpec)) {
//                     String s = principal.getProperty(PROP_ID);
//                     E.unexpectedIf(S.isBlank(s), "Cannot determine id of principal");
//                     Object id = $.convert(s).to(dao.idType());
//                     String cacheKey = S.string(id);
//                     Object cached = plugin.cachedUser(cacheKey);
//                     if (null == cached) {
//                         cached = dao.findById(id);
//                         if (null != cached) {
//                             plugin.cacheUser(cacheKey, cached);
//                         }
//                     }
//                     return cached;
//                 }
//                 String name = principal.getName();
//                 int pos = name.indexOf(':');
//                 if (pos > 0) {
//                     querySpec = name.substring(0, pos);
//                     name = name.substring(pos + 1);
//                 }
//                 String cacheKey = S.concat(querySpec, "::", name);
//                 Object cached = plugin.cachedUser(cacheKey);
//                 if (null == cached) {
//                     Object val = userKeyType == String.class ? name : $.convert(name).to(userKeyType);
//                     cached = dao.findOneBy(querySpec, val);
//                     if (null != cached) {
//                         plugin.cacheUser(cacheKey, cached);
//                     }
//                 }
//                 return cached;
//             }
//         }
//         return null;
//     }
// 
//     @Override
//     protected void initialized() {
//         App app = App.instance();
// 
//         userType = spec.rawType();
//         userKeyType = $.fieldOf(userType, AAAConfig.user.key.get()).getType();
//         dao = app.dbServiceManager().dao(userType);
// 
//         querySpec = S.string(options.get(KEY_USER_KEY));
//         if (S.blank(querySpec)) {
//             querySpec = AAAConfig.user.key.get();
//         }
//     }
// 
//     public static String userKey(String userIdentifier) {
//         return S.concat(AAAConfig.user.key.get(), "::", userIdentifier);
//     }
// }


// Path: src/main/java/act/aaa/AAAPlugin.java
import act.Act;
import act.aaa.util.LoginUserFinder;
import act.app.ActionContext;
import act.app.ActionContext.PreFireSessionResolvedEvent;
import act.app.App;
import act.app.event.AppStop;
import act.app.event.SysEventId;
import act.event.*;
import act.util.LogSupportedDestroyableBase;
import org.osgl.$;
import org.osgl.aaa.*;
import org.osgl.aaa.impl.DumbAuditor;
import org.osgl.cache.CacheService;
import org.osgl.http.H;
import org.osgl.util.E;
import org.osgl.util.S;
import osgl.version.Version;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

            return "Permission";
        } else if (Privilege.class.isAssignableFrom(clz)) {
            return "Privilege";
        } else {
            return "Role";
        }
    }

    private String cacheKey(Class<? extends AAAObject> clz, String name) {
        return cacheKey(typeName(clz), name);
    }

    private String cacheKey(AAAObject object) {
        return cacheKey(typeName(object), object.getName());
    }

    private String cacheKey(String typeName, String name) {
        return S.concat(name, "-", typeName);
    }

    private void onLogin(String userIdentifier) {
        flushUserAndPrincipalCache(userIdentifier);
    }

    private void onLogout(String userIdentifier) {
        flushUserAndPrincipalCache(userIdentifier);
    }

    private void flushUserAndPrincipalCache(String userIdentifier) {
        evictUser(userIdentifier);
        evictUser(LoginUserFinder.userKey(userIdentifier));