001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.core.i18n;
021
022 import com.google.common.collect.Lists;
023 import org.apache.commons.lang.StringUtils;
024 import org.sonar.api.ServerComponent;
025
026 import java.util.List;
027 import java.util.Locale;
028
029 public class RuleI18nManager implements ServerComponent {
030
031 private static final String NAME_SUFFIX = ".name";
032 private static final String RULE_PREFIX = "rule.";
033
034 private I18nManager i18nManager;
035 private RuleKey[] ruleKeys;
036
037 public RuleI18nManager(I18nManager i18nManager) {
038 this.i18nManager = i18nManager;
039 }
040
041 public void start() {
042 List<RuleKey> list = Lists.newArrayList();
043 for (String propertyKey : i18nManager.getPropertyKeys()) {
044 if (isRuleProperty(propertyKey)) {
045 list.add(extractRuleKey(propertyKey));
046 }
047 }
048 this.ruleKeys = list.toArray(new RuleKey[list.size()]);
049 }
050
051 public String getName(String repositoryKey, String ruleKey, Locale locale) {
052 return message(repositoryKey, ruleKey, locale, NAME_SUFFIX);
053 }
054
055 public String getDescription(String repositoryKey, String ruleKey, Locale locale) {
056 String relatedProperty = new StringBuilder().append(RULE_PREFIX).append(repositoryKey).append(".").append(ruleKey).append(NAME_SUFFIX).toString();
057
058 Locale localeWithoutCountry = (locale.getCountry() == null ? locale : new Locale(locale.getLanguage()));
059 String ruleDescriptionFilePath = "rules/" + repositoryKey + "/" + ruleKey + ".html";
060 String description = i18nManager.messageFromFile(localeWithoutCountry, ruleDescriptionFilePath, relatedProperty, true);
061 if (description == null) {
062 // Following line is to ensure backward compatibility (SONAR-3319)
063 description = lookUpDescriptionInFormerLocation(ruleKey, relatedProperty, localeWithoutCountry);
064 if (description == null && !"en".equals(localeWithoutCountry.getLanguage())) {
065 // nothing was found, let's get the value of the default bundle
066 description = i18nManager.messageFromFile(Locale.ENGLISH, ruleDescriptionFilePath, relatedProperty, true);
067 }
068 }
069 return description;
070 }
071
072 /*
073 * Method used to ensure backward compatibility for language plugins that store HTML rule description files in the former
074 * location (which was used prior to Sonar 3.0).
075 *
076 * See http://jira.codehaus.org/browse/SONAR-3319
077 */
078 private String lookUpDescriptionInFormerLocation(String ruleKey, String relatedProperty, Locale localeWithoutCountry) {
079 String description = i18nManager.messageFromFile(localeWithoutCountry, ruleKey + ".html", relatedProperty, true);
080 if (description == null && !"en".equals(localeWithoutCountry.getLanguage())) {
081 // nothing was found, let's get the value of the default bundle
082 description = i18nManager.messageFromFile(Locale.ENGLISH, ruleKey + ".html", relatedProperty, true);
083 }
084 return description;
085 }
086
087 public String getParamDescription(String repositoryKey, String ruleKey, String paramKey, Locale locale) {
088 return message(repositoryKey, ruleKey, locale, ".param." + paramKey);
089 }
090
091 String message(String repositoryKey, String ruleKey, Locale locale, String suffix) {
092 String propertyKey = new StringBuilder().append(RULE_PREFIX).append(repositoryKey).append(".").append(ruleKey).append(suffix).toString();
093 return i18nManager.message(locale, propertyKey, null);
094 }
095
096 public List<RuleKey> searchNames(String search, Locale locale) {
097 List<RuleKey> result = Lists.newArrayList();
098 for (RuleKey ruleKey : ruleKeys) {
099 String name = i18nManager.message(locale, ruleKey.getNameProperty(), null);
100 if (name != null && StringUtils.indexOfIgnoreCase(name, search) >= 0) {
101 result.add(ruleKey);
102 }
103 }
104 return result;
105 }
106
107 RuleKey[] getRuleKeys() {
108 return ruleKeys;
109 }
110
111 static RuleKey extractRuleKey(String propertyKey) {
112 String s = StringUtils.substringBetween(propertyKey, RULE_PREFIX, NAME_SUFFIX);
113 String ruleKey = StringUtils.substringAfter(s, ".");
114 String repository = StringUtils.substringBefore(s, ".");
115 return new RuleKey(repository, ruleKey);
116 }
117
118 static boolean isRuleProperty(String propertyKey) {
119 return StringUtils.startsWith(propertyKey, RULE_PREFIX) && StringUtils.endsWith(propertyKey, NAME_SUFFIX) && !propertyKey.contains(".param.");
120 }
121
122 public static class RuleKey {
123 private String repositoryKey;
124 private String key;
125
126 RuleKey(String repositoryKey, String key) {
127 this.repositoryKey = repositoryKey;
128 this.key = key;
129 }
130
131 public String getRepositoryKey() {
132 return repositoryKey;
133 }
134
135 public String getKey() {
136 return key;
137 }
138
139 public String getNameProperty() {
140 return new StringBuilder().append(RULE_PREFIX).append(repositoryKey).append(".").append(key).append(NAME_SUFFIX).toString();
141 }
142
143 @Override
144 public boolean equals(Object o) {
145 if (this == o) {
146 return true;
147 }
148 if (o == null || getClass() != o.getClass()) {
149 return false;
150 }
151 RuleKey ruleKey = (RuleKey) o;
152 if (!key.equals(ruleKey.key)) {
153 return false;
154 }
155 if (!repositoryKey.equals(ruleKey.repositoryKey)) {
156 return false;
157 }
158 return true;
159 }
160
161 @Override
162 public int hashCode() {
163 int result = repositoryKey.hashCode();
164 result = 31 * result + key.hashCode();
165 return result;
166 }
167
168 @Override
169 public String toString() {
170 return new StringBuilder().append(repositoryKey).append(":").append(key).toString();
171 }
172 }
173 }