All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xlrit.gears.server.graphql.TranslationResolver Maven / Gradle / Ivy

The newest version!
package com.xlrit.gears.server.graphql;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.annotation.PostConstruct;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;

@Controller
@RequiredArgsConstructor
public class TranslationResolver {
	private static final Logger LOG = LoggerFactory.getLogger(TranslationResolver.class);

	private final ObjectMapper objectMapper;

	private ObjectNode translationsNode;

	@PostConstruct
	public void initialize() {
		translationsNode =  objectMapper.createObjectNode();
		loadTranslationResources();
	}

	private void loadTranslationResources() {
		Map> resourcesByLanguage = Arrays.stream(getTranslationResources())
			.collect(Collectors.groupingBy(this::getLanguage));

		LOG.debug("resourcesByLanguage: {}...", resourcesByLanguage);

		resourcesByLanguage.forEach((language, resources) -> {
			LOG.info("Loading translations for language '{}'...", language);
			ObjectNode languageTranslations = objectMapper.createObjectNode();
			for (Resource resource : resources) {
				LOG.info("Loading translations from {}...", resource);
				merge(languageTranslations, loadTranslationsFrom(resource));
			}
			translationsNode.set(language, languageTranslations);
		});
	}

	@SneakyThrows
	private ObjectNode loadTranslationsFrom(Resource resource) {
		try (InputStream is = resource.getInputStream()) {
			JsonNode result = objectMapper.readTree(is);
			assert result.isObject();
			return (ObjectNode) result;
		}
	}

	@SneakyThrows
	private String getLanguage(Resource resource) {
		String url = resource.getURL().toString();
		String[] parts = url.split("/");
		return parts[parts.length - 2];
	}

	@SneakyThrows
	private Resource[] getTranslationResources() {
		var patternResolver = new PathMatchingResourcePatternResolver();
		Resource[] resources = patternResolver.getResources("classpath*:/locales/*/*.json");
		LOG.debug("Matched translation resources: {}", (Object) resources);
		return resources;
	}

	@QueryMapping
	public JsonNode translations() {
		return translationsNode;
	}

	private static void merge(ObjectNode target, ObjectNode source) {
		Iterator fieldNames = source.fieldNames();
		while (fieldNames.hasNext()) {
			String fieldName = fieldNames.next();
			JsonNode sourceValue = source.get(fieldName);
			JsonNode targetValue = target.get(fieldName);

			if (targetValue == null || targetValue.isNull()) {
				target.set(fieldName, sourceValue);
			}
			else if (targetValue instanceof ObjectNode targetObj && sourceValue instanceof ObjectNode sourceObj) {
				merge(targetObj, sourceObj);
			}
		}
	}
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy