001/*
002 * Copyright 2017-2022 Product Mog LLC, 2022-2026 Revetware LLC.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * 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
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.lokalized;
018
019import org.jspecify.annotations.NonNull;
020import org.jspecify.annotations.Nullable;
021
022import javax.annotation.concurrent.ThreadSafe;
023
024import static java.util.Objects.requireNonNull;
025
026/**
027 * Response returned by a {@link TranslationFailureHandler}.
028 *
029 * @author <a href="https://revetkn.com">Mark Allen</a>
030 * @since 3.0.0
031 */
032@ThreadSafe
033public final class TranslationFailureResponse {
034        @NonNull
035        private static final TranslationFailureResponse RETURN_KEY;
036        @NonNull
037        private static final TranslationFailureResponse THROW_EXCEPTION;
038
039        static {
040                RETURN_KEY = new TranslationFailureResponse(Action.RETURN_KEY, null);
041                THROW_EXCEPTION = new TranslationFailureResponse(Action.THROW_EXCEPTION, null);
042        }
043
044        @NonNull
045        private final Action action;
046        @Nullable
047        private final String translation;
048
049        private TranslationFailureResponse(@NonNull Action action, @Nullable String translation) {
050                requireNonNull(action);
051
052                this.action = action;
053                this.translation = translation;
054        }
055
056        /**
057         * Returns the lookup key itself after interpolating supplied placeholders into it.
058         *
059         * @return the response, not null
060         */
061        @NonNull
062        public static TranslationFailureResponse returnKey() {
063                return RETURN_KEY;
064        }
065
066        /**
067         * Returns a caller-specified string.
068         *
069         * @param translation translation to return, not null
070         * @return the response, not null
071         */
072        @NonNull
073        public static TranslationFailureResponse returnString(@NonNull String translation) {
074                requireNonNull(translation);
075                return new TranslationFailureResponse(Action.RETURN_STRING, translation);
076        }
077
078        /**
079         * Throws an exception for the failed lookup.
080         * <p>
081         * Resolution failures rethrow their original runtime cause. Missing translations and lookups for which no
082         * alternative matched throw {@link MissingTranslationException}.
083         *
084         * @return the response, not null
085         */
086        @NonNull
087        public static TranslationFailureResponse throwException() {
088                return THROW_EXCEPTION;
089        }
090
091        @NonNull
092        Action getAction() {
093                return action;
094        }
095
096        @NonNull
097        String getTranslation() {
098                if (translation == null)
099                        throw new IllegalStateException("No translation is available for this response");
100
101                return translation;
102        }
103
104        enum Action {
105                RETURN_KEY,
106                RETURN_STRING,
107                THROW_EXCEPTION
108        }
109}