001package com.identityworksllc.iiq.common;
002
003import sailpoint.tools.GeneralException;
004
005import java.io.Serializable;
006import java.util.ArrayList;
007import java.util.List;
008import java.util.Objects;
009import java.util.StringJoiner;
010
011/**
012 * Extends Pair by adding one more item
013 *
014 * @param <A> The first item type
015 * @param <B> The second item type
016 * @param <C> The third item type
017 */
018public class Triple<A, B, C> implements Serializable {
019    /**
020     * Constructs a new triple of the three items given
021     *
022     * @param first The first time
023     * @param second The second item
024     * @param third The third item
025     *
026     * @return A typed Triple containing those three items
027     */
028    public static <X, Y, Z> Triple<X, Y, Z> of(X first, Y second, Z third) {
029        return new Triple<>(first, second, third);
030    }
031
032    /**
033     * The first item in the triple
034     */
035    private final A first;
036
037    /**
038     * The second item in the triple
039     */
040    private final B second;
041
042    /**
043     * The third item in the triple
044     */
045    private final C third;
046
047    /**
048     * Creates a new Triple of the three given values
049     */
050    private Triple(A a, B b, C c) {
051        this.first = a;
052        this.second = b;
053        this.third = c;
054    }
055
056    @Override
057    public boolean equals(Object o) {
058        if (this == o) return true;
059        if (o == null || getClass() != o.getClass()) return false;
060        Triple<?, ?, ?> triple = (Triple<?, ?, ?>) o;
061        return Objects.equals(first, triple.first) && Objects.equals(second, triple.second) && Objects.equals(third, triple.third);
062    }
063
064    /**
065     * Gets the first item
066     * @return The first item
067     */
068    public A getFirst() {
069        return first;
070    }
071
072    /**
073     * Gets the second item
074     * @return The second item
075     */
076    public B getSecond() {
077        return second;
078    }
079
080    /**
081     * Gets the third item
082     * @return The third item
083     */
084    public C getThird() {
085        return third;
086    }
087
088    @Override
089    public int hashCode() {
090        return Objects.hash(first, second, third);
091    }
092
093    /**
094     * Maps this object to another value using the given TriFunction or lambda equivalent.
095     *
096     * @param mapping The mapping to apply
097     * @return The output of the mapping
098     * @param <R> The output type, defined by the mapping object's type
099     * @throws GeneralException if anything fails during mapping
100     */
101    public <R> R map(TriFunction<? super A, ? super B, ? super C, R> mapping) throws GeneralException {
102        return mapping.apply(getFirst(), getSecond(), getThird());
103    }
104
105    @Override
106    public String toString() {
107        return new StringJoiner(", ", Triple.class.getSimpleName() + "[", "]")
108                .add("first=" + first)
109                .add("second=" + second)
110                .add("third=" + third)
111                .toString();
112    }
113}