001package com.identityworksllc.iiq.common; 002 003import sailpoint.api.SailPointContext; 004import sailpoint.object.QueryOptions; 005import sailpoint.object.Reference; 006import sailpoint.object.SailPointObject; 007import sailpoint.tools.GeneralException; 008 009import java.io.Serializable; 010import java.util.Arrays; 011import java.util.List; 012import java.util.Objects; 013import java.util.function.Function; 014 015/** 016 * Constructs IIQ {@link Reference} objects using a standardized API 017 */ 018public final class Ref { 019 /** 020 * A constant that can be passed to context.search() to retrieve an object for use here 021 */ 022 @SuppressWarnings("unused") 023 public static final List<String> REFERENCE_PROPS = Arrays.asList("id"); 024 025 /** 026 * Retrieves a dehydrated object given the type and ID 027 * @param type The type of the object to create a reference to 028 * @param id The object ID 029 * @return A Reference to that object 030 */ 031 public static Reference of(Class<? extends SailPointObject> type, String id) { 032 return new Reference(type.getName(), Objects.requireNonNull(id)); 033 } 034 035 /** 036 * Retrieves a dehydrated object given the type and parameters 037 * @param type The type of the object to create a reference to 038 * @param parameters The result of a {@link SailPointContext#search(Class, QueryOptions, List)} call with the 'id' in the first position 039 * @return A Reference to that object 040 */ 041 public static Reference of(Class<? extends SailPointObject> type, Object[] parameters) { 042 if (parameters == null || parameters.length < 1) { 043 throw new IllegalArgumentException("The parameters must contain at least an object ID"); 044 } 045 if (parameters[0] instanceof String) { 046 return new Reference(type.getName(), (String)parameters[0]); 047 } else { 048 throw new IllegalArgumentException("The first item in the parameters must be a String object ID"); 049 } 050 } 051 052 /** 053 * Retrieves a dehydrated reference from the object 054 * @param object The object to dehydrate 055 * @return The dehydrated reference 056 */ 057 public static Reference of(SailPointObject object) { 058 return new Reference(Objects.requireNonNull(object)); 059 } 060 061 /** 062 * Creates a type transforming function that will take any object that this class 063 * recognizes and convert it into a Reference of the appropriate type. 064 * 065 * This could be used, for example, as the second parameter passed to TransformingIterator's 066 * constructor. 067 * 068 * @param targetClass The target class to retrieve a reference for 069 * @param <T> The type of the target class 070 * @return a function converting the input to a reference 071 */ 072 public static <T extends SailPointObject> Function<?, Reference> transformer(Class<T> targetClass) { 073 return o -> { 074 if (o instanceof String) { 075 return Ref.of(targetClass, (String)o); 076 } else if (o instanceof Object[]) { 077 return Ref.of(targetClass, (Object[])o); 078 } else if (o instanceof SailPointObject) { 079 return Ref.of((SailPointObject) o); 080 } else { 081 throw new IllegalArgumentException("Invalid input type: " + Utilities.safeClassName(o)); 082 } 083 }; 084 } 085 086 /** 087 * Private utility constructor 088 */ 089 private Ref() {} 090 091 092}