Search in sources :

Example 1 with MOCI18n

use of eu.okaeri.i18n.configs.impl.MOCI18n in project okaeri-platform by OkaeriPoland.

the class MessagesComponentResolver method make.

@Override
@SuppressWarnings({ "unchecked", "ResultOfMethodCallIgnored" })
public Object make(@NonNull ComponentCreator creator, @NonNull BeanManifest manifest, @NonNull Injector injector) {
    if (!LocaleConfig.class.isAssignableFrom(manifest.getType())) {
        throw new IllegalArgumentException("Component of @Messages on type requires class to be a LocaleConfig: " + manifest);
    }
    Placeholders defaultPlaceholders = injector.getExact("placeholders", Placeholders.class).orElseThrow(() -> new IllegalArgumentException("cannot find placeholders required for @Messages"));
    long start = System.currentTimeMillis();
    Class<? extends LocaleConfig> beanClazz = (Class<? extends LocaleConfig>) manifest.getType();
    Messages messages = beanClazz.getAnnotation(Messages.class);
    String path = messages.path();
    String suffix = messages.suffix();
    Class<? extends Configurer> provider = messages.provider();
    Locale defaultLocale = Locale.forLanguageTag(messages.defaultLocale());
    boolean unpack = messages.unpack();
    File directory = new File(this.dataFolder, path);
    boolean directoryExisted = directory.exists();
    Map<Locale, String> packedLocales = new LinkedHashMap<>();
    if (unpack) {
        directory.mkdirs();
    }
    // unpack files from the resources
    try {
        JarFile jarFile = new JarFile(this.jarFile);
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry jarEntry = entries.nextElement();
            String entryName = jarEntry.getName();
            if (!entryName.startsWith(path + "/") || entryName.endsWith("/")) {
                continue;
            }
            File file = new File(this.dataFolder, entryName);
            if (file.exists()) {
                continue;
            }
            InputStream is = jarFile.getInputStream(jarEntry);
            FileOutputStream fos = (unpack && !directoryExisted) ? new FileOutputStream(file) : null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while (is.available() > 0) {
                int read = is.read();
                if (fos != null)
                    fos.write(read);
                baos.write(read);
            }
            if (fos != null)
                fos.close();
            is.close();
            String name = file.getName();
            String localeName = name.substring(0, name.length() - suffix.length());
            Locale locale = Locale.forLanguageTag(localeName);
            packedLocales.put(locale, new String(baos.toByteArray(), StandardCharsets.UTF_8));
        }
    } catch (IOException exception) {
        throw new RuntimeException("Failed to unpack resources", exception);
    }
    // prepare serdes
    OkaeriSerdesPack[] serdesPacks = Stream.of(this.defaultConfigurerSerdes).map(injector::createInstance).distinct().toArray(OkaeriSerdesPack[]::new);
    // load file locales
    try {
        LocaleConfig template = LocaleConfigManager.createTemplate(beanClazz);
        File[] files = directory.listFiles((dir, name) -> name.toLowerCase(Locale.ROOT).endsWith(suffix));
        if (files == null)
            files = new File[0];
        MOCI18n i18n = new MOCI18n();
        i18n.setDefaultLocale(defaultLocale);
        i18n.registerLocaleProvider(this.i18nLocaleProvider);
        i18n.setPlaceholders(defaultPlaceholders.copy());
        List<Locale> loadedLocales = new ArrayList<>();
        injector.registerInjectable(path, template);
        // check path directory for locale files
        for (File file : files) {
            // read locale from name
            String name = file.getName();
            String localeName = name.substring(0, name.length() - suffix.length());
            Locale locale = Locale.forLanguageTag(localeName);
            // create configurer
            Configurer configurer = (provider == Messages.DEFAULT.class) ? this.defaultConfigurerProvider.get() : injector.createInstance(provider);
            // register
            LocaleConfig localeConfig = LocaleConfigManager.create(beanClazz, configurer, file, !defaultLocale.equals(locale));
            i18n.registerConfig(locale, localeConfig);
            creator.increaseStatistics("localeConfigs", 1);
            loadedLocales.add(locale);
        }
        // load packes locales
        for (Map.Entry<Locale, String> entry : packedLocales.entrySet()) {
            // gather data
            Locale locale = entry.getKey();
            String configString = entry.getValue();
            // already loaded from file
            if (loadedLocales.contains(locale))
                continue;
            // create configurer
            Configurer configurer = (provider == Messages.DEFAULT.class) ? this.defaultConfigurerProvider.get() : injector.createInstance(provider);
            // register
            LocaleConfig localeConfig = ConfigManager.create(beanClazz, (it) -> {
                it.withConfigurer(configurer);
                if (!defaultLocale.equals(locale))
                    it.getDeclaration().getFields().forEach((field) -> field.updateValue(null));
                it.load(configString);
            });
            i18n.registerConfig(locale, localeConfig);
            creator.increaseStatistics("localeConfigs", 1);
            loadedLocales.add(locale);
        }
        // default locale was not overwritten by a file
        if (!loadedLocales.contains(defaultLocale)) {
            // create configurer
            Configurer configurer = (provider == Messages.DEFAULT.class) ? this.defaultConfigurerProvider.get() : injector.createInstance(provider);
            // register default locale based on interface values
            LocaleConfig defaultLocaleConfig = ConfigManager.create(beanClazz, it -> {
                it.withBindFile(new File(directory, messages.defaultLocale() + suffix));
                it.withConfigurer(configurer);
                if (unpack && !directoryExisted)
                    it.saveDefaults();
            });
            i18n.registerConfig(defaultLocale, defaultLocaleConfig);
            creator.increaseStatistics("localeConfigs", 1);
            loadedLocales.add(defaultLocale);
        }
        long took = System.currentTimeMillis() - start;
        creator.log(ComponentHelper.buildComponentMessage().type("Loaded messages").name(beanClazz.getSimpleName()).took(took).meta("path", path).meta("suffix", suffix).meta("provider", provider.getSimpleName()).footer("  > " + loadedLocales.stream().map(Locale::toString).collect(Collectors.joining(", "))).build());
        manifest.setName(path);
        return i18n;
    } catch (Exception exception) {
        throw new RuntimeException("Messages configuration load failure", exception);
    }
}
Also used : LocaleConfig(eu.okaeri.i18n.configs.LocaleConfig) java.util(java.util) PlaceholdersFactory(eu.okaeri.platform.core.placeholder.PlaceholdersFactory) JarFile(java.util.jar.JarFile) Injector(eu.okaeri.injector.Injector) Messages(eu.okaeri.platform.core.annotation.Messages) JarEntry(java.util.jar.JarEntry) Configurer(eu.okaeri.configs.configurer.Configurer) ComponentResolver(eu.okaeri.platform.core.component.creator.ComponentResolver) Method(java.lang.reflect.Method) Inject(eu.okaeri.injector.annotation.Inject) LocaleConfigManager(eu.okaeri.i18n.configs.LocaleConfigManager) NonNull(lombok.NonNull) MOCI18n(eu.okaeri.i18n.configs.impl.MOCI18n) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Placeholders(eu.okaeri.placeholders.Placeholders) BeanManifest(eu.okaeri.platform.core.component.manifest.BeanManifest) Stream(java.util.stream.Stream) ComponentHelper(eu.okaeri.platform.core.component.ComponentHelper) java.io(java.io) LocaleProvider(eu.okaeri.i18n.provider.LocaleProvider) ComponentCreator(eu.okaeri.platform.core.component.creator.ComponentCreator) OkaeriSerdesPack(eu.okaeri.configs.serdes.OkaeriSerdesPack) ConfigManager(eu.okaeri.configs.ConfigManager) ConfigurerProvider(eu.okaeri.persistence.document.ConfigurerProvider) OkaeriSerdesPack(eu.okaeri.configs.serdes.OkaeriSerdesPack) Configurer(eu.okaeri.configs.configurer.Configurer) Messages(eu.okaeri.platform.core.annotation.Messages) LocaleConfig(eu.okaeri.i18n.configs.LocaleConfig) JarFile(java.util.jar.JarFile) JarEntry(java.util.jar.JarEntry) Placeholders(eu.okaeri.placeholders.Placeholders) JarFile(java.util.jar.JarFile) MOCI18n(eu.okaeri.i18n.configs.impl.MOCI18n)

