001package com.identityworksllc.iiq.common.cache; 002 003import com.identityworksllc.iiq.common.Utilities; 004import org.apache.commons.logging.Log; 005import org.apache.commons.logging.LogFactory; 006import sailpoint.api.SailPointContext; 007import sailpoint.api.SailPointFactory; 008import sailpoint.object.SailPointObject; 009import sailpoint.tools.GeneralException; 010 011import java.lang.reflect.Modifier; 012 013/** 014 * A cache generator to automatically pull and cache SailPoint objects 015 * @param <T> The cached object type, which must be a concrete subclass of SailPointObject 016 */ 017@SuppressWarnings("unused") 018public class SailPointObjectCacheGenerator<T extends SailPointObject> implements CacheGenerator<T> { 019 020 /** 021 * Class logger 022 */ 023 private static final Log log = LogFactory.getLog(SailPointObjectCacheGenerator.class); 024 025 /** 026 * The object type being generated 027 */ 028 private final Class<T> objectType; 029 030 /** 031 * Constructs a new Sailpoint cache generator for this object type 032 * @param type The object type 033 * @throws IllegalArgumentException if the input type is not a concrete subclass of SailPointObject 034 */ 035 public SailPointObjectCacheGenerator(Class<T> type) { 036 if (Modifier.isAbstract(type.getModifiers())) { 037 throw new IllegalArgumentException("The type passed to " + SailPointObjectCacheGenerator.class.getName() + " must be a concrete type"); 038 } 039 this.objectType = type; 040 } 041 042 /** 043 * Gets the value for the given key. The Key can be either a name or an ID. This 044 * method must be invoked in a thread that has a SailPointContext. 045 * 046 * If the key is not a string, or if no such object exists, null will be returned. 047 * 048 * The object will be detached via {@link Utilities#detach(SailPointContext, SailPointObject)}. 049 * 050 * @param key The key for which to retrieve a value 051 * @return The object, or null if there is an issue loading it 052 */ 053 @SuppressWarnings("unchecked") 054 @Override 055 public T getValue(Object key) { 056 try { 057 if (key instanceof String) { 058 SailPointContext context = SailPointFactory.getCurrentContext(); 059 if (context == null) { 060 throw new IllegalStateException("This factory method must be invoked in a thread that has a SailPointContext"); 061 } 062 SailPointObject object = context.getObject(objectType, (String)key); 063 if (object != null) { 064 object.clearPersistentIdentity(); 065 object = Utilities.detach(context, object); 066 return (T) object; 067 } else { 068 if (log.isWarnEnabled()) { 069 log.warn("No such object: type [" + objectType.getName() + "], name or ID [" + key + "]"); 070 } 071 } 072 } 073 } catch(GeneralException e) { 074 log.error("Unable to load SailPointObject for caching", e); 075 return null; 076 } 077 return null; 078 } 079 080}