Class Utilities
- java.lang.Object
-
- com.identityworksllc.iiq.common.Utilities
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Utilities.PropertyLookupNone
Used as an indicator that the quick property lookup produced nothing.
-
Field Summary
Fields Modifier and Type Field Description static String
GLOBAL_MAP_PREFIX
The prefix inCustomGlobal
used bygetPluginVersionedGlobalMap()
.static String
IDW_WORKER_POOL
The name of the worker pool, stored in CustomGlobal by defaultstatic String
MOST_RECENT_LOCALE
The key used to store the user’s most recent locale on their UIPrefs, captured bytryCaptureLocationInfo(SailPointContext, Identity)
static String
MOST_RECENT_TIMEZONE
The key used to store the user’s most recent timezone on their UIPrefs, captured bytryCaptureLocationInfo(SailPointContext, Identity)
static Object
NONE
A magic constant for use with thegetQuickProperty(Object, String)
method.
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static <S,T extends Collection<S>>
voidaddMapped(Map<String,T> map, String key, S value)
Adds the given value to aCollection
at the given key in the map.static void
addSessionMessage(sailpoint.api.SailPointContext context, sailpoint.tools.Message message)
Adds a message banner to the current browser session which will show up at the top of each page.static sailpoint.object.IdentitySelector.MatchExpression
andMatchTerm(sailpoint.object.IdentitySelector.MatchExpression input, sailpoint.object.IdentitySelector.MatchTerm newTerm)
Adds a new MatchTerm as an ‘and’ to an existing MatchExpression, transforming an existing ‘or’ into a sub-expression if needed.static boolean
caseInsensitiveContains(Collection<? extends Object> collection, Object value)
Returns true if the collection contains the given value ignoring casestatic void
cleanVersionedCache(String prefix, int currentVersion)
Iterates through theCustomGlobal
, removing any object with the prefix plus older plugin versions.static <T> T
computeGlobalSingleton(String key, Supplier<T> factory)
Gets a global singleton value from CustomGlobal.static String
consoleInvoke(String command)
Invokes a command via the IIQ console which will run as though it was typed at the command promptstatic boolean
containsMessage(Throwable t, String cause)
Returns true if the Throwable message (or any of its causes) contain the given messagestatic boolean
containsProperty(sailpoint.object.Filter input, String property)
Returns true if the given filter references the given property anywhere.static boolean
containsProperty(sailpoint.object.IdentitySelector.MatchExpression input, String property)
Returns true if the given match expression references the given property anywhere.static boolean
containsProperty(sailpoint.object.IdentitySelector.MatchTerm term, String property)
Returns true if the given match term references the given property anywhere.static String
convertDateFormat(Object something, String inputDateFormat, String outputDateFormat)
Converts the input object using the two date formats provided by invoking the four-argumentconvertDateFormat(Object, String, String, ZoneId)
.static String
convertDateFormat(Object something, String inputDateFormat, String outputDateFormat, ZoneId zoneId)
Converts the input object using the two date formats provided.static boolean
dateAtLeastDaysAgo(Date testDate, int days)
Determines whether the test date is at least N days ago.static boolean
dateAtLeastYearsAgo(Date testDate, int years)
Determines whether the test date is at least N years ago.static Period
dateDifference(long firstTimeMillis, long secondTimeMillis)
Coerces the long millisecond timestamps to Date objects, then returns the result ofdateDifference(Date, Date)
.static Period
dateDifference(Date firstTime, Date secondTime)
Converts two Date objects toLocalDate
at the system default time zone and returns the number of days between them.static <T extends sailpoint.object.SailPointObject>
Tdetach(sailpoint.api.SailPointContext context, T o)
Detaches the given object as much as possible from the database context by converting it to XML and back again.static void
ensureAllNotNullOrEmpty(String... values)
Throws an exception if the string is null or emptystatic void
ensureNotNullOrEmpty(String value)
Throws an exception if the string is null or emptystatic void
evictRuleRunnerPool()
Uses reflection to evict the RuleRunner pool cachestatic <S,T>
List<T>extractProperty(List<S> input, String property, Class<T> expectedType)
Extracts the value of the given property from each item in the list and returns a new list containing those property values.static sailpoint.object.IdentitySelector.MatchExpression
filterToMatchExpression(sailpoint.object.Filter input)
Transfors an input Filter into a MatchExpressionstatic sailpoint.object.IdentitySelector.MatchTerm
filterToMatchTerm(sailpoint.object.Filter input)
Transfors an input Filter into a MatchTermstatic String
firstNotNullOrEmpty(String... inputs)
Returns the first item in the list that is not null or empty.static String
format(String messageTemplate, Object... params)
Formats the input message template using Java’s MessageFormat class and the SLogger.Formatter class.static <T> T
fuzzyGet(Map<String,Object> map, String fuzzyKey)
Retrieves a key from the given Map in a ‘fuzzy’ way.static sailpoint.object.Script
getAsScript(Object input)
Gets the input object as a thread-safe Script.static sailpoint.object.Attributes<String,Object>
getAttributes(Object source)
Gets the attributes of the given source object.static TimeZone
getClientTimeZone(sailpoint.object.Identity identity, sailpoint.web.UserContext userContext)
Gets the time zone associated with the logged in user’s session, based on a UserContext or Identity.static List<String>
getCountryNames()
Extracts a list of all country names from the JDK’s Locale class.static <T> T
getFirstNotNothing(T... items)
Returns the first item in the input that is not nothing according to theisNothing(Object)
method.static <T> T
getFirstNotNull(List<? extends T> items)
Returns the first item in the input that is not null, an empty Optional, or a Supplier that returns null.static <T> T
getFirstNotNull(T... items)
Returns the first item in the input that is not null, an empty Optional, or a Supplier that returns null.static Properties
getIIQProperties()
Gets the iiq.properties file contents (properly closing it, unlike IIQ…)static com.fasterxml.jackson.databind.ObjectMapper
getJacksonObjectMapper()
Returns a default Jackson object mapper, independent of IIQ versions.static Date
getLocalDate(Date inputDate, sailpoint.object.Identity identity)
IIQ tries to display timestamps in a locale-specific way to the user.static String
getLocalizedMessage(sailpoint.object.Identity target, sailpoint.tools.Message message)
Localizes a message based on the locale information captured on the target Identity.static String
getPluginVersion()
Gets the current plugin version from the environment, or NA if not definedstatic ConcurrentHashMap<String,Object>
getPluginVersionedGlobalMap()
Gets aConcurrentHashMap
fromCustomGlobal
that will be replaced with a new, empty Map whenever the plugin version is incremented.static int
getPluginVersionInt()
Gets the current plugin version from the environment, or NA if not definedstatic Object
getProperty(Object source, String paramPropertyPath)
Gets the given property by introspectionstatic Object
getProperty(Object source, String paramPropertyPath, boolean gracefulNulls)
Gets the given property by introspection and ‘dot-walking’ the given path.static Object
getQuickProperty(Object source, String propertyPath)
Returns a “quick property” which does not involve introspection.static ExecutorService
getSharedBackgroundPool()
Gets the shared background pool, an instance ofForkJoinPool
.static <A,B>
booleanisAssignableFrom(Class<A> parentClass, Class<B> testClass)
Returns true if parentClass is assignable from testClass, e.g.static boolean
isFlagNotSet(Object flagValue)
Returns the inverse ofisFlagSet(Object)
.static boolean
isFlagSet(Object flagValue)
Check if a String, Boolean, or Number flag object should be considered equivalent to boolean true.static boolean
isFlagSet(String stringFlag)
Forwards toisFlagSet(Object)
static <A,B>
booleanisNotAssignableFrom(Class<A> parentClass, Class<B> testClass)
Returns the inverse ofisAssignableFrom(Class, Class)
.static boolean
isNotEmpty(Collection<?> list)
Returns true if the input is NOT an empty Collection.static boolean
isNotEmpty(Map<?,?> map)
Returns true if the input is NOT an empty Map.static boolean
isNothing(Object thing)
Returns true if the given object is ‘nothing’: a null, empty string, empty map, empty Collection, empty Optional, or empty Iterable.static boolean
isNotNullEmptyOrWhitespace(String input)
Returns true if the input string is not null and contains any non-whitespace characters.static boolean
isNotNumber(String input)
Returns true if the input is NOT only digitsstatic boolean
isNullEmptyOrWhitespace(String input)
Returns true if the input string is null, empty, or contains only whitespace characters according toCharacter.isWhitespace(char)
.static boolean
isNumber(String input)
Returns true if this string contains only digitsstatic String
isoOffsetTimestamp()
Returns the current time in the standard ISO offset (date T time+1:00) formatstatic boolean
isSomething(Object thing)
Returns true ifisNothing(Object)
would return false.static sailpoint.api.MessageAccumulator
listMessageAccumulator(List<String> target, boolean dated)
Creates a MessageAccumulator that just inserts the message into the target list.static <T> List<T>
listOf(T... objects)
Returns a new modifiable list with the objects specified added to it.static <S,T>
booleanmapConformsToType(Map<?,?> inputMap, Class<S> expectedKeyType, Class<T> expectedValueType)
Returns true if every key and value in the Map can be cast to the types given.static <S,T>
Map<S,T>mapOf(Object... input)
Creates a map from a varargs list of items, where every other item is a key or value.static sailpoint.object.CompoundFilter
matchExpressionToCompoundFilter(sailpoint.object.IdentitySelector.MatchExpression input)
Transforms a MatchExpression selector into a CompoundFilterstatic sailpoint.object.IdentitySelector.MatchTerm
matchTerm(String property, Object value, sailpoint.object.Application application)
Create a MatchTerm from scratchstatic sailpoint.object.Filter
matchTermToFilter(sailpoint.object.IdentitySelector.MatchTerm term, sailpoint.object.Application defaultApplication, List<sailpoint.object.Application> applications)
Transforms a MatchTerm into a Filter, which can be useful for then modifying itstatic Date
max(Date... dates)
Returns the maximum of the given dates.static Date
min(Date... dates)
Returns the maximum of the given dates.static boolean
nullSafeNotEq(Object a, Object b)
Returns true ifUtil.nullSafeEq(Object, Object)
would return false and vice versa.static String
nullToEmpty(String maybeNull)
Returns the input string if it is not null.static <T> List<T>
nullToEmpty(Collection<T> input)
Converts the given collection to an empty list (if a null value is passed), the input object (if a List is passed), or a copy of the input object in a new ArrayList (if any other Collection is passed).static sailpoint.object.Attributes<String,Object>
nullToEmpty(Map<String,? extends Object> input)
Converts the given collection to an empty Attributes, if a null object is passed, the input object (if an Attributes is passed), or a new Attributes containing all elements from the input Map (if any other type of Map is passed).static String
nullToEmptyString(String maybeNull)
Returns the input string if it is not null, explicitly noting the input as a String to make Beanshell happy at runtime.static Optional<LocalDateTime>
parseDateString(String inputString, String format)
Parses the input string into a LocalDateTime, returning anOptional
if the date parses properly.static <V> Map<String,V>
prefixMap(Map<String,V> map, String prefix)
Constructs a new map with each key having the prefix added to it.static <T> T
quietRun(sailpoint.api.SailPointContext context, Object thing, Map<String,Object> params)
Attempts to dynamically evaluate whatever thing is passed in and return the output of running the thing.static <T> T
safeCast(Object input, Class<T> targetClass)
Safely casts the given input to the target type.static String
safeClassName(Object any)
Returns the class name of the object, or the string ‘null’, suitable for logging safelystatic boolean
safeContainsAll(Object maybeBiggerCollection, Object maybeSmallerCollection)
Returns true if the bigger collection contains all elements in the smaller collection.static long
safeDateTimestamp(Date input)
Returns a long timestamp for the input Date, returningLong.MIN_VALUE
if the Date is null.static <A,B>
voidsafeForeach(Map<A,B> map, BiConsumer<A,B> function)
Invokes an action against each key-value pair in the Map.static <T> Stream<T>
safeKeyStream(Map<T,?> map)
Returns a stream for the given map’s keys if it’s not null, or an empty stream if it isstatic List<String>
safeListify(Object value)
Safely converts the given input to a List.static <S,T>
Map<S,T>safeMapCast(Object input, Class<S> keyType, Class<T> valueType)
Returns a Map cast to the given generic types if and only if it passes the check inmapConformsToType(Map, Class, Class)
for the same type parameters.static int
safeSize(String input)
Returns the length of the input string, returning 0 if the string is nullstatic int
safeSize(Collection<?> input)
Returns the size of the input collection, returning 0 if the collection is nullstatic <T> int
safeSize(T[] input)
Returns the size of the input array, returning 0 if the array is nullstatic <T> Stream<T>
safeStream(List<T> list)
Returns a stream for the given list if it’s not null, or an empty stream if it isstatic <T> Stream<T>
safeStream(Set<T> set)
Returns a stream for the given set if it’s not null, or an empty stream if it isstatic <T> Stream<T>
safeStream(T[] array)
Returns a stream for the given array if it’s not null, or an empty stream if it isstatic String
safeString(Object whatever)
Returns the given value as a “safe string”.static <T,S extends T>
TsafeSubscript(List<S> list, int index)
Performs a safe subscript operation against the givenList
.static <T,S extends T>
TsafeSubscript(List<S> list, int index, T defaultObject)
Performs a safe subscript operation against the givenList
.static <T,S extends T>
TsafeSubscript(S[] list, int index)
Performs a safe subscript operation against the given array.static <T,S extends T>
TsafeSubscript(S[] list, int index, T defaultValue)
Performs a safe subscript operation against the given array.static String
safeSubstring(String input, int start, int end)
Safely substring the given input String, accounting for odd index situations.static String
safeTrim(String input)
Returns a trimmed version of the input string, returning an empty string if it is null.static void
setAttribute(Object source, String attributeName, Object value)
Sets the given attribute on the given object, if it supports attributes.static <T> Set<T>
setOf(T... objects)
Returns a new modifiable set with the objects specified added to it.static <K> List<Map<? super K,?>>
sortCopiedMapListByKey(List<Map<? super K,?>> listOfMaps, K key)
The same assortMapListByKey(List, Object)
, except that the list will be copied and returned, rather than sorted in place.static <K> void
sortMapListByKey(List<Map<? super K,?>> listOfMaps, K key)
Sorts the given list of Maps in place by the value of the given key.static <S,T>
voidsynchronizedPutIfAbsent(Map<S,T> target, S key, Supplier<T> value)
Adds the given key and value to the Map if no existing value for the key is present.static Duration
timeDifference(long firstTime, long secondTime)
Coerces the millisecond timestamps to Date objects, then invokes the APItimeDifference(Date, Date)
.static Duration
timeDifference(Date firstTime, Date secondTime)
Converts two Date objects toLocalDateTime
at the system default time zone and returns theDuration
between them.static String
timestamp()
Returns the current time in a standard formatstatic String
toXml(Object input)
Translates the input to XML, if a serializer is registered for it.static void
tryCaptureLocationInfo(sailpoint.api.SailPointContext context, sailpoint.object.Identity currentUser)
Attempts to capture the user’s time zone information from the current JSF context / HTTP session, if one is available.static void
tryCaptureLocationInfo(sailpoint.api.SailPointContext context, sailpoint.web.UserContext currentUser)
Attempts to capture the user’s time zone information from the user context.static sailpoint.server.SPKeyStore
tryGetKeystore()
Attempts to get the SPKeyStore, a class whose getInstance() is for some reason protected.static String
velocityRender(String template, Map<String,?> args)
Renders the given template using Velocity, passing the given arguments to the renderer.static sailpoint.object.Filter
wildcardToFilter(String property, String input, boolean caseInsensitive)
Transforms a wildcard like ‘a*’ to a Filter.static <T> T
withDefault(Object maybeNull, T defaultValue, Functions.FunctionWithError<Object,T> valueProducer)
Uses the valueProducer to extract the value from the input object if it is not null, otherwise returns the default value.static <T> void
withIterator(Functions.SupplierWithError<Iterator<T>> iteratorSupplier, Functions.ConsumerWithError<Iterator<T>> iteratorConsumer)
Safely handles the given iterator by passing it to the Consumer and, regardless of outcome, by flushing it when the Consumer returns.static <T> void
withIterator(Iterator<T> iterator, Functions.ConsumerWithError<Iterator<T>> iteratorConsumer)
Safely handles the given iterator by passing it to the Consumer and, regardless of outcome, by flushing it when the Consumer returns.static void
withJavaLock(Lock lock, Callable<?> callback)
Obtains the lock, then executes the callbackstatic void
withJavaTimeoutLock(Lock lock, long timeoutMillis, Callable<?> callback)
Obtains the lock, then executes the callbackstatic void
withNoCommitConnection(sailpoint.api.SailPointContext context, Functions.ConnectionHandler consumer)
Creates a new database connection using the context provided, sets its auto-commit flag to false, then passes it to the consumer provided.static <V extends sailpoint.object.SailPointObject>
voidwithPersistentLock(sailpoint.api.SailPointContext context, Class<V> sailpointClass, String id, int timeoutSeconds, Functions.ConsumerWithError<V> callback)
Obtains a persistent lock on the object (sets lock = 1 in the DB), then executes the callback.static void
withPrivateContext(bsh.This bshThis, String methodName)
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.static void
withPrivateContext(bsh.This bshThis, String methodName, List<Object> params)
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.static void
withPrivateContext(Functions.ConsumerWithError<sailpoint.api.SailPointContext> runner)
Begins a private, temporary SailpointContext session and then invokes the given Consumer as a callback.static <T> T
withPrivateContext(Functions.FunctionWithError<sailpoint.api.SailPointContext,T> runner)
Begins a private, temporary SailpointContext session and then invokes the given Function as a callback.static void
withPrivateContextIterate(bsh.This bshThis, String methodName, Collection<Object> params)
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.static <V extends sailpoint.object.SailPointObject>
voidwithTransactionLock(sailpoint.api.SailPointContext context, Class<V> sailpointClass, String id, int timeoutSeconds, Functions.ConsumerWithError<V> callback)
Obtains a transaction lock on the object (selects it ‘for update’), then executes the callback.
-
-
-
Field Detail
-
GLOBAL_MAP_PREFIX
public static final String GLOBAL_MAP_PREFIX
The prefix inCustomGlobal
used bygetPluginVersionedGlobalMap()
.- See Also:
- Constant Field Values
-
IDW_WORKER_POOL
public static final String IDW_WORKER_POOL
The name of the worker pool, stored in CustomGlobal by default- See Also:
- Constant Field Values
-
MOST_RECENT_LOCALE
public static final String MOST_RECENT_LOCALE
The key used to store the user’s most recent locale on their UIPrefs, captured bytryCaptureLocationInfo(SailPointContext, Identity)
- See Also:
- Constant Field Values
-
MOST_RECENT_TIMEZONE
public static final String MOST_RECENT_TIMEZONE
The key used to store the user’s most recent timezone on their UIPrefs, captured bytryCaptureLocationInfo(SailPointContext, Identity)
- See Also:
- Constant Field Values
-
NONE
public static final Object NONE
A magic constant for use with thegetQuickProperty(Object, String)
method.If the property is not an available ‘quick property’, this object will be returned.
-
-
Method Detail
-
addMapped
public static <S,T extends Collection<S>> void addMapped(Map<String,T> map, String key, S value)
Adds the given value to aCollection
at the given key in the map.If the map does not have a
Collection
at the given key, a newArrayList
is added, then the value is added to that.This method is null safe. If the map or key is null, this method has no effect.
- Type Parameters:
S
- The key typeT
- The list element type- Parameters:
map
- The map to modifykey
- The map key that points to the list to add the value tovalue
- The value to add to the list
-
addSessionMessage
public static void addSessionMessage(sailpoint.api.SailPointContext context, sailpoint.tools.Message message) throws sailpoint.tools.GeneralException
Adds a message banner to the current browser session which will show up at the top of each page.This requires that a FacesContext exist in the current session. You can’t always assume this to be the case.
If you’re using the BaseCommonPluginResource class, it has a method to construct a new FacesContext if one doesn’t exist.
- Parameters:
context
- The IIQ contextmessage
- The Message to add- Throws:
sailpoint.tools.GeneralException
- if anything goes wrong
-
andMatchTerm
public static sailpoint.object.IdentitySelector.MatchExpression andMatchTerm(sailpoint.object.IdentitySelector.MatchExpression input, sailpoint.object.IdentitySelector.MatchTerm newTerm)
Adds a new MatchTerm as an ‘and’ to an existing MatchExpression, transforming an existing ‘or’ into a sub-expression if needed.- Parameters:
input
- The input MatchExpressionnewTerm
- The new term to ‘and’ with the existing expressions- Returns:
- The resulting match term
-
caseInsensitiveContains
public static boolean caseInsensitiveContains(Collection<? extends Object> collection, Object value)
Returns true if the collection contains the given value ignoring case- Parameters:
collection
- The collection to checkvalue
- The value to check for- Returns:
- True if the collection contains the value, comparing case-insensitively
-
computeGlobalSingleton
public static <T> T computeGlobalSingleton(String key, Supplier<T> factory)
Gets a global singleton value from CustomGlobal.If it doesn’t exist, uses the supplied factory (in a synchronized thread) to create it.
NOTE: This should NOT be an instance of a class defined in a plugin. If the plugin is redeployed and its classloader refreshes, it will cause the return value from this method to NOT match the "new" class in the new classloader, causing ClassCastExceptions.
- Type Parameters:
T
- the expected output type- Parameters:
key
- The keyfactory
- The factory to use if the stored value is null- Returns:
- the object from the global cache
-
consoleInvoke
public static String consoleInvoke(String command) throws Exception
Invokes a command via the IIQ console which will run as though it was typed at the command prompt- Parameters:
command
- The command to run- Returns:
- the results of the command
- Throws:
Exception
- if a failure occurs during run
-
containsMessage
public static boolean containsMessage(Throwable t, String cause)
Returns true if the Throwable message (or any of its causes) contain the given message- Parameters:
t
- The throwable to checkcause
- The message to check for- Returns:
- True if the message appears anywhere
-
containsProperty
public static boolean containsProperty(sailpoint.object.IdentitySelector.MatchExpression input, String property)
Returns true if the given match expression references the given property anywhere.This is mainly intended for one-off operations to find roles with particular selectors.
- Parameters:
input
- The filter inputproperty
- The property to check for- Returns:
- True if the MatchExpression references the given property anywhere in its tree
-
containsProperty
public static boolean containsProperty(sailpoint.object.IdentitySelector.MatchTerm term, String property)
Returns true if the given match term references the given property anywhere.This is mainly intended for one-off operations to find roles with particular selectors.
- Parameters:
term
- The MatchTerm to checkproperty
- The property to check for- Returns:
- True if the MatchTerm references the given property anywhere in its tree
-
containsProperty
public static boolean containsProperty(sailpoint.object.Filter input, String property)
Returns true if the given filter references the given property anywhere.This is mainly intended for one-off operations to find roles with particular selectors.
If either the filter or the property is null, returns false.
- Parameters:
input
- The filter inputproperty
- The property to check for- Returns:
- True if the Filter references the given property anywhere in its tree
-
convertDateFormat
public static String convertDateFormat(Object something, String inputDateFormat, String outputDateFormat)
Converts the input object using the two date formats provided by invoking the four-argumentconvertDateFormat(Object, String, String, ZoneId)
.The system default ZoneId will be used.
- Parameters:
something
- The input object, which can be a string or various date objectsinputDateFormat
- The input date format, which will be applied to a string inputoutputDateFormat
- The output date format, which will be applied to the intermediate date- Returns:
- The input object formatted according to the output date format
- Throws:
DateTimeParseException
- if there is a failure parsing the date
-
convertDateFormat
public static String convertDateFormat(Object something, String inputDateFormat, String outputDateFormat, ZoneId zoneId)
Converts the input object using the two date formats provided.If the input object is a String (the most likely case), it will be transformed into an intermediate date using the inputDateFormat. Date type inputs (Date, LocalDate, LocalDateTime, and Long) will be converted directly to an intermediate date.
JDBC classes like Date and Timestamp extend java.util.Date, so that logic would apply here.
The intermediate date will then be formatted using the outputDateFormat at the appropriate ZoneId.
- Parameters:
something
- The input object, which can be a string or various date objectsinputDateFormat
- The input date format, which will be applied to a string inputoutputDateFormat
- The output date format, which will be applied to the intermediate datezoneId
- The time zone to use for parsing and formatting- Returns:
- The input object formatted according to the output date format
- Throws:
DateTimeParseException
- if there is a failure parsing the date
-
dateAtLeastDaysAgo
public static boolean dateAtLeastDaysAgo(Date testDate, int days)
Determines whether the test date is at least N days ago.- Parameters:
testDate
- The test datedays
- The number of dates- Returns:
- True if this date is equal to or earlier than the calendar date N days ago
-
dateAtLeastYearsAgo
public static boolean dateAtLeastYearsAgo(Date testDate, int years)
Determines whether the test date is at least N years ago.NOTE: This method checks using actual calendar years, rather than calculating a number of days and comparing that. It will take into account leap years and other date weirdness.
- Parameters:
testDate
- The test dateyears
- The number of years- Returns:
- True if this date is equal to or earlier than the calendar date N years ago
-
dateDifference
public static Period dateDifference(Date firstTime, Date secondTime)
Converts two Date objects toLocalDate
at the system default time zone and returns the number of days between them.If you pass the dates in the wrong order (first parameter is the later date), they will be silently swapped before returning the Duration.
- Parameters:
firstTime
- The first time to comparesecondTime
- The second time to compare- Returns:
- The
Period
between the two days
-
dateDifference
public static Period dateDifference(long firstTimeMillis, long secondTimeMillis)
Coerces the long millisecond timestamps to Date objects, then returns the result ofdateDifference(Date, Date)
.- Parameters:
firstTimeMillis
- The first time to comparesecondTimeMillis
- The second time to compare- Returns:
- The
Period
between the two days
-
detach
public static <T extends sailpoint.object.SailPointObject> T detach(sailpoint.api.SailPointContext context, T o) throws sailpoint.tools.GeneralException
Detaches the given object as much as possible from the database context by converting it to XML and back again.Converting to XML requires resolving all Hibernate lazy-loaded references.
- Type Parameters:
T
- A class extending SailPointObject- Parameters:
context
- The context to use to parse the XMLo
- The object to detach- Returns:
- A reference to the object detached from any Hibernate session
- Throws:
sailpoint.tools.GeneralException
- if a parsing failure occurs
-
ensureAllNotNullOrEmpty
public static void ensureAllNotNullOrEmpty(String... values)
Throws an exception if the string is null or empty- Parameters:
values
- The strings to test
-
ensureNotNullOrEmpty
public static void ensureNotNullOrEmpty(String value)
Throws an exception if the string is null or empty- Parameters:
value
- The string to test
-
evictRuleRunnerPool
public static void evictRuleRunnerPool() throws Exception
Uses reflection to evict the RuleRunner pool cache- Throws:
Exception
- if anything goes wrong
-
extractProperty
public static <S,T> List<T> extractProperty(List<S> input, String property, Class<T> expectedType) throws sailpoint.tools.GeneralException
Extracts the value of the given property from each item in the list and returns a new list containing those property values.If the input list is null or empty, an empty list will be returned.
This is roughly identical to
input.stream().map(item -> (T)Utilities.getProperty(item, property)).collect(Collectors.toList())
- Type Parameters:
S
- The input typeT
- The output type- Parameters:
input
- The input listproperty
- The property to extractexpectedType
- The expected type of the output objects- Returns:
- A list of the extracted values
- Throws:
sailpoint.tools.GeneralException
- if extraction goes wrong
-
filterToMatchExpression
public static sailpoint.object.IdentitySelector.MatchExpression filterToMatchExpression(sailpoint.object.Filter input)
Transfors an input Filter into a MatchExpression- Parameters:
input
- The Filter- Returns:
- The MatchExpression
-
filterToMatchTerm
public static sailpoint.object.IdentitySelector.MatchTerm filterToMatchTerm(sailpoint.object.Filter input)
Transfors an input Filter into a MatchTerm- Parameters:
input
- The Filter- Returns:
- The MatchTerm
-
firstNotNullOrEmpty
public static String firstNotNullOrEmpty(String... inputs)
Returns the first item in the list that is not null or empty.If all items are null or empty, or the input is itself a null or empty array, an empty string will be returned. This method will never return null.
- Parameters:
inputs
- The input strings- Returns:
- The first not null or empty item, or an empty string if none is found
-
format
public static String format(String messageTemplate, Object... params)
Formats the input message template using Java’s MessageFormat class and the SLogger.Formatter class.If no parameters are provided, the message template is returned as-is.
- Parameters:
messageTemplate
- The message template into which parameters should be injectedparams
- The parameters to be injected- Returns:
- The resulting string
-
fuzzyGet
public static <T> T fuzzyGet(Map<String,Object> map, String fuzzyKey)
Retrieves a key from the given Map in a ‘fuzzy’ way.Keys will be matched ignoring case and whitespace.
For example, given the actual key "toolboxConfig", the following inputs would also match:
"toolbox config" "Toolbox Config" "ToolboxConfig"
The first matching key will be returned, so it is up to the caller to ensure that the input does not match more than one actual key in the Map. For some Map types, "first matching key" may be nondeterministic if more than one key matches.
If either the provided key or the map is null, this method will return null.
- Type Parameters:
T
- The return type, for convenience- Parameters:
map
- The map from which to query the valuefuzzyKey
- The fuzzy key- Returns:
- The value from the map
-
getAsScript
public static sailpoint.object.Script getAsScript(Object input)
Gets the input object as a thread-safe Script.If the input is a String, it will be interpreted as the source of a Script. If the input is already a Script object, it will be copied for thread safety and the copy returned.
- Parameters:
input
- The input object, either a string or a script- Returns:
- The output
-
getAttributes
public static sailpoint.object.Attributes<String,Object> getAttributes(Object source)
Gets the attributes of the given source object.If the source is not a Sailpoint object, or if it’s one of the objects without attributes, this method returns null.
- Parameters:
source
- The source object, which may implement an Attributes container method- Returns:
- The attributes, if any, or null
-
getClientTimeZone
public static TimeZone getClientTimeZone(sailpoint.object.Identity identity, sailpoint.web.UserContext userContext)
Gets the time zone associated with the logged in user’s session, based on a UserContext or Identity.As a fallback, the
WebUtil
API is used to try to retrieve the time zone from the HTTP session.You can use
tryCaptureLocationInfo(SailPointContext, UserContext)
in a plugin REST API or QuickLink textScript context to permanently store the Identity’s local time zone as a UI preference.- Parameters:
userContext
- The user context to check for a time zone, or nullidentity
- The identity to check for a time zone, or null- Returns:
- The time zone for this user
-
getCountryNames
public static List<String> getCountryNames()
Extracts a list of all country names from the JDK’s Locale class.This will be as up-to-date as your JDK itself is.
- Returns:
- A sorted list of country names
-
getFirstNotNothing
@SafeVarargs public static <T> T getFirstNotNothing(T... items)
Returns the first item in the input that is not nothing according to theisNothing(Object)
method.- Type Parameters:
T
- The superclass of all input items- Parameters:
items
- The input items- Returns:
- if the item is not null or empty
-
getFirstNotNull
public static <T> T getFirstNotNull(List<? extends T> items)
Returns the first item in the input that is not null, an empty Optional, or a Supplier that returns null.- Type Parameters:
T
- The superclass of all input items- Parameters:
items
- The input items- Returns:
- if the item is not null or empty
-
getFirstNotNull
@SafeVarargs public static <T> T getFirstNotNull(T... items)
Returns the first item in the input that is not null, an empty Optional, or a Supplier that returns null.- Type Parameters:
T
- The superclass of all input items- Parameters:
items
- The input items- Returns:
- if the item is not null or empty
-
getIIQProperties
public static Properties getIIQProperties() throws sailpoint.tools.GeneralException
Gets the iiq.properties file contents (properly closing it, unlike IIQ…)- Returns:
- The IIQ properties
- Throws:
sailpoint.tools.GeneralException
- if any load failures occur
-
getJacksonObjectMapper
public static com.fasterxml.jackson.databind.ObjectMapper getJacksonObjectMapper()
Returns a default Jackson object mapper, independent of IIQ versions.The template ObjectMapper is generated on the first invocation. All returned values will be copies of that.
- Returns:
- A copy of our cached ObjectMapper
-
getLocalDate
public static Date getLocalDate(Date inputDate, sailpoint.object.Identity identity)
IIQ tries to display timestamps in a locale-specific way to the user.It does this by storing the browser’s time zone in the HTTP session and converting dates to a local value before display. This includes things like scheduled task execution times, etc.
However, for date form fields, which should be timeless (i.e. just a date, no time component), IIQ sends a value “of midnight at the browser’s time zone”. Depending on the browser’s offset from the server time, this can result (in the worst case) in the actual selected instant being a full day ahead or behind the intended value.
This method corrects the offset using Java 8’s Time API, which allows for timeless representations, to determine the date the user intended to select, then converting that back to midnight in the server time zone. The result is stored back onto the Field.
If the time is offset from midnight but the user time zone is the same as the server time zone, it means we’re in a weird context where IIQ does not know the user’s time zone, and we have to guess. We will guess up to +12 and -11 from the server timezone, which should cover most cases. However, if you have users directly around the world from your server timezone, you may see problems.
If the input date is null, returns null.
- Parameters:
inputDate
- The input date for the useridentity
- The identity who has timezone information stored- Returns:
- The calculated local date, based on the input date and the Identity’s time zone
-
getLocalizedMessage
public static String getLocalizedMessage(sailpoint.object.Identity target, sailpoint.tools.Message message)
Localizes a message based on the locale information captured on the target Identity.This information can be captured in any plugin web service or other session-attached code using
tryCaptureLocationInfo(SailPointContext, UserContext)
If no locale information has been captured, the system default will be used instead.
- Parameters:
target
- The target usermessage
- The non-null message to translate- Returns:
- The localized message
-
getPluginVersion
public static String getPluginVersion()
Gets the current plugin version from the environment, or NA if not defined- Returns:
- The current plugin cache version
-
getPluginVersionInt
public static int getPluginVersionInt()
Gets the current plugin version from the environment, or NA if not defined- Returns:
- The current plugin cache version
-
cleanVersionedCache
public static void cleanVersionedCache(String prefix, int currentVersion)
Iterates through theCustomGlobal
, removing any object with the prefix plus older plugin versions.For example, if you have just added new versioned object ‘some.object.2’, because the plugin version is 2, you will want to remove ‘some.object.1’ and ‘some.object.0’ if they exist. This method does that.
Note that the final dot in ‘some.object.’ is part of the prefix that you must provide. This method will NOT assume that the prefix ought to end with a dot.
- Parameters:
prefix
- The prefixcurrentVersion
- The current object version
-
getPluginVersionedGlobalMap
public static ConcurrentHashMap<String,Object> getPluginVersionedGlobalMap()
Gets aConcurrentHashMap
fromCustomGlobal
that will be replaced with a new, empty Map whenever the plugin version is incremented.This will prevent plugins from accidentally accessing objects from an older version of the plugin classloader. When a new storage map is created, older maps in
CustomGlobal
will be cleaned up by invokingcleanVersionedCache(String, int)
.The cache prefix is ‘com.identityworksllc.iiq.common.Utilities.globalMap.’
- Returns:
- A
ConcurrentHashMap
specific to the current plugin version
-
getProperty
public static Object getProperty(Object source, String paramPropertyPath) throws sailpoint.tools.GeneralException
Gets the given property by introspection- Parameters:
source
- The source objectparamPropertyPath
- The property path- Returns:
- The object at the given path
- Throws:
sailpoint.tools.GeneralException
- if a failure occurs
-
getProperty
public static Object getProperty(Object source, String paramPropertyPath, boolean gracefulNulls) throws sailpoint.tools.GeneralException
Gets the given property by introspection and ‘dot-walking’ the given path.Paths have the following semantics:
-
Certain common ‘quick paths’ will be recognized and returned immediately, rather than using reflection to construct the output.
-
A dot ‘.’ is used to separate path elements. Quotes are supported.
-
Paths are evaluated against the current context.
-
Elements within Collections and Maps can be addressed using three different syntaxes, depending on your needs: list[1], list.1, or list._1. Similarly, map[key], map.key, or map._key. Three options are available to account for Sailpoint’s various parsers.
-
If an element is a Collection, the context object (and thus output) becomes a Collection. All further properties (other than indexes) are evalulated against each item in the collection. For example, on an Identity, the property ‘links.application.name’ resolves to a List of Strings.
This does not cascade. For example, links.someMultiValuedAttribute will result in a List of Lists, one for each item in ‘links’, rather than a single List containing all values of the attribute. TODO improve nested expansion, if it makes sense.
If you pass true for ‘gracefulNulls’, a null value or an invalid index at any point in the path will simply result in a null output. If it is not set, a NullPointerException or IndexOutOfBoundsException will be thrown as appropriate.
- Parameters:
source
- The context object against which to evaluate the pathparamPropertyPath
- The property path to evaluategracefulNulls
- If true, encountering a null or bad index mid-path will result in an overall null return value, not an exception- Returns:
- The object at the given path
- Throws:
sailpoint.tools.GeneralException
- if a failure occurs
-
-
getQuickProperty
public static Object getQuickProperty(Object source, String propertyPath) throws sailpoint.tools.GeneralException
Returns a “quick property” which does not involve introspection.If the property is not in this list, the result will be
NONE
.- Parameters:
source
- The source objectpropertyPath
- The property path to check- Returns:
- the object, if this is a known “quick property” or Utilities.NONE if not
- Throws:
sailpoint.tools.GeneralException
- if a failure occurs
-
getSharedBackgroundPool
public static ExecutorService getSharedBackgroundPool()
Gets the shared background pool, an instance ofForkJoinPool
.This is stored in the core CustomGlobal class so that it can be shared across all IIQ classloader contexts and will not leak when a new plugin is deployed.
The parallelism count can be changed in SystemConfiguration under the key 'commonThreadPoolParallelism'.
- Returns:
- An instance of the shared background pool
-
isAssignableFrom
public static <A,B> boolean isAssignableFrom(Class<A> parentClass, Class<B> testClass)
Returns true if parentClass is assignable from testClass, e.g.if the following code would not fail to compile:
TestClass ot = new TestClass(); ParentClass tt = ot;
This is also equivalent to ‘b instanceof A’ or ‘B extends A’.
Primitive types and their boxed equivalents have special handling.
- Type Parameters:
A
- The parent typeB
- The potential child type- Parameters:
parentClass
- The first (parent-ish) classtestClass
- The second (child-ish) class- Returns:
- True if parentClass is assignable from testClass
-
isFlagNotSet
public static boolean isFlagNotSet(Object flagValue)
Returns the inverse ofisFlagSet(Object)
.- Parameters:
flagValue
- The flag value to check- Returns:
- True if the flag is NOT a ‘true’ value
-
isFlagSet
public static boolean isFlagSet(String stringFlag)
Forwards toisFlagSet(Object)
- Parameters:
stringFlag
- The string to check against the set of ‘true’ values- Returns:
- True if the string input flag is set
-
isFlagSet
public static boolean isFlagSet(Object flagValue)
Check if a String, Boolean, or Number flag object should be considered equivalent to boolean true.For strings, true values are: (true, yes, 1, Y), all case-insensitive. All other strings are false.
Boolean ‘true’ will also be interpreted as a true value.
Numeric ‘1’ will also be interpreted as a true value.
All other values, including null, will always be false.
- Parameters:
flagValue
- String representation of a flag- Returns:
- if flag is true
-
isNotAssignableFrom
public static <A,B> boolean isNotAssignableFrom(Class<A> parentClass, Class<B> testClass)
Returns the inverse ofisAssignableFrom(Class, Class)
.In other words, returns true if the following code would fail to compile:
TestClass ot = new TestClass(); ParentClass tt = ot;
- Type Parameters:
A
- The parent typeB
- The potential child type- Parameters:
parentClass
- The first (parent-ish) classtestClass
- The second (child-ish) class- Returns:
- True if parentClass is NOT assignable from testClass
-
isNotEmpty
public static boolean isNotEmpty(Map<?,?> map)
Returns true if the input is NOT an empty Map.- Parameters:
map
- The map to check- Returns:
- True if the input is NOT an empty map
-
isNotEmpty
public static boolean isNotEmpty(Collection<?> list)
Returns true if the input is NOT an empty Collection.- Parameters:
list
- The list to check- Returns:
- True if the input is NOT an empty collection
-
isNotNullEmptyOrWhitespace
public static boolean isNotNullEmptyOrWhitespace(String input)
Returns true if the input string is not null and contains any non-whitespace characters.- Parameters:
input
- The input string to check- Returns:
- True if the input is not null, empty, or only whitespace
-
isNotNumber
public static boolean isNotNumber(String input)
Returns true if the input is NOT only digits- Parameters:
input
- The input to check- Returns:
- True if the input contains any non-digit characters
-
isNothing
public static boolean isNothing(Object thing)
Returns true if the given object is ‘nothing’: a null, empty string, empty map, empty Collection, empty Optional, or empty Iterable.If the given object is a Supplier, returns true if
Supplier.get()
returns a ‘nothing’ result.Iterables will be flushed using
Util.flushIterator(Iterator)
. That means this may be a slow process for Iterables.- Parameters:
thing
- The object to test for nothingness- Returns:
- True if the object is nothing
-
isNullEmptyOrWhitespace
public static boolean isNullEmptyOrWhitespace(String input)
Returns true if the input string is null, empty, or contains only whitespace characters according toCharacter.isWhitespace(char)
.- Parameters:
input
- The input string- Returns:
- True if the input is null, empty, or only whitespace
-
isNumber
public static boolean isNumber(String input)
Returns true if this string contains only digits- Parameters:
input
- The input string- Returns:
- True if this string contains only digits
-
isSomething
public static boolean isSomething(Object thing)
Returns true ifisNothing(Object)
would return false.- Parameters:
thing
- The thing to check- Returns:
- True if the object is NOT a ‘nothing’ value
-
isoOffsetTimestamp
public static String isoOffsetTimestamp()
Returns the current time in the standard ISO offset (date T time+1:00) format- Returns:
- The formatted current time
-
listMessageAccumulator
public static sailpoint.api.MessageAccumulator listMessageAccumulator(List<String> target, boolean dated)
Creates a MessageAccumulator that just inserts the message into the target list.- Parameters:
target
- The target list, to which messages will be added. Must be thread-safe for add.dated
- If true, messages will be prepended with the output oftimestamp()
- Returns:
- The resulting MessageAccumulator implementation
-
listOf
@SafeVarargs public static <T> List<T> listOf(T... objects)
Returns a new modifiable list with the objects specified added to it.A new list will be returned on each invocation. This method will never return null.
In Java 11+, the List.of() method constructs a list of arbitrary type, which is not modifiable by default.
- Type Parameters:
T
- The type of the list- Parameters:
objects
- The objects to add to the list- Returns:
- A list containing each of the items
-
mapConformsToType
public static <S,T> boolean mapConformsToType(Map<?,?> inputMap, Class<S> expectedKeyType, Class<T> expectedValueType)
Returns true if every key and value in the Map can be cast to the types given.Passing a null for either Class parameter will ignore that check.
A true result should guarantee no ClassCastExceptions will result from casting the Map keys to any of the given values.
If both expected types are null or equal to
Object
, this method will trivially return true. If the map is null or empty, this method will trivially return true.NOTE that this method will iterate over all key-value pairs in the Map, so may be quite expensive if the Map is large.
- Type Parameters:
S
- The map key typeT
- The map value type- Parameters:
inputMap
- The input map to checkexpectedKeyType
- The type implemented or extended by all Map keysexpectedValueType
- The type implemented or exended by all Map values- Returns:
- True if all map keys and values will NOT throw an exception on being cast to either given type, false otherwise
-
mapOf
public static <S,T> Map<S,T> mapOf(Object... input)
Creates a map from a varargs list of items, where every other item is a key or value.If the arguments list does not have enough items for the final value, null will be used.
- Type Parameters:
S
- The key typeT
- The value type- Parameters:
input
- The input items, alternating key and value- Returns:
- on failures
-
matchExpressionToCompoundFilter
public static sailpoint.object.CompoundFilter matchExpressionToCompoundFilter(sailpoint.object.IdentitySelector.MatchExpression input)
Transforms a MatchExpression selector into a CompoundFilter- Parameters:
input
- The input expression- Returns:
- The newly created CompoundFilter corresponding to the MatchExpression
-
matchTerm
public static sailpoint.object.IdentitySelector.MatchTerm matchTerm(String property, Object value, sailpoint.object.Application application)
Create a MatchTerm from scratch- Parameters:
property
- The property to testvalue
- The value to testapplication
- The application to associate the term with (or null)- Returns:
- The newly created MatchTerm
-
matchTermToFilter
public static sailpoint.object.Filter matchTermToFilter(sailpoint.object.IdentitySelector.MatchTerm term, sailpoint.object.Application defaultApplication, List<sailpoint.object.Application> applications)
Transforms a MatchTerm into a Filter, which can be useful for then modifying it- Parameters:
term
- The matchterm to transformdefaultApplication
- The default application if none is specified (may be null)applications
- The list of applications- Returns:
- The new Filter object
-
max
public static Date max(Date... dates)
Returns the maximum of the given dates.If no values are passed, returns the earliest possible date.
- Parameters:
dates
- The dates to find the max of- Returns:
- The maximum date in the array
-
min
public static Date min(Date... dates)
Returns the maximum of the given dates.If no values are passed, returns the latest possible date. The returned value is always a new object, not one of the actual objects in the input.
- Parameters:
dates
- The dates to find the max of- Returns:
- The maximum date in the array
-
nullSafeNotEq
public static boolean nullSafeNotEq(Object a, Object b)
Returns true ifUtil.nullSafeEq(Object, Object)
would return false and vice versa.Two null values will be considered equal.
- Parameters:
a
- The first valueb
- The second value- Returns:
- True if the values are NOT equal
-
nullToEmpty
public static String nullToEmpty(String maybeNull)
Returns the input string if it is not null.Otherwise, returns an empty string.
- Parameters:
maybeNull
- The input string, which is possibly null- Returns:
- The input string or an empty string
-
nullToEmpty
public static sailpoint.object.Attributes<String,Object> nullToEmpty(Map<String,? extends Object> input)
Converts the given collection to an empty Attributes, if a null object is passed, the input object (if an Attributes is passed), or a new Attributes containing all elements from the input Map (if any other type of Map is passed).- Parameters:
input
- The input map or attributes- Returns:
- The result as described above
-
nullToEmpty
public static <T> List<T> nullToEmpty(Collection<T> input)
Converts the given collection to an empty list (if a null value is passed), the input object (if a List is passed), or a copy of the input object in a new ArrayList (if any other Collection is passed).- Type Parameters:
T
- The type of the list- Parameters:
input
- The input collection- Returns:
- The result as described above
-
nullToEmptyString
public static String nullToEmptyString(String maybeNull)
Returns the input string if it is not null, explicitly noting the input as a String to make Beanshell happy at runtime.Identical to
nullToEmpty(String)
, except Beanshell can’t decide which of the method variants to call when the input is null. This leads to scripts sometimes callingnullToEmpty(Map)
instead. (Java would be able to infer the overload to invoke at compile time by using the variable type.)- Parameters:
maybeNull
- The input string, which is possibly null- Returns:
- The input string or an empty string
-
parseDateString
public static Optional<LocalDateTime> parseDateString(String inputString, String format)
Parses the input string into a LocalDateTime, returning anOptional
if the date parses properly.If the date does not parse properly, or if the input is null, returns an
Optional.empty()
.- Parameters:
inputString
- The input stringformat
- The format used to parse the input string perDateTimeFormatter
rules- Returns:
- The parsed string
-
prefixMap
public static <V> Map<String,V> prefixMap(Map<String,V> map, String prefix)
Constructs a new map with each key having the prefix added to it.This can be used to merge two maps without overwriting keys from either one, for example.
- Type Parameters:
V
- The value type of the map- Parameters:
map
- The input map, which will not be modifiedprefix
- The prefix to add to each key- Returns:
- A new
HashMap
with each key prefixed by the given prefix
-
quietRun
public static <T> T quietRun(sailpoint.api.SailPointContext context, Object thing, Map<String,Object> params) throws sailpoint.tools.GeneralException
Attempts to dynamically evaluate whatever thing is passed in and return the output of running the thing.If the thing is not of a known type, this method silently returns null.
The following types of things are accept3ed:
- sailpoint.object.Rule: Evaluates as a SailPoint rule
- sailpoint.object.Script: Evaluates as a SailPoint script after being cloned
- java.lang.String: Evaluates as a SailPoint script
- java.util.function.Function: Accepts the Map of parameters, returns a value
- java.util.function.Consumer: Accepts the Map of parameters
- sailpoint.object.JavaRuleExecutor: Evaluates as a Java rule
For Function and Consumer things, the context and a log will be added to the params.
- Type Parameters:
T
- the context-sensitive type of the return- Parameters:
context
- The sailpoint contextthing
- The thing to runparams
- The parameters to pass to the thing, if any- Returns:
- The return value from the thing executed, or null
- Throws:
sailpoint.tools.GeneralException
- if any failure occurs
-
safeCast
public static <T> T safeCast(Object input, Class<T> targetClass)
Safely casts the given input to the target type.If the object cannot be cast to the target type, this method returns null instead of throwing a ClassCastException.
If the input object is null, this method returns null.
If the targetClass is null, this method throws a
NullPointerException
.- Type Parameters:
T
- The expected return type- Parameters:
input
- The input object to casttargetClass
- The target class to which it should be cast- Returns:
- The object cast to the given type, or null if it cannot be cast
-
safeClassName
public static String safeClassName(Object any)
Returns the class name of the object, or the string ‘null’, suitable for logging safely- Parameters:
any
- The object to get the type of- Returns:
- The class name, or the string ‘null’
-
safeContainsAll
public static boolean safeContainsAll(Object maybeBiggerCollection, Object maybeSmallerCollection)
Returns true if the bigger collection contains all elements in the smaller collection.If the inputs are null, the comparison will always be false. If the inputs are not collections, they will be coerced to collections before comparison.
- Parameters:
maybeBiggerCollection
- An object that may be the bigger collectionmaybeSmallerCollection
- AN object that may be the smaller collection- Returns:
- True if the bigger collection contains all elements of the smaller collection
-
safeDateTimestamp
public static long safeDateTimestamp(Date input)
Returns a long timestamp for the input Date, returningLong.MIN_VALUE
if the Date is null.- Parameters:
input
- The input date- Returns:
- The timestamp of the date, or Long.MIN_VALUE if it is null
-
safeForeach
public static <A,B> void safeForeach(Map<A,B> map, BiConsumer<A,B> function)
Invokes an action against each key-value pair in the Map.If the Map is null, or if the function is null, no action is taken and no exception is thrown.
- Type Parameters:
A
- The type of the map’s keysB
- The type of the map’s values- Parameters:
map
- The mapfunction
- A BiConsumer that will be applied to each key-avlue pair in the Map
-
safeKeyStream
public static <T> Stream<T> safeKeyStream(Map<T,?> map)
Returns a stream for the given map’s keys if it’s not null, or an empty stream if it is- Type Parameters:
T
- The type of the map’s keys- Parameters:
map
- The map- Returns:
- A stream from the map’s keys, or an empty stream
-
safeListify
public static List<String> safeListify(Object value)
Safely converts the given input to a List.If the input is a String, it will be added to a new List and returned.
If the input is a Number, Boolean, or
Message
, it will be converted to String, added to a List, and returned.If the input is already a List, the input object will be returned as-is.
If the input is an array of strings, they will be added to a new list and returned.
If the input is an array of any other type of object, they will be converted to strings, added to a new list, and returned.
If the input is any other kind of Collection, all elements will be added to a new List and returned.
If the input is a
Stream
, all elements will be converted to Strings usingsafeString(Object)
, then added to a new List and returned.All other values result in an empty list.
This method never returns null.
Unlike
Util.otol(Object)
, this method does not split strings as CSVs.It’s not my problem if your existing lists have something other than Strings in them.
- Parameters:
value
- The value to listify- Returns:
- The resulting List
-
safeMapCast
public static <S,T> Map<S,T> safeMapCast(Object input, Class<S> keyType, Class<T> valueType)
Returns a Map cast to the given generic types if and only if it passes the check inmapConformsToType(Map, Class, Class)
for the same type parameters.If the input is not a Map or if the key/value types do not conform to the expected types, this method returns null.
- Type Parameters:
S
- The resulting key typeT
- The resulting value type- Parameters:
input
- The input mapkeyType
- The key typevalueType
- The value type- Returns:
- The resulting Map
-
safeSize
public static <T> int safeSize(T[] input)
Returns the size of the input array, returning 0 if the array is null- Type Parameters:
T
- The type of the array (just for compiler friendliness)- Parameters:
input
- The array to get the size of- Returns:
- The size of the array
-
safeSize
public static int safeSize(Collection<?> input)
Returns the size of the input collection, returning 0 if the collection is null- Parameters:
input
- The collection to get the size of- Returns:
- The size of the collection
-
safeSize
public static int safeSize(String input)
Returns the length of the input string, returning 0 if the string is null- Parameters:
input
- The string to get the length of- Returns:
- The size of the string
-
safeStream
public static <T> Stream<T> safeStream(T[] array)
Returns a stream for the given array if it’s not null, or an empty stream if it is- Type Parameters:
T
- The type of the array- Parameters:
array
- The array- Returns:
- A stream from the array, or an empty stream
-
safeStream
public static <T> Stream<T> safeStream(List<T> list)
Returns a stream for the given list if it’s not null, or an empty stream if it is- Type Parameters:
T
- The type of the list- Parameters:
list
- The list- Returns:
- A stream from the list, or an empty stream
-
safeStream
public static <T> Stream<T> safeStream(Set<T> set)
Returns a stream for the given set if it’s not null, or an empty stream if it is- Type Parameters:
T
- The type of the list- Parameters:
set
- The list- Returns:
- A stream from the list, or an empty stream
-
safeString
public static String safeString(Object whatever)
Returns the given value as a “safe string”.If the value is null, it will be returned as an empty string. If the value is already a String, it will be returned as-is. If the value is anything else, it will be passed through
String.valueOf(Object)
.If the input is an array, it will be converted to a temporary list for String.valueOf() output.
The output will never be null.
- Parameters:
whatever
- The thing to return- Returns:
- The string
-
safeSubscript
public static <T,S extends T> T safeSubscript(S[] list, int index)
Performs a safe subscript operation against the given array.If the array is null, or if the index is out of bounds, this method returns null instead of throwing an exception.
- Type Parameters:
T
- The expected return type- Parameters:
list
- The array to get the value fromindex
- The index from which to get the value.- Returns:
- The value at the given index in the array, or null
-
safeSubscript
public static <T,S extends T> T safeSubscript(S[] list, int index, T defaultValue)
Performs a safe subscript operation against the given array.If the array is null, or if the index is out of bounds, this method returns the default instead of throwing an exception.
- Type Parameters:
T
- The expected return type- Parameters:
list
- The array to get the value fromindex
- The index from which to get the value.defaultValue
- The default value to return if the input is null- Returns:
- The value at the given index in the array, or null
-
safeSubscript
public static <T,S extends T> T safeSubscript(List<S> list, int index)
Performs a safe subscript operation against the givenList
.If the list is null, or if the index is out of bounds, this method returns null instead of throwing an exception.
Equivalent to safeSubscript(list, index, null).
- Type Parameters:
T
- The expected return type- Parameters:
list
- The List to get the value fromindex
- The index from which to get the value.- Returns:
- The value at the given index in the List, or null
-
safeSubscript
public static <T,S extends T> T safeSubscript(List<S> list, int index, T defaultObject)
Performs a safe subscript operation against the givenList
.If the list is null, or if the index is out of bounds, this method returns the given default object instead of throwing an exception.
- Type Parameters:
S
- The actual type of the list, which must be a subclass of TT
- The expected return type- Parameters:
list
- The List to get the value fromindex
- The index from which to get the value.defaultObject
- The default object to return in null or out-of-bounds cases- Returns:
- The value at the given index in the List, or null
-
safeSubstring
public static String safeSubstring(String input, int start, int end)
Safely substring the given input String, accounting for odd index situations.This method should never throw a StringIndexOutOfBounds exception.
Negative values will be interpreted as distance from the end, like Python.
If the start index is higher than the end index, or if the start index is higher than the string length, the substring is not defined and an empty string will be returned.
If the end index is higher than the length of the string, the whole remaining string after the start index will be returned.
- Parameters:
input
- The input string to substringstart
- The start indexend
- The end index- Returns:
- The substring
-
safeTrim
public static String safeTrim(String input)
Returns a trimmed version of the input string, returning an empty string if it is null.- Parameters:
input
- The input string to trim- Returns:
- A non-null trimmed copy of the input string
-
setAttribute
public static void setAttribute(Object source, String attributeName, Object value)
Sets the given attribute on the given object, if it supports attributes.The attributes on some object types may be called other things like arguments.
- Parameters:
source
- The source object, which may implement an Attributes container methodattributeName
- The name of the attribute to setvalue
- The value to set in that attribute
-
setOf
@SafeVarargs public static <T> Set<T> setOf(T... objects)
Returns a new modifiable set with the objects specified added to it.A new set will be returned on each invocation. This method will never return null.
- Type Parameters:
T
- The type of each item- Parameters:
objects
- The objects to add to the set- Returns:
- A set containing each of the items
-
sortCopiedMapListByKey
public static <K> List<Map<? super K,?>> sortCopiedMapListByKey(List<Map<? super K,?>> listOfMaps, K key)
The same assortMapListByKey(List, Object)
, except that the list will be copied and returned, rather than sorted in place.- Type Parameters:
K
- The type of the key- Parameters:
listOfMaps
- The list of maps to sortkey
- The key to extract from each map and sort by- Returns:
- A new list, copied from the input, sorted according to the given key
-
sortMapListByKey
public static <K> void sortMapListByKey(List<Map<? super K,?>> listOfMaps, K key)
Sorts the given list of Maps in place by the value of the given key.If the value is a
Number
, it will be passed toString.valueOf(Object)
. If the value is aDate
, its epoch millisecond timestamp will be passed toString.valueOf(Object)
. Otherwise, the input will be passed toUtil.otoa(Object)
.Nulls will always be sorted higher than non-nulls, both if the List contains a null instead of a Map object, or if the value corresponding to the sort key is null.
- Type Parameters:
K
- The type of the key- Parameters:
listOfMaps
- The list of maps to sortkey
- The key to extract from each map and sort by
-
synchronizedPutIfAbsent
public static <S,T> void synchronizedPutIfAbsent(Map<S,T> target, S key, Supplier<T> value)
Adds the given key and value to the Map if no existing value for the key is present.The Map will be synchronized so that only one thread is guaranteed to be able to insert the initial value using this method.
We make no guarantees about ‘put’ operations done other ways.
If possible, you should use a
ConcurrentMap
, which already handles this situation with greater finesse.- Type Parameters:
S
- The key typeT
- The value type- Parameters:
target
- The target Map to which the value should be inserted if missingkey
- The key to insertvalue
- A supplier for the value to insert
-
timeDifference
public static Duration timeDifference(Date firstTime, Date secondTime)
Converts two Date objects toLocalDateTime
at the system default time zone and returns theDuration
between them.If you pass the dates in the wrong order (first parameter is the later date), they will be silently swapped before returning the Duration.
- Parameters:
firstTime
- The first time to comparesecondTime
- The second time to compare- Returns:
- The
Period
between the two days
-
timeDifference
public static Duration timeDifference(long firstTime, long secondTime)
Coerces the millisecond timestamps to Date objects, then invokes the APItimeDifference(Date, Date)
.- Parameters:
firstTime
- The first millisecond timestampsecondTime
- The second millisecond timestamp- Returns:
- The difference between the two times as a
Duration
. - See Also:
timeDifference(Date, Date)
-
timestamp
public static String timestamp()
Returns the current time in a standard format- Returns:
- The current time
-
toXml
public static String toXml(Object input) throws sailpoint.tools.xml.ConfigurationException
Translates the input to XML, if a serializer is registered for it.In general, this can be anything in ‘sailpoint.object’, a Map, a List, a String, or other primitives.
- Parameters:
input
- The object to serialize- Returns:
- the output XML
- Throws:
sailpoint.tools.xml.ConfigurationException
- if the object type cannot be serialized
-
tryCaptureLocationInfo
public static void tryCaptureLocationInfo(sailpoint.api.SailPointContext context, sailpoint.object.Identity currentUser)
Attempts to capture the user’s time zone information from the current JSF context / HTTP session, if one is available.The time zone and locale will be captured to the user’s UIPreferences as ‘mostRecentTimezone’ and ‘mostRecentLocale’.
If a session is not available, this method does nothing.
The JSF session is available in a subset of rule contexts, most notably the QuickLink textScript context, which runs on each load of the user’s home.jsf page.
If you are trying to capture a time zone in a plugin REST API call, you should use
tryCaptureLocationInfo(SailPointContext, UserContext)
, passing the plugin resource itself as aUserContext
.- Parameters:
context
- The current IIQ contextcurrentUser
- The user to modify with the detected information
-
tryCaptureLocationInfo
public static void tryCaptureLocationInfo(sailpoint.api.SailPointContext context, sailpoint.web.UserContext currentUser) throws sailpoint.tools.GeneralException
Attempts to capture the user’s time zone information from the user context.This could be used via a web services call where the
BaseResource
class is aUserContext
.- Parameters:
context
- The current IIQ contextcurrentUser
- The current user context- Throws:
sailpoint.tools.GeneralException
- if there is no currently logged in user
-
tryGetKeystore
public static sailpoint.server.SPKeyStore tryGetKeystore() throws sailpoint.tools.GeneralException
Attempts to get the SPKeyStore, a class whose getInstance() is for some reason protected.- Returns:
- The keystore, if we could get it
- Throws:
sailpoint.tools.GeneralException
- If the keystore could not be retrieved
-
velocityRender
public static String velocityRender(String template, Map<String,?> args) throws IOException
Renders the given template using Velocity, passing the given arguments to the renderer.Velocity will be initialized on the first invocation of this method.
TODO invoke the Sailpoint utility in versions over 8.2
- Parameters:
template
- The VTL template stringargs
- The arguments to pass to the template renderer- Returns:
- The rendered string
- Throws:
IOException
- if any Velocity failures occur
-
wildcardToFilter
public static sailpoint.object.Filter wildcardToFilter(String property, String input, boolean caseInsensitive)
Transforms a wildcard like ‘a*’ to a Filter.This method cannot support mid-string cases like ‘a*a’ at this time.
- Parameters:
property
- The property being filteredinput
- The input (e.g., ‘a*’caseInsensitive
- Whether the Filter should be case-insensitive- Returns:
- A filter matching the given wildcard
-
withDefault
public static <T> T withDefault(Object maybeNull, T defaultValue, Functions.FunctionWithError<Object,T> valueProducer)
Uses the valueProducer to extract the value from the input object if it is not null, otherwise returns the default value.- Type Parameters:
T
- The return type- Parameters:
maybeNull
- An object which may be nulldefaultValue
- The value to return if the object is nullvalueProducer
- The generator of the value to return if the value is not nothing- Returns:
- The result of the value producer, or the default
-
withIterator
public static <T> void withIterator(Iterator<T> iterator, Functions.ConsumerWithError<Iterator<T>> iteratorConsumer) throws sailpoint.tools.GeneralException
Safely handles the given iterator by passing it to the Consumer and, regardless of outcome, by flushing it when the Consumer returns.- Type Parameters:
T
- The iterator type- Parameters:
iterator
- The iterator to processiteratorConsumer
- The iterator consumer, which will be invoked with the iterator- Throws:
sailpoint.tools.GeneralException
- if any failures occur
-
withIterator
public static <T> void withIterator(Functions.SupplierWithError<Iterator<T>> iteratorSupplier, Functions.ConsumerWithError<Iterator<T>> iteratorConsumer) throws sailpoint.tools.GeneralException
Safely handles the given iterator by passing it to the Consumer and, regardless of outcome, by flushing it when the Consumer returns.- Type Parameters:
T
- The iterator type- Parameters:
iteratorSupplier
- The iterator supplier, which will be invoked onceiteratorConsumer
- The iterator consumer, which will be invoked with the iterator- Throws:
sailpoint.tools.GeneralException
- if any failures occur
-
withJavaLock
public static void withJavaLock(Lock lock, Callable<?> callback) throws sailpoint.tools.GeneralException
Obtains the lock, then executes the callback- Parameters:
lock
- The lock to lock before doing the executioncallback
- The callback to invoke after locking- Throws:
sailpoint.tools.GeneralException
- if any failures occur or if the lock is interrupted
-
withJavaTimeoutLock
public static void withJavaTimeoutLock(Lock lock, long timeoutMillis, Callable<?> callback) throws sailpoint.tools.GeneralException
Obtains the lock, then executes the callback- Parameters:
lock
- The lock to lock before doing the executiontimeoutMillis
- The timeout for the lock, in millisecondscallback
- The callback to invoke after locking- Throws:
sailpoint.tools.GeneralException
- if any failures occur or if the lock is interrupted
-
withNoCommitConnection
public static void withNoCommitConnection(sailpoint.api.SailPointContext context, Functions.ConnectionHandler consumer) throws sailpoint.tools.GeneralException
Creates a new database connection using the context provided, sets its auto-commit flag to false, then passes it to the consumer provided.The consumer is responsible for committing.
- Parameters:
context
- The context to produce the connectionconsumer
- The consumer lambda or class to handle the connection- Throws:
sailpoint.tools.GeneralException
- on failures
-
withPersistentLock
public static <V extends sailpoint.object.SailPointObject> void withPersistentLock(sailpoint.api.SailPointContext context, Class<V> sailpointClass, String id, int timeoutSeconds, Functions.ConsumerWithError<V> callback) throws sailpoint.tools.GeneralException
Obtains a persistent lock on the object (sets lock = 1 in the DB), then executes the callback.The lock will have a duration of 1 minute, so you should ensure that your operation is relatively short.
- Parameters:
context
- The Sailpoint contextsailpointClass
- The Sailpoint class to lockid
- The ID of the Sailpoint objecttimeoutSeconds
- How long to wait, in seconds, before throwingObjectAlreadyLockedException
callback
- The callback to invoke after locking which will be called with the locked object- Throws:
sailpoint.tools.GeneralException
- if any failures occur or if the lock is interrupted
-
withPrivateContext
public static void withPrivateContext(bsh.This bshThis, String methodName) throws sailpoint.tools.GeneralException
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.- Parameters:
bshThis
- The ‘this’ object from the current Beanshell scriptmethodName
- The callback method name to invoke after creating the private context- Throws:
sailpoint.tools.GeneralException
- on any Beanshell failures
-
withPrivateContext
public static void withPrivateContext(bsh.This bshThis, String methodName, List<Object> params) throws sailpoint.tools.GeneralException
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.The ‘params’ will be appended to the method call. The first argument to the Beanshell method will be the SailPointContext, and the remaining arguments will be the parameters.
- Parameters:
bshThis
- The ‘this’ object from the current Beanshell scriptmethodName
- The callback method name to invoke after creating the private contextparams
- Any other parameters to pass to the Beanshell method- Throws:
sailpoint.tools.GeneralException
- on any Beanshell failures
-
withPrivateContext
public static void withPrivateContext(Functions.ConsumerWithError<sailpoint.api.SailPointContext> runner) throws sailpoint.tools.GeneralException
Begins a private, temporary SailpointContext session and then invokes the given Consumer as a callback.The Consumer’s input will be the temporary context.
- Parameters:
runner
- The runner- Throws:
sailpoint.tools.GeneralException
- if anything fails at any point
-
withPrivateContext
public static <T> T withPrivateContext(Functions.FunctionWithError<sailpoint.api.SailPointContext,T> runner) throws sailpoint.tools.GeneralException
Begins a private, temporary SailpointContext session and then invokes the given Function as a callback.The Function’s input will be the temporary context. The result of the Function will be returned.
- Type Parameters:
T
- The output type of the function- Parameters:
runner
- A function that performs some action and returns a value- Returns:
- The value returned from the runner
- Throws:
sailpoint.tools.GeneralException
- if anything fails at any point
-
withPrivateContextIterate
public static void withPrivateContextIterate(bsh.This bshThis, String methodName, Collection<Object> params) throws sailpoint.tools.GeneralException
Begins a private, temporary SailpointContext session and then calls the given Beanshell method within the previous Beanshell environment.Each item in the ‘params’ list will be passed individually, so the method is expected to take two arguments: the context and the Object.
- Parameters:
bshThis
- The ‘this’ object from the current Beanshell scriptmethodName
- The callback method name to invoke after creating the private contextparams
- Any other parameters to pass to the Beanshell method- Throws:
sailpoint.tools.GeneralException
- on any Beanshell failures
-
withTransactionLock
public static <V extends sailpoint.object.SailPointObject> void withTransactionLock(sailpoint.api.SailPointContext context, Class<V> sailpointClass, String id, int timeoutSeconds, Functions.ConsumerWithError<V> callback) throws sailpoint.tools.GeneralException
Obtains a transaction lock on the object (selects it ‘for update’), then executes the callback.- Type Parameters:
V
- The type of the SailPointObject to lock- Parameters:
context
- The Sailpoint contextsailpointClass
- The Sailpoint class to lockid
- The ID of the Sailpoint objecttimeoutSeconds
- How long to wait, in seconds, before throwingObjectAlreadyLockedException
callback
- The callback to invoke after locking- Throws:
sailpoint.tools.GeneralException
- if any failures occur or if the lock is interrupted
-
-