/* * JBoss, a division of Red Hat * Copyright 2009, Red Hat Middleware, LLC, and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.picketlink.idm.impl.cache; import org.picketlink.idm.cache.*; import org.picketlink.idm.api.*; import org.picketlink.idm.api.cfg.IdentityConfigurationRegistry; import org.picketlink.idm.api.query.UserQuery; import org.picketlink.idm.api.query.GroupQuery; import org.picketlink.idm.api.query.RoleQuery; import org.picketlink.idm.impl.api.model.GroupKey; import org.jboss.cache.*; import org.jboss.cache.eviction.ExpirationAlgorithmConfig; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Collection; import java.util.Collections; import java.util.Set; import java.util.SortedSet; import java.util.logging.Logger; import java.util.logging.Level; /** * */ public class JBossCacheAPICacheProviderImpl implements APICacheProvider { //TODO: dobule check if invalidate methods remove everything that is needed... private static Logger log = Logger.getLogger(JBossCacheAPICacheProviderImpl.class.getName()); private Cache cache; public static final String CONFIG_FILE_OPTION = "cache.configFile"; public static final String CONFIG_CACHE_REGISTRY_OPTION = "cache.cacheRegistryName"; public static final String CACHE_PROVIDER_REGISTRY_NAME = "cache.providerRegistryName"; public static final String CACHE_SCOPE = "cache.scope"; public static final String NODE_OBJECT_KEY = "object"; public static final String NODE_QUERY_KEY = "query"; public static final String NODE_QUERY_UNIQUE_KEY = "query_unique"; public static final String NODE_MAIN_ROOT = "IDM_ROOT"; public static final String NODE_COMMON_ROOT = "COMMON_ROOT"; public static final String NODE_USERS = "USERS"; public static final String NODE_USERS_COUNT = "USERS_COUNT"; public static final String NODE_USERS_QUERIES = "USERS_QUERIES"; public static final String NODE_USERS_CRITERIA = "USERS_CRITERIA"; public static final String NODE_USERS_SEARCHES = "USERS_SEARCHES"; public static final String NODE_GROUPS = "GROUPS"; public static final String NODE_GROUPS_COUNT = "GROUPS_COUNT"; public static final String NODE_GROUPS_QUERIES = "GROUPS_QUERIES"; public static final String NODE_GROUPS_CRITERIA = "GROUPS_CRITERIA"; public static final String NODE_GROUPS_SEARCHES = "GROUPS_SEARCHES"; public static final String NODE_ROLES = "ROLES"; public static final String NODE_ROLE_TYPES = "ROLE_TYPES"; public static final String NODE_ROLE_QUERIES = "ROLE_QUERIES"; public static final String NODE_ATTRIBUTES = "ATTRIBUTES"; public static final String NODE_ROLE_PROPERTIES = "NODE_ROLE_PROPERTIES"; public static final String NODE_ROLE_TYPE_PROPERTIES = "NODE_ROLE_TYPE_PROPERTIES"; public static final String NODE_ROLE_SEARCHES = "NODE_ROLE_SEARCHES"; public static final String NODE_ROLE_TYPE_SEARCHES = "NODE_ROLE_TYPE_SEARCHES"; public static final String NODE_RELATIONSHIP_SEARCHES = "NODE_ROLE_TYPE_SEARCHES"; public static final String NULL_NS_NODE = "PL_COMMON_NS"; public static final String MAIN_ROOT = "NODE_MAIN_ROOT"; private int expiration = -1; private Fqn getRootNode() { return Fqn.fromString("/" + MAIN_ROOT); } private Fqn getNamespacedFqn(String ns) { String namespace = ns != null ? ns : NULL_NS_NODE; namespace = namespace.replaceAll("/", "_"); return Fqn.fromString(getRootNode() + "/" + namespace); } private Fqn getFqn(String ns, String node, Object o) { return Fqn.fromString(getNamespacedFqn(ns) + "/" + node + "/" + o); } private Fqn getFqn(String ns, String node) { return Fqn.fromString(getNamespacedFqn(ns) + "/" + node); } public void initialize(Map<String, String> properties, IdentityConfigurationRegistry configurationRegistry) { CacheFactory factory = new DefaultCacheFactory(); String registryName = properties.get(CONFIG_CACHE_REGISTRY_OPTION); // Get cache from registry if (registryName != null) { try { this.cache = (Cache)configurationRegistry.getObject(registryName); } catch (Exception e) { throw new IllegalArgumentException("Cannot find JBoss Cache 'Cache' object in configuration registry with provided" + "name: " + registryName); } return; } String config = properties.get(CONFIG_FILE_OPTION); if (config == null) { throw new IllegalArgumentException("Cannot find '" + CONFIG_FILE_OPTION + "' in passed properties. Failed to initialize" + "cache provider."); } this.cache = factory.createCache(config); this.cache.create(); this.cache.start(); } public void initialize(InputStream jbossCacheConfiguration) { CacheFactory factory = new DefaultCacheFactory(); if (jbossCacheConfiguration == null) { throw new IllegalArgumentException("JBoss Cache configuration InputStream is null"); } this.cache = factory.createCache(jbossCacheConfiguration); this.cache.create(); this.cache.start(); } public void initialize(Cache cache) { this.cache = cache; CacheStatus status = cache.getCacheStatus(); if (status.createAllowed()) { this.cache.create(); } if (status.startAllowed()) { this.cache.start(); } } Cache getCache() { return cache; } public void invalidate(String ns) { boolean success = cache.getRoot().removeChild(getNamespacedFqn(ns)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating namespace:" + ns + "; success=" + success); } } public void invalidateAll() { boolean success = cache.getRoot().removeChild(getRootNode()); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating whole cache - success=" + success); } } public String getNamespace(String realmId) { if (realmId == null) { return NODE_COMMON_ROOT; } return realmId; } public String getNamespace(String realmId, String sessionId) { if (sessionId == null) { return getNamespace(realmId); } return realmId + "/" + sessionId; } public void putUser(String ns, User user) { Fqn nodeFqn = getFqn(ns, NODE_USERS, user.getKey()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, user); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User stored in cache: " + user.getId() + ";namespace=" + ns); } } } public User getUser(String ns, String id) { Fqn nodeFqn = getFqn(ns, NODE_USERS, id); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { User user = (User)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && user != null) { log.finer(this.toString() + "User found in cache: id=" + user.getId() + ";namespace=" + ns); } return user; } return null; } public void removeUser(String ns, String id) { Fqn nodeFqn = getFqn(ns, NODE_USERS, id); getCache().getRoot().removeChild(nodeFqn); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User removed from cache: id= " + id + ";namespace=" + ns); } } public void putUsers(String ns, IdentitySearchCriteria criteria, Collection<User> users) { Fqn nodeFqn = getFqn(ns, NODE_USERS_CRITERIA, criteria != null ? criteria.hashCode() : null); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(users)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User criteria search stored in cache: users.size()=" + users.size() + "; criteria.hash()=" + criteria + ";namespace=" + ns); } } } public Collection<User> getUsers(String ns, IdentitySearchCriteria criteria) { Fqn nodeFqn = getFqn(ns, NODE_USERS_CRITERIA, criteria != null ? criteria.hashCode() : null); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<User> users = (Collection<User>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && users != null) { log.finer(this.toString() + "User criteria search found in cache: users.size()=" + users.size() + "; criteria.hash()=" + criteria + ";namespace=" + ns); } return users; } return null; } public void invalidateUsers(String ns) { getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS_COUNT)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS_CRITERIA)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS_QUERIES)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS_SEARCHES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Users cache. Namespace:" + ns + ";namespace=" + ns); } } public void putUserCount(String ns, int count) { Fqn nodeFqn = getFqn(ns, NODE_USERS_COUNT); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, count); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Users count stored in cache: " + count + ";namespace=" + ns); } } } public int getUserCount(String ns) { Fqn nodeFqn = getFqn(ns, NODE_USERS_COUNT); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { int count = -1; Integer i = (Integer)node.get(NODE_OBJECT_KEY); if (i != null) { count = i.intValue(); } if (log.isLoggable(Level.FINER) && count != -1) { log.finer(this.toString() + "User count found in cache: " + count + ";namespace=" + ns); } return count; } return -1; } public void invalidateUserCount(String ns) { getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_USERS_COUNT)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating User count. Namespace:" + ns + ";namespace=" + ns); } } public void putGroup(String ns, Group group) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS, group.getKey()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, group); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group stored in cache: " + group.getKey() + ";namespace=" + ns); } } } public Group getGroup(String ns, String groupType, String groupName) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS, GroupKey.parseKey(groupName, groupType)); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Group group = (Group)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && group != null) { log.finer(this.toString() + "Group found in cache: id=" + group.getKey() + ";namespace=" + ns); } return group; } return null; } public void removeGroup(String ns, String groupType, String groupName) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS, GroupKey.parseKey(groupName, groupType)); getCache().getRoot().removeChild(nodeFqn); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group removed from cache: id= " + GroupKey.parseKey(groupName, groupType) + ";namespace=" + ns); } } public void putGroups(String ns, IdentitySearchCriteria criteria, Collection<Group> groups) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_CRITERIA, criteria != null ? criteria.hashCode() : null); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(groups)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group criteria search stored in cache: groups.size()=" + groups.size() + "; criteria.hash()=" + criteria + ";namespace=" + ns); } } } public Collection<Group> getGroups(String ns, IdentitySearchCriteria criteria) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_CRITERIA, criteria != null ? criteria.hashCode() : null); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<Group> groups = (Collection<Group>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && groups != null) { log.finer(this.toString() + "Group criteria search found in cache: groups.size()=" + groups.size() + "; criteria.hash()=" + criteria + ";namespace=" + ns); } return groups; } return null; } public void invalidateGroups(String ns) { getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_GROUPS)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_GROUPS_COUNT)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_GROUPS_CRITERIA)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_GROUPS_QUERIES)); getCache().getRoot().removeChild(Fqn.fromString(getNamespacedFqn(ns) + "/" + NODE_GROUPS_SEARCHES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Groups cache. Namespace:" + ns + ";namespace=" + ns); } } public void putGroupCount(String ns, String groupType, int count) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_COUNT, groupType); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, count); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group count stored in cache: type=" + groupType + "; count=" + count + ";namespace=" + ns); } } } public int getGroupCount(String ns, String groupType) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_COUNT, groupType); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { int count = -1; Integer i = (Integer)node.get(NODE_OBJECT_KEY); if (i != null) { count = i.intValue(); } if (log.isLoggable(Level.FINER) && count != -1) { log.finer(this.toString() + "Group count found in cache: groupType=" + groupType + "; count=" + count + ";namespace=" + ns); } return count; } return -1; } public void invalidateGroupCount(String ns, String groupType) { cache.getRoot().removeChild(getFqn(ns, NODE_GROUPS_COUNT, groupType)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Group count. Namespace:" + ns); } } public void putRole(String ns, Role role) { Fqn nodeFqn = getFqn(ns, NODE_ROLES, role.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, role); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Role stored in cache: " + role + ";namespace=" + ns); } } } public Role getRole(String ns, Role role) { Fqn nodeFqn = getFqn(ns, NODE_ROLES, role.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Role result = (Role)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && result != null) { log.finer(this.toString() + "Role found in cache: id=" + result + ";namespace=" + ns); } return result; } return null; } public void removeRole(String ns, Role role) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLES, role.hashCode())); } public void putRoleType(String ns, RoleType role) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPES, role.getName()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, role); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "RoleType stored in cache: name=" + role.getName() + ";namespace=" + ns); } } } public RoleType getRoleType(String ns, RoleType role) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPES, role.getName()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { RoleType result = (RoleType)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && result != null) { log.finer(this.toString() + "RoleType found in cache: name=" + role.getName() + ";namespace=" + ns); } return result; } return null; } public void removeRoleType(String ns, RoleType roleType) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_TYPES, roleType.getName())); } public void putAttributes(String ns, String id, Map<String, Attribute> attributes) { Fqn nodeFqn = getFqn(ns, NODE_ATTRIBUTES, id); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, Collections.unmodifiableMap(attributes)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Attributes stored in cache: id=" + id + "; attributes.size()=" + attributes.size() + ";namespace=" + ns); } } } public Map<String, Attribute> getAttributes(String ns, String id) { Fqn nodeFqn = getFqn(ns, NODE_ATTRIBUTES, id); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Map<String, Attribute> attributes = (Map<String, Attribute>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && attributes != null) { log.finer(this.toString() + "Attributes search found in cache: attributes.size()=" + attributes.size() + "; id=" + id + ";namespace=" + ns); } return attributes; } return null; } public void invalidateAttributes(String ns, String id) { cache.getRoot().removeChild(getFqn(ns, NODE_ATTRIBUTES, id)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Attributes. id=" + id +";namespace:" + ns); } } public void invalidateAttributes(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_ATTRIBUTES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Attributes. Namespace:" + ns); } } public void putProperties(String ns, Role role, Map<String, String> properties) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_PROPERTIES, role.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, Collections.unmodifiableMap(properties)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Role properties stored in cache: role=" + role + "; properties.size()=" + properties.size() + ";namespace=" + ns); } } } public Map<String, String> getProperties(String ns, Role role) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_PROPERTIES, role.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Map<String, String> props = (Map<String, String>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && props != null) { log.finer(this.toString() + "Role properties found in cache: properties.size()=" + props.size() + "; role=" + role + ";namespace=" + ns); } return props; } return null; } public void invalidateRoleProperties(String ns, Role role) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_PROPERTIES, role.hashCode())); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Role properties. role=" + role + "; Namespace:" + ns); } } public void invalidateRoleProperties(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_PROPERTIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Role properties. Namespace:" + ns); } } public void putProperties(String ns, RoleType roleType, Map<String, String> properties) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPE_PROPERTIES, roleType.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, Collections.unmodifiableMap(properties)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "RoleType properties stored in cache: roleType=" + roleType + "; properties.size()=" + properties.size() + ";namespace=" + ns); } } } public Map<String, String> getProperties(String ns, RoleType roleType) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPE_PROPERTIES, roleType.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Map<String, String> props = (Map<String, String>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && props != null) { log.finer(this.toString() + "RoleType properties found in cache: properties.size()=" + props.size() + "; roleType=" + roleType + ";namespace=" + ns); } return props; } return null; } public void invalidateRoleTypeProperties(String ns, RoleType roleType) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_TYPE_PROPERTIES, roleType.hashCode())); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating RoleType properties. roleType=" + roleType + "; Namespace:" + ns); } } public void invalidateRoleTypeProperties(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_TYPE_PROPERTIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating RoleType properties. Namespace:" + ns); } } public void invalidateAllSearches(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_USERS_SEARCHES)); cache.getRoot().removeChild(getFqn(ns, NODE_GROUPS_SEARCHES)); cache.getRoot().removeChild(getFqn(ns, NODE_RELATIONSHIP_SEARCHES)); cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_SEARCHES)); cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_TYPE_SEARCHES)); // Probably should have separate invalidate methods, but for now need to be part of search invalidation cache.getRoot().removeChild(getFqn(ns, NODE_ROLES)); cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_TYPES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating all searches. Namespace:" + ns); } } public void putUserSearch(String ns, UserSearch search, Collection<User> results) { Fqn nodeFqn = getFqn(ns, NODE_USERS_SEARCHES, search.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(results)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User search stored in cache: results.size()=" + results.size() + ";namespace=" + ns); } } } public Collection<User> getUserSearch(String ns, UserSearch search) { Fqn nodeFqn = getFqn(ns, NODE_USERS_SEARCHES, search.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<User> props = (Collection<User>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && props != null) { log.finer(this.toString() + "User search found in cache: properties.size()=" + props.size() + ";namespace=" + ns); } return props; } return null; } public void putGroupSearch(String ns, GroupSearch search, Collection<Group> results) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_SEARCHES, search.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(results)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group search stored in cache: results.size()=" + results.size() + ";namespace=" + ns); } } } public Collection<Group> getGroupSearch(String ns, GroupSearch search) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_SEARCHES, search.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<Group> results = (Collection<Group>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && results != null) { log.finer(this.toString() + "Group search found in cache: results.size()=" + results.size() + ";namespace=" + ns); } return results; } return null; } public void putRelationshipSearch(String ns, RelationshipSearch search, Boolean result) { Fqn nodeFqn = getFqn(ns, NODE_RELATIONSHIP_SEARCHES, search.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode == null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, result); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Relationship search stored in cache: result=" + result + ";namespace=" + ns); } } } public Boolean getRelationshipSearch(String ns, RelationshipSearch search) { Fqn nodeFqn = getFqn(ns, NODE_RELATIONSHIP_SEARCHES, search.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Boolean result = (Boolean)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && result != null) { log.finer(this.toString() + "Relationship search found in cache: properties.size()=" + result + ";namespace=" + ns); } return result; } return null; } public void putRoleSearch(String ns, RoleSearch search, Collection<Role> results) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_SEARCHES, search.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(results)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Role search stored in cache: results.size()=" + results.size() + ";namespace=" + ns); } } } public Collection<Role> getRoleSearch(String ns, RoleSearch search) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_SEARCHES, search.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<Role> results = (Collection<Role>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && results != null) { log.finer(this.toString() + "Role search found in cache: results.size()=" + results.size() + ";namespace=" + ns); } return results; } return null; } public void putRoleTypeSearch(String ns, RoleTypeSearch search, Collection<RoleType> results) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPE_SEARCHES, search.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_OBJECT_KEY, unmodifiableCollection(results)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "RoleType search stored in cache: results.size()=" + results.size() + ";namespace=" + ns); } } } public Collection<RoleType> getRoleTypeSearch(String ns, RoleTypeSearch search) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_TYPE_SEARCHES, search.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<RoleType> results = (Collection<RoleType>)node.get(NODE_OBJECT_KEY); if (log.isLoggable(Level.FINER) && results != null) { log.finer(this.toString() + "RoleType search found in cache: results.size()=" + results.size() + ";namespace=" + ns); } return results; } return null; } public void invalidateAllQueries(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_USERS_QUERIES)); cache.getRoot().removeChild(getFqn(ns, NODE_GROUPS_QUERIES)); cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_QUERIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating all queries. Namespace:" + ns); } } public void putUserQuery(String ns, UserQuery q, Collection<User> results) { Fqn nodeFqn = getFqn(ns, NODE_USERS_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_KEY, results); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User query stored in cache: q.hashCode()=" + q.hashCode() + "; results.size()=" + results.size() + ";namespace=" + ns); } } } public void putUserQueryUnique(String ns, UserQuery q, User user) { Fqn nodeFqn = getFqn(ns, NODE_USERS_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_UNIQUE_KEY, user); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "User query stored in cache: q.hashCode()=" + q.hashCode() + "; user=" + user + ";namespace=" + ns); } } } public Collection<User> getUserQuery(String ns, UserQuery q) { Fqn nodeFqn = getFqn(ns, NODE_USERS_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<User> users = (Collection<User>)node.get(NODE_QUERY_KEY); if (log.isLoggable(Level.FINER) && users != null) { log.finer(this.toString() + "User query found in cache: users.size()=" + users.size() + "; query.hash()=" + q.hashCode() + ";namespace=" + ns); } return users; } return null; } public User getUserQueryUnique(String ns, UserQuery q) { Fqn nodeFqn = getFqn(ns, NODE_USERS_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { User users = (User)node.get(NODE_QUERY_UNIQUE_KEY); if (log.isLoggable(Level.FINER) && users != null) { log.finer(this.toString() + "User query found in cache: user=" + users + ";namespace=" + ns); } return users; } return null; } public void invalidateUserQueries(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_USERS_QUERIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating User queries. Namespace:" + ns); } } public void putGroupQuery(String ns, GroupQuery q, Collection<Group> results) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_KEY, unmodifiableCollection(results)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group query stored in cache: q.hashCode()=" + q.hashCode() + "; results.size()=" + results.size() + ";namespace=" + ns); } } } public void putGroupQueryUnique(String ns, GroupQuery q, Group group) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_UNIQUE_KEY, group); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Group query stored in cache: q.hashCode()=" + q.hashCode() + "; group=" + group + ";namespace=" + ns); } } } public Collection<Group> getGroupQuery(String ns, GroupQuery q) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<Group> groups = (Collection<Group>)node.get(NODE_QUERY_KEY); if (log.isLoggable(Level.FINER) && groups != null) { log.finer(this.toString() + "Group query found in cache: groups.size()=" + groups.size() + "; query.hash()=" + q.hashCode() + ";namespace=" + ns); } return groups; } return null; } public Group getGroupQueryUnique(String ns, GroupQuery q) { Fqn nodeFqn = getFqn(ns, NODE_GROUPS_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Group group = (Group)node.get(NODE_QUERY_UNIQUE_KEY); if (log.isLoggable(Level.FINER) && group != null) { log.finer(this.toString() + "Group query found in cache: group=" + group + ";namespace=" + ns); } return group; } return null; } public void invalidateGroupQueries(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_GROUPS_QUERIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Group queries. Namespace:" + ns); } } public void putRoleQuery(String ns, RoleQuery q, Collection<Role> results) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_KEY, results); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Role query stored in cache: q.hashCode()=" + q.hashCode() + "; results.size()=" + results.size() + ";namespace=" + ns); } } } public void putRoleQueryUnique(String ns, RoleQuery q, Role role) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_QUERIES, q.hashCode()); Node ioNode = getCache().getRoot().addChild(nodeFqn); if (ioNode != null) { setExpiration(ioNode); ioNode.put(NODE_QUERY_UNIQUE_KEY, role); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Role query stored in cache: q.hashCode()=" + q.hashCode() + "; role=" + role + ";namespace=" + ns); } } } public Collection<Role> getRoleQuery(String ns, RoleQuery q) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Collection<Role> roles = (Collection<Role>)node.get(NODE_QUERY_KEY); if (log.isLoggable(Level.FINER) && roles != null) { log.finer(this.toString() + "Role query found in cache: users.size()=" + roles.size() + "; query.hash()=" + q.hashCode() + ";namespace=" + ns); } return roles; } return null; } public Role getRoleQueryUnique(String ns, RoleQuery q) { Fqn nodeFqn = getFqn(ns, NODE_ROLE_QUERIES, q.hashCode()); Node node = getCache().getRoot().getChild(nodeFqn); if (node != null) { Role role = (Role)node.get(NODE_QUERY_UNIQUE_KEY); if (log.isLoggable(Level.FINER) && role != null) { log.finer(this.toString() + "Role query found in cache: role=" + role + ";namespace=" + ns); } return role; } return null; } public void invalidateRoleQueries(String ns) { cache.getRoot().removeChild(getFqn(ns, NODE_ROLE_QUERIES)); if (log.isLoggable(Level.FINER)) { log.finer(this.toString() + "Invalidating Role queries. Namespace:" + ns); } } private Collection unmodifiableCollection(Collection collection) { if (collection == null) { return collection; } if (collection instanceof List) { return Collections.unmodifiableList((List)collection); } if (collection instanceof SortedSet) { return Collections.unmodifiableSortedSet((SortedSet)collection); } if (collection instanceof Set) { return Collections.unmodifiableSet((Set)collection); } return Collections.unmodifiableCollection(collection); } public void setExpiration(Node node) { if (expiration != -1 && expiration > 0) { Long future = new Long(System.currentTimeMillis() + expiration); node.put(ExpirationAlgorithmConfig.EXPIRATION_KEY, future); } } public int getExpiration() { return expiration; } public void setExpiration(int expiration) { this.expiration = expiration; } }