org.lanternpowered.server.text.gson.JsonTextTranslatableSerializer.java Source code

Java tutorial

Introduction

Here is the source code for org.lanternpowered.server.text.gson.JsonTextTranslatableSerializer.java

Source

/*
 * This file is part of LanternServer, licensed under the MIT License (MIT).
 *
 * Copyright (c) LanternPowered <https://www.lanternpowered.org>
 * Copyright (c) SpongePowered <https://www.spongepowered.org>
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the Software), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.lanternpowered.server.text.gson;

import static org.lanternpowered.server.text.gson.TextConstants.TRANSLATABLE;
import static org.lanternpowered.server.text.gson.TextConstants.TRANSLATABLE_ARGS;

import com.google.common.collect.ImmutableList;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import io.netty.util.concurrent.FastThreadLocal;
import org.lanternpowered.server.text.LanternTextSerializer;
import org.lanternpowered.server.text.translation.MinecraftTranslation;
import org.lanternpowered.server.text.translation.TranslationManager;
import org.lanternpowered.server.util.FastThreadLocals;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.TextRepresentable;
import org.spongepowered.api.text.TranslatableText;
import org.spongepowered.api.text.serializer.TextSerializers;
import org.spongepowered.api.text.translation.Translation;

import java.lang.reflect.Type;
import java.util.Locale;

public final class JsonTextTranslatableSerializer extends JsonTextBaseSerializer
        implements JsonSerializer<TranslatableText>, JsonDeserializer<TranslatableText> {

    private final static FastThreadLocal<Locale> currentLocale = FastThreadLocals.withInitial(() -> Locale.ENGLISH);

    /**
     * Sets the current locale that should be used to translate all
     * the text components if {@link #networkingFormat} is set to true.
     * 
     * <p>This will only be applied to the current thread, so this will
     * can be used in concurrent environments.</p>
     * 
     * @param locale the locale
     */
    public static void setCurrentLocale(Locale locale) {
        currentLocale.set(locale);
    }

    /**
     * Removes the current locale that is attached to the thread, toggling
     * the locale back to the default.
     */
    public static void removeCurrentLocale() {
        currentLocale.remove();
    }

    public static Locale getCurrentLocale() {
        return currentLocale.get();
    }

    private final TranslationManager translationManager;
    private final boolean networkingFormat;
    private final boolean removeComplexity;

    JsonTextTranslatableSerializer(TranslationManager translationManager, boolean networkingFormat,
            boolean removeComplexity) {
        this.translationManager = translationManager;
        this.networkingFormat = networkingFormat;
        this.removeComplexity = removeComplexity;
    }

    @Override
    public TranslatableText deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        final JsonObject obj = element.getAsJsonObject();
        final String name = obj.get(TRANSLATABLE).getAsString();
        final Translation translation = this.translationManager.get(name);
        final Object[] arguments;
        if ((element = obj.get(TRANSLATABLE_ARGS)) != null) {
            final Text[] with = context.deserialize(element, Text[].class);
            arguments = new Object[with.length];
            System.arraycopy(with, 0, arguments, 0, with.length);
        } else {
            arguments = new Object[0];
        }
        final TranslatableText.Builder builder = Text.builder(translation, arguments);
        deserialize(obj, builder, context);
        return builder.build();
    }

    @SuppressWarnings("deprecation")
    @Override
    public JsonElement serialize(TranslatableText src, Type typeOfSrc, JsonSerializationContext context) {
        final Translation translation = src.getTranslation();
        if (this.networkingFormat && !(translation instanceof MinecraftTranslation)) {
            final ImmutableList<Object> arguments = src.getArguments();
            final Object[] rawArguments = arguments.toArray(new Object[arguments.size()]);
            final Locale locale = currentLocale.get();
            for (int i = 0; i < rawArguments.length; i++) {
                Object object = rawArguments[i];
                if (object instanceof TextRepresentable) {
                    if (!(object instanceof Text)) {
                        object = ((TextRepresentable) object).toText();
                    }
                    rawArguments[i] = ((LanternTextSerializer) TextSerializers.LEGACY_FORMATTING_CODE)
                            .serialize((Text) object, locale);
                } else {
                    rawArguments[i] = object.toString();
                }
            }
            final String content = src.getTranslation().get(locale, rawArguments);
            return JsonTextLiteralSerializer.serializeLiteralText(src, content, context, this.removeComplexity);
        }
        final JsonObject obj = new JsonObject();
        obj.addProperty(TRANSLATABLE, src.getTranslation().getId());
        final ImmutableList<Object> arguments = src.getArguments();
        if (!arguments.isEmpty()) {
            final JsonArray argumentsArray = new JsonArray();
            for (Object object : arguments) {
                // Only primitive strings and text json is allowed,
                // so we need to convert the objects if possible
                if (object instanceof TextRepresentable) {
                    if (!(object instanceof Text)) {
                        object = ((TextRepresentable) object).toText();
                    }
                    argumentsArray.add(context.serialize(object, Text.class));
                } else {
                    argumentsArray.add(new JsonPrimitive(object.toString()));
                }
            }
            obj.add(TRANSLATABLE_ARGS, argumentsArray);
        }
        serialize(obj, src, context);
        return obj;
    }

}