Class HybridObjectMatcher

  • All Implemented Interfaces:
    sailpoint.object.Filter.FilterVisitor, sailpoint.search.Matcher

    public class HybridObjectMatcher
    extends sailpoint.search.HybridReflectiveMatcher
    This class implements an extension to SailPoint’s most advanced matcher, the HybridReflectiveMatcher, permitting in-memory matching of arbitrary SailPointObjects.

    It can consume an arbitrary Filter, like all other Matcher implementations, but supports a greater variety of filters than any OOTB Matcher implementation.

    The match semantics for this class are intended to be close to Sailpoint’s Hibernate filters. For example, collection-valued properties will match single values they contain using a Filter.eq(String, Object) filter. This means can still do links.application.name == “Active Directory”. (This requires special handling because ‘links.application.name’ resolves to a List, which is not equal to a String. In Hibernate, it resolves to an ‘exists’ SQL query. In this class, it is treated as a ‘list contains’.)

    The property lookup in this class uses Utilities.getProperty(Object, String), allowing any semantics of that method’s path syntax. Indexed variables may be used to get entries within list or map properties, such as affiliations[0]. Null references are also gracefully ignored without error.

    SailPoint’s filters have a syntax limitation around array indexing, e.g. links[0], and the Filter.compile() API requires valid identifiers at every point in a path. This means that a path like ‘links[0]’ will fail to compile with an exception. To work around this, you can pass an index in your path as ‘_X’, e.g. ‘links._0.name’ for index 0. However, If you build the Filter in code, such as with Filter.eq, you can safely use ‘forbidden’ syntax like links[0].


    If a database lookup is needed, such as a subquery, it will be done transparently (this is the “hybrid” aspect and it mostly delegates to the superclass), but they are avoided if possible. Subquery filters are restricted to database-friendly properties, as they always need to perform a live query. Collection-criteria filters may or may not have such a restriction, depending on the collection.

    IMPORTANT: The state in memory may differ from database state, such as if changes have not been committed, so use caution when invoking hybrid queries.

    Filter.collectionCondition(String, Filter) is NOT supported and will throw an exception.


    If you invoke the constructor with ‘allowObjectPropertyEquals’, then special self-referential behavior is enabled in ‘eq’, ‘in’, ‘ne’, and ‘containsAll’ Filters. If the equality check fails against the literal value, the matcher will assume that the value is a property on the original context object. That property’s value is retrieved and the comparison is repeated. This isn’t something that will come up often, but there is no substitute when it does.


    IMPORTANT IMPORTANT IMPORTANT!!! MAINTAINER NOTE: Do not modify this class unless you know what you are doing, because this matcher sits behind FakeContext, which itself is behind the offline IIQCommon tests. You may break the offline tests. Verify everything.

    • Field Summary

      • Fields inherited from class sailpoint.search.JavaMatcher

        evaluationStack, filter, matchCompleted, matchedValues, objectToMatch
    • Constructor Summary

      Constructors 
      Constructor Description
      HybridObjectMatcher​(sailpoint.api.SailPointContext context, sailpoint.object.Filter filter)
      Constructor for the basic case where defaults are used for allowObjectPropertyEquals (false) and tolerantPaths (true)
      HybridObjectMatcher​(sailpoint.api.SailPointContext context, sailpoint.object.Filter filter, boolean allowObjectPropertyEquals)
      Constructor allowing the user to specify whether to allow object properties in equals
      HybridObjectMatcher​(sailpoint.api.SailPointContext context, sailpoint.object.Filter filter, boolean allowObjectPropertyEquals, boolean tolerantPaths)
      Constructor allowing the user to specify all boolean options
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      Object getPropertyValue​(sailpoint.object.Filter.LeafFilter leaf, Object o)
      Walk the property tree and also resolve certain types of objects nested.
      boolean matches​(Object o)
      Returns true if the properties of the input object satisfy this Matcher’s Filter.
      void visitContainsAll​(sailpoint.object.Filter.LeafFilter filter)
      Handles the ‘containsAll’ filter type.
      void visitEQ​(sailpoint.object.Filter.LeafFilter filter)
      Extends the OOTB behavior of ‘equals’ Filters for a couple of specific cases.
      void visitIn​(sailpoint.object.Filter.LeafFilter filter)
      Performs the ‘in’ Filter operation, checking whether the value of the given property is in the specified list of values.
      void visitLike​(sailpoint.object.Filter.LeafFilter filter)
      Performs a ‘like’ evaluation, which includes starts-with, contains, and ends-with.
      void visitNE​(sailpoint.object.Filter.LeafFilter filter)
      Performs a ‘ne’ (not equals) evaluation.
      void visitSubquery​(sailpoint.object.Filter.LeafFilter filter)
      Performs a subquery against the database.
      • Methods inherited from class sailpoint.search.JavaMatcher

        getMatchedValues, visitAnd, visitGE, visitGT, visitIsEmpty, visitIsNull, visitLE, visitLT, visitNot, visitNotNull, visitOr
      • Methods inherited from class sailpoint.object.Filter.BaseFilterVisitor

        visitCollectionCondition, visitJoin, visitLeftJoin
    • Constructor Detail

      • HybridObjectMatcher

        public HybridObjectMatcher​(sailpoint.api.SailPointContext context,
                                   sailpoint.object.Filter filter)
        Constructor for the basic case where defaults are used for allowObjectPropertyEquals (false) and tolerantPaths (true)
        Parameters:
        context - The Sailpoint context
        filter - The filter to evaluate
      • HybridObjectMatcher

        public HybridObjectMatcher​(sailpoint.api.SailPointContext context,
                                   sailpoint.object.Filter filter,
                                   boolean allowObjectPropertyEquals)
        Constructor allowing the user to specify whether to allow object properties in equals
        Parameters:
        context - The Sailpoint context
        filter - The filter to evaluate
        allowObjectPropertyEquals - If true, object property comparisons will be allowed
      • HybridObjectMatcher

        public HybridObjectMatcher​(sailpoint.api.SailPointContext context,
                                   sailpoint.object.Filter filter,
                                   boolean allowObjectPropertyEquals,
                                   boolean tolerantPaths)
        Constructor allowing the user to specify all boolean options
        Parameters:
        context - The Sailpoint context
        filter - The filter to evaluate
        allowObjectPropertyEquals - If true, object property comparisons will be allowed
        tolerantPaths - If true, walking paths resulting in an exception (e.g., can’t read an object from the database) partway down the path will return null instead
    • Method Detail

      • getPropertyValue

        public Object getPropertyValue​(sailpoint.object.Filter.LeafFilter leaf,
                                       Object o)
                                throws sailpoint.tools.GeneralException
        Walk the property tree and also resolve certain types of objects nested.
        Overrides:
        getPropertyValue in class sailpoint.search.ReflectiveMatcher
        Parameters:
        leaf - The filter from which to get the information
        o - The object to initially walk from
        Returns:
        The property value associated with the path
        Throws:
        sailpoint.tools.GeneralException - If any lookup failures occur during path walking
      • matches

        public boolean matches​(Object o)
                        throws sailpoint.tools.GeneralException
        Returns true if the properties of the input object satisfy this Matcher’s Filter.

        Filter property names should be specified in the path syntax supported by Utilities.getProperty(Object, String).

        Specified by:
        matches in interface sailpoint.search.Matcher
        Overrides:
        matches in class sailpoint.search.JavaMatcher
        Throws:
        sailpoint.tools.GeneralException
        See Also:
        JavaMatcher.matches(Object)
      • visitContainsAll

        public void visitContainsAll​(sailpoint.object.Filter.LeafFilter filter)
                              throws sailpoint.tools.GeneralException
        Handles the ‘containsAll’ filter type.

        By default, defers to the superclass.

        If the normal behavior fails to match, and allowObjectPropertyEquals is true, the relevant property is retrieved and the containsAll operation repeated against it.

        Specified by:
        visitContainsAll in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitContainsAll in class sailpoint.search.JavaMatcher
        Parameters:
        filter - The filter to evaluate
        Throws:
        sailpoint.tools.GeneralException - on failures to read the attributes in question
      • visitEQ

        public void visitEQ​(sailpoint.object.Filter.LeafFilter filter)
                     throws sailpoint.tools.GeneralException
        Extends the OOTB behavior of ‘equals’ Filters for a couple of specific cases.

        First, if the object’s property value is a Collection and the test parameter is a String or a Boolean, we check to see if the Collection contains the single value. This is the way Filters behave when translated to HQL, thanks to SQL joins, so we want to retain that behavior here.

        Second, if we have allowed object properties to be used on both sides of the ‘equals’ Filter, and there is still not a valid match, we attempt to evaluate the test argument as an object property and compare those.

        Specified by:
        visitEQ in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitEQ in class sailpoint.search.JavaMatcher
        Parameters:
        filter - The filter to check for equality
        Throws:
        sailpoint.tools.GeneralException - if an IIQ error occurs
      • visitIn

        public void visitIn​(sailpoint.object.Filter.LeafFilter filter)
                     throws sailpoint.tools.GeneralException
        Performs the ‘in’ Filter operation, checking whether the value of the given property is in the specified list of values.
        Specified by:
        visitIn in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitIn in class sailpoint.search.JavaMatcher
        Parameters:
        filter - The ‘in’ Filter
        Throws:
        sailpoint.tools.GeneralException - if anything goes wrong
      • visitLike

        public void visitLike​(sailpoint.object.Filter.LeafFilter filter)
                       throws sailpoint.tools.GeneralException
        Performs a ‘like’ evaluation, which includes starts-with, contains, and ends-with.

        This forwards to the default implementation first, then attempts to evaluate against each item in the list, as Hibernate would do.

        Specified by:
        visitLike in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitLike in class sailpoint.search.JavaMatcher
        Parameters:
        filter - The filter to evaluate
        Throws:
        sailpoint.tools.GeneralException - if anything goes wrong
      • visitNE

        public void visitNE​(sailpoint.object.Filter.LeafFilter filter)
                     throws sailpoint.tools.GeneralException
        Performs a ‘ne’ (not equals) evaluation.
        Specified by:
        visitNE in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitNE in class sailpoint.search.JavaMatcher
        Parameters:
        filter - The not-equals Filter to evaluate
        Throws:
        sailpoint.tools.GeneralException - if anything fails
      • visitSubquery

        public void visitSubquery​(sailpoint.object.Filter.LeafFilter filter)
                           throws sailpoint.tools.GeneralException
        Performs a subquery against the database.
        Specified by:
        visitSubquery in interface sailpoint.object.Filter.FilterVisitor
        Overrides:
        visitSubquery in class sailpoint.search.HybridReflectiveMatcher
        Throws:
        sailpoint.tools.GeneralException
        See Also:
        HybridReflectiveMatcher.visitSubquery(sailpoint.object.Filter.LeafFilter)