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 *      https://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>
025 * Although the implementation is immutable, there is no restriction on the objects
026 * that may be stored. If mutable objects are stored in the triple, then the triple
027 * itself effectively becomes mutable.
028 * </p>
029 *
030 * <p>
031 * #ThreadSafe# if all three objects are thread-safe.
032 * </p>
033 *
034 * @param <L> The left element type.
035 * @param <M> The middle element type.
036 * @param <R> The right element type.
037 * @since 3.2
038 */
039public class ImmutableTriple<L, M, R> extends Triple<L, M, R> {
040
041    /**
042     * An empty array.
043     * <p>
044     * Consider using {@link #emptyArray()} to avoid generics warnings.
045     * </p>
046     *
047     * @since 3.10
048     */
049    public static final ImmutableTriple<?, ?, ?>[] EMPTY_ARRAY = {};
050
051    /**
052     * An immutable triple of nulls.
053     */
054    // This is not defined with generics to avoid warnings in call sites.
055    @SuppressWarnings("rawtypes")
056    private static final ImmutableTriple NULL = new ImmutableTriple<>(null, null, null);
057
058    /** Serialization version. */
059    private static final long serialVersionUID = 1L;
060
061    /**
062     * Gets the empty array singleton that can be assigned without compiler warning.
063     *
064     * @param <L> The left element type.
065     * @param <M> The middle element type.
066     * @param <R> The right element type.
067     * @return The empty array singleton that can be assigned without compiler warning.
068     * @since 3.10
069     */
070    @SuppressWarnings("unchecked")
071    public static <L, M, R> ImmutableTriple<L, M, R>[] emptyArray() {
072        return (ImmutableTriple<L, M, R>[]) EMPTY_ARRAY;
073    }
074
075    /**
076     * Gets the immutable triple of nulls singleton.
077     *
078     * @param <L> The left element of this triple. Value is {@code null}.
079     * @param <M> The middle element of this triple. Value is {@code null}.
080     * @param <R> The right element of this triple. Value is {@code null}.
081     * @return An immutable triple of nulls.
082     * @since 3.6
083     */
084    @SuppressWarnings("unchecked")
085    public static <L, M, R> ImmutableTriple<L, M, R> nullTriple() {
086        return NULL;
087    }
088
089    /**
090     * Creates an immutable triple of three objects inferring the generic types.
091     *
092     * @param <L> The left element type.
093     * @param <M> The middle element type.
094     * @param <R> The right element type.
095     * @param left  The left element, may be null.
096     * @param middle  The middle element, may be null.
097     * @param right  The right element, may be null.
098     * @return An immutable triple formed from the three parameters, not null.
099     */
100    public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
101        return left != null | middle != null || right != null ? new ImmutableTriple<>(left, middle, right) : nullTriple();
102    }
103
104    /**
105     * Creates an immutable triple of three non-null objects inferring the generic types.
106     *
107     * @param <L> The left element type.
108     * @param <M> The middle element type.
109     * @param <R> The right element type.
110     * @param left  The left element, may not be null.
111     * @param middle  The middle element, may not be null.
112     * @param right  The right element, may not be null.
113     * @return An immutable triple formed from the three parameters, not null.
114     * @throws NullPointerException Thrown if any input is null.
115     * @since 3.13.0
116     */
117    public static <L, M, R> ImmutableTriple<L, M, R> ofNonNull(final L left, final M middle, final R right) {
118        return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(middle, "middle"), Objects.requireNonNull(right, "right"));
119    }
120
121    /** Left object. */
122
123    public final L left;
124
125    /** Middle object. */
126    public final M middle;
127
128    /** Right object. */
129    public final R right;
130
131    /**
132     * Constructs a new triple instance.
133     *
134     * @param left  The left value, may be null.
135     * @param middle The middle value, may be null.
136     * @param right  The right value, may be null.
137     */
138    public ImmutableTriple(final L left, final M middle, final R right) {
139        this.left = left;
140        this.middle = middle;
141        this.right = right;
142    }
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public L getLeft() {
149        return left;
150    }
151
152    /**
153     * {@inheritDoc}
154     */
155    @Override
156    public M getMiddle() {
157        return middle;
158    }
159
160    /**
161     * {@inheritDoc}
162     */
163    @Override
164    public R getRight() {
165        return right;
166    }
167}
168