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