[jboss-identity-commits] JBoss Identity SVN: r260 - in idm/trunk: idm/src/main/java/org/jboss/identity/idm/impl and 7 other directories.

jboss-identity-commits at lists.jboss.org jboss-identity-commits at lists.jboss.org
Thu Jan 29 13:51:55 EST 2009


Author: bdaw
Date: 2009-01-29 13:51:55 -0500 (Thu, 29 Jan 2009)
New Revision: 260

Added:
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/IdentityStoreCacheSupport.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/JBossCacheIdentityStoreWrapper.java
   idm/trunk/idm/src/test/resources/logging.properties
Modified:
   idm/trunk/idm-spi/src/main/java/org/jboss/identity/idm/spi/store/IdentityStore.java
   idm/trunk/idm/pom.xml
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/AttributeFilterSearchControl.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/NameFilterSearchControl.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/PageSearchControl.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/SortByNameSearchControl.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/model/ldap/LDAPIdentityObjectImpl.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObject.java
   idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObjectType.java
   idm/trunk/idm/src/test/java/org/jboss/identity/idm/impl/SimpleIdentityObjectTypeImpl.java
Log:
- Simple wrapper around IdentityStore providing caching using JBossCache. Still needs some work...

Modified: idm/trunk/idm/pom.xml
===================================================================
--- idm/trunk/idm/pom.xml	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/pom.xml	2009-01-29 18:51:55 UTC (rev 260)
@@ -58,6 +58,12 @@
          <version>3.3.2.GA</version>
       </dependency>
       <dependency>
+         <groupId>org.jboss.cache</groupId>
+         <artifactId>jbosscache-core</artifactId>
+         <version>3.0.2.GA</version>
+      </dependency>
+
+      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <scope>test</scope>

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/AttributeFilterSearchControl.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/AttributeFilterSearchControl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/AttributeFilterSearchControl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -26,6 +26,7 @@
 import org.jboss.identity.idm.spi.searchcontrol.IdentityObjectSearchControl;
 
 import java.util.Map;