Aggregations

ConfigManager (eu.okaeri.configs.ConfigManager)1 Configurer (eu.okaeri.configs.configurer.Configurer)1 OkaeriSerdesPack (eu.okaeri.configs.serdes.OkaeriSerdesPack)1 LocaleConfig (eu.okaeri.i18n.configs.LocaleConfig)1 LocaleConfigManager (eu.okaeri.i18n.configs.LocaleConfigManager)1 MOCI18n (eu.okaeri.i18n.configs.impl.MOCI18n)1 LocaleProvider (eu.okaeri.i18n.provider.LocaleProvider)1 Injector (eu.okaeri.injector.Injector)1 Inject (eu.okaeri.injector.annotation.Inject)1 ConfigurerProvider (eu.okaeri.persistence.document.ConfigurerProvider)1 Placeholders (eu.okaeri.placeholders.Placeholders)1 Messages (eu.okaeri.platform.core.annotation.Messages)1 ComponentHelper (eu.okaeri.platform.core.component.ComponentHelper)1 ComponentCreator (eu.okaeri.platform.core.component.creator.ComponentCreator)1 ComponentResolver (eu.okaeri.platform.core.component.creator.ComponentResolver)1 BeanManifest (eu.okaeri.platform.core.component.manifest.BeanManifest)1 PlaceholdersFactory (eu.okaeri.platform.core.placeholder.PlaceholdersFactory)1 java.io (java.io)1 Method (java.lang.reflect.Method)1 StandardCharsets (java.nio.charset.StandardCharsets)1