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.rules; 021 022import org.apache.commons.lang.ArrayUtils; 023import org.apache.commons.lang.StringUtils; 024import org.sonar.api.ServerComponent; 025import org.sonar.api.database.DatabaseSession; 026import org.sonar.api.profiles.*; 027import org.sonar.api.rules.ActiveRule; 028import org.sonar.api.rules.ActiveRuleParam; 029import org.sonar.api.utils.ValidationMessages; 030import org.sonar.jpa.session.DatabaseSessionFactory; 031 032import java.io.StringReader; 033import java.io.StringWriter; 034import java.io.Writer; 035import java.util.ArrayList; 036import java.util.Arrays; 037import java.util.List; 038 039public final class ProfilesConsole implements ServerComponent { 040 041 private DatabaseSessionFactory sessionFactory; 042 private XMLProfileParser xmlProfileParser; 043 private XMLProfileSerializer xmlProfileSerializer; 044 private List<ProfileExporter> exporters = new ArrayList<ProfileExporter>(); 045 private List<ProfileImporter> importers = new ArrayList<ProfileImporter>(); 046 047 public ProfilesConsole(DatabaseSessionFactory sessionFactory, XMLProfileParser xmlProfileParser, XMLProfileSerializer xmlProfileSerializer, 048 ProfileExporter[] exporters, 049 ProfileImporter[] importers) { 050 this.xmlProfileParser = xmlProfileParser; 051 this.xmlProfileSerializer = xmlProfileSerializer; 052 this.sessionFactory = sessionFactory; 053 this.exporters.addAll(Arrays.asList(exporters)); 054 this.importers.addAll(Arrays.asList(importers)); 055 } 056 057 public String backupProfile(int profileId) { 058 DatabaseSession session = sessionFactory.getSession(); 059 RulesProfile profile = loadProfile(session, profileId); 060 if (profile != null) { 061 Writer writer = new StringWriter(); 062 xmlProfileSerializer.write(profile, writer); 063 return writer.toString(); 064 } 065 return null; 066 } 067 068 public ValidationMessages restoreProfile(String xmlBackup, boolean deleteExisting) { 069 ValidationMessages messages = ValidationMessages.create(); 070 RulesProfile profile = xmlProfileParser.parse(new StringReader(xmlBackup), messages); 071 if (profile != null && !messages.hasErrors()) { 072 DatabaseSession session = sessionFactory.getSession(); 073 RulesProfile existingProfile = session.getSingleResult(RulesProfile.class, "name", profile.getName(), "language", profile.getLanguage()); 074 if (existingProfile != null && !deleteExisting) { 075 messages.addErrorText("The profile " + profile + " already exists. Please delete it before restoring."); 076 077 } else { 078 if (existingProfile!=null) { 079 session.removeWithoutFlush(existingProfile); 080 } 081 session.saveWithoutFlush(profile); 082 session.commit(); 083 } 084 } 085 return messages; 086 } 087 088 private RulesProfile loadProfile(DatabaseSession session, int profileId) { 089 return session.getSingleResult(RulesProfile.class, "id", profileId); 090 } 091 092 public List<ProfileExporter> getProfileExportersForLanguage(String language) { 093 List<ProfileExporter> result = new ArrayList<ProfileExporter>(); 094 for (ProfileExporter exporter : exporters) { 095 if (exporter.getSupportedLanguages() == null || exporter.getSupportedLanguages().length == 0 || ArrayUtils.contains(exporter.getSupportedLanguages(), language)) { 096 result.add(exporter); 097 } 098 } 099 return result; 100 } 101 102 public List<ProfileImporter> getProfileImportersForLanguage(String language) { 103 List<ProfileImporter> result = new ArrayList<ProfileImporter>(); 104 for (ProfileImporter importer : importers) { 105 if (importer.getSupportedLanguages() == null || importer.getSupportedLanguages().length == 0 || ArrayUtils.contains(importer.getSupportedLanguages(), language)) { 106 result.add(importer); 107 } 108 } 109 return result; 110 } 111 112 public String exportProfile(int profileId, String exporterKey) { 113 DatabaseSession session = sessionFactory.getSession(); 114 RulesProfile profile = loadProfile(session, profileId); 115 if (profile != null) { 116 ProfileExporter exporter = getProfileExporter(exporterKey); 117 if (exporter == null) { 118 throw new IllegalArgumentException("No such exporter"); 119 } 120 Writer writer = new StringWriter(); 121 exporter.exportProfile(profile, writer); 122 return writer.toString(); 123 } 124 return null; 125 } 126 127 /** 128 * Important : the ruby controller has already create the profile 129 */ 130 public ValidationMessages importProfile(String profileName, String language, String importerKey, String profileDefinition) { 131 ValidationMessages messages = ValidationMessages.create(); 132 ProfileImporter importer = getProfileImporter(importerKey); 133 RulesProfile profile = importer.importProfile(new StringReader(profileDefinition), messages); 134 if (!messages.hasErrors()) { 135 DatabaseSession session = sessionFactory.getSession(); 136 RulesProfile persistedProfile = session.getSingleResult(RulesProfile.class, "name", profileName, "language", language); 137 for (ActiveRule activeRule : profile.getActiveRules()) { 138 ActiveRule persistedActiveRule = persistedProfile.activateRule(activeRule.getRule(), activeRule.getSeverity()); 139 for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) { 140 persistedActiveRule.setParameter(activeRuleParam.getKey(), activeRuleParam.getValue()); 141 } 142 } 143 session.saveWithoutFlush(persistedProfile); 144 session.commit(); 145 } 146 return messages; 147 } 148 149 public ProfileExporter getProfileExporter(String exporterKey) { 150 for (ProfileExporter exporter : exporters) { 151 if (StringUtils.equals(exporterKey, exporter.getKey())) { 152 return exporter; 153 } 154 } 155 return null; 156 } 157 158 public ProfileImporter getProfileImporter(String exporterKey) { 159 for (ProfileImporter importer : importers) { 160 if (StringUtils.equals(exporterKey, importer.getKey())) { 161 return importer; 162 } 163 } 164 return null; 165 } 166}