diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2011-07-29 17:25:22 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2011-07-29 17:25:22 +0200 |
commit | 93d8dec0e5eb0fc6da292f6409a460aa0c9e86b6 (patch) | |
tree | 7cd459a72ffe1e135652e3d3ea32ad42c92029ce /sonar-core | |
parent | c0b2515521498a50261ea95fdcfda7a94c01a7d5 (diff) | |
download | sonarqube-93d8dec0e5eb0fc6da292f6409a460aa0c9e86b6.tar.gz sonarqube-93d8dec0e5eb0fc6da292f6409a460aa0c9e86b6.zip |
SONAR-75 rule search engine supports localized titles
Diffstat (limited to 'sonar-core')
3 files changed, 189 insertions, 66 deletions
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 4a8ee47f82f..65304cd44c0 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 @@ -131,6 +131,10 @@ public class I18nManager implements I18n, ServerExtension { return result; } + Set<String> getPropertyKeys() { + return propertyToBundles.keySet(); + } + ResourceBundle getBundle(String bundleKey, Locale locale) { try { ClassLoader classloader = bundleToClassloaders.get(bundleKey); diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java b/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java index 764871806cc..6d681196c28 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java @@ -19,93 +19,126 @@ */ package org.sonar.core.i18n; +import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerComponent; +import java.util.List; import java.util.Locale; public class RuleI18nManager implements ServerComponent { private I18nManager i18nManager; + private RuleKey[] ruleKeys; public RuleI18nManager(I18nManager i18nManager) { this.i18nManager = i18nManager; } + public void start() { + List<RuleKey> list = Lists.newArrayList(); + for (String propertyKey : i18nManager.getPropertyKeys()) { + if (isRuleProperty(propertyKey)) { + list.add(extractRuleKey(propertyKey)); + } + } + this.ruleKeys = list.toArray(new RuleKey[list.size()]); + } + public String getName(String repositoryKey, String ruleKey, Locale locale) { - return message(repositoryKey, ruleKey, locale, ".name", ruleKey); + return message(repositoryKey, ruleKey, locale, ".name"); } public String getDescription(String repositoryKey, String ruleKey, Locale locale) { - String relatedProperty = "rule." + repositoryKey + "." + ruleKey + ".name"; + String relatedProperty = new StringBuilder().append("rule.").append(repositoryKey).append(".").append(ruleKey).append(".name").toString(); // TODO add cache String description = i18nManager.messageFromFile(locale, ruleKey + ".html", relatedProperty); if (description == null && !Locale.ENGLISH.equals(locale)) { description = i18nManager.messageFromFile(Locale.ENGLISH, ruleKey + ".html", relatedProperty); } - return StringUtils.defaultString(description, ""); + return description; } public String getParamDescription(String repositoryKey, String ruleKey, String paramKey, Locale locale) { - return message(repositoryKey, ruleKey, locale, ".param." + paramKey, ""); + return message(repositoryKey, ruleKey, locale, ".param." + paramKey); } - private String message(String repositoryKey, String ruleKey, Locale locale, String suffix, String defaultValue) { + String message(String repositoryKey, String ruleKey, Locale locale, String suffix) { String propertyKey = new StringBuilder().append("rule.").append(repositoryKey).append(".").append(ruleKey).append(suffix).toString(); - return i18nManager.message(locale, propertyKey, defaultValue); + return i18nManager.message(locale, propertyKey, null); + } + + public List<RuleKey> searchNames(String search, Locale locale) { + List<RuleKey> result = Lists.newArrayList(); + for (RuleKey ruleKey : ruleKeys) { + String name = i18nManager.message(locale, ruleKey.getNameProperty(), null); + if (name != null && StringUtils.indexOfIgnoreCase(name, search) >= 0) { + result.add(ruleKey); + } + } + return result; + } + + RuleKey[] getRuleKeys() { + return ruleKeys; } -// static class RuleKey { -// private String repositoryKey; -// private String key; -// -// RuleKey(String repositoryKey, String key) { -// this.repositoryKey = repositoryKey; -// this.key = key; -// } -// -// public String getRepositoryKey() { -// return repositoryKey; -// } -// -// public String getKey() { -// return key; -// } -// -// @Override -// public boolean equals(Object o) { -// if (this == o) return true; -// if (o == null || getClass() != o.getClass()) return false; -// -// RuleKey ruleKey = (RuleKey) o; -// -// if (!key.equals(ruleKey.key)) return false; -// if (!repositoryKey.equals(ruleKey.repositoryKey)) return false; -// -// return true; -// } -// -// @Override -// public int hashCode() { -// int result = repositoryKey.hashCode(); -// result = 31 * result + key.hashCode(); -// return result; -// } -// -// @Override -// public String toString() { -// return new StringBuilder().append(repositoryKey).append(":").append(key).toString(); -// } -// } -// -// static class RuleMessages { -// private String name; -// private String description; -// -// RuleMessages(String name, String description) { -// this.name = name; -// this.description = description; -// } -// } + static RuleKey extractRuleKey(String propertyKey) { + String s = StringUtils.substringBetween(propertyKey, "rule.", ".name"); + String ruleKey = StringUtils.substringAfter(s, "."); + String repository = StringUtils.substringBefore(s, "."); + return new RuleKey(repository, ruleKey); + } + + static boolean isRuleProperty(String propertyKey) { + return StringUtils.startsWith(propertyKey, "rule.") && StringUtils.endsWith(propertyKey, ".name") && propertyKey.indexOf(".param.") < 0; + } + + public static class RuleKey { + private String repositoryKey; + private String key; + + RuleKey(String repositoryKey, String key) { + this.repositoryKey = repositoryKey; + this.key = key; + } + + public String getRepositoryKey() { + return repositoryKey; + } + + public String getKey() { + return key; + } + + public String getNameProperty() { + return new StringBuilder().append("rule.").append(repositoryKey).append(".").append(key).append(".name").toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RuleKey ruleKey = (RuleKey) o; + + if (!key.equals(ruleKey.key)) return false; + if (!repositoryKey.equals(ruleKey.repositoryKey)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = repositoryKey.hashCode(); + result = 31 * result + key.hashCode(); + return result; + } + + @Override + public String toString() { + return new StringBuilder().append(repositoryKey).append(":").append(key).toString(); + } + } } diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/RuleI18nManagerTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/RuleI18nManagerTest.java index 17608330075..448b3ade323 100644 --- a/sonar-core/src/test/java/org/sonar/core/i18n/RuleI18nManagerTest.java +++ b/sonar-core/src/test/java/org/sonar/core/i18n/RuleI18nManagerTest.java @@ -19,16 +19,18 @@ */ package org.sonar.core.i18n; +import com.google.common.collect.Sets; import org.hamcrest.core.Is; import org.junit.Test; +import java.util.Arrays; +import java.util.List; import java.util.Locale; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.isNotNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.junit.matchers.JUnitMatchers.hasItem; +import static org.mockito.Mockito.*; public class RuleI18nManagerTest { @Test @@ -39,7 +41,7 @@ public class RuleI18nManagerTest { ruleI18n.getName("checkstyle", "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck", Locale.ENGLISH); String propertyKey = "rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.name"; - verify(i18n).message(Locale.ENGLISH, propertyKey, "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck" /* default value is the key */); + verify(i18n).message(Locale.ENGLISH, propertyKey, null /* no default value */); verifyNoMoreInteractions(i18n); } @@ -51,7 +53,7 @@ public class RuleI18nManagerTest { ruleI18n.getParamDescription("checkstyle", "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck", "pattern", Locale.ENGLISH); String propertyKey = "rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.param.pattern"; - verify(i18n).message(Locale.ENGLISH, propertyKey, "" /* default value must be blank */); + verify(i18n).message(Locale.ENGLISH, propertyKey, null /* no default value */); verifyNoMoreInteractions(i18n); } @@ -68,11 +70,11 @@ public class RuleI18nManagerTest { } @Test - public void shoudlReturnBlankIfMissingDescription() { + public void shoudlReturnNullIfMissingDescription() { I18nManager i18n = mock(I18nManager.class); RuleI18nManager ruleI18n = new RuleI18nManager(i18n); - assertThat(ruleI18n.getDescription("checkstyle", "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck", Locale.ENGLISH), Is.is("")); + assertThat(ruleI18n.getDescription("checkstyle", "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck", Locale.ENGLISH), nullValue()); } @Test @@ -87,4 +89,88 @@ public class RuleI18nManagerTest { verify(i18n).messageFromFile(Locale.ENGLISH, "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.html", propertyKeyForName); verifyNoMoreInteractions(i18n); } + + @Test + public void shouldBeRuleKey() { + assertThat(RuleI18nManager.isRuleProperty("rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.name"), Is.is(true)); + assertThat(RuleI18nManager.isRuleProperty("rule.pmd.Header.name"), Is.is(true)); + } + + @Test + public void shouldNotBeRuleKey() { + // this is the parameter "name" + assertThat(RuleI18nManager.isRuleProperty("rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.param.name"), Is.is(false)); + assertThat(RuleI18nManager.isRuleProperty("by"), Is.is(false)); + assertThat(RuleI18nManager.isRuleProperty("something.else"), Is.is(false)); + assertThat(RuleI18nManager.isRuleProperty("checkstyle.page.name"), Is.is(false)); + } + + @Test + public void shouldExtractRuleKey() { + RuleI18nManager.RuleKey ruleKey = RuleI18nManager.extractRuleKey("rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.name"); + assertThat(ruleKey.getRepositoryKey(), Is.is("checkstyle")); + assertThat(ruleKey.getKey(), Is.is("com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck")); + assertThat(ruleKey.getNameProperty(), Is.is("rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.name")); + + ruleKey = RuleI18nManager.extractRuleKey("rule.pmd.Header.name"); + assertThat(ruleKey.getRepositoryKey(), Is.is("pmd")); + assertThat(ruleKey.getKey(), Is.is("Header")); + assertThat(ruleKey.getNameProperty(), Is.is("rule.pmd.Header.name")); + } + + @Test + public void shouldRegisterRuleKeysAtStartup() { + I18nManager i18n = mock(I18nManager.class); + when(i18n.getPropertyKeys()).thenReturn(Sets.newHashSet( + // rules + "rule.pmd.Header.name", "rule.pmd.Header.param.pattern", "rule.checkstyle.com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.name", + // other + "by", "something.else")); + RuleI18nManager ruleI18n = new RuleI18nManager(i18n); + ruleI18n.start(); + + List<RuleI18nManager.RuleKey> keys = Arrays.asList(ruleI18n.getRuleKeys()); + assertThat(keys.size(), Is.is(2)); + assertThat(keys, hasItem(new RuleI18nManager.RuleKey("pmd", "Header"))); + assertThat(keys, hasItem(new RuleI18nManager.RuleKey("checkstyle", "com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck"))); + } + + @Test + public void shouldSearchEnglishNames() { + I18nManager i18n = mock(I18nManager.class); + when(i18n.getPropertyKeys()).thenReturn(Sets.newHashSet("rule.pmd.Header.name", "rule.checkstyle.AnnotationUseStyleCheck.name")); + when(i18n.message(Locale.ENGLISH, "rule.pmd.Header.name", null)).thenReturn("HEADER PMD CHECK"); + when(i18n.message(Locale.ENGLISH, "rule.checkstyle.AnnotationUseStyleCheck.name", null)).thenReturn("check annotation style"); + + RuleI18nManager ruleI18n = new RuleI18nManager(i18n); + ruleI18n.start(); + + List<RuleI18nManager.RuleKey> result = ruleI18n.searchNames("ANNOTATion", Locale.ENGLISH); + assertThat(result.size(), Is.is(1)); + assertThat(result.get(0).getRepositoryKey(), Is.is("checkstyle")); + + result = ruleI18n.searchNames("bibopaloula", Locale.ENGLISH); + assertThat(result.size(), Is.is(0)); + } + + @Test + public void shouldSearchLocalizedNames() { + I18nManager i18n = mock(I18nManager.class); + when(i18n.getPropertyKeys()).thenReturn(Sets.newHashSet("rule.pmd.Header.name", "rule.checkstyle.AnnotationUseStyleCheck.name")); + when(i18n.message(Locale.ENGLISH, "rule.pmd.Header.name", null)).thenReturn("HEADER PMD CHECK"); + when(i18n.message(Locale.ENGLISH, "rule.checkstyle.AnnotationUseStyleCheck.name", null)).thenReturn("check annotation style"); + when(i18n.message(Locale.FRENCH, "rule.checkstyle.AnnotationUseStyleCheck.name", null)).thenReturn("vérifie le style des annotations"); + + RuleI18nManager ruleI18n = new RuleI18nManager(i18n); + ruleI18n.start(); + + List<RuleI18nManager.RuleKey> result = ruleI18n.searchNames("annotation", Locale.FRENCH); + assertThat(result.size(), Is.is(1)); + assertThat(result.get(0).getKey(), Is.is("AnnotationUseStyleCheck")); + + // search only in the french bundle + result = ruleI18n.searchNames("vérifie", Locale.FRENCH); + assertThat(result.size(), Is.is(1)); + assertThat(result.get(0).getKey(), Is.is("AnnotationUseStyleCheck")); + } } |