/*
* JBoss, a division of Red Hat
* Copyright 2006, 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.jboss.identity.idm.impl.cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Node;
import org.jboss.identity.idm.spi.model.IdentityObject;
import org.jboss.identity.idm.spi.model.IdentityObjectType;
import org.jboss.identity.idm.spi.model.IdentityObjectRelationshipType;
import org.jboss.identity.idm.spi.model.IdentityObjectAttribute;
import org.jboss.identity.idm.spi.model.IdentityObjectRelationship;
import org.jboss.identity.idm.spi.search.IdentityObjectSearchCriteria;
import org.jboss.identity.idm.spi.cache.IdentityStoreCacheProvider;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Set;
import java.util.Map;
import java.util.Collection;
import java.io.InputStream;
/**
* Helper class providing caching support for IdentityStore. Stores search methods results using hash from a set of used
* IdentityObjectSearchControl objects as a key. *
*
* TODO: update cache tree structure documentation to all used nodes/keys...
* Cache structure:
*
* CACHE_ROOT (real)
* |
* |-JBID_ROOT_NODE
* |
* |-OBJECT_TYPES_NODE
* | |
* | |-OBJECT_TYPES_IDS_NODE
* | | |
* | | |- (IdentityObjectType names)
* | | | key[NODE_OBJECT_KEY] -> IdentityObject
* | | |- ...
* | |
* | |-OBJECT_TYPES_NAMES_NODE
* | | |
* | | |- (IdentityObjectType names)
* | | | key[NODE_OBJECT_KEY] -> IdentityObject
* | | | key[NODE_ATTRIBUTES_KEY] -> Map<String, IdentityObjectAttribute>
* | | |- ...
* | |
* | |-OBJECT_TYPES_SEARCH_NODE
* | |
* | |
* | |- ...
* |
* |-RELATIONSHIPS_NODE
* |
*
* @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
* @version : 0.1 $
*/
public class IdentityStoreCacheProviderImpl implements IdentityStoreCacheProvider
{
private static Logger log = Logger.getLogger(IdentityStoreCacheProvider.class.getName());
//Structure
public static final String JBID_ROOT_NODE = "/jboss_id_idm";
public static final String OBJECT_TYPES_NODE = JBID_ROOT_NODE + "/object_types";
public static final String OBJECT_TYPES_IDS_NODE = OBJECT_TYPES_NODE + "/by_ids";
public static final String OBJECT_TYPES_NAMES_NODE = OBJECT_TYPES_NODE + "/by_names";
public static final String OBJECT_TYPES_SEARCH_BY_TYPE_NODE = OBJECT_TYPES_NODE + "/search_by_type";
public static final String OBJECT_TYPES_SEARCH_NODE = OBJECT_TYPES_NODE + "/search";
// Don't populate children as resident nodes!
public static final String OBJECT_TYPES_COUNT_NODE = OBJECT_TYPES_NODE + "/count";
public static final String RELATIONSHIPS_SEARCH_NODE = JBID_ROOT_NODE + "/relationship_types_names";
public static final String RELATIONSHIPS_SEARCH_SIMPLE_NODE = RELATIONSHIPS_SEARCH_NODE + "/simple";
public static final String RELATIONSHIPS_SEARCH_COMPLEX_NODE = RELATIONSHIPS_SEARCH_NODE + "/complex";
public static final String RELATIONSHIP_NAMES_SEARCH_NODE = JBID_ROOT_NODE + "/relationship_names_search";
public static final String RELATIONSHIP_NAMES_SEARCH_IO_NODE = RELATIONSHIP_NAMES_SEARCH_NODE + "/identity_object";
public static final String RELATIONSHIP_NAMES_SEARCH_ALL_NODE = RELATIONSHIP_NAMES_SEARCH_NODE + "/all";
// Node keys
public static final String NODE_OBJECT_KEY = "object";
public static final String NODE_ATTRIBUTES_KEY = "attributes";
public static final String NODE_REL_NAME_KEY = "relationship_name";
public static final String NODE_REL_TYPE_KEY = "relationship_type";
public static final String NODE_REL_FROM_KEY = "relationship_from";
public static final String NODE_REL_TO_KEY = "relationship_to";
public static final String NODE_SEARCH_RESULTS_KEY = "search_results";
// FQNs
public static final Fqn FQN_OBJECT_TYPES = Fqn.fromString(OBJECT_TYPES_NODE);
public static final Fqn FQN_OBJECT_TYPES_NAMES = Fqn.fromString(OBJECT_TYPES_NAMES_NODE);
public static final Fqn FQN_OBJECT_TYPES_IDS = Fqn.fromString(OBJECT_TYPES_IDS_NODE);
public static final Fqn FQN_OBJECT_TYPES_SEARCH_BY_TYPE = Fqn.fromString(OBJECT_TYPES_SEARCH_BY_TYPE_NODE);
public static final Fqn FQN_OBJECT_TYPES_SEARCH = Fqn.fromString(OBJECT_TYPES_SEARCH_NODE);
public static final Fqn FQN_OBJECT_TYPES_COUNT = Fqn.fromString(OBJECT_TYPES_COUNT_NODE);
public static final Fqn FQN_RELATIONSHIPS = Fqn.fromString(RELATIONSHIPS_SEARCH_NODE);
public static final Fqn FQN_RELATIONSHIPS_COMPLEX = Fqn.fromString(RELATIONSHIPS_SEARCH_COMPLEX_NODE);
public static final Fqn FQN_RELATIONSHIPS_SIMPLE = Fqn.fromString(RELATIONSHIPS_SEARCH_SIMPLE_NODE);
protected final Cache cache;
public IdentityStoreCacheProviderImpl(InputStream cacheConfigInputStream)
{
CacheFactory factory = new DefaultCacheFactory();
this.cache = factory.createCache(cacheConfigInputStream);
this.cache.start();
}
private Fqn createIONameNodeFQN(String ioTypeName, String ioName)
{
return Fqn.fromElements(OBJECT_TYPES_NAMES_NODE, ioTypeName, ioName);
}
private Fqn createIONameNodeFQN(IdentityObject io)
{
return Fqn.fromElements(OBJECT_TYPES_NAMES_NODE, io.getIdentityType().getName(), io.getName());
}
private Fqn createIOIdNodeFQN(IdentityObject io)
{
return Fqn.fromElements(OBJECT_TYPES_IDS_NODE, io.getIdentityType().getName(), io.getId());
}
private Fqn createIOTypeCountNodeFQN(IdentityObjectType iot)
{
return Fqn.fromElements(OBJECT_TYPES_COUNT_NODE, iot.getName());
}
private Fqn createIOTypeSearchNodeFQN(IdentityObjectType iot, Object searchId)
{
return Fqn.fromElements(OBJECT_TYPES_SEARCH_BY_TYPE_NODE, iot.getName(), searchId);
}
private Fqn createIOSearchNodeFQN(IdentityObject io, IdentityObjectRelationshipType relationshipType, boolean parent, Object searchId)
{
return Fqn.fromElements(OBJECT_TYPES_SEARCH_NODE, io.getIdentityType().getName(), relationshipType == null ? "null" : relationshipType.getName(),
io.getName() + "_" + parent, searchId);
}
private Fqn createRelationshipNamesIdentityObjectSearchFqn(IdentityObject identityObject, Object searchId)
{
return Fqn.fromElements(RELATIONSHIP_NAMES_SEARCH_IO_NODE, identityObject.getIdentityType() + "_" + identityObject.getName(),
searchId);
}
private Fqn createRelationshipNamesAllSearchFqn(Object searchId)
{
return Fqn.fromElements(RELATIONSHIP_NAMES_SEARCH_ALL_NODE, searchId);
}
private Fqn createRelationshipsSimpleSearchFqn(IdentityObject fromIdentity,
IdentityObject toIdentity,
IdentityObjectRelationshipType relationshipType)
{
//TODO: fixme - null relationshipType
return Fqn.fromElements(RELATIONSHIPS_SEARCH_SIMPLE_NODE, fromIdentity.getIdentityType().getName() + "_" + toIdentity.getName(),
toIdentity.getIdentityType().getName() + "_" + toIdentity.getName(), relationshipType == null ? "null" : relationshipType );
}
private Fqn createRelationshipsComplexSearchFqn(IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
boolean parent,
boolean named,
String name)
{
return Fqn.fromElements(RELATIONSHIPS_SEARCH_COMPLEX_NODE, identity.getIdentityType().getName() + "_" + identity.getName(),
parent, relationshipType, named + "_" + name);
}
public static boolean isSchemaFqn(Fqn fqn)
{
if (fqn.equals(JBID_ROOT_NODE) ||
fqn.equals(OBJECT_TYPES_NODE) ||
fqn.equals(OBJECT_TYPES_IDS_NODE) ||
fqn.equals(OBJECT_TYPES_NAMES_NODE) ||
fqn.equals(RELATIONSHIPS_SEARCH_NODE))
{
return true;
}
return false;
}
public static boolean isFqnObjectTypeChild(Fqn fqn)
{
return fqn.isChildOf(FQN_OBJECT_TYPES);
}
public static boolean isFqnObjectTypeIdsChild(Fqn fqn)
{
return fqn.isChildOf(FQN_OBJECT_TYPES_IDS);
}
public static boolean isFqnObjectTypeNamesChild(Fqn fqn)
{
return fqn.isChildOf(FQN_OBJECT_TYPES_NAMES);
}
public static boolean isFqnObjectTypeSearchChild(Fqn fqn)
{
return fqn.isChildOf(FQN_OBJECT_TYPES_SEARCH_BY_TYPE);
}
public static boolean isFqnRelationshipsChild(Fqn fqn)
{
return fqn.isChildOf(FQN_RELATIONSHIPS);
}
private void removeNodeChildren(String path)
{
Fqn fqn = Fqn.fromString(path);
Node node = getCache().getRoot().getChild(fqn);
if (node != null)
{
Set<Object> names = node.getChildrenNames();
for (Object name : names)
{
node.removeChild(name);
}
}
}
protected Logger getLog()
{
return log;
}
protected Cache getCache()
{
return cache;
}
public void initResidentNodes(Set<String> supportedIdentityObjectTypes,
Set<String> supportedRelationshipTypes)
{
getCache().getRoot().addChild(Fqn.fromString(IdentityStoreCacheProviderImpl.JBID_ROOT_NODE)).setResident(true);
getCache().getRoot().addChild(Fqn.fromString(IdentityStoreCacheProviderImpl.OBJECT_TYPES_NODE)).setResident(true);
getCache().getRoot().addChild(FQN_OBJECT_TYPES_IDS).setResident(true);
getCache().getRoot().addChild(FQN_OBJECT_TYPES_NAMES).setResident(true);
getCache().getRoot().addChild(FQN_OBJECT_TYPES_SEARCH).setResident(true);
getCache().getRoot().addChild(FQN_OBJECT_TYPES_SEARCH_BY_TYPE).setResident(true);
getCache().getRoot().addChild(FQN_OBJECT_TYPES_COUNT).setResident(true);
getCache().getRoot().addChild(Fqn.fromString(RELATIONSHIP_NAMES_SEARCH_ALL_NODE)).setResident(true);
getCache().getRoot().addChild(Fqn.fromString(RELATIONSHIP_NAMES_SEARCH_IO_NODE)).setResident(true);
getCache().getRoot().addChild(Fqn.fromString(RELATIONSHIPS_SEARCH_COMPLEX_NODE)).setResident(true);
getCache().getRoot().addChild(Fqn.fromString(RELATIONSHIPS_SEARCH_SIMPLE_NODE)).setResident(true);
for (String objectTypeName : supportedIdentityObjectTypes)
{
Fqn nodeFqn = Fqn.fromRelativeElements(FQN_OBJECT_TYPES_NAMES, "/" + objectTypeName);
getCache().getRoot().addChild(nodeFqn).setResident(true);
nodeFqn = Fqn.fromRelativeElements(FQN_OBJECT_TYPES_IDS, "/" + objectTypeName);
getCache().getRoot().addChild(nodeFqn).setResident(true);
}
}
public void putIntoCache(IdentityObject io)
{
Fqn nodeFqn = createIONameNodeFQN(io);
Node ioNode = getCache().getRoot().addChild(nodeFqn);
// in case this node was already present in cache
if (!ioNode.getKeys().contains(NODE_OBJECT_KEY))
{
ioNode.put(NODE_OBJECT_KEY, io);
}
nodeFqn = createIOIdNodeFQN(io);
ioNode = getCache().getRoot().addChild(nodeFqn);
// in case this node was already present in cache
if (!ioNode.getKeys().contains(NODE_OBJECT_KEY))
{
ioNode.put(NODE_OBJECT_KEY, io);
}
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject stored in cache: " + io.getName() + "; " + io.getId());
}
}
public void putIntoCache(IdentityObject io, Map<String, IdentityObjectAttribute> attributesMap)
{
Fqn nodeFqn = createIONameNodeFQN(io);
Node ioNode = getCache().getRoot().addChild(nodeFqn);
// in case this node was already present in cache
if (!ioNode.getKeys().contains(NODE_OBJECT_KEY))
{
ioNode.put(NODE_OBJECT_KEY, io);
}
if (!ioNode.getKeys().contains(NODE_ATTRIBUTES_KEY))
{
ioNode.put(NODE_ATTRIBUTES_KEY, attributesMap);
}
nodeFqn = createIOIdNodeFQN(io);
ioNode = getCache().getRoot().addChild(nodeFqn);
// in case this node was already present in cache
if (!ioNode.getKeys().contains(NODE_OBJECT_KEY))
{
ioNode.put(NODE_OBJECT_KEY, io);
}
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject stored in cache with attributes map: " + io.getName() + "; " + io.getId()
+ "; type=" + io.getIdentityType().getName() );
}
}
public void removeFromCache(IdentityObject io)
{
Fqn nodeFqn = createIONameNodeFQN(io);
getCache().getRoot().removeChild(nodeFqn);
nodeFqn = createIOIdNodeFQN(io);
getCache().getRoot().removeChild(nodeFqn);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject removed from cache: " + io.getName() + "; " + io.getId()
+ "; type=" + io.getIdentityType().getName() );
}
}
public void removeAttributesFromCache(IdentityObject io)
{
Fqn nodeFqn = createIONameNodeFQN(io);
Node ioNode = getCache().getRoot().addChild(nodeFqn);
ioNode.remove(NODE_ATTRIBUTES_KEY);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject attributes removed from cache: name=" + io.getName() + "; id=" + io.getId()
+ "; type=" + io.getIdentityType().getName() );
}
}
public IdentityObject getFromCache(String name, IdentityObjectType identityObjectType)
{
Fqn nodeFqn = Fqn.fromElements(OBJECT_TYPES_NODE, identityObjectType.getName(), name);
Node ioNode = getCache().getRoot().getChild(nodeFqn);
if (ioNode != null)
{
IdentityObject io = (IdentityObject)ioNode.get(NODE_OBJECT_KEY);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject found in cache: name=" + io.getName() + "; id=" + io.getId());
}
return io;
}
return null;
}
public Map<String, IdentityObjectAttribute> getAttributesFromCache(String name, IdentityObjectType identityObjectType)
{
Fqn nodeFqn = Fqn.fromElements(OBJECT_TYPES_NODE, identityObjectType.getName(), name);
Node ioNode = getCache().getRoot().getChild(nodeFqn);
if (ioNode != null)
{
Map<String, IdentityObjectAttribute> attrs = (Map<String, IdentityObjectAttribute>)ioNode.get(NODE_ATTRIBUTES_KEY);
if (attrs != null)
{
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject attributes found in cache: name=" + name + "; type=" + identityObjectType.getName());
}
}
return attrs;
}
return null;
}
public IdentityObject getFromCache(String id)
{
Node idsNode = getCache().getRoot().getChild(OBJECT_TYPES_IDS_NODE);
for (Node typeNode : (Set<Node>)idsNode.getChildren())
{
for (Object name : typeNode.getChildrenNames())
{
if (name.toString().equals(id))
{
IdentityObject io = (IdentityObject)typeNode.getChild(name).get(NODE_OBJECT_KEY);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject found in cache: name" + io.getName() + "; type" + io.getIdentityType().getName());
}
return io;
}
}
}
return null;
}
public void putIdentityObjectSearchIntoCache(IdentityObjectType identityType,
IdentityObjectSearchCriteria criteria,
Collection<IdentityObject> results)
{
Fqn nodeFqn = createIOTypeSearchNodeFQN(identityType, getControlsHash(criteria));
Node searchNode = getCache().getRoot().addChild(nodeFqn);
searchNode.put(NODE_SEARCH_RESULTS_KEY, results);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject search results stored in cache: type" + identityType.getName());
}
}
public Collection<IdentityObject> getIdentityObjectSearchFromCache(IdentityObjectType identityType,
IdentityObjectSearchCriteria criteria)
{
Fqn nodeFqn = createIOTypeSearchNodeFQN(identityType, getControlsHash(criteria));
Node searchNode = getCache().getRoot().getChild(nodeFqn);
Collection<IdentityObject> results = null;
if (searchNode != null)
{
results = (Collection<IdentityObject>)searchNode.get(NODE_SEARCH_RESULTS_KEY);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject search results found in cache: type" + identityType.getName());
}
}
return results;
}
public void putIdentityObjectSearchToCache(IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
boolean parent,
IdentityObjectSearchCriteria criteria,
Collection<IdentityObject> results)
{
Fqn nodeFqn = createIOSearchNodeFQN(identity, relationshipType, parent, getControlsHash(criteria));
Node searchNode = getCache().getRoot().addChild(nodeFqn);
searchNode.put(NODE_SEARCH_RESULTS_KEY, results);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject search results stored in cache: IdentityObject name= " + identity.getName()
+ "; IdentityObject type= " + identity.getIdentityType().getName() + "; IdentityObjectRelationshipType= " + relationshipType +
"; parent= " + parent);
}
}
public Collection<IdentityObject> getIdentityObjectSearchFromCache(IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
boolean parent,
IdentityObjectSearchCriteria criteria)
{
Fqn nodeFqn = createIOSearchNodeFQN(identity, relationshipType, parent, getControlsHash(criteria));
Node searchNode = getCache().getRoot().getChild(nodeFqn);
Collection<IdentityObject> results = null;
if (searchNode != null)
{
results = (Collection<IdentityObject>)searchNode.get(NODE_SEARCH_RESULTS_KEY);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject search results found in cache: IdentityObject name= " + identity.getName()
+ "; IdentityObject type= " + identity.getIdentityType().getName() + "; IdentityObjectRelationshipType= " + relationshipType +
"; parent= " + parent);
}
}
return results;
}
public void putRelationshipsSearchIntoCache(IdentityObject fromIdentity,
IdentityObject toIdentity,
IdentityObjectRelationshipType relationshipType,
Set<IdentityObjectRelationship> results)
{
Fqn fqn = createRelationshipsSimpleSearchFqn(fromIdentity, toIdentity, relationshipType);
Node node = getCache().getRoot().addChild(fqn);
node.put(NODE_SEARCH_RESULTS_KEY, results);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search stored in cache: fromIdentity" +
fromIdentity.toString() + "; toIdentity=" + toIdentity.toString() +
"; relationshipType=" + relationshipType.getName() ) ;
}
}
public Set<IdentityObjectRelationship> getRelationshipsSearchFromCache(IdentityObject fromIdentity,
IdentityObject toIdentity,
IdentityObjectRelationshipType relationshipType)
{
Fqn fqn = createRelationshipsSimpleSearchFqn(fromIdentity, toIdentity, relationshipType);
Node node = getCache().getRoot().getChild(fqn);
if (node != null)
{
if (node.getKeys().contains(NODE_SEARCH_RESULTS_KEY) && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search found in cache: fromIdentity" +
fromIdentity.toString() + "; toIdentity=" + toIdentity.toString() +
"; relationshipType=" + relationshipType.getName() ) ;
}
return (Set<IdentityObjectRelationship>)node.get(NODE_SEARCH_RESULTS_KEY);
}
return null;
}
public void putRelationshipSearchIntoCache(IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
boolean parent,
boolean named,
String name,
Set<IdentityObjectRelationship> results)
{
Fqn fqn = createRelationshipsComplexSearchFqn(identity, relationshipType, parent, named, name);
Node node = getCache().getRoot().addChild(fqn);
node.put(NODE_SEARCH_RESULTS_KEY, results);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search stored in cache: " +
"identity" + identity.toString() +
"; relationshipType=" + relationshipType.getName() +
"; parent=" + parent +
"; named=" + named +
"; name=" + name) ;
}
}
public Set<IdentityObjectRelationship> getRelationshipsSearchFromCache(IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
boolean parent,
boolean named,
String name)
{
Fqn fqn = createRelationshipsComplexSearchFqn(identity, relationshipType, parent, named, name);
Node node = getCache().getRoot().getChild(fqn);
Set<IdentityObjectRelationship> results = null;
if (node != null)
{
results = (Set<IdentityObjectRelationship>)node.get(NODE_SEARCH_RESULTS_KEY);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search found in cache: " +
"identity" + identity.toString() +
"; relationshipType=" + relationshipType.getName() +
"; parent=" + parent +
"; named=" + named +
"; name=" + name) ;
}
}
return results;
}
public void invalidateCachedIdentityObjectSearches(IdentityObject io)
{
Fqn fqn = Fqn.fromElements(OBJECT_TYPES_SEARCH_BY_TYPE_NODE, io.getIdentityType().getName());
getCache().getRoot().removeChild(fqn);
// It can be in any result in the type searches
removeNodeChildren(OBJECT_TYPES_SEARCH_NODE);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObject searches invalidated in cache: identityObject=" + io.toString());
}
}
public void putIdentityObjectCountIntoCache(IdentityObjectType identityType, int count)
{
Fqn fqn = createIOTypeCountNodeFQN(identityType);
Node node = getCache().getRoot().addChild(fqn);
node.put(NODE_OBJECT_KEY, count);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectType count search strored in cache: " +
"identityObjectType=" + identityType.getName() +
"; count=" + count);
}
}
public int getIdentityObjectCountFromCache(IdentityObjectType identityType)
{
Fqn fqn = createIOTypeCountNodeFQN(identityType);
Node node = getCache().getRoot().getChild(fqn);
if (node != null && node.getKeys().contains(NODE_OBJECT_KEY))
{
int count = (Integer)(node.get(NODE_OBJECT_KEY));
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectType count search result found in cache: " +
"identityObjectType=" + identityType.getName() +
"; count=" + count);
}
return count;
}
// -1 means nothing in cache
return -1;
}
public void invalidateCachedIdentityObjectCount(IdentityObjectType identityType)
{
Fqn fqn = createIOTypeCountNodeFQN(identityType);
Node node = getCache().getRoot().addChild(fqn);
node.remove(NODE_OBJECT_KEY);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectType count search result invalidated in cache: " +
"identityObjectType=" + identityType.getName());
}
}
public void invalidateCachedRelationshipSearches(IdentityObject fromIdentity,
IdentityObject toIdentity,
IdentityObjectRelationshipType relationshipType,
String relationshipName)
{
String fromName = fromIdentity.getIdentityType().getName() + "_" + fromIdentity.getName();
String toName = toIdentity.getIdentityType().getName() + "_" + toIdentity.getName();
// Simple
// Fqn fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_SIMPLE_NODE, fromName, toName, relationshipType.getName());
// getCache().getRoot().removeChild(fqn);
Fqn fqn = createRelationshipsSimpleSearchFqn(fromIdentity, toIdentity, relationshipType);
getCache().getRoot().removeChild(fqn);
// Complex
String relNameElement;
if (relationshipName != null)
{
relNameElement = true + relationshipName;
}
else
{
relNameElement = false + relationshipName;
}
fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_COMPLEX_NODE, fromName, true, relationshipType.getName(), relNameElement);
getCache().getRoot().removeChild(fqn);
fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_COMPLEX_NODE, toName, false, relationshipType.getName(), relNameElement);
getCache().getRoot().removeChild(fqn);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search result invalidated in cache: fromIdentity" +
fromIdentity.toString() + "; toIdentity=" + toIdentity.toString() +
"; relationshipType=" + relationshipType.getName() ) ;
}
}
public void invalidateCachedRelationshipSearches(IdentityObject identity1, IdentityObject identity2, boolean named)
{
String name1 = identity1.getIdentityType().getName() + "_" + identity1.getName();
String name2 = identity2.getIdentityType().getName() + "_" + identity2.getName();
// Complex search
Fqn fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_COMPLEX_NODE, name1);
getCache().getRoot().removeChild(fqn);
fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_COMPLEX_NODE, name2);
getCache().getRoot().removeChild(fqn);
// Simple search
getCache().getRoot().removeChild(Fqn.fromElements(RELATIONSHIPS_SEARCH_SIMPLE_NODE, name1));
getCache().getRoot().removeChild(Fqn.fromElements(RELATIONSHIPS_SEARCH_SIMPLE_NODE, name2));
fqn = Fqn.fromElements(RELATIONSHIPS_SEARCH_SIMPLE_NODE);
Set<String> names = getCache().getRoot().getChildrenNames();
for (String childName : names)
{
//
getCache().getRoot().removeChild(Fqn.fromElements(fqn, childName, name1));
getCache().getRoot().removeChild(Fqn.fromElements(fqn, childName, name2));
}
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationship search result invalidated in cache for: identity1" +
identity1.toString() + "; identity2=" + identity2.toString() +
"; named=" + named ) ;
}
}
public void invalidateRelationshipNameSearches(String name)
{
//TODO: at the moment it just trash up all relationships searches
removeNodeChildren(RELATIONSHIP_NAMES_SEARCH_ALL_NODE);
removeNodeChildren(RELATIONSHIP_NAMES_SEARCH_IO_NODE);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationshipName search results invalidated in cache: name" +
name ) ;
}
}
public void putRelationshipNamesSearchIntoCache(IdentityObjectSearchCriteria criteria, Set<String> results)
{
Fqn fqn = createRelationshipNamesAllSearchFqn(getControlsHash(criteria));
Node node = getCache().getRoot().addChild(fqn);
node.put(NODE_SEARCH_RESULTS_KEY, results);
if (getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationshipName search results invalidated in cache: criteria hash=" +
getControlsHash(criteria)) ;
}
}
public Set<String> getRelationshipNamesSearchFromCache(IdentityObjectSearchCriteria criteria)
{
Fqn fqn = createRelationshipNamesAllSearchFqn(getControlsHash(criteria));
Node node = getCache().getRoot().getChild(fqn);
if (node != null)
{
Set<String> results = (Set<String>)node.get(NODE_SEARCH_RESULTS_KEY);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationshipName search result found in cache: criteria hash=" +
getControlsHash(criteria)) ;
}
return results;
}
return null;
}
public void putRelationshipNamesSearchIntoCache(IdentityObject identity,
IdentityObjectSearchCriteria criteria,
Set<String> results)
{
Fqn fqn = createRelationshipNamesIdentityObjectSearchFqn(identity, getControlsHash(criteria));
Node node = getCache().getRoot().addChild(fqn);
node.put(NODE_SEARCH_RESULTS_KEY, results);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationshipName search result stored in cache: " +
"criteria hash=" + getControlsHash(criteria) +
"identity=" + identity.toString()) ;
}
}
public Set<String> getRelationshipNamesSearchFromCache(IdentityObject identity, IdentityObjectSearchCriteria criteria)
{
Fqn fqn = createRelationshipNamesIdentityObjectSearchFqn(identity, getControlsHash(criteria));
Node node = getCache().getRoot().getChild(fqn);
if (node != null)
{
Set<String> results = (Set<String>)node.get(NODE_SEARCH_RESULTS_KEY);
if (results != null && getLog().isLoggable(Level.FINER))
{
getLog().finer(this.toString() + "IdentityObjectRelationshipName search result found in cache: " +
"criteria hash=" + getControlsHash(criteria) +
"identity=" + identity.toString()) ;
}
return results;
}
return null;
}
private int getControlsHash(IdentityObjectSearchCriteria criteria)
{
// Convert criteria to Set to have the same hashcode regardles order of criteria
int hashcode = 0;
if (criteria != null)
{
hashcode = criteria.hashCode();
}
return hashcode;
}
}