Class Utilities


  • public class Utilities
    extends Object
    Static utility methods that are useful throughout any IIQ codebase, supplementing SailPoint’s Util in many places.
    • 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.
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static <S,​T extends Collection<S>>
      void
      addMapped​(Map<String,​T> map, String key, S value)
      Adds the given value to a Collection 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 case
      static void cleanVersionedCache​(String prefix, int currentVersion)
      Iterates through the CustomGlobal, 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 prompt
      static boolean containsMessage​(Throwable t, String cause)
      Returns true if the Throwable message (or any of its causes) contain the given message
      static 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-argument convertDateFormat(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 of dateDifference(Date, Date).
      static Period dateDifference​(Date firstTime, Date secondTime)
      Converts two Date objects to LocalDate at the system default time zone and returns the number of days between them.
      static <T extends sailpoint.object.SailPointObject>
      T
      detach​(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 empty
      static void ensureNotNullOrEmpty​(String value)
      Throws an exception if the string is null or empty
      static void evictRuleRunnerPool()
      Uses reflection to evict the RuleRunner pool cache
      static <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 MatchExpression
      static sailpoint.object.IdentitySelector.MatchTerm filterToMatchTerm​(sailpoint.object.Filter input)
      Transfors an input Filter into a MatchTerm
      static 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 the isNothing(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 defined
      static ConcurrentHashMap<String,​Object> getPluginVersionedGlobalMap()
      Gets a ConcurrentHashMap from CustomGlobal 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 defined
      static Object getProperty​(Object source, String paramPropertyPath)
      Gets the given property by introspection
      static 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 of ForkJoinPool.
      static <A,​B>
      boolean
      isAssignableFrom​(Class<A> parentClass, Class<B> testClass)
      Returns true if parentClass is assignable from testClass, e.g.
      static boolean isFlagNotSet​(Object flagValue)
      Returns the inverse of isFlagSet(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 to isFlagSet(Object)
      static <A,​B>
      boolean
      isNotAssignableFrom​(Class<A> parentClass, Class<B> testClass)
      Returns the inverse of isAssignableFrom(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 digits
      static boolean isNullEmptyOrWhitespace​(String input)
      Returns true if the input string is null, empty, or contains only whitespace characters according to Character.isWhitespace(char).
      static boolean isNumber​(String input)
      Returns true if this string contains only digits
      static String isoOffsetTimestamp()
      Returns the current time in the standard ISO offset (date T time+1:00) format
      static boolean isSomething​(Object thing)
      Returns true if isNothing(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>
      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.
      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 CompoundFilter
      static sailpoint.object.IdentitySelector.MatchTerm matchTerm​(String property, Object value, sailpoint.object.Application application)
      Create a MatchTerm from scratch
      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
      static 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 if Util.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 an Optional 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 safely
      static 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, returning Long.MIN_VALUE if the Date is null.
      static <A,​B>
      void
      safeForeach​(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 is
      static 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 in mapConformsToType(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 null
      static int safeSize​(Collection<?> input)
      Returns the size of the input collection, returning 0 if the collection is null
      static <T> int safeSize​(T[] input)
      Returns the size of the input array, returning 0 if the array is null
      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
      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
      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
      static String safeString​(Object whatever)
      Returns the given value as a “safe string”.
      static <T,​S extends T>
      T
      safeSubscript​(List<S> list, int index)
      Performs a safe subscript operation against the given List.
      static <T,​S extends T>
      T
      safeSubscript​(List<S> list, int index, T defaultObject)
      Performs a safe subscript operation against the given List.
      static <T,​S extends T>
      T
      safeSubscript​(S[] list, int index)
      Performs a safe subscript operation against the given array.
      static <T,​S extends T>
      T
      safeSubscript​(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 as sortMapListByKey(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>
      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.
      static Duration timeDifference​(long firstTime, long secondTime)
      Coerces the millisecond timestamps to Date objects, then invokes the API timeDifference(Date, Date).
      static Duration timeDifference​(Date firstTime, Date secondTime)
      Converts two Date objects to LocalDateTime at the system default time zone and returns the Duration between them.
      static String timestamp()
      Returns the current time in a standard format
      static 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 callback
      static void withJavaTimeoutLock​(Lock lock, long timeoutMillis, Callable<?> callback)
      Obtains the lock, then executes the callback
      static 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>
      void
      withPersistentLock​(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>
      void
      withTransactionLock​(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.
    • 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 a Collection at the given key in the map.

        If the map does not have a Collection at the given key, a new ArrayList 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 type
        T - The list element type
        Parameters:
        map - The map to modify
        key - The map key that points to the list to add the value to
        value - 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 context
        message - 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 MatchExpression
        newTerm - 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 check
        value - 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 key
        factory - 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 check
        cause - 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 input
        property - 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 check
        property - 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 input
        property - 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-argument convertDateFormat(Object, String, String, ZoneId).

        The system default ZoneId will be used.

        Parameters:
        something - The input object, which can be a string or various date objects
        inputDateFormat - The input date format, which will be applied to a string input
        outputDateFormat - 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 objects
        inputDateFormat - The input date format, which will be applied to a string input
        outputDateFormat - The output date format, which will be applied to the intermediate date
        zoneId - 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 date
        days - 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 date
        years - 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 to LocalDate 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 compare
        secondTime - 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 of dateDifference(Date, Date).
        Parameters:
        firstTimeMillis - The first time to compare
        secondTimeMillis - 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 XML
        o - 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
      • 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 type
        T - The output type
        Parameters:
        input - The input list
        property - The property to extract
        expectedType - 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 injected
        params - 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 value
        fuzzyKey - 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,​ObjectgetAttributes​(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 null
        identity - The identity to check for a time zone, or null
        Returns:
        The time zone for this user
      • getCountryNames

        public static List<StringgetCountryNames()
        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 the isNothing(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 user
        identity - 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 user
        message - 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 the CustomGlobal, 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 prefix
        currentVersion - The current object version
      • getPluginVersionedGlobalMap

        public static ConcurrentHashMap<String,​ObjectgetPluginVersionedGlobalMap()
        Gets a ConcurrentHashMap from CustomGlobal 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 invoking cleanVersionedCache(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 object
        paramPropertyPath - 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 path
        paramPropertyPath - The property path to evaluate
        gracefulNulls - 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 object
        propertyPath - 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 of ForkJoinPool.

        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 type
        B - The potential child type
        Parameters:
        parentClass - The first (parent-ish) class
        testClass - The second (child-ish) class
        Returns:
        True if parentClass is assignable from testClass
      • isFlagNotSet

        public static boolean isFlagNotSet​(Object flagValue)
        Returns the inverse of isFlagSet(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 to isFlagSet(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 of isAssignableFrom(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 type
        B - The potential child type
        Parameters:
        parentClass - The first (parent-ish) class
        testClass - 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 to Character.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 if isNothing(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 of timestamp()
        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 type
        T - The map value type
        Parameters:
        inputMap - The input map to check
        expectedKeyType - The type implemented or extended by all Map keys
        expectedValueType - 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 type
        T - 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 test
        value - The value to test
        application - 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 transform
        defaultApplication - 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 if Util.nullSafeEq(Object, Object) would return false and vice versa.

        Two null values will be considered equal.

        Parameters:
        a - The first value
        b - 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,​ObjectnullToEmpty​(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 calling nullToEmpty(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<LocalDateTimeparseDateString​(String inputString,
                                                              String format)
        Parses the input string into a LocalDateTime, returning an Optional 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 string
        format - The format used to parse the input string per DateTimeFormatter 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 modified
        prefix - 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 context
        thing - The thing to run
        params - 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 cast
        targetClass - 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 collection
        maybeSmallerCollection - 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, returning Long.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 keys
        B - The type of the map’s values
        Parameters:
        map - The map
        function - 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<StringsafeListify​(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 using safeString(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 in mapConformsToType(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 type
        T - The resulting value type
        Parameters:
        input - The input map
        keyType - The key type
        valueType - 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 from
        index - 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 from
        index - 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 given List.

        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 from
        index - 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 given List.

        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 T
        T - The expected return type
        Parameters:
        list - The List to get the value from
        index - 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 substring
        start - The start index
        end - 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 method
        attributeName - The name of the attribute to set
        value - 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 as sortMapListByKey(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 sort
        key - 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 to String.valueOf(Object). If the value is a Date, its epoch millisecond timestamp will be passed to String.valueOf(Object). Otherwise, the input will be passed to Util.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 sort
        key - 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 type
        T - The value type
        Parameters:
        target - The target Map to which the value should be inserted if missing
        key - The key to insert
        value - A supplier for the value to insert
      • timeDifference

        public static Duration timeDifference​(Date firstTime,
                                              Date secondTime)
        Converts two Date objects to LocalDateTime at the system default time zone and returns the Duration 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 compare
        secondTime - The second time to compare
        Returns:
        The Period between the two days
      • 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 a UserContext.

        Parameters:
        context - The current IIQ context
        currentUser - 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 a UserContext.

        Parameters:
        context - The current IIQ context
        currentUser - 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 string
        args - 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 filtered
        input - 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 null
        defaultValue - The value to return if the object is null
        valueProducer - 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 process
        iteratorConsumer - 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 once
        iteratorConsumer - 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 execution
        callback - 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 execution
        timeoutMillis - The timeout for the lock, in milliseconds
        callback - 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 connection
        consumer - 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 context
        sailpointClass - The Sailpoint class to lock
        id - The ID of the Sailpoint object
        timeoutSeconds - How long to wait, in seconds, before throwing ObjectAlreadyLockedException
        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 script
        methodName - 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 script
        methodName - The callback method name to invoke after creating the private context
        params - 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 script
        methodName - The callback method name to invoke after creating the private context
        params - 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 context
        sailpointClass - The Sailpoint class to lock
        id - The ID of the Sailpoint object
        timeoutSeconds - How long to wait, in seconds, before throwing ObjectAlreadyLockedException
        callback - The callback to invoke after locking
        Throws:
        sailpoint.tools.GeneralException - if any failures occur or if the lock is interrupted