package org.molgenis.data.i18n; import org.molgenis.data.DataService; import org.molgenis.data.Entity; import org.molgenis.data.i18n.model.I18nStringMetaData; import org.molgenis.data.i18n.model.LanguageMetadata; import org.molgenis.data.settings.AppSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.List; import java.util.ListResourceBundle; import java.util.Locale; import java.util.ResourceBundle; import java.util.stream.Collectors; import static org.molgenis.data.i18n.model.I18nStringMetaData.I18N_STRING; import static org.molgenis.data.i18n.model.LanguageMetadata.LANGUAGE; import static org.molgenis.security.core.runas.RunAsSystemProxy.runAsSystem; /** * ResourceBundle Control that gets it content from the i18nstrings repository */ public class MolgenisResourceBundleControl extends ResourceBundle.Control { private static final Logger LOG = LoggerFactory.getLogger(MolgenisResourceBundleControl.class); private final DataService dataService; private final AppSettings appSettings; public MolgenisResourceBundleControl(DataService dataService, AppSettings appSettings) { this.dataService = dataService; this.appSettings = appSettings; } @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { String languageCode = locale.getLanguage(); // Only handle i18nstrings bundle if (!baseName.equals(I18N_STRING)) return null; // Only handle languages that are present in the languages repository if (runAsSystem(() -> dataService.query(LANGUAGE).eq(LanguageMetadata.CODE, languageCode).count()) == 0) return null; return new MolgenisResourceBundle(dataService, languageCode, appSettings); } protected static class MolgenisResourceBundle extends ListResourceBundle { private final DataService dataService; private final String languageCode; private final AppSettings appSettings; private String appLanguageCode; public MolgenisResourceBundle(DataService dataService, String languageCode, AppSettings appSettings) { this.dataService = dataService; this.languageCode = languageCode; this.appSettings = appSettings; } @Override protected Object[][] getContents() { List<Entity> entities = runAsSystem(() -> dataService.findAll(I18N_STRING).collect(Collectors.toList())); appLanguageCode = appSettings.getLanguageCode(); boolean exists = (appLanguageCode != null) && runAsSystem(() -> { return (dataService.findOneById(LANGUAGE, appLanguageCode) != null); }); if (!exists) appLanguageCode = null; Object[][] contents = new Object[entities.size()][2]; int i = 0; for (Entity entity : entities) { String msgid = entity.getString(I18nStringMetaData.MSGID); String msg = entity.getString(languageCode); if (msg == null) { // Missing translation for this language, return in app language LOG.warn("Missing '{}' msg for language '{}'", msgid, languageCode); if (appLanguageCode != null) { msg = entity.getString(appLanguageCode); } // Also missing in app language, use default if (msg == null) { msg = entity.getString(LanguageService.DEFAULT_LANGUAGE_CODE); } if (msg == null) { msg = "#" + msgid + "#"; } } contents[i++] = new Object[] { msgid, msg }; } return contents; } } }