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 */ 020package org.sonar.core.i18n; 021 022import com.google.common.collect.Lists; 023import org.apache.commons.lang.StringUtils; 024import org.sonar.api.ServerComponent; 025 026import java.util.List; 027import java.util.Locale; 028 029public 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}