+import java.util.Collections;
 
 /**
  * @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
@@ -41,11 +42,39 @@
       {
          throw new IllegalArgumentException("attributes is null");
       }
-      this.attributes = attributes;
+      this.attributes = Collections.unmodifiableMap(attributes);
    }
 
    public Map<String, String[]> getValues()
    {
       return attributes;
    }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o)
+      {
+         return true;
+      }
+      if (o == null || getClass() != o.getClass())
+      {
+         return false;
+      }
+
+      AttributeFilterSearchControl that = (AttributeFilterSearchControl)o;
+
+      if (!attributes.equals(that.attributes))
+      {
+         return false;
+      }
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return attributes.hashCode();
+   }
 }

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/NameFilterSearchControl.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/NameFilterSearchControl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/NameFilterSearchControl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -43,4 +43,32 @@
    {
       return filter;
    }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o)
+      {
+         return true;
+      }
+      if (o == null || getClass() != o.getClass())
+      {
+         return false;
+      }
+
+      NameFilterSearchControl that = (NameFilterSearchControl)o;
+
+      if (filter != null ? !filter.equals(that.filter) : that.filter != null)
+      {
+         return false;
+      }
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return filter != null ? filter.hashCode() : 0;
+   }
 }

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/PageSearchControl.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/PageSearchControl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/PageSearchControl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -50,4 +50,38 @@
    {
       return limit;
    }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o)
+      {
+         return true;
+      }
+      if (o == null || getClass() != o.getClass())
+      {
+         return false;
+      }
+
+      PageSearchControl that = (PageSearchControl)o;
+
+      if (limit != that.limit)
+      {
+         return false;
+      }
+      if (offset != that.offset)
+      {
+         return false;
+      }
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int result = offset;
+      result = 31 * result + limit;
+      return result;
+   }
 }

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/SortByNameSearchControl.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/SortByNameSearchControl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/api/SortByNameSearchControl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -42,4 +42,32 @@
    {
       return ascending;
    }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o)
+      {
+         return true;
+      }
+      if (o == null || getClass() != o.getClass())
+      {
+         return false;
+      }
+
+      SortByNameSearchControl that = (SortByNameSearchControl)o;
+
+      if (ascending != that.ascending)
+      {
+         return false;
+      }
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (ascending ? 1 : 0);
+   }
 }

Added: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/IdentityStoreCacheSupport.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/IdentityStoreCacheSupport.java	                        (rev 0)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/IdentityStoreCacheSupport.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -0,0 +1,800 @@
+/*
+* 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.Node;
+import org.jboss.identity.idm.spi.model.IdentityObject;
+import org.jboss.identity.idm.spi.model.IdentityObjectAttribute;
+import org.jboss.identity.idm.spi.model.IdentityObjectType;
+import org.jboss.identity.idm.spi.model.IdentityObjectRelationshipType;
+import org.jboss.identity.idm.spi.model.IdentityObjectRelationship;
+import org.jboss.identity.idm.spi.searchcontrol.IdentityObjectSearchControl;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+import java.util.List;
+import java.util.Arrays;
+import java.util.HashSet;
+
+/**
+ *
+ * TODO: update the structure...
+ * 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 abstract class IdentityStoreCacheSupport
+{
+
+   // TODO: more logging... 
+
+   // Node paths
+
+   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);
+
+
+   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.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 abstract Logger getLog();
+
+   protected abstract Cache getCache();
+
+   protected void initResidentNodes(Set<String> supportedIdentityObjectTypes,
+                                    Set<String> supportedRelationshipTypes)
+   {
+      getCache().getRoot().addChild(Fqn.fromString(IdentityStoreCacheSupport.JBID_ROOT_NODE)).setResident(true);
+      getCache().getRoot().addChild(Fqn.fromString(IdentityStoreCacheSupport.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);
+      }
+   }
+
+   protected 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 storred in cache: " + io.getName() + "; " + io.getId());
+      }
+   }
+
+   protected 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 storred in cache with attributes map: " + io.getName() + "; " + io.getId()
+            + "; type=" + io.getIdentityType().getName() );
+      }
+   }
+
+   protected 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() );
+      }
+   }
+
+   protected 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() );
+      }
+   }
+
+   protected 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;
+
+   }
+
+   protected 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;
+
+   }
+
+   protected 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;
+
+   }
+
+   protected void putIdentityObjectSearchIntoCache(IdentityObjectType identityType,
+                                                 IdentityObjectSearchControl[] controls,
+                                                 Collection<IdentityObject> results)
+   {
+      Fqn nodeFqn = createIOTypeSearchNodeFQN(identityType, getControlsHash(controls));
+
+      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());
+      }
+   }
+
+   protected Collection<IdentityObject> getIdentityObjectSearchFromCache(IdentityObjectType identityType,
+                                                                       IdentityObjectSearchControl[] controls)
+   {
+      Fqn nodeFqn = createIOTypeSearchNodeFQN(identityType, getControlsHash(controls));
+
+      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;
+
+   }
+
+   protected void putIdentityObjectSearchToCache(IdentityObject identity,
+                                               IdentityObjectRelationshipType relationshipType,
+                                               boolean parent,
+                                               IdentityObjectSearchControl[] controls,
+                                               Collection<IdentityObject> results)
+   {
+
+      Fqn nodeFqn = createIOSearchNodeFQN(identity, relationshipType, parent, getControlsHash(controls));
+
+      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);
+      }
+
+   }
+
+   protected Collection<IdentityObject> getIdentityObjectSearchFromCache(IdentityObject identity,
+                                                                       IdentityObjectRelationshipType relationshipType,
+                                                                       boolean parent,
+                                                                       IdentityObjectSearchControl[] controls)
+   {
+
+      Fqn nodeFqn = createIOSearchNodeFQN(identity, relationshipType, parent, getControlsHash(controls));
+
+      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;
+
+   }
+
+   protected 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);
+
+   }
+
+
+
+   protected Set<IdentityObjectRelationship> getRelationshipsSearchFromCache(IdentityObject fromIdentity,
+                                                                           IdentityObject toIdentity,
+                                                                           IdentityObjectRelationshipType relationshipType)
+   {
+      Fqn fqn = createRelationshipsSimpleSearchFqn(fromIdentity, toIdentity, relationshipType);
+      Node node = getCache().getRoot().getChild(fqn);
+
+      if (node != null)
+      {
+         return (Set<IdentityObjectRelationship>)node.get(NODE_SEARCH_RESULTS_KEY);
+      }
+      return null;
+   }
+
+   protected 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);
+
+   }
+
+
+
+   protected 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);
+
+      if (node != null)
+      {
+         return (Set<IdentityObjectRelationship>)node.get(NODE_SEARCH_RESULTS_KEY);
+      }
+      return null;
+      
+   }
+
+   protected 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);
+   }
+
+   protected void putIdentityObjectCountIntoCache(IdentityObjectType identityType, int count)
+   {
+      Fqn fqn = createIOTypeCountNodeFQN(identityType);
+      Node node = getCache().getRoot().addChild(fqn);
+
+      node.put(NODE_OBJECT_KEY, count);
+
+   }
+
+   protected int getIdentityObjectCountFromCache(IdentityObjectType identityType)
+   {
+      Fqn fqn = createIOTypeCountNodeFQN(identityType);
+      Node node = getCache().getRoot().getChild(fqn);
+
+
+      if (node != null && node.getKeys().contains(NODE_OBJECT_KEY))
+      {
+         return (Integer)(node.get(NODE_OBJECT_KEY));
+      }
+      // -1 means nothing in cache
+      return -1;
+   }
+
+
+   protected void invalidateCachedIdentityObjectCount(IdentityObjectType identityType)
+   {
+      Fqn fqn = createIOTypeCountNodeFQN(identityType);
+      Node node = getCache().getRoot().addChild(fqn);
+
+      node.remove(NODE_OBJECT_KEY);
+   }
+
+   protected 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);
+
+      // 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);
+
+   }
+
+   protected 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));
+      }
+
+   }
+
+   protected 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);
+   }
+
+
+
+   protected void putRelationshipNamesSearchIntoCache(IdentityObjectSearchControl[] controls, Set<String> results)
+   {
+
+      Fqn fqn = createRelationshipNamesAllSearchFqn(getControlsHash(controls));
+
+      Node node = getCache().getRoot().addChild(fqn);
+
+      node.put(NODE_SEARCH_RESULTS_KEY, results);
+
+   }
+
+   protected Set<String> getRelationshipNamesSearchFromCache(IdentityObjectSearchControl[] controls)
+   {
+
+      Fqn fqn = createRelationshipNamesAllSearchFqn(getControlsHash(controls));
+
+      Node node = getCache().getRoot().getChild(fqn);
+
+      if (node != null)
+      {
+         return (Set<String>)node.get(NODE_SEARCH_RESULTS_KEY);
+      }
+
+      return null;
+   }
+
+   protected void putRelationshipNamesSearchIntoCache(IdentityObject identity,
+                                                      IdentityObjectSearchControl[] controls,
+                                                      Set<String> results)
+   {
+
+      Fqn fqn = createRelationshipNamesIdentityObjectSearchFqn(identity, getControlsHash(controls));
+
+      Node node = getCache().getRoot().addChild(fqn);
+
+      node.put(NODE_SEARCH_RESULTS_KEY, results);
+
+   }
+
+   protected Set<String> getRelationshipNamesSearchFromCache(IdentityObject identity, IdentityObjectSearchControl[] controls)
+   {
+
+      
+      Fqn fqn = createRelationshipNamesIdentityObjectSearchFqn(identity, getControlsHash(controls));
+
+      Node node = getCache().getRoot().getChild(fqn);
+
+      if (node != null)
+      {
+         return (Set<String>)node.get(NODE_SEARCH_RESULTS_KEY);
+      }
+      return null;
+   }
+
+   private int getControlsHash(IdentityObjectSearchControl[] controls)
+   {
+      // Convert controls to Set to have the same hashcode regardles order of controls
+      int hashcode = 0;
+
+      if (controls != null)
+      {
+         List<IdentityObjectSearchControl> list = Arrays.asList(controls);
+         Set<IdentityObjectSearchControl> controlsSet = new HashSet<IdentityObjectSearchControl>(list);
+         hashcode = controlsSet.hashCode();
+      }
+
+      return hashcode;
+   }
+
+}

Added: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/JBossCacheIdentityStoreWrapper.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/JBossCacheIdentityStoreWrapper.java	                        (rev 0)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/cache/JBossCacheIdentityStoreWrapper.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -0,0 +1,566 @@
+/*
+* 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.identity.idm.spi.store.IdentityStore;
+import org.jboss.identity.idm.spi.store.FeaturesMetaData;
+import org.jboss.identity.idm.spi.store.IdentityStoreInvocationContext;
+import org.jboss.identity.idm.spi.store.IdentityStoreSession;
+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.IdentityObjectRelationship;
+import org.jboss.identity.idm.spi.model.IdentityObjectCredential;
+import org.jboss.identity.idm.spi.model.IdentityObjectAttribute;
+import org.jboss.identity.idm.spi.searchcontrol.IdentityObjectSearchControl;
+import org.jboss.identity.idm.spi.exception.OperationNotSupportedException;
+import org.jboss.identity.idm.spi.configuration.metadata.IdentityObjectAttributeMetaData;
+import org.jboss.identity.idm.spi.configuration.metadata.IdentityStoreConfigurationMetaData;
+import org.jboss.identity.idm.exception.IdentityException;
+import org.jboss.cache.Cache;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.transaction.GenericTransactionManagerLookup;
+import org.jboss.cache.config.Configuration;
+
+import java.util.Map;
+import java.util.Collection;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * IdentityStore implementation that wraps another IdentityStore and uses JBossCache to cache results.
+ *
+ * @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
+ * @version : 0.1 $
+ */
+public class JBossCacheIdentityStoreWrapper extends IdentityStoreCacheSupport implements IdentityStore
+{
+
+   private static Logger log = Logger.getLogger(JBossCacheIdentityStoreWrapper.class.getName());
+
+
+   //TODO: cache and IdentitySession transaction
+
+   private final IdentityStore identityStore;
+
+   private final Cache cache;
+
+   // if update/add/remove operation on attributes should result in getAttributes() query to store new set in cache
+   // with many updates it can add additional cost
+   private boolean reloadAttributesToCacheOnUpdate = true;
+
+   public JBossCacheIdentityStoreWrapper(IdentityStore identityStore)
+   {
+
+      this.identityStore = identityStore;
+
+
+      Configuration config = new Configuration();
+
+
+//      config.setTransactionManagerLookupClass( GenericTransactionManagerLookup.class.getName() );
+//
+//      config.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+//
+//      config.setCacheMode(Configuration.CacheMode.LOCAL);
+//
+//      config.setLockAcquisitionTimeout(15000);
+
+      CacheFactory factory = new DefaultCacheFactory();
+
+      this.cache = factory.createCache(config);
+
+      this.cache.start();
+
+      initResidentNodes(identityStore.getSupportedFeatures().getSupportedIdentityObjectTypes(),
+         identityStore.getSupportedFeatures().getSupportedRelationshipTypes());
+
+      log.fine("------------------------------------------------------");
+      log.fine("JBossCacheIdentityStoreWrapper created ....." +
+         "(IdentityStore: " + identityStore.getId() + ")");
+      log.fine("------------------------------------------------------");
+
+   }
+
+   public void bootstrap(IdentityStoreConfigurationMetaData configurationMD) throws IdentityException
+   {
+      identityStore.bootstrap(configurationMD);
+   }
+
+   public String getId()
+   {
+      return identityStore.getId();
+   }
+
+   public IdentityStoreSession createIdentityStoreSession() throws IdentityException
+   {
+      return identityStore.createIdentityStoreSession();
+   }
+
+   public FeaturesMetaData getSupportedFeatures()
+   {
+      return identityStore.getSupportedFeatures();
+   }
+
+   
+
+   public IdentityObject createIdentityObject(IdentityStoreInvocationContext invocationCtx,
+                                              String name,
+                                              IdentityObjectType identityObjectType) throws IdentityException
+   {
+      IdentityObject io = identityStore.createIdentityObject(invocationCtx, name, identityObjectType);
+
+      if (io != null)
+      {
+         //should also invalidate IO searches cache - searches/type - clear all children
+         invalidateCachedIdentityObjectSearches(io);
+         invalidateCachedIdentityObjectCount(identityObjectType);
+
+         putIntoCache(io);
+      }
+      return io;
+   }
+
+
+
+   public IdentityObject createIdentityObject(IdentityStoreInvocationContext invocationCtx,
+                                              String name,
+                                              IdentityObjectType identityObjectType,
+                                              Map<String, String[]> attributes) throws IdentityException
+   {
+      IdentityObject io = identityStore.createIdentityObject(invocationCtx, name, identityObjectType, attributes);
+
+
+
+      if (io != null)
+      {
+         //should also invalidate IO searches cache - searches/type - clear all children
+         invalidateCachedIdentityObjectSearches(io);
+
+         //grab profile - because IS can add extra attributes we canno rely only on attributes passed
+
+         putIntoCache(io, identityStore.getAttributes(invocationCtx, io));
+      }
+      return io;
+   }
+
+   public void removeIdentityObject(IdentityStoreInvocationContext invocationCtx,
+                                    IdentityObject identity) throws IdentityException
+   {
+      identityStore.removeIdentityObject(invocationCtx, identity);
+
+      removeFromCache(identity);
+
+      invalidateCachedIdentityObjectSearches(identity);
+      invalidateCachedIdentityObjectCount(identity.getIdentityType());
+   }
+
+   public int getIdentityObjectsCount(IdentityStoreInvocationContext invocationCtx,
+                                      IdentityObjectType identityType) throws IdentityException
+   {
+      int count = getIdentityObjectCountFromCache(identityType);
+
+      if (count == -1)
+      {
+         count = identityStore.getIdentityObjectsCount(invocationCtx, identityType);
+
+         putIdentityObjectCountIntoCache(identityType, count);
+      }
+
+      return count;
+
+   }
+
+
+
+   public IdentityObject findIdentityObject(IdentityStoreInvocationContext invocationContext,
+                                            String name,
+                                            IdentityObjectType identityObjectType) throws IdentityException
+   {
+      IdentityObject io = getFromCache(name, identityObjectType);
+
+      if (io == null)
+      {
+         io = identityStore.findIdentityObject(invocationContext, name, identityObjectType);
+         putIntoCache(io);
+         return io;
+      }
+
+      return io;
+   }
+
+   public IdentityObject findIdentityObject(IdentityStoreInvocationContext invocationContext,
+                                            String id) throws IdentityException
+   {
+      IdentityObject io = getFromCache(id);
+
+      if (io == null)
+      {
+         io = identityStore.findIdentityObject(invocationContext, id);
+         putIntoCache(io);
+         return io;
+      }
+
+      return io;
+   }
+
+   public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext invocationCtx,
+                                                        IdentityObjectType identityType,
+                                                        IdentityObjectSearchControl[] controls) throws IdentityException
+   {
+
+      Collection<IdentityObject> results = getIdentityObjectSearchFromCache(identityType, controls);
+
+      if (results == null)
+      {
+         results = identityStore.findIdentityObject(invocationCtx, identityType, controls);
+
+         putIdentityObjectSearchIntoCache(identityType, controls, results);
+
+         // Put all the results into cache separately
+         for (IdentityObject result : results)
+         {
+            putIntoCache(result);
+         }
+      }
+
+      return results;
+
+
+
+   }
+
+   
+
+   public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext invocationCtx,
+                                                        IdentityObject identity,
+                                                        IdentityObjectRelationshipType relationshipType,
+                                                        boolean parent,
+                                                        IdentityObjectSearchControl[] controls) throws IdentityException
+   {
+
+      Collection<IdentityObject> results = getIdentityObjectSearchFromCache(identity, relationshipType, parent, controls);
+
+      if (results == null)
+      {
+         results = identityStore.findIdentityObject(invocationCtx, identity, relationshipType, parent, controls);
+
+         putIdentityObjectSearchToCache(identity, relationshipType,parent,controls, results);
+
+         for (IdentityObject result : results)
+         {
+            putIntoCache(result);
+         }
+      }
+      return results;
+   }
+
+
+
+
+   public IdentityObjectRelationship createRelationship(IdentityStoreInvocationContext invocationCxt,
+                                                        IdentityObject fromIdentity,
+                                                        IdentityObject toIdentity,
+                                                        IdentityObjectRelationshipType relationshipType,
+                                                        String relationshipName,
+                                                        boolean createNames) throws IdentityException
+   {
+      return identityStore.createRelationship(invocationCxt,
+         fromIdentity, toIdentity, relationshipType, relationshipName, createNames);
+   }
+
+   public void removeRelationship(IdentityStoreInvocationContext invocationCxt,
+                                  IdentityObject fromIdentity,
+                                  IdentityObject toIdentity,
+                                  IdentityObjectRelationshipType relationshipType,
+                                  String relationshipName) throws IdentityException
+   {
+      identityStore.removeRelationship(invocationCxt, fromIdentity, toIdentity, relationshipType, relationshipName);
+
+      invalidateCachedRelationshipSearches(fromIdentity, toIdentity, relationshipType, relationshipName);
+      
+   }
+
+
+
+
+   public void removeRelationships(IdentityStoreInvocationContext invocationCtx,
+                                   IdentityObject identity1,
+                                   IdentityObject identity2,
+                                   boolean named) throws IdentityException
+   {
+      identityStore.removeRelationships(invocationCtx, identity1, identity2, named);
+
+      invalidateCachedRelationshipSearches(identity1, identity2, named);
+
+   }
+
+
+   public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt,
+                                                               IdentityObject fromIdentity,
+                                                               IdentityObject toIdentity,
+                                                               IdentityObjectRelationshipType relationshipType) throws IdentityException
+   {
+
+
+      Set<IdentityObjectRelationship> results = getRelationshipsSearchFromCache(fromIdentity, toIdentity, relationshipType);
+
+      if (results == null)
+      {
+         results = identityStore.resolveRelationships(invocationCxt, fromIdentity, toIdentity, relationshipType);
+
+         putRelationshipsSearchIntoCache(fromIdentity, toIdentity, relationshipType, results);
+      }
+
+      return results;
+
+   }
+
+   public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCtx,
+                                                               IdentityObject identity,
+                                                               IdentityObjectRelationshipType relationshipType,
+                                                               boolean parent,
+                                                               boolean named,
+                                                               String name) throws IdentityException
+   {
+      Set<IdentityObjectRelationship> results = getRelationshipsSearchFromCache(identity, relationshipType, parent, named, name);
+
+      if (results == null)
+      {
+         results = identityStore.resolveRelationships(invocationCtx,
+         identity, relationshipType, parent, named, name);
+
+         putRelationshipSearchIntoCache(identity, relationshipType, parent, named, name, results);
+      }
+
+      return results;
+   }
+
+   public String createRelationshipName(IdentityStoreInvocationContext ctx,
+                                        String name) throws IdentityException, OperationNotSupportedException
+   {
+
+      invalidateRelationshipNameSearches(name);
+
+      return identityStore.createRelationshipName(ctx, name);
+   }
+
+   public String removeRelationshipName(IdentityStoreInvocationContext ctx,
+                                        String name) throws IdentityException, OperationNotSupportedException
+   {
+      invalidateRelationshipNameSearches(name);
+
+      return identityStore.removeRelationshipName(ctx, name);
+   }
+
+   public Set<String> getRelationshipNames(IdentityStoreInvocationContext ctx,
+                                           IdentityObjectSearchControl[] controls) throws IdentityException, OperationNotSupportedException
+   {
+      Set<String> results = getRelationshipNamesSearchFromCache(controls);
+
+      if (results == null)
+      {
+         results = identityStore.getRelationshipNames(ctx, controls);
+
+         putRelationshipNamesSearchIntoCache(controls, results);
+      }
+
+      return results;
+
+   }
+
+   public Set<String> getRelationshipNames(IdentityStoreInvocationContext ctx,
+                                           IdentityObject identity,
+                                           IdentityObjectSearchControl[] controls) throws IdentityException, OperationNotSupportedException
+   {
+
+
+      Set<String> results = getRelationshipNamesSearchFromCache(identity, controls);
+
+      if (results == null)
+      {
+         results = identityStore.getRelationshipNames(ctx, identity, controls);
+
+         putRelationshipNamesSearchIntoCache(identity, controls, results);
+      }
+
+      return results;
+   }
+
+   
+
+   public boolean validateCredential(IdentityStoreInvocationContext ctx,
+                                     IdentityObject identityObject,
+                                     IdentityObjectCredential credential) throws IdentityException
+   {
+      // Should not be cached
+      return identityStore.validateCredential(ctx, identityObject, credential);
+   }
+
+   public void updateCredential(IdentityStoreInvocationContext ctx,
+                                IdentityObject identityObject,
+                                IdentityObjectCredential credential) throws IdentityException
+   {
+      // Should not be cached
+      identityStore.updateCredential(ctx, identityObject, credential);
+   }
+
+   public Set<String> getSupportedAttributeNames(IdentityStoreInvocationContext invocationContext,
+                                                 IdentityObjectType identityType) throws IdentityException
+   {
+      // Doesn't need to be cached
+      return identityStore.getSupportedAttributeNames(invocationContext, identityType);
+   }
+
+   public Map<String, IdentityObjectAttributeMetaData> getAttributesMetaData(IdentityStoreInvocationContext invocationContext,
+                                                                             IdentityObjectType identityType)
+   {
+      // Doesn't need to be cached
+      return identityStore.getAttributesMetaData(invocationContext, identityType);
+   }
+
+   public Map<String, IdentityObjectAttribute> getAttributes(IdentityStoreInvocationContext invocationContext,
+                                                             IdentityObject identity) throws IdentityException
+   {
+      Map<String, IdentityObjectAttribute> results = getAttributesFromCache(identity.getName(), identity.getIdentityType());
+
+      if (results == null)
+      {
+         results = identityStore.getAttributes(invocationContext, identity);
+
+         if (results != null && results.size() > 0)
+         {
+            putIntoCache(identity, results);
+         }
+      }
+
+      return results;
+   }
+
+   public IdentityObjectAttribute getAttribute(IdentityStoreInvocationContext invocationContext,
+                                               IdentityObject identity,
+                                               String name) throws IdentityException
+   {
+      Map<String, IdentityObjectAttribute> results = getAttributesFromCache(identity.getName(), identity.getIdentityType());
+
+      if (results != null && results.containsKey(name))
+      {
+         return results.get(name);
+      }
+      else
+      {
+         return identityStore.getAttribute(invocationContext, identity, name);
+
+         //TODO: add this attribute to the node map
+      }
+
+   }
+
+   public void updateAttributes(IdentityStoreInvocationContext invocationCtx,
+                                IdentityObject identity,
+                                IdentityObjectAttribute[] attributes) throws IdentityException
+   {
+      identityStore.updateAttributes(invocationCtx, identity, attributes);
+
+      removeAttributesFromCache(identity);
+
+      if (reloadAttributesToCacheOnUpdate)
+      {
+         Map<String, IdentityObjectAttribute> results = identityStore.getAttributes(invocationCtx, identity);
+
+         if (results != null && results.size() > 0)
+         {
+            putIntoCache(identity, results);
+         }
+      }
+      else
+      {
+         // update attributes in node map directly
+      }
+      
+   }
+
+   public void addAttributes(IdentityStoreInvocationContext invocationCtx,
+                             IdentityObject identity,
+                             IdentityObjectAttribute[] attributes) throws IdentityException
+   {
+      identityStore.addAttributes(invocationCtx, identity, attributes);
+
+      removeAttributesFromCache(identity);
+
+      if (reloadAttributesToCacheOnUpdate)
+      {
+         Map<String, IdentityObjectAttribute> results = identityStore.getAttributes(invocationCtx, identity);
+
+         if (results != null && results.size() > 0)
+         {
+            putIntoCache(identity, results);
+         }
+      }
+      else
+      {
+         // add attributes in node map directly
+      }
+   }
+
+   public void removeAttributes(IdentityStoreInvocationContext invocationCtx,
+                                IdentityObject identity,
+                                String[] attributeNames) throws IdentityException
+   {
+      identityStore.removeAttributes(invocationCtx, identity, attributeNames);
+
+      removeAttributesFromCache(identity);
+
+      if (reloadAttributesToCacheOnUpdate)
+      {
+         Map<String, IdentityObjectAttribute> results = identityStore.getAttributes(invocationCtx, identity);
+
+         if (results != null && results.size() > 0)
+         {
+            putIntoCache(identity, results);
+         }
+      }
+      else
+      {
+         // remove attributes in node map directly
+      }
+   }
+
+   protected Logger getLog()
+   {
+      return log;
+   }
+
+   protected Cache getCache()
+   {
+      return cache;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "JBossCacheIdentityStoreWrapper (IdentityStore=" + identityStore.getId() + ")";
+   }
+}

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/model/ldap/LDAPIdentityObjectImpl.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/model/ldap/LDAPIdentityObjectImpl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/model/ldap/LDAPIdentityObjectImpl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -28,12 +28,13 @@
 
 import java.util.Set;
 import java.util.Map;
