001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3.tuple;
018
019import java.util.Objects;
020
021/**
022 * An immutable triple consisting of three {@link Object} elements.
023 *
024 * <p>Although the implementation is immutable, there is no restriction on the objects
025 * that may be stored. If mutable objects are stored in the triple, then the triple
026 * itself effectively becomes mutable.</p>
027 *
028 * <p>#ThreadSafe# if all three objects are thread-safe</p>
029 *
030 * @param <L> the left element type
031 * @param <M> the middle element type
032 * @param <R> the right element type
033 *
034 * @since 3.2
035 */
036public class ImmutableTriple<L, M, R> extends Triple<L, M, R> {
037
038    /**
039     * An empty array.
040     * <p>
041     * Consider using {@link #emptyArray()} to avoid generics warnings.
042     * </p>
043     *
044     * @since 3.10.
045     */
046    public static final ImmutableTriple<?, ?, ?>[] EMPTY_ARRAY = {};
047
048    /**
049     * An immutable triple of nulls.
050     */
051    // This is not defined with generics to avoid warnings in call sites.
052    @SuppressWarnings("rawtypes")
053    private static final ImmutableTriple NULL = new ImmutableTriple<>(null, null, null);
054
055    /** Serialization version */
056    private static final long serialVersionUID = 1L;
057
058    /**
059     * Returns the empty array singleton that can be assigned without compiler warning.
060     *
061     * @param <L> the left element type
062     * @param <M> the middle element type
063     * @param <R> the right element type
064     * @return the empty array singleton that can be assigned without compiler warning.
065     *
066     * @since 3.10.
067     */
068    @SuppressWarnings("unchecked")
069    public static <L, M, R> ImmutableTriple<L, M, R>[] emptyArray() {
070        return (ImmutableTriple<L, M, R>[]) EMPTY_ARRAY;
071    }
072
073    /**
074     * Returns an immutable triple of nulls.
075     *
076     * @param <L> the left element of this triple. Value is {@code null}.
077     * @param <M> the middle element of this triple. Value is {@code null}.
078     * @param <R> the right element of this triple. Value is {@code null}.
079     * @return an immutable triple of nulls.
080     * @since 3.6
081     */
082    @SuppressWarnings("unchecked")
083    public static <L, M, R> ImmutableTriple<L, M, R> nullTriple() {
084        return NULL;
085    }
086
087    /**
088     * Obtains an immutable triple of three objects inferring the generic types.
089     *
090     * <p>This factory allows the triple to be created using inference to
091     * obtain the generic types.</p>
092     *
093     * @param <L> the left element type
094     * @param <M> the middle element type
095     * @param <R> the right element type
096     * @param left  the left element, may be null
097     * @param middle  the middle element, may be null
098     * @param right  the right element, may be null
099     * @return a triple formed from the three parameters, not null
100     */
101    public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
102        return left != null | middle != null || right != null ? new ImmutableTriple<>(left, middle, right) : nullTriple();
103    }
104
105    /**
106     * Obtains an immutable triple of three non-null objects inferring the generic types.
107     *
108     * <p>This factory allows the triple to be created using inference to
109     * obtain the generic types.</p>
110     *
111     * @param <L> the left element type
112     * @param <M> the middle element type
113     * @param <R> the right element type
114     * @param left  the left element, may not be null
115     * @param middle  the middle element, may not be null
116     * @param right  the right element, may not be null
117     * @return a triple formed from the three parameters, not null
118     * @throws NullPointerException if any input is null
119     * @since 3.13.0
120     */
121    public static <L, M, R> ImmutableTriple<L, M, R> ofNonNull(final L left, final M middle, final R right) {
122        return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(middle, "middle"), Objects.requireNonNull(right, "right"));
123    }
124
125    /** Left object */
126    public final L left;
127    /** Middle object */
128    public final M middle;
129
130    /** Right object */
131    public final R right;
132
133    /**
134     * Create a new triple instance.
135     *
136     * @param left  the left value, may be null
137     * @param middle the middle value, may be null
138     * @param right  the right value, may be null
139     */
140    public ImmutableTriple(final L left, final M middle, final R right) {
141        this.left = left;
142        this.middle = middle;
143        this.right = right;
144    }
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override
150    public L getLeft() {
151        return left;
152    }
153
154    /**
155     * {@inheritDoc}
156     */
157    @Override
158    public M getMiddle() {
159        return middle;
160    }
161
162    /**
163     * {@inheritDoc}
164     */
165    @Override
166    public R getRight() {
167        return right;
168    }
169}
170