Package org.jboss.identity.idm.impl.cache

Source Code of org.jboss.identity.idm.impl.cache.IdentityStoreCacheProviderImpl

/*
* 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;
   }
}
TOP

Related Classes of org.jboss.identity.idm.impl.cache.IdentityStoreCacheProviderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.