+import java.io.Serializable;
 
 /**
  * @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
  * @version : 0.1 $
  */
-public class LDAPIdentityObjectImpl implements IdentityObject
+public class LDAPIdentityObjectImpl implements IdentityObject, Serializable
 {
    private String dn;
 

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObject.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObject.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObject.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -25,7 +25,9 @@
 import org.jboss.identity.idm.spi.model.IdentityObject;
 import org.jboss.identity.idm.spi.model.IdentityObjectType;
 
+import java.io.Serializable;
 
+
 /**
  * Very simple identity object
  *
@@ -33,7 +35,7 @@
  *
  * @since Aug 6, 2008
  */
-public class SimpleIdentityObject implements IdentityObject
+public class SimpleIdentityObject implements IdentityObject, Serializable
 {
 
    private final String name;

Modified: idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObjectType.java
===================================================================
--- idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObjectType.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/main/java/org/jboss/identity/idm/impl/types/SimpleIdentityObjectType.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -24,11 +24,13 @@
 
 import org.jboss.identity.idm.spi.model.IdentityObjectType;
 
+import java.io.Serializable;
+
 /**
  * @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
  * @version : 0.1 $
  */
-public class SimpleIdentityObjectType implements IdentityObjectType
+public class SimpleIdentityObjectType implements IdentityObjectType, Serializable
 {
    private String name;
 

Modified: idm/trunk/idm/src/test/java/org/jboss/identity/idm/impl/SimpleIdentityObjectTypeImpl.java
===================================================================
--- idm/trunk/idm/src/test/java/org/jboss/identity/idm/impl/SimpleIdentityObjectTypeImpl.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm/src/test/java/org/jboss/identity/idm/impl/SimpleIdentityObjectTypeImpl.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -24,11 +24,13 @@
 
 import org.jboss.identity.idm.spi.model.IdentityObjectType;
 
+import java.io.Serializable;
+
 /**
  * @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
  * @version : 0.1 $
  */
-public class SimpleIdentityObjectTypeImpl implements IdentityObjectType
+public class SimpleIdentityObjectTypeImpl implements IdentityObjectType, Serializable
 {
    String name;
 

Added: idm/trunk/idm/src/test/resources/logging.properties
===================================================================
--- idm/trunk/idm/src/test/resources/logging.properties	                        (rev 0)
+++ idm/trunk/idm/src/test/resources/logging.properties	2009-01-29 18:51:55 UTC (rev 260)
@@ -0,0 +1,61 @@
+# Properties file which configures the operation of the JDK
+# logging facility.
+
+# The system will look for this config file, first using
+# a System property specified at startup:
+#
+# >java -Djava.util.logging.config.file=myLoggingConfigFilePath
+#
+# If this property is not specified, then the config file is
+# retrieved from its default location at:
+#
+# JDK_HOME/jre/lib/logging.properties
+
+# Global logging properties.
+# ------------------------------------------
+# The set of handlers to be loaded upon startup.
+# Comma-separated list of class names.
+# (? LogManager docs say no comma here, but JDK example has comma.)
+handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+
+# Default global logging level.
+# Loggers and Handlers may override this level
+.level=FINER
+
+# Loggers
+# ------------------------------------------
+# Loggers are usually attached to packages.
+# Here, the level for each package is specified.
+# The global level is used by default, so levels
+# specified here simply act as an override.
+
+#myapp.ui.level=ALL
+#myapp.business.level=CONFIG
+#myapp.data.level=SEVERE
+
+# Handlers
+# -----------------------------------------
+
+# --- ConsoleHandler ---
+# Override of global logging level
+java.util.logging.ConsoleHandler.level=FINER
+java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
+
+# --- FileHandler ---
+# Override of global logging level
+java.util.logging.FileHandler.level=ALL
+
+# Naming style for the output file:
+# (The output file is placed in the directory
+# defined by the "user.home" System property.)
+java.util.logging.FileHandler.pattern=%h/java%u.log
+
+# Limiting size of output file in bytes:
+java.util.logging.FileHandler.limit=50000
+
+# Number of output files to cycle through, by appending an
+# integer to the base file name:
+java.util.logging.FileHandler.count=1
+
+# Style of output (Simple or XML):
+java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
\ No newline at end of file

Modified: idm/trunk/idm-spi/src/main/java/org/jboss/identity/idm/spi/store/IdentityStore.java
===================================================================
--- idm/trunk/idm-spi/src/main/java/org/jboss/identity/idm/spi/store/IdentityStore.java	2009-01-28 22:31:17 UTC (rev 259)
+++ idm/trunk/idm-spi/src/main/java/org/jboss/identity/idm/spi/store/IdentityStore.java	2009-01-29 18:51:55 UTC (rev 260)
@@ -96,8 +96,8 @@
                                        Map<String, String[]> attributes) throws IdentityException;
 
 
-   
 
+
    /**
     * Remove given identity
     *




More information about the jboss-identity-commits mailing list