diff options
Diffstat (limited to 'sonar-core')
4 files changed, 154 insertions, 2 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/GwtI18n.java b/sonar-core/src/main/java/org/sonar/core/i18n/GwtI18n.java new file mode 100644 index 00000000000..d3de526be98 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/i18n/GwtI18n.java @@ -0,0 +1,82 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.i18n; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.StringEscapeUtils; +import org.sonar.api.ServerComponent; + +import java.util.*; + +public class GwtI18n implements ServerComponent { + public static final String GWT_BUNDLE = I18nManager.BUNDLE_PACKAGE + "gwt"; + + private I18nManager manager; + private String[] propertyKeys; + + public GwtI18n(I18nManager manager) { + this.manager = manager; + } + + public void start() { + doStart(getBundle(Locale.ENGLISH)); + } + + void doStart(ResourceBundle englishBundle) { + List<String> keys = Lists.newArrayList(); + Enumeration<String> enumeration = englishBundle.getKeys(); + while (enumeration.hasMoreElements()) { + String propertyKey = enumeration.nextElement(); + keys.add(propertyKey); + } + propertyKeys = keys.toArray(new String[keys.size()]); + } + + String[] getPropertyKeys() { + return propertyKeys; + } + + public String getJsDictionnary(Locale locale) { + ResourceBundle bundle = getBundle(locale); + return getJsDictionnary(bundle); + } + + String getJsDictionnary(ResourceBundle bundle) { + StringBuilder js = new StringBuilder("var l10n = {"); + for (int index = 0; index < propertyKeys.length; index++) { + String key = propertyKeys[index]; + String value = StringEscapeUtils.escapeJavaScript(bundle.getString(key)); + if (index > 0) { + js.append(","); + } + js.append("\"").append(key).append("\": \"").append(value).append("\""); + } + js.append("};"); + return js.toString(); + } + + ResourceBundle getBundle(Locale locale) { + try { + return ResourceBundle.getBundle(GWT_BUNDLE, locale, manager.getLanguagePackClassLoader()); + } catch (MissingResourceException e) { + throw new IllegalStateException("The English bundle for GWT extensions is not deployed", e); + } + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/I18nManager.java b/sonar-core/src/main/java/org/sonar/core/i18n/I18nManager.java index 65304cd44c0..9004a699a9f 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/I18nManager.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/I18nManager.java @@ -44,6 +44,7 @@ public class I18nManager implements I18n, ServerExtension { private PluginRepository pluginRepository; private Map<String, ClassLoader> bundleToClassloaders; private Map<String, String> propertyToBundles; + private ClassLoader languagePackClassLoader; public I18nManager(PluginRepository pluginRepository) { this.pluginRepository = pluginRepository; @@ -60,7 +61,7 @@ public class I18nManager implements I18n, ServerExtension { private void initClassloaders() { if (bundleToClassloaders == null) { - ClassLoader coreClassLoader = pluginRepository.getPlugin(ENGLISH_PACK_PLUGIN_KEY).getClass().getClassLoader(); + languagePackClassLoader = pluginRepository.getPlugin(ENGLISH_PACK_PLUGIN_KEY).getClass().getClassLoader(); bundleToClassloaders = Maps.newHashMap(); for (PluginMetadata metadata : pluginRepository.getMetadata()) { if (!metadata.isCore() && !ENGLISH_PACK_PLUGIN_KEY.equals(metadata.getBasePlugin())) { @@ -72,7 +73,7 @@ public class I18nManager implements I18n, ServerExtension { } else if (metadata.isCore()) { // bundles of core plugins are defined into language packs. All language packs are supposed // to share the same classloader (english pack classloader) - bundleToClassloaders.put(BUNDLE_PACKAGE + metadata.getKey(), coreClassLoader); + bundleToClassloaders.put(BUNDLE_PACKAGE + metadata.getKey(), languagePackClassLoader); } } } @@ -178,4 +179,8 @@ public class I18nManager implements I18n, ServerExtension { } return BUNDLE_PACKAGE + "core"; } + + ClassLoader getLanguagePackClassLoader() { + return languagePackClassLoader; + } } diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java new file mode 100644 index 00000000000..bf45baf4869 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.i18n; + +import com.google.common.collect.Lists; +import org.hamcrest.core.Is; +import org.junit.Before; +import org.junit.Test; + +import java.util.Locale; +import java.util.ResourceBundle; + +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; +import static org.junit.matchers.JUnitMatchers.hasItems; +import static org.mockito.Mockito.mock; + +public class GwtI18nTest { + + private GwtI18n i18n; + private ResourceBundle bundle; + + @Before + public void init() { + bundle = ResourceBundle.getBundle("org.sonar.core.i18n.GwtI18nTest.gwt", Locale.ENGLISH); + i18n = new GwtI18n(mock(I18nManager.class)); + i18n.doStart(bundle); + } + + @Test + public void shouldListAllPropertyKeysAtStartup() { + assertThat(i18n.getPropertyKeys().length, Is.is(2)); + assertThat(Lists.newArrayList(i18n.getPropertyKeys()), hasItems("one", "two")); + } + + @Test + public void shouldEncodeJavascriptValues() { + String js = i18n.getJsDictionnary(bundle); + assertThat(js, containsString("var l10n = {")); + assertThat(js, containsString("one\": \"One")); + assertThat(js, containsString("two\": \"Two")); + assertThat(js, containsString("};")); + assertThat(js, not(containsString(",};"))); // IE does not support empty key-values + } +} diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/GwtI18nTest/gwt.properties b/sonar-core/src/test/resources/org/sonar/core/i18n/GwtI18nTest/gwt.properties new file mode 100644 index 00000000000..da5fa91137a --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/i18n/GwtI18nTest/gwt.properties @@ -0,0 +1,2 @@ +one=One +two=Two
\ No newline at end of file |