001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
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.api.rules;
021    
022    import org.apache.commons.collections.CollectionUtils;
023    import org.sonar.api.BatchExtension;
024    import org.sonar.api.Plugin;
025    import org.sonar.api.Plugins;
026    import org.sonar.api.database.daos.DaoFacade;
027    import org.sonar.api.database.daos.RulesDao;
028    import org.sonar.api.resources.Language;
029    
030    import java.util.*;
031    
032    public class RulesManager implements BatchExtension {
033    
034      private final Set<Language> languages;
035      private final RulesRepository<?>[] repositories;
036      private final Map<Language, List<RulesRepository<?>>> rulesByLanguage;
037      private final Map<Language, List<Plugin>> pluginsByLanguage;
038      private final Map<String, Map<String, Rule>> rulesByPluginAndKey = new HashMap<String, Map<String, Rule>>();
039      private final RulesDao rulesDao;
040      private final Plugins plugins;
041    
042      public RulesManager(Plugins plugins, RulesRepository[] repositories, DaoFacade dao) {
043        this.plugins = plugins;
044        this.rulesDao = dao.getRulesDao();
045    
046        languages = new HashSet<Language>();
047        rulesByLanguage = new HashMap<Language, List<RulesRepository<?>>>();
048        pluginsByLanguage = new HashMap<Language, List<Plugin>>();
049        this.repositories = repositories;
050    
051        for (RulesRepository<?> repository : repositories) {
052          languages.add(repository.getLanguage());
053    
054          List<RulesRepository<?>> list = rulesByLanguage.get(repository.getLanguage());
055          if (list == null) {
056            list = new ArrayList<RulesRepository<?>>();
057            rulesByLanguage.put(repository.getLanguage(), list);
058          }
059          list.add(repository);
060    
061          List<Plugin> languagePlugins = pluginsByLanguage.get(repository.getLanguage());
062          if (languagePlugins == null) {
063            languagePlugins = new ArrayList<Plugin>();
064            pluginsByLanguage.put(repository.getLanguage(), languagePlugins);
065          }
066          languagePlugins.add(plugins.getPluginByExtension(repository));
067        }
068      }
069    
070      protected RulesManager(DaoFacade dao) {
071        this.rulesDao = dao.getRulesDao();
072        plugins = new Plugins();
073        languages = new HashSet<Language>();
074        rulesByLanguage = new HashMap<Language, List<RulesRepository<?>>>();
075        pluginsByLanguage = new HashMap<Language, List<Plugin>>();
076        repositories = null;
077    
078      }
079    
080      public Set<Language> getLanguages() {
081        return languages;
082      }
083    
084      public List<RulesRepository<?>> getRulesRepositories(Language language) {
085        List<RulesRepository<?>> rulesRepositories = rulesByLanguage.get(language);
086        if (CollectionUtils.isNotEmpty(rulesRepositories)) {
087          return rulesRepositories;
088        }
089        return Collections.emptyList();
090      }
091    
092      public List<RulesRepository<?>> getRulesRepositories() {
093        return Arrays.asList(repositories);
094      }
095    
096      public List<Plugin> getPlugins(Language language) {
097        List<Plugin> result = pluginsByLanguage.get(language);
098        if (!CollectionUtils.isEmpty(result)) {
099          return result;
100        }
101        return Collections.emptyList();
102      }
103    
104      public Map<String, Long> countRulesByCategory(Language language) {
105        return countRulesByCategory(language, rulesDao);
106      }
107    
108      protected Map<String, Long> countRulesByCategory(Language language, RulesDao rulesDao) {
109        Map<String, Long> countByCategory = new HashMap<String, Long>();
110        List<Plugin> result = getPlugins(language);
111        if (!CollectionUtils.isEmpty(result)) {
112          List<String> keys = getPluginKeys(getPlugins(language));
113          for (RulesCategory rulesCategory : rulesDao.getCategories()) {
114            Long rulesCount = rulesDao.countRules(keys, rulesCategory.getName());
115            countByCategory.put(rulesCategory.getName(), rulesCount);
116          }
117        }
118        return countByCategory;
119      }
120    
121      private List<String> getPluginKeys(List<Plugin> plugins) {
122        ArrayList<String> keys = new ArrayList<String>();
123        for (Plugin plugin : plugins) {
124          keys.add(plugin.getKey());
125        }
126        return keys;
127      }
128    
129      public List<Plugin> getExportablePlugins(Language language) {
130        List<Plugin> targets = new ArrayList<Plugin>();
131        List<RulesRepository<?>> rulesRepositories = getRulesRepositories(language);
132        for (RulesRepository<?> repository : rulesRepositories) {
133          if (repository instanceof ConfigurationExportable) {
134            targets.add(plugins.getPluginByExtension(repository));
135          }
136        }
137        return targets;
138      }
139    
140      public List<Plugin> getImportablePlugins(Language language) {
141        List<Plugin> targets = new ArrayList<Plugin>();
142        for (RulesRepository<?> repository : getRulesRepositories(language)) {
143          if (repository instanceof ConfigurationImportable) {
144            targets.add(plugins.getPluginByExtension(repository));
145          }
146        }
147        return targets;
148      }
149    
150      public Map<String, Rule> getPluginRulesIndexedByKey(String pluginKey) {
151        Map<String, Rule> rulesByKey = rulesByPluginAndKey.get(pluginKey);
152        if (rulesByKey == null) {
153          rulesByKey = new HashMap<String, Rule>();
154          List<Rule> rules = rulesDao.getRulesByPlugin(pluginKey);
155          if (rules != null) {
156            for (Rule rule : rules) {
157              rulesByKey.put(rule.getKey(), rule);
158            }
159          }
160          rulesByPluginAndKey.put(pluginKey, rulesByKey);
161        }
162        return rulesByKey;
163      }
164    
165      public Collection<Rule> getPluginRules(String pluginKey) {
166        Map<String, Rule> rulesByKey = getPluginRulesIndexedByKey(pluginKey);
167        return rulesByKey.values();
168      }
169    
170      public Rule getPluginRule(String pluginKey, String ruleKey) {
171        Map<String, Rule> rulesByKey = getPluginRulesIndexedByKey(pluginKey);
172        return rulesByKey.get(ruleKey);
173      }
174    
175    }