Class Bag<AV extends AttributeValue>

  • Type Parameters:
    AV - type of every element in the bag
    All Implemented Interfaces:
    Iterable<AV>, Value
    Direct Known Subclasses:
    AttributeBag

    public class Bag<AV extends AttributeValue>
    extends Object
    implements Value, Iterable<AV>
    Bag of values (elements) as defined in §7.3.2 of XACML core specification (Attribute bags): The values in a bag are not ordered, and some of the values may be duplicates. There SHALL be no notion of a bag containing bags, or a bag containing values of differing types; i.e., a bag in XACML SHALL contain only values that are of the same data-type. Note that this is consistent with the mathematical definition of a bag a.k.a. multiset.

    All implementations of this interface must override all the methods of this class except the final ones (this class only throws UnsupportedOperationException for these), and guarantee the immutability of their bag instances. In particular, iterator() must return an immutable Iterator ( not supported. It is required to ensure that values of a given attribute remain constant during an evaluation of a request, as mandated by the XACML spec, section 7.3.5:

    "Regardless of any dynamic modifications of the request context during policy evaluation, the PDP SHALL behave as if each bag of attribute values is fully populated in the context before it is first tested, and is thereafter immutable during evaluation. (That is, every subsequent test of that attribute shall use the same bag of values that was initially tested.)"

    equals(Object) are implemented according to the mathematical definition of bag/multiset, and hashCode() accordingly. Note that multiplicity matters in multisets, therefore this is different from XACML set-equals function which ignores duplicates.

    NB for developers: we could make this class abstract and let subclasses implement methods except the ones with 'final' modifier. However, we need a common Bag superclass (esp. for internal subclasses in Bags) that is concrete, in order to use it as the Class instance returned by Object.getClass() and be able to use it in BagDatatype.cast(Value) to cast any bag instance.

    • Constructor Detail

      • Bag

        protected Bag​(Datatype<AV> elementDatatype,
                      com.google.common.collect.ImmutableMultiset<AV> elements)
        Constructor
        Parameters:
        elementDatatype - bag element datatype (non-null)
        elements - bag elements (non-null)
    • Method Detail

      • getElementDatatype

        public final Datatype<AV> getElementDatatype()
        Get this bag's element datatype (datatype of every element in the bag)
        Returns:
        this bag's element datatype
      • equals

        public final boolean equals​(Object other)
        Compares the element data-types, and calls equals() on the elements(), therefore Multiset.equals(Object), which complies with the mathematical definition of multisets and XACML spec for bags. Note that this is different from XACML set-equals function which does not consider the multiplicity of elements like multisets.
        Overrides:
        equals in class Object
      • hashCode

        public final int hashCode()
        Override Object#hashCode() to apply XACML spec §7.3.2: "The values in a bag are not ordered, and some of the values may be duplicates"
        Overrides:
        hashCode in class Object
      • isEmpty

        public final boolean isEmpty()
        Returns true iff the bag contains no value
        Returns:
        true iff the bag contains no value
      • size

        public final int size()
        Get bag size
        Returns:
        bag size
      • contains

        public final boolean contains​(AV v)
        Returns true if this bag contains the specified element. More formally, returns true if and only if this bag contains at least one element e such that (v==null ? e==null : v.equals(e)).
        Parameters:
        v - element whose presence in this bag is to be tested
        Returns:
        true if this collection contains the specified element
      • elements

        public final com.google.common.collect.Multiset<AV> elements()
        Get all elements in the bag.

        Beware the non-null: implementations must return an empty multiset and not null if the bag is empty.

        Returns:
        all elements as a non-null multiset
      • getSingleElement

        public AV getSingleElement()
        Get the single element in the bag if it is a singleton
        Returns:
        the one-and-only one element in the bag; null if bag is empty or contains multiple elements
      • getReasonWhyEmpty

        public IndeterminateEvaluationException getReasonWhyEmpty()
        Get the reason why isEmpty() returns true iff it does; or null if it doesn't or if reason is unknown.
        Returns:
        reason why the bag is empty, if it is. NB: cannot be declared static because overridden by various empty Bag subclasses using member attributes