001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2023–2025 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
006 * the License.  You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
012 * specific language governing permissions and limitations under the License.
013 */
014package org.microbean.bean;
015
016/**
017 * An interface whose implementations can be ranked numerically in descending order (the highest or greatest rank
018 * <dfn>outranks</dfn>, or wins, or trumps, or comes first).
019 *
020 * <p>In addition, an implementation may be designated as an {@linkplain #alternate() alternate}, which may affect the
021 * interpretation of the implementation's {@linkplain #rank() rank}, usually by conferring a rank that cannot be
022 * outranked by any other.</p>
023 *
024 * <p>Given a series of {@link Ranked} implementations sorted by {@linkplain #rank() rank}, the first element of the
025 * series will bear the highest, or greatest, {@linkplain #rank() rank}.</p>
026 *
027 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
028 *
029 * @see #alternate()
030 *
031 * @see #rank()
032 *
033 * @see #outranks(Ranked)
034 *
035 * @see #outranks(int)
036 *
037 * @see #outranks(int, int)
038 *
039 * @deprecated This class is deprecated for future removal.
040 */
041@Deprecated
042public interface Ranked {
043
044
045  /*
046   * Static fields.
047   */
048
049
050  /**
051   * The default rank ({@value}) when returned by an implementation of the {@link #rank()} method.
052   *
053   * @see #rank()
054   */
055  public static final int DEFAULT_RANK = 0;
056
057
058  /*
059   * Instance methods.
060   */
061
062
063  /**
064   * Returns the rank of this {@link Ranked} implementation.
065   *
066   * <p>Implementations of this method may return any integer: positive, zero, or negative.</p>
067   *
068   * <p>The default implementation of this method returns the value of the {@link #DEFAULT_RANK} field ({@value
069   * #DEFAULT_RANK}).</p>
070   *
071   * <p>Overrides of this method must return a determinate value.</p>
072   *
073   * @return the rank of this {@link Ranked} implementation
074   *
075   * @see #outranks(int, int)
076   */
077  // Highest rank wins (comes first), i.e. descending order
078  public default int rank() {
079    return DEFAULT_RANK;
080  }
081
082  /**
083   * Returns {@code true} if this {@link Ranked} is to be considered an <em>alternate</em>, which may have an effect on
084   * how the return value of the {@link #rank()} method is interpreted in some situations.
085   *
086   * <p>The default implementation of this method returns {@code false}.</p>
087   *
088   * <p>Overrides of this method must be idempotent and return a determinate value.</p>
089   *
090   * @return {@code true} if this {@link Ranked} is to be considered an <em>alternate</em>
091   */
092  public default boolean alternate() {
093    return false;
094  }
095
096  /**
097   * Returns {@code true} if this {@link Ranked} outranks the supplied {@link Ranked} according to the rules described
098   * in the {@linkplain #outranks(int, int) specification for the <code>outranks(int, int)</code> method}.
099   *
100   * <p>Overriding this method, while possible and permitted, is discouraged.</p>
101   *
102   * @param other a {@link Ranked}; may be {@code null} (in which case this method will return {@code true})
103   *
104   * @return {@code true} if this {@link Ranked} outranks the supplied {@link Ranked}
105   *
106   * @see #outranks(int, int)
107   */
108  public default boolean outranks(final Ranked other) {
109    return other == null || outranks(this.rank(), other.rank());
110  }
111
112  /**
113   * Returns {@code true} if this {@link Ranked} bears a {@linkplain #rank() rank} that outranks the rank represented by
114   * {@code j} according to the rules described in the {@linkplain #outranks(int, int) specification for the
115   * <code>outranks(int, int)</code> method}.
116   *
117   * <p>Overriding this method, while possible and permitted, is discouraged.</p>
118   *
119   * @param j a rank
120   *
121   * @return {@code true} if this {@link Ranked} bears a {@linkplain #rank() rank} that {@linkplain #outranks(int, int)
122   * outranks} the supplied rank
123   *
124   * @see #outranks(int, int)
125   */
126  public default boolean outranks(final int j) {
127    return outranks(this.rank(), j);
128  }
129
130
131  /*
132   * Static methods.
133   */
134
135
136  /**
137   * Returns {@code true} if and only if {@code r0} is non-{@code null} and {@linkplain #outranks(Ranked) outranks}
138   * {@code r1}.
139   *
140   * @param r0 a {@link Ranked}; may be {@code null} in which case {@code false} will be returned
141   *
142   * @param r1 a {@link Ranked}; may be {@code null}
143   *
144   * @return {@code true} if and only if {@code r0} is non-{@code null} and {@linkplain #outranks(Ranked) outranks}
145   * {@code r1}
146   *
147   * @see #outranks(Ranked)
148   */
149  public static boolean outranks(final Ranked r0, final Ranked r1) {
150    return r0 != null && r0.outranks(r1);
151  }
152
153  /**
154   * Returns {@code true} if and only if a rank represented by {@code i} outranks a rank represented by {@code j}.
155   *
156   * <p>Given two ranks, <em>i</em> and <em>j</em>, <em>i</em> <em>outranks</em> <em>j</em> if and only if <em>i</em> is
157   * greater than ({@code >}) <em>j</em>.</p>
158   *
159   * @param i an {@code int} representing a rank
160   *
161   * @param j an {@code int} representing a rank
162   *
163   * @return {@code true} if and only if {@code i} outranks {@code j}
164   *
165   * @microbean.idempotency This method is idempotent and deterministic.
166   *
167   * @microbean.threadsafety This method is safe for concurrent use by multiple threads.
168   */
169  public static boolean outranks(final int i, final int j) {
170    return i > j;
171  }
172
173}