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.server.ui; 021 022import com.google.common.collect.ListMultimap; 023import com.google.common.collect.Lists; 024import org.slf4j.LoggerFactory; 025import org.sonar.api.CoreProperties; 026import org.sonar.api.config.License; 027import org.sonar.api.config.PropertyDefinitions; 028import org.sonar.api.config.Settings; 029import org.sonar.api.platform.ComponentContainer; 030import org.sonar.api.platform.PluginMetadata; 031import org.sonar.api.platform.PluginRepository; 032import org.sonar.api.profiles.ProfileExporter; 033import org.sonar.api.profiles.ProfileImporter; 034import org.sonar.api.resources.Language; 035import org.sonar.api.resources.ResourceType; 036import org.sonar.api.resources.ResourceTypes; 037import org.sonar.api.rules.RulePriority; 038import org.sonar.api.rules.RuleRepository; 039import org.sonar.api.utils.ValidationMessages; 040import org.sonar.api.web.*; 041import org.sonar.api.workflow.Review; 042import org.sonar.api.workflow.internal.DefaultReview; 043import org.sonar.api.workflow.internal.DefaultWorkflowContext; 044import org.sonar.api.workflow.screen.Screen; 045import org.sonar.core.i18n.RuleI18nManager; 046import org.sonar.core.persistence.Database; 047import org.sonar.core.persistence.DatabaseMigrator; 048import org.sonar.core.purge.PurgeDao; 049import org.sonar.core.resource.ResourceIndexerDao; 050import org.sonar.core.workflow.WorkflowEngine; 051import org.sonar.markdown.Markdown; 052import org.sonar.server.configuration.Backup; 053import org.sonar.server.configuration.ProfilesManager; 054import org.sonar.server.filters.Filter; 055import org.sonar.server.filters.FilterExecutor; 056import org.sonar.server.filters.FilterResult; 057import org.sonar.server.notifications.reviews.ReviewsNotificationManager; 058import org.sonar.server.platform.GlobalSettingsUpdater; 059import org.sonar.server.platform.Platform; 060import org.sonar.server.platform.ServerIdGenerator; 061import org.sonar.server.plugins.*; 062import org.sonar.server.rules.ProfilesConsole; 063import org.sonar.server.rules.RulesConsole; 064import org.sonar.updatecenter.common.Version; 065 066import javax.annotation.Nullable; 067import java.net.InetAddress; 068import java.sql.Connection; 069import java.util.Collection; 070import java.util.List; 071import java.util.Map; 072import java.util.Set; 073 074public final class JRubyFacade { 075 076 private static final JRubyFacade SINGLETON = new JRubyFacade(); 077 private JRubyI18n i18n; 078 079 public static JRubyFacade getInstance() { 080 return SINGLETON; 081 } 082 083 public FilterResult executeFilter(Filter filter) { 084 return getContainer().getComponentByType(FilterExecutor.class).execute(filter); 085 } 086 087 public Collection<ResourceType> getResourceTypesForFilter() { 088 return getContainer().getComponentByType(ResourceTypes.class).getAll(ResourceTypes.AVAILABLE_FOR_FILTERS); 089 } 090 091 public Collection<ResourceType> getResourceTypes() { 092 return getContainer().getComponentByType(ResourceTypes.class).getAll(); 093 } 094 095 public ResourceType getResourceType(String qualifier) { 096 return getContainer().getComponentByType(ResourceTypes.class).get(qualifier); 097 } 098 099 public String getResourceTypeStringProperty(String resourceTypeQualifier, String resourceTypeProperty) { 100 ResourceType resourceType = getResourceType(resourceTypeQualifier); 101 if (resourceType != null) { 102 return resourceType.getStringProperty(resourceTypeProperty); 103 } 104 return null; 105 } 106 107 public List<String> getQualifiersWithProperty(final String propertyKey) { 108 List<String> qualifiers = Lists.newArrayList(); 109 for (ResourceType type : getResourceTypes()) { 110 if (type.getBooleanProperty(propertyKey) == Boolean.TRUE) { 111 qualifiers.add(type.getQualifier()); 112 } 113 } 114 return qualifiers; 115 } 116 117 public Boolean getResourceTypeBooleanProperty(String resourceTypeQualifier, String resourceTypeProperty) { 118 ResourceType resourceType = getResourceType(resourceTypeQualifier); 119 if (resourceType != null) { 120 return resourceType.getBooleanProperty(resourceTypeProperty); 121 } 122 return null; 123 } 124 125 public Collection<String> getResourceLeavesQualifiers(String qualifier) { 126 return getContainer().getComponentByType(ResourceTypes.class).getLeavesQualifiers(qualifier); 127 } 128 129 public Collection<String> getResourceChildrenQualifiers(String qualifier) { 130 return getContainer().getComponentByType(ResourceTypes.class).getChildrenQualifiers(qualifier); 131 } 132 133 // UPDATE CENTER ------------------------------------------------------------ 134 135 public void downloadPlugin(String pluginKey, String pluginVersion) { 136 getContainer().getComponentByType(PluginDownloader.class).download(pluginKey, Version.create(pluginVersion)); 137 } 138 139 public void cancelPluginDownloads() { 140 getContainer().getComponentByType(PluginDownloader.class).cancelDownloads(); 141 } 142 143 public List<String> getPluginDownloads() { 144 return getContainer().getComponentByType(PluginDownloader.class).getDownloads(); 145 } 146 147 public void uninstallPlugin(String pluginKey) { 148 getContainer().getComponentByType(PluginDeployer.class).uninstall(pluginKey); 149 } 150 151 public void cancelPluginUninstalls() { 152 getContainer().getComponentByType(PluginDeployer.class).cancelUninstalls(); 153 } 154 155 public List<String> getPluginUninstalls() { 156 return getContainer().getComponentByType(PluginDeployer.class).getUninstalls(); 157 } 158 159 public UpdateCenterMatrix getUpdateCenterMatrix(boolean forceReload) { 160 return getContainer().getComponentByType(UpdateCenterMatrixFactory.class).getMatrix(forceReload); 161 } 162 163 // PLUGINS ------------------------------------------------------------------ 164 165 public PropertyDefinitions getPropertyDefinitions() { 166 return getContainer().getComponentByType(PropertyDefinitions.class); 167 } 168 169 public boolean hasPlugin(String key) { 170 return getContainer().getComponentByType(PluginRepository.class).getPlugin(key) != null; 171 } 172 173 public Collection<PluginMetadata> getPluginsMetadata() { 174 return getContainer().getComponentByType(PluginRepository.class).getMetadata(); 175 } 176 177 // SYNTAX HIGHLIGHTING ------------------------------------------------------ 178 179 public String colorizeCode(String code, String language) { 180 try { 181 return getContainer().getComponentByType(CodeColorizers.class).toHtml(code, language); 182 183 } catch (Exception e) { 184 LoggerFactory.getLogger(getClass()).error("Can not highlight the code, language= " + language, e); 185 return code; 186 } 187 } 188 189 public static String markdownToHtml(String input) { 190 return Markdown.convertToHtml(input); 191 } 192 193 public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage, Object[] availableMeasures) { 194 return getContainer().getComponentByType(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage, (String[]) availableMeasures); 195 } 196 197 public List<ViewProxy<Widget>> getWidgets() { 198 return getContainer().getComponentByType(Views.class).getWidgets(); 199 } 200 201 public ViewProxy<Widget> getWidget(String id) { 202 return getContainer().getComponentByType(Views.class).getWidget(id); 203 } 204 205 public List<ViewProxy<Page>> getPages(String section, String resourceScope, String resourceQualifier, String resourceLanguage, Object[] availableMeasures) { 206 return getContainer().getComponentByType(Views.class).getPages(section, resourceScope, resourceQualifier, resourceLanguage, (String[]) availableMeasures); 207 } 208 209 public List<ViewProxy<Page>> getResourceTabs() { 210 return getContainer().getComponentByType(Views.class).getPages(NavigationSection.RESOURCE_TAB, null, null, null, null); 211 } 212 213 public List<ViewProxy<Page>> getResourceTabs(String scope, String qualifier, String language, Object[] availableMeasures) { 214 return getContainer().getComponentByType(Views.class).getPages(NavigationSection.RESOURCE_TAB, scope, qualifier, language, (String[]) availableMeasures); 215 } 216 217 public List<ViewProxy<Page>> getResourceTabsForMetric(String scope, String qualifier, String language, Object[] availableMeasures, String metric) { 218 return getContainer().getComponentByType(Views.class).getPagesForMetric(NavigationSection.RESOURCE_TAB, scope, qualifier, language, (String[]) availableMeasures, metric); 219 } 220 221 public ViewProxy<Page> getPage(String id) { 222 return getContainer().getComponentByType(Views.class).getPage(id); 223 } 224 225 public Collection<RubyRailsWebservice> getRubyRailsWebservices() { 226 return getContainer().getComponentsByType(RubyRailsWebservice.class); 227 } 228 229 public Collection<Language> getLanguages() { 230 return getContainer().getComponentsByType(Language.class); 231 } 232 233 public Database getDatabase() { 234 return getContainer().getComponentByType(Database.class); 235 } 236 237 public boolean createDatabase() { 238 return getContainer().getComponentByType(DatabaseMigrator.class).createDatabase(); 239 } 240 241 /* PROFILES CONSOLE : RULES AND METRIC THRESHOLDS */ 242 243 public List<RuleRepository> getRuleRepositories() { 244 return getContainer().getComponentByType(RulesConsole.class).getRepositories(); 245 } 246 247 public RuleRepository getRuleRepository(String repositoryKey) { 248 return getContainer().getComponentByType(RulesConsole.class).getRepository(repositoryKey); 249 } 250 251 public Set<RuleRepository> getRuleRepositoriesByLanguage(String languageKey) { 252 return getContainer().getComponentByType(RulesConsole.class).getRepositoriesByLanguage(languageKey); 253 } 254 255 public String backupProfile(int profileId) { 256 return getContainer().getComponentByType(ProfilesConsole.class).backupProfile(profileId); 257 } 258 259 public ValidationMessages restoreProfile(String xmlBackup, boolean deleteExisting) { 260 return getContainer().getComponentByType(ProfilesConsole.class).restoreProfile(xmlBackup, deleteExisting); 261 } 262 263 public List<ProfileExporter> getProfileExportersForLanguage(String language) { 264 return getContainer().getComponentByType(ProfilesConsole.class).getProfileExportersForLanguage(language); 265 } 266 267 public List<ProfileImporter> getProfileImportersForLanguage(String language) { 268 return getContainer().getComponentByType(ProfilesConsole.class).getProfileImportersForLanguage(language); 269 } 270 271 /** 272 * @throws IllegalArgumentException if no such exporter 273 */ 274 public String exportProfile(int profileId, String exporterKey) { 275 return getContainer().getComponentByType(ProfilesConsole.class).exportProfile(profileId, exporterKey); 276 } 277 278 public ValidationMessages importProfile(String profileName, String language, String importerKey, String fileContent) { 279 return getContainer().getComponentByType(ProfilesConsole.class).importProfile(profileName, language, importerKey, fileContent); 280 } 281 282 public String getProfileExporterMimeType(String exporterKey) { 283 return getContainer().getComponentByType(ProfilesConsole.class).getProfileExporter(exporterKey).getMimeType(); 284 } 285 286 public void renameProfile(int profileId, String newProfileName) { 287 getProfilesManager().renameProfile(profileId, newProfileName); 288 } 289 290 public void copyProfile(long profileId, String newProfileName) { 291 getProfilesManager().copyProfile((int) profileId, newProfileName); 292 } 293 294 public void deleteProfile(long profileId) { 295 getProfilesManager().deleteProfile((int) profileId); 296 } 297 298 public ValidationMessages changeParentProfile(int profileId, String parentName, String userName) { 299 return getProfilesManager().changeParentProfile(profileId, parentName, userName); 300 } 301 302 public void ruleActivated(int parentProfileId, int activeRuleId, String userName) { 303 getProfilesManager().activated(parentProfileId, activeRuleId, userName); 304 } 305 306 public void ruleParamChanged(int parentProfileId, int activeRuleId, String paramKey, String oldValue, String newValue, String userName) { 307 getProfilesManager().ruleParamChanged(parentProfileId, activeRuleId, paramKey, oldValue, newValue, userName); 308 } 309 310 public void ruleSeverityChanged(int parentProfileId, int activeRuleId, int oldSeverityId, int newSeverityId, String userName) { 311 getProfilesManager().ruleSeverityChanged(parentProfileId, activeRuleId, RulePriority.values()[oldSeverityId], 312 RulePriority.values()[newSeverityId], userName); 313 } 314 315 public void ruleDeactivated(int parentProfileId, int deactivatedRuleId, String userName) { 316 getProfilesManager().deactivated(parentProfileId, deactivatedRuleId, userName); 317 } 318 319 public void revertRule(int profileId, int activeRuleId, String userName) { 320 getProfilesManager().revert(profileId, activeRuleId, userName); 321 } 322 323 public List<Footer> getWebFooters() { 324 return getContainer().getComponentsByType(Footer.class); 325 } 326 327 public Backup getBackup() { 328 return getContainer().getComponentByType(Backup.class); 329 } 330 331 private ProfilesManager getProfilesManager() { 332 return getContainer().getComponentByType(ProfilesManager.class); 333 } 334 335 public void setGlobalProperty(String key, @Nullable String value) { 336 getContainer().getComponentByType(GlobalSettingsUpdater.class).setProperty(key, value); 337 } 338 339 public Settings getSettings() { 340 return getContainer().getComponentByType(Settings.class); 341 } 342 343 public String getConfigurationValue(String key) { 344 return getContainer().getComponentByType(Settings.class).getString(key); 345 } 346 347 public List<InetAddress> getValidInetAddressesForServerId() { 348 return getContainer().getComponentByType(ServerIdGenerator.class).getAvailableAddresses(); 349 } 350 351 public String generateServerId(String organisation, String ipAddress) { 352 return getContainer().getComponentByType(ServerIdGenerator.class).generate(organisation, ipAddress); 353 } 354 355 public Connection getConnection() { 356 try { 357 return getContainer().getComponentByType(Database.class).getDataSource().getConnection(); 358 } catch (Exception e) { 359 /* activerecord does not correctly manage exceptions when connection can not be opened. */ 360 return null; 361 } 362 } 363 364 public Object getCoreComponentByClassname(String className) { 365 if (className == null) { 366 return null; 367 } 368 369 try { 370 Class<?> aClass = Class.forName(className); 371 return getContainer().getComponentByType(aClass); 372 373 } catch (ClassNotFoundException e) { 374 LoggerFactory.getLogger(getClass()).error("Component not found: " + className, e); 375 return null; 376 } 377 } 378 379 public Object getComponentByClassname(String pluginKey, String className) { 380 Object component = null; 381 ComponentContainer container = getContainer(); 382 Class<?> componentClass = container.getComponentByType(DefaultServerPluginRepository.class).getClass(pluginKey, className); 383 if (componentClass != null) { 384 component = container.getComponentByType(componentClass); 385 } 386 return component; 387 } 388 389 public String getMessage(String rubyLocale, String key, String defaultValue, Object... parameters) { 390 if (i18n == null) { 391 i18n = getContainer().getComponentByType(JRubyI18n.class); 392 } 393 return i18n.message(rubyLocale, key, defaultValue, parameters); 394 } 395 396 public String getRuleName(String rubyLocale, String repositoryKey, String key) { 397 if (i18n == null) { 398 i18n = getContainer().getComponentByType(JRubyI18n.class); 399 } 400 return i18n.getRuleName(rubyLocale, repositoryKey, key); 401 } 402 403 public String getRuleDescription(String rubyLocale, String repositoryKey, String key) { 404 if (i18n == null) { 405 i18n = getContainer().getComponentByType(JRubyI18n.class); 406 } 407 return i18n.getRuleDescription(rubyLocale, repositoryKey, key); 408 } 409 410 public String getRuleParamDescription(String rubyLocale, String repositoryKey, String key, String paramKey) { 411 if (i18n == null) { 412 i18n = getContainer().getComponentByType(JRubyI18n.class); 413 } 414 return i18n.getRuleParamDescription(rubyLocale, repositoryKey, key, paramKey); 415 } 416 417 public List<RuleI18nManager.RuleKey> searchRuleName(String rubyLocale, String searchText) { 418 if (i18n == null) { 419 i18n = getContainer().getComponentByType(JRubyI18n.class); 420 } 421 return i18n.searchRuleName(rubyLocale, searchText); 422 } 423 424 public String getJsL10nDictionnary(String rubyLocale) { 425 if (i18n == null) { 426 i18n = getContainer().getComponentByType(JRubyI18n.class); 427 } 428 return i18n.getJsDictionnary(rubyLocale); 429 } 430 431 public void indexProjects() { 432 getContainer().getComponentByType(ResourceIndexerDao.class).indexProjects(); 433 } 434 435 public void indexResource(long resourceId) { 436 getContainer().getComponentByType(ResourceIndexerDao.class).indexResource(resourceId); 437 } 438 439 public void deleteResourceTree(long rootProjectId) { 440 getContainer().getComponentByType(PurgeDao.class).deleteResourceTree(rootProjectId); 441 } 442 443 public void logError(String message) { 444 LoggerFactory.getLogger(getClass()).error(message); 445 } 446 447 public boolean hasSecretKey() { 448 return getContainer().getComponentByType(Settings.class).getEncryption().hasSecretKey(); 449 } 450 451 public String encrypt(String clearText) { 452 return getContainer().getComponentByType(Settings.class).getEncryption().encrypt(clearText); 453 } 454 455 public String generateRandomSecretKey() { 456 return getContainer().getComponentByType(Settings.class).getEncryption().generateRandomSecretKey(); 457 } 458 459 public License parseLicense(String base64) { 460 return License.readBase64(base64); 461 } 462 463 public String getServerHome() { 464 return getContainer().getComponentByType(Settings.class).getString(CoreProperties.SONAR_HOME); 465 } 466 467 public ReviewsNotificationManager getReviewsNotificationManager() { 468 return getContainer().getComponentByType(ReviewsNotificationManager.class); 469 } 470 471 public ComponentContainer getContainer() { 472 return Platform.getInstance().getContainer(); 473 } 474 475 // REVIEWS ------------------------------------------------------------------ 476 477 public List<Screen> listAvailableReviewScreens(Review review, DefaultWorkflowContext context) { 478 return getContainer().getComponentByType(WorkflowEngine.class).listAvailableScreens(review, context, true); 479 } 480 481 public ListMultimap<Long, Screen> listAvailableReviewsScreens(DefaultReview[] reviews, DefaultWorkflowContext context) { 482 return getContainer().getComponentByType(WorkflowEngine.class).listAvailableScreens(reviews, context, true); 483 } 484 485 public Screen getReviewScreen(String commandKey) { 486 return getContainer().getComponentByType(WorkflowEngine.class).getScreen(commandKey); 487 } 488 489 public void executeReviewCommand(String commandKey, DefaultReview review, DefaultWorkflowContext context, Map<String, String> parameters) { 490 try { 491 getContainer().getComponentByType(WorkflowEngine.class).execute(commandKey, review, context, parameters); 492 } catch (RuntimeException e) { 493 LoggerFactory.getLogger(JRubyFacade.class).error("Fail to execute command: " + commandKey + " on review " + review.getReviewId(), e); 494 throw e; 495 } 496 } 497}