diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2011-06-21 18:06:11 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2011-06-21 18:13:15 +0200 |
commit | 88e6ec0762914d72dd42fb8be3b1ce0fb1e447c2 (patch) | |
tree | 022f19acf8e838dd59a6521e40931125331280b0 /plugins/sonar-core-plugin | |
parent | fe7eb1d29d9775f3da0d8b98ada1a5e927555cab (diff) | |
download | sonarqube-88e6ec0762914d72dd42fb8be3b1ce0fb1e447c2.tar.gz sonarqube-88e6ec0762914d72dd42fb8be3b1ce0fb1e447c2.zip |
SONAR-2497 Merge i18n plugin with core
Diffstat (limited to 'plugins/sonar-core-plugin')
16 files changed, 489 insertions, 0 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index f3b72b9e0c1..87d1e406442 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -34,6 +34,7 @@ import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; import org.sonar.plugins.core.duplicationsviewer.DuplicationsViewerDefinition; import org.sonar.plugins.core.hotspots.Hotspots; +import org.sonar.plugins.core.i18n.I18nManager; import org.sonar.plugins.core.metrics.UserManagedMetrics; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; import org.sonar.plugins.core.sensors.*; @@ -227,6 +228,9 @@ public class CorePlugin extends SonarPlugin { extensions.add(NewCoverageFileAnalyzer.class); extensions.add(NewCoverageAggregator.class); + // i18n + extensions.add(I18nManager.class); + return extensions; } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/I18nManager.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/I18nManager.java new file mode 100644 index 00000000000..8438b706622 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/I18nManager.java @@ -0,0 +1,203 @@ +/* + * 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.plugins.core.i18n; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.apache.commons.collections.EnumerationUtils; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchExtension; +import org.sonar.api.ServerExtension; +import org.sonar.api.i18n.I18n; +import org.sonar.api.i18n.LanguagePack; +import org.sonar.api.platform.PluginRepository; +import org.sonar.api.utils.Logs; +import org.sonar.api.utils.SonarException; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; + +public final class I18nManager implements I18n, ServerExtension, BatchExtension { + + private static final Logger LOG = LoggerFactory.getLogger(I18nManager.class); + public static final String packagePathToSearchIn = "org/sonar/i18n"; + + private PluginRepository pluginRepository; + private LanguagePack[] languagePacks; + private Map<String, String> keys = Maps.newHashMap(); + private Properties unknownKeys = new Properties(); + private BundleClassLoader bundleClassLoader = new BundleClassLoader(); + + public I18nManager(PluginRepository pluginRepository, LanguagePack[] languagePacks) { + this.pluginRepository = pluginRepository; + this.languagePacks = languagePacks; + } + + public I18nManager(PluginRepository pluginRepository) { + this(pluginRepository, new LanguagePack[0]); + } + + + public void start() { + doStart(InstalledPlugin.create(pluginRepository)); + } + + void doStart(List<InstalledPlugin> installedPlugins) { + Logs.INFO.info("Loading i18n bundles"); + Set<URI> alreadyLoadedResources = Sets.newHashSet(); + for (InstalledPlugin plugin : installedPlugins) { + searchAndStoreBundleNames(plugin.key, plugin.classloader, alreadyLoadedResources); + } + for (LanguagePack pack : languagePacks) { + addLanguagePack(pack); + } + } + + private void addLanguagePack(LanguagePack languagePack) { + LOG.debug("Search for bundles in language pack : {}", languagePack); + for (String pluginKey : languagePack.getPluginKeys()) { + String bundleBaseName = buildBundleBaseName(pluginKey); + for (Locale locale : languagePack.getLocales()) { + String bundlePropertiesFile = new StringBuilder(bundleBaseName).append('_').append(locale.toString()).append(".properties").toString(); + ClassLoader classloader = languagePack.getClass().getClassLoader(); + LOG.info("Adding locale {} for bundleName : {} from classloader : {}", new Object[]{locale, bundleBaseName, classloader}); + bundleClassLoader.addResource(bundlePropertiesFile, classloader); + } + } + } + + private String buildBundleBaseName(String pluginKey) { + return packagePathToSearchIn + "/" + pluginKey; + } + + private void searchAndStoreBundleNames(String pluginKey, ClassLoader classloader, Set<URI> alreadyLoadedResources) { + String bundleBaseName = buildBundleBaseName(pluginKey); + String bundleDefaultPropertiesFile = bundleBaseName + ".properties"; + try { + LOG.debug("Search for ResourceBundle base file '" + bundleDefaultPropertiesFile + "' in the classloader : " + classloader); + List<URL> resources = EnumerationUtils.toList(classloader.getResources(bundleDefaultPropertiesFile)); + if (resources.size() > 0) { + if (resources.size() > 1) { + LOG.warn("File '{}' found several times in the classloader : {}. Only the first one will be taken in account.", + bundleDefaultPropertiesFile, classloader); + } + + URL propertiesUrl = resources.get(0); + if (!alreadyLoadedResources.contains(propertiesUrl.toURI())) { + LOG.debug("Found the ResourceBundle base file : {} from classloader : {}", propertiesUrl, classloader); + LOG.debug("Add bundleName : {} from classloader : {}", bundleBaseName, classloader); + bundleClassLoader.addResource(bundleDefaultPropertiesFile, classloader); + alreadyLoadedResources.add(propertiesUrl.toURI()); + + Properties bundleContent = new Properties(); + InputStream input = null; + try { + input = propertiesUrl.openStream(); + bundleContent.load(input); + Enumeration<String> keysToAdd = (Enumeration<String>) bundleContent.propertyNames(); + while (keysToAdd.hasMoreElements()) { + String key = keysToAdd.nextElement(); + if (keys.containsKey(key)) { + LOG.warn("DUPLICATE KEY : Key '{}' defined in bundle '{}' is already defined in bundle '{}'. It is ignored.", new Object[]{ + key, bundleBaseName, keys.get(key)}); + } else { + keys.put(key, bundleBaseName); + } + } + } finally { + IOUtils.closeQuietly(input); + } + } + } + } catch (Exception e) { + LOG.error("Fail to load '" + bundleDefaultPropertiesFile + "' in classloader : " + classloader, e); + throw new SonarException("Fail to load '" + bundleDefaultPropertiesFile + "' in classloader : " + classloader, e); + } + } + + public String message(final Locale locale, final String key, final String defaultText, final Object... objects) { + String result = defaultText; + try { + String bundleBaseName = keys.get(key); + if (bundleBaseName == null) { + LOG.warn("UNKNOWN KEY : Key '{}' not found in any bundle. Default value '{}' is returned.", key, defaultText); + unknownKeys.put(key, defaultText); + } else { + try { + ResourceBundle bundle = ResourceBundle.getBundle(bundleBaseName, locale, bundleClassLoader); + + String value = bundle.getString(key); + if ("".equals(value)) { + LOG.warn("VOID KEY : Key '{}' (from bundle '{}') returns a void value. Default value '{}' is returned.", new Object[]{key, + bundleBaseName, defaultText}); + } else { + result = value; + } + } catch (MissingResourceException e) { + LOG.warn("BUNDLE NOT LOADED : Failed loading bundle {} from classloader {}. Default value '{}' is returned.", new Object[]{ + bundleBaseName, bundleClassLoader, defaultText}); + } + } + } catch (Exception e) { + LOG.error("Exception when retrieving I18n string.", e); + } + + if (objects.length > 0) { + LOG.debug("Translation : {}, {}, {}, {}", new String[]{locale.toString(), key, defaultText, Arrays.deepToString(objects)}); + return MessageFormat.format(result, objects); + } else { + return result; + } + } + + /** + * @return the unknownKeys + */ + public Properties getUnknownKeys() { + return unknownKeys; + } + + + private static class BundleClassLoader extends URLClassLoader { + private Map<String, ClassLoader> resources = Maps.newHashMap(); + + public BundleClassLoader() { + super(new URL[]{}, null); + } + + public void addResource(String resourceName, ClassLoader classloader) { + resources.put(resourceName, classloader); + } + + @Override + public URL findResource(String name) { + if (resources.containsKey(name)) { + return resources.get(name).getResource(name); + } + return null; + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/InstalledPlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/InstalledPlugin.java new file mode 100644 index 00000000000..abe4b3cf0de --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/i18n/InstalledPlugin.java @@ -0,0 +1,46 @@ +/* + * 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.plugins.core.i18n; + +import com.google.common.collect.Lists; +import org.sonar.api.Plugin; +import org.sonar.api.platform.PluginMetadata; +import org.sonar.api.platform.PluginRepository; + +import java.util.List; + +class InstalledPlugin { + String key; + ClassLoader classloader; + + InstalledPlugin(String key, ClassLoader classloader) { + this.key = key; + this.classloader = classloader; + } + + static List<InstalledPlugin> create(PluginRepository pluginRepository) { + List<InstalledPlugin> result = Lists.newArrayList(); + for (PluginMetadata metadata : pluginRepository.getMetadata()) { + Plugin entryPoint = pluginRepository.getPlugin(metadata.getKey()); + result.add(new InstalledPlugin(metadata.getKey(), entryPoint.getClass().getClassLoader())); + } + return result; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/FrenchLanguagePack.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/FrenchLanguagePack.java new file mode 100644 index 00000000000..e781f5a891f --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/FrenchLanguagePack.java @@ -0,0 +1,39 @@ +/* + * 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.plugins.core.i18n; + +import org.sonar.api.i18n.LanguagePack; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +public class FrenchLanguagePack extends LanguagePack { + + @Override + public List<String> getPluginKeys() { + return Arrays.asList("test"); + } + + @Override + public List<Locale> getLocales() { + return Arrays.asList(Locale.FRENCH); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/I18nManagerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/I18nManagerTest.java new file mode 100644 index 00000000000..380f65efe3d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/I18nManagerTest.java @@ -0,0 +1,122 @@ +/* + * 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.plugins.core.i18n; + +import com.google.common.collect.Lists; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.i18n.LanguagePack; +import org.sonar.api.platform.PluginRepository; + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +public class I18nManagerTest { + + public static String TEST_PLUGIN_CLASS_NAME = "org.sonar.plugins.core.i18n.StandardPlugin"; + public static String FRENCH_PACK_CLASS_NAME = "org.sonar.plugins.core.i18n.FrenchLanguagePack"; + public static String QUEBEC_PACK_CLASS_NAME = "org.sonar.plugins.core.i18n.QuebecLanguagePack"; + + private static URL classSource = I18nManagerTest.class.getProtectionDomain().getCodeSource().getLocation(); + private I18nManager manager; + + @Before + public void createManager() throws Exception { + List<InstalledPlugin> plugins = Lists.newArrayList( + new InstalledPlugin("test", new TestClassLoader(getClass().getClassLoader().getResource("StandardPlugin.jar"))), + new InstalledPlugin("fake1", getClass().getClassLoader()), + new InstalledPlugin("fake2", getClass().getClassLoader()) + ); + + TestClassLoader frenchPackClassLoader = new TestClassLoader(getClass().getClassLoader().getResource("FrenchPlugin.jar")); + LanguagePack frenchPack = (LanguagePack) frenchPackClassLoader.loadClass(FRENCH_PACK_CLASS_NAME).newInstance(); + + TestClassLoader quebecPackClassLoader = new TestClassLoader(getClass().getClassLoader().getResource("QuebecPlugin.jar")); + LanguagePack quebecPack = (LanguagePack) quebecPackClassLoader.loadClass(QUEBEC_PACK_CLASS_NAME).newInstance(); + + manager = new I18nManager(mock(PluginRepository.class), new LanguagePack[]{frenchPack, quebecPack}); + manager.doStart(plugins); + } + + @Test + public void shouldTranslateWithoutRegionalVariant() { + List<String> sentence = Arrays.asList("it", "is", "cold"); + String result = ""; + for (String token : sentence) { + result += manager.message(Locale.FRENCH, token, token) + " "; + } + assertEquals("Il fait froid ", result); + } + + @Test + public void shouldTranslateWithRegionalVariant() { + // it & is are taken from the french language pack + // and cold is taken from the quebec language pack + List<String> sentence = Arrays.asList("it", "is", "cold"); + String result = ""; + for (String token : sentence) { + result += manager.message(Locale.CANADA_FRENCH, token, token) + " "; + } + assertEquals("Il fait frette ", result); + } + + @Test + public void shouldTranslateReturnsDefaultBundleValue() { + String result = manager.message(Locale.FRENCH, "only.english", "Default"); + assertEquals("Ketchup", result); + } + + @Test + public void shouldTranslateUnknownValue() { + String result = manager.message(Locale.FRENCH, "unknown", "Default value for Unknown"); + assertEquals("Default value for Unknown", result); + Assert.assertEquals(1, manager.getUnknownKeys().size()); + Assert.assertEquals("Default value for Unknown", manager.getUnknownKeys().getProperty("unknown")); + } + + public static class TestClassLoader extends URLClassLoader { + public TestClassLoader(URL url) { + super(new URL[]{url, classSource}, Thread.currentThread().getContextClassLoader()); + } + + protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + Class c = findLoadedClass(name); + if (c == null) { + if (name.equals(TEST_PLUGIN_CLASS_NAME) || name.equals(QUEBEC_PACK_CLASS_NAME) || name.equals(FRENCH_PACK_CLASS_NAME)) { + c = findClass(name); + } else { + return super.loadClass(name, resolve); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/QuebecLanguagePack.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/QuebecLanguagePack.java new file mode 100644 index 00000000000..c8ed96a4edb --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/i18n/QuebecLanguagePack.java @@ -0,0 +1,39 @@ +/* + * 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.plugins.core.i18n; + +import org.sonar.api.i18n.LanguagePack; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +public class QuebecLanguagePack extends LanguagePack { + + @Override + public List<String> getPluginKeys() { + return Arrays.asList("test"); + } + + @Override + public List<Locale> getLocales() { + return Arrays.asList(Locale.CANADA_FRENCH); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin.jar b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin.jar Binary files differnew file mode 100644 index 00000000000..ab61bd88697 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin.jar diff --git a/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/META-INF/MANIFEST.MF b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..a45029d3531 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0
+Created-By: 1.6.0_17 (Apple Inc.)
+
diff --git a/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/org/sonar/i18n/test_fr.properties b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/org/sonar/i18n/test_fr.properties new file mode 100644 index 00000000000..cc8efa7afc3 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/FrenchPlugin/org/sonar/i18n/test_fr.properties @@ -0,0 +1,4 @@ +it=Il +is=fait +cold=froid + diff --git a/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin.jar b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin.jar Binary files differnew file mode 100644 index 00000000000..101df34ba6d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin.jar diff --git a/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/META-INF/MANIFEST.MF b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..a45029d3531 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0
+Created-By: 1.6.0_17 (Apple Inc.)
+
diff --git a/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/org/sonar/i18n/test_fr_CA.properties b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/org/sonar/i18n/test_fr_CA.properties new file mode 100644 index 00000000000..38b5b84ccdf --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/QuebecPlugin/org/sonar/i18n/test_fr_CA.properties @@ -0,0 +1,2 @@ +cold=frette + diff --git a/plugins/sonar-core-plugin/src/test/resources/StandardPlugin.jar b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin.jar Binary files differnew file mode 100644 index 00000000000..73deac7e8b6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin.jar diff --git a/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/META-INF/MANIFEST.MF b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..a45029d3531 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0
+Created-By: 1.6.0_17 (Apple Inc.)
+
diff --git a/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/org/sonar/i18n/test.properties b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/org/sonar/i18n/test.properties new file mode 100644 index 00000000000..88aabfe61a2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/StandardPlugin/org/sonar/i18n/test.properties @@ -0,0 +1,4 @@ +it=It +is=is +cold=cold +only.english=Ketchup diff --git a/plugins/sonar-core-plugin/src/test/resources/logback-test.xml b/plugins/sonar-core-plugin/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..cdc8866fe3a --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/logback-test.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<configuration> + <appender name="STDOUT" + class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <pattern> + %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + </pattern> + </layout> + </appender> + + <root> + <level value="INFO"/> + <appender-ref ref="STDOUT"/> + </root> +</configuration>
\ No newline at end of file |