001/*
002 * Copyright 2017-2022 Product Mog LLC, 2022-2025 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 javax.annotation.Nonnull;
020import javax.annotation.concurrent.NotThreadSafe;
021import java.util.Collections;
022import java.util.HashMap;
023import java.util.Locale;
024import java.util.Map;
025
026import static java.util.Objects.requireNonNull;
027
028/**
029 * Exception thrown when no translation is found when {@link com.lokalized.DefaultStrings.FailureMode} is configured to be {@link com.lokalized.DefaultStrings.FailureMode#FAIL_FAST}.
030 * <p>
031 * In production, you would normally prefer {@link com.lokalized.DefaultStrings.FailureMode#USE_FALLBACK}.
032 * <p>
033 * This class is intended for use by a single thread.
034 *
035 * @author <a href="https://revetkn.com">Mark Allen</a>
036 */
037@NotThreadSafe
038public class MissingTranslationException extends RuntimeException {
039        @Nonnull
040        private final String key;
041        @Nonnull
042        private final Locale locale;
043        @Nonnull
044        private final Map<String, Object> placeholders;
045
046        /**
047         * Constructs a new exception with the unsupported locale.
048         *
049         * @param locale the unsupported locale which triggered this exception, not null
050         */
051        public MissingTranslationException(@Nonnull String message,
052                                                                                                                                                 @Nonnull String key,
053                                                                                                                                                 @Nonnull Map<String, Object> placeholders,
054                                                                                                                                                 @Nonnull Locale locale) {
055                super(requireNonNull(message));
056
057                requireNonNull(key);
058                requireNonNull(placeholders);
059                requireNonNull(locale);
060
061                this.key = key;
062                this.placeholders = Collections.unmodifiableMap(new HashMap<>(placeholders));
063                this.locale = locale;
064        }
065
066        /**
067         * The translation key that triggered this exception.
068         *
069         * @return the translation key, not null
070         */
071        @Nonnull
072        public String getKey() {
073                return this.key;
074        }
075
076        /**
077         * The placeholders specified for the failed translation attempt.
078         *
079         * @return the placeholders, not null
080         */
081        @Nonnull
082        public Map<String, Object> getPlaceholders() {
083                return this.placeholders;
084        }
085
086        /**
087         * The locale that triggered this exception.
088         *
089         * @return the locale, not null
090         */
091        @Nonnull
092        public Locale getLocale() {
093                return this.locale;
094        }
095}