/*
* 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.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.exception.OperationNotSupportedException;
import org.jboss.identity.idm.spi.configuration.IdentityStoreConfigurationContext;
import org.jboss.identity.idm.spi.search.IdentityObjectSearchCriteria;
import org.jboss.identity.idm.exception.IdentityException;
import java.util.Map;
import java.util.Collection;
import java.util.Set;
import java.util.logging.Logger;
import java.io.InputStream;
/**
* 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 JBossCacheAttributeStoreWrapper implements IdentityStore
{
private static Logger log = Logger.getLogger(JBossCacheIdentityStoreWrapper.class.getName());
//TODO: cache and IdentitySession transaction
private final IdentityStore identityStore;
public JBossCacheIdentityStoreWrapper(IdentityStore identityStore, InputStream cacheConfigInputStream) throws IdentityException
{
super(identityStore, cacheConfigInputStream);
this.identityStore = identityStore;
initResidentNodes(identityStore.getSupportedFeatures().getSupportedIdentityObjectTypes(),
identityStore.getSupportedFeatures().getSupportedRelationshipTypes());
log.fine("------------------------------------------------------");
log.fine("JBossCacheIdentityStoreWrapper created ....." +
"(IdentityStore: " + identityStore.getId() + ")");
log.fine("------------------------------------------------------");
}
public void bootstrap(IdentityStoreConfigurationContext configurationContext) throws IdentityException
{
identityStore.bootstrap(configurationContext);
}
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,
IdentityObjectSearchCriteria 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,
IdentityObjectSearchCriteria 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
{
invalidateCachedRelationshipSearches(fromIdentity, toIdentity, relationshipType, relationshipName);
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,
IdentityObjectSearchCriteria 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,
IdentityObjectSearchCriteria 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 Map<String, String> getRelationshipNameProperties(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
return identityStore.getRelationshipNameProperties(ctx, name);
}
public void setRelationshipNameProperties(IdentityStoreInvocationContext ctx, String name, Map<String, String> properties) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
identityStore.setRelationshipNameProperties(ctx, name, properties);
}
public void removeRelationshipNameProperties(IdentityStoreInvocationContext ctx, String name, Set<String> properties) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
identityStore.removeRelationshipNameProperties(ctx, name, properties);
}
public Map<String, String> getRelationshipProperties(IdentityStoreInvocationContext ctx, IdentityObjectRelationship relationship) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
return identityStore.getRelationshipProperties(ctx, relationship);
}
public void setRelationshipProperties(IdentityStoreInvocationContext ctx, IdentityObjectRelationship relationship, Map<String, String> properties) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
identityStore.setRelationshipProperties(ctx, relationship, properties);
}
public void removeRelationshipProperties(IdentityStoreInvocationContext ctx, IdentityObjectRelationship relationship, Set<String> properties) throws IdentityException, OperationNotSupportedException
{
//TODO: apply caching
identityStore.removeRelationshipProperties(ctx, relationship, properties);
}
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);
}
@Override
public String toString()
{
return "JBossCacheIdentityStoreWrapper (IdentityStore=" + identityStore.getId() + ")";
}
}