*/
package org.sonar.core.db;
+import org.sonar.api.ServerComponent;
import org.sonar.core.persistence.DbSession;
import javax.annotation.CheckForNull;
import java.io.Serializable;
+import java.util.Collection;
import java.util.List;
-public interface Dao<E extends Dto<K>, K extends Serializable> {
+public interface Dao<E extends Dto<K>, K extends Serializable> extends ServerComponent {
@CheckForNull
E getByKey(K key, DbSession session);
E insert(E item, DbSession session);
- List<E> insert(List<E> items, DbSession session);
+ List<E> insert(List<E> items, DbSession session);
void delete(E item, DbSession session);
- void delete(List<E> items, DbSession session);
+ void delete(Collection<E> items, DbSession session);
void deleteByKey(K key, DbSession session);
*/
public final class DatabaseUtils {
private DatabaseUtils() {
+ // only static methods
}
public static void closeQuietly(@Nullable Connection connection) {
public class QualityProfileKey implements Serializable{
private final String name, lang;
- protected QualityProfileKey(String name, String lang) {
+ private QualityProfileKey(String name, String lang) {
this.lang = lang;
this.name = name;
}
*/
package org.sonar.core.persistence;
-import org.sonar.core.cluster.NullQueue;
-
-import org.sonar.core.cluster.WorkQueue;
import com.google.common.collect.Maps;
import com.google.common.io.Closeables;
import org.apache.commons.io.FileUtils;
import org.dbunit.IDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.IDatabaseConnection;
-import org.dbunit.dataset.*;
+import org.dbunit.dataset.CompositeDataSet;
+import org.dbunit.dataset.DataSetException;
+import org.dbunit.dataset.IDataSet;
+import org.dbunit.dataset.ITable;
+import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.ext.mssql.InsertIdentityOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.config.Settings;
+import org.sonar.core.cluster.NullQueue;
+import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.config.Logback;
import java.io.File;
import java.util.Map;
import java.util.Properties;
-import static org.mockito.Mockito.mock;
import static org.junit.Assert.fail;
public abstract class AbstractDaoTestCase {
+
private static final Logger LOG = LoggerFactory.getLogger(AbstractDaoTestCase.class);
private static Database database;
private static DatabaseCommands databaseCommands;
databaseCommands = DatabaseCommands.forDialect(database.getDialect());
databaseTester = new DataSourceDatabaseTester(database.getDataSource());
- myBatis = new MyBatis(database, new Logback(),queue);
+ myBatis = new MyBatis(database, new Logback(), queue);
myBatis.start();
}
*/
package org.sonar.core.persistence;
-import org.sonar.core.cluster.NullQueue;
-
-import org.sonar.core.cluster.WorkQueue;
import com.google.common.collect.Maps;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.dbutils.DbUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.config.Settings;
+import org.sonar.core.cluster.NullQueue;
+import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.config.Logback;
import org.sonar.core.persistence.dialect.Dialect;
import java.util.Map;
import java.util.Properties;
-import static org.mockito.Mockito.mock;
import static org.junit.Assert.fail;
/**
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
}
@Override
- public void delete(List<E> items, DbSession session) {
- //TODO check for bulk inserts
+ public void delete(Collection<E> items, DbSession session) {
for(E item:items) {
- this.delete(item, session);
+ delete(item, session);
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.db;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.qualityprofile.db.QualityProfileDao;
+import org.sonar.server.rule2.ActiveRuleDao;
+import org.sonar.server.rule2.RuleDao;
+
+/**
+ * Facade for all db components
+ */
+public class DbClient implements ServerComponent {
+
+ private final MyBatis myBatis;
+ private final RuleDao ruleDao;
+ private final ActiveRuleDao activeRuleDao;
+ private final QualityProfileDao qProfileDao;
+
+ public DbClient(MyBatis myBatis, RuleDao ruleDao, ActiveRuleDao activeRuleDao,
+ QualityProfileDao qProfileDao) {
+ this.myBatis = myBatis;
+ this.ruleDao = ruleDao;
+ this.activeRuleDao = activeRuleDao;
+ this.qProfileDao = qProfileDao;
+ }
+
+ public DbSession openSession(boolean batch) {
+ return myBatis.openSession(batch);
+ }
+
+ public RuleDao ruleDao() {
+ return ruleDao;
+ }
+
+ public ActiveRuleDao activeRuleDao() {
+ return activeRuleDao;
+ }
+
+ public QualityProfileDao qualityProfileDao() {
+ return qProfileDao;
+ }
+}
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.*;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.profiling.Profiling;
import org.sonar.core.purge.PurgeProfiler;
import org.sonar.server.component.ws.ComponentsWs;
import org.sonar.server.component.ws.ProjectsWs;
import org.sonar.server.component.ws.ResourcesWs;
+import org.sonar.server.db.DbClient;
import org.sonar.server.db.EmbeddedDatabaseFactory;
import org.sonar.server.db.migrations.DatabaseMigrations;
import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.debt.*;
+import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
+import org.sonar.server.debt.DebtModelBackup;
+import org.sonar.server.debt.DebtModelLookup;
+import org.sonar.server.debt.DebtModelOperations;
+import org.sonar.server.debt.DebtModelPluginRepository;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.debt.DebtModelXMLExporter;
+import org.sonar.server.debt.DebtRulesXMLImporter;
import org.sonar.server.es.ESIndex;
import org.sonar.server.es.ESNode;
-import org.sonar.server.issue.*;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.DefaultIssueFinder;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogFormatter;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.IssueStatsFinder;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.PublicRubyIssueService;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.issue.actionplan.ActionPlanWs;
import org.sonar.server.issue.filter.IssueFilterService;
import org.sonar.server.platform.ws.RestartHandler;
import org.sonar.server.platform.ws.ServerWs;
import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.plugins.*;
+import org.sonar.server.plugins.BatchWs;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginJarInstaller;
+import org.sonar.server.plugins.ServerPluginJarsInstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitygate.QgateProjectFinder;
import org.sonar.server.qualitygate.QualityGates;
import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualitygate.ws.*;
-import org.sonar.server.qualityprofile.*;
-import org.sonar.server.qualityprofile.ws.ActivateRuleAction;
+import org.sonar.server.qualitygate.ws.QGatesAppAction;
+import org.sonar.server.qualitygate.ws.QGatesCopyAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeselectAction;
+import org.sonar.server.qualitygate.ws.QGatesDestroyAction;
+import org.sonar.server.qualitygate.ws.QGatesListAction;
+import org.sonar.server.qualitygate.ws.QGatesRenameAction;
+import org.sonar.server.qualitygate.ws.QGatesSearchAction;
+import org.sonar.server.qualitygate.ws.QGatesSelectAction;
+import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesShowAction;
+import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesWs;
+import org.sonar.server.qualityprofile.ActiveRuleService;
+import org.sonar.server.qualityprofile.DefaultProfilesCache;
+import org.sonar.server.qualityprofile.ESActiveRule;
+import org.sonar.server.qualityprofile.ProfilesManager;
+import org.sonar.server.qualityprofile.QProfileActiveRuleOperations;
+import org.sonar.server.qualityprofile.QProfileBackup;
+import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.QProfileOperations;
+import org.sonar.server.qualityprofile.QProfileProjectLookup;
+import org.sonar.server.qualityprofile.QProfileProjectOperations;
+import org.sonar.server.qualityprofile.QProfileRepositoryExporter;
+import org.sonar.server.qualityprofile.QProfileRuleLookup;
+import org.sonar.server.qualityprofile.QProfiles;
+import org.sonar.server.qualityprofile.RuleActivationContextFactory;
+import org.sonar.server.qualityprofile.ws.RuleActivationActions;
import org.sonar.server.qualityprofile.ws.ProfilesWs;
import org.sonar.server.qualityprofile.ws.QProfileRecreateBuiltInAction;
import org.sonar.server.qualityprofile.ws.QProfilesWs;
-import org.sonar.server.rule.*;
-import org.sonar.server.rule.ws.*;
+import org.sonar.server.rule.DeprecatedRulesDefinition;
+import org.sonar.server.rule.ESRuleTags;
+import org.sonar.server.rule.RegisterRules;
+import org.sonar.server.rule.RubyRuleService;
+import org.sonar.server.rule.RuleDefinitionsLoader;
+import org.sonar.server.rule.RuleOperations;
+import org.sonar.server.rule.RuleRegistry;
+import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.rule.RuleTagLookup;
+import org.sonar.server.rule.RuleTagOperations;
+import org.sonar.server.rule.RuleTags;
+import org.sonar.server.rule.Rules;
+import org.sonar.server.rule.ws.AddTagsWsHandler;
+import org.sonar.server.rule.ws.RemoveTagsWsHandler;
+import org.sonar.server.rule.ws.RuleSearchWsHandler;
+import org.sonar.server.rule.ws.RuleShowWsHandler;
+import org.sonar.server.rule.ws.RuleTagsWs;
+import org.sonar.server.rule.ws.RulesWs;
import org.sonar.server.rule2.RuleService;
import org.sonar.server.rule2.ws.RulesWebService;
import org.sonar.server.rule2.ws.SearchAction;
+import org.sonar.server.rule2.ws.SetTagsAction;
import org.sonar.server.rule2.ws.TagsAction;
import org.sonar.server.search.IndexUtils;
import org.sonar.server.source.CodeColorizers;
import org.sonar.server.source.ws.ScmWriter;
import org.sonar.server.source.ws.ShowAction;
import org.sonar.server.source.ws.SourcesWs;
-import org.sonar.server.startup.*;
+import org.sonar.server.startup.CleanPreviewAnalysisCache;
+import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.GwtPublisher;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterDashboards;
+import org.sonar.server.startup.RegisterDebtModel;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterQualityProfiles;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
import org.sonar.server.test.ws.TestsWs;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
import org.sonar.server.ui.PageDecorations;
import org.sonar.server.ui.Views;
import org.sonar.server.updatecenter.ws.UpdateCenterWs;
-import org.sonar.server.user.*;
+import org.sonar.server.user.DefaultUserService;
+import org.sonar.server.user.DoPrivileged;
+import org.sonar.server.user.GroupMembershipFinder;
+import org.sonar.server.user.GroupMembershipService;
+import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.user.SecurityRealmFactory;
import org.sonar.server.user.ws.UsersWs;
-import org.sonar.server.util.*;
+import org.sonar.server.util.BooleanTypeValidation;
+import org.sonar.server.util.FloatTypeValidation;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringListTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TextTypeValidation;
+import org.sonar.server.util.TypeValidations;
import org.sonar.server.ws.ListingWs;
import org.sonar.server.ws.WebServiceEngine;
new TempFolderProvider(),
System2.INSTANCE,
org.sonar.server.rule2.RuleDao.class,
- org.sonar.server.rule2.ActiveRuleDao.class
+ org.sonar.server.rule2.ActiveRuleDao.class,
+ DbClient.class
));
components.addAll(CorePropertyDefinitions.all());
components.addAll(DatabaseMigrations.CLASSES);
pico.addSingleton(QProfileRecreateBuiltInAction.class);
pico.addSingleton(QProfilesWs.class);
pico.addSingleton(ProfilesWs.class);
- pico.addSingleton(ActivateRuleAction.class);
+ pico.addSingleton(RuleActivationActions.class);
pico.addSingleton(ActiveRuleService.class);
pico.addSingleton(RuleActivationContextFactory.class);
pico.addSingleton(SearchAction.class);
pico.addSingleton(org.sonar.server.rule2.ws.ShowAction.class);
pico.addSingleton(TagsAction.class);
+ pico.addSingleton(SetTagsAction.class);
// rule tags
pico.addSingleton(ESRuleTags.class);
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.rule.RuleParamDto;
-import org.sonar.server.rule2.ActiveRuleDao;
+import org.sonar.server.db.DbClient;
import org.sonar.server.user.UserSession;
import org.sonar.server.util.TypeValidations;
public class ActiveRuleService implements ServerComponent {
- private final MyBatis myBatis;
- private final ActiveRuleDao activeRuleDao;
+ private final DbClient db;
private final TypeValidations typeValidations;
private final RuleActivationContextFactory contextFactory;
- public ActiveRuleService(MyBatis myBatis, ActiveRuleDao activeRuleDao,
+ public ActiveRuleService(DbClient db,
RuleActivationContextFactory contextFactory, TypeValidations typeValidations) {
- this.myBatis = myBatis;
- this.activeRuleDao = activeRuleDao;
+ this.db = db;
this.contextFactory = contextFactory;
this.typeValidations = typeValidations;
}
* Activate a rule on a Quality profile. Update configuration (severity/parameters) if the rule is already
* activated.
*/
- public List<ActiveRuleChange> activate(RuleActivation activation, UserSession userSession) {
- verifyPermission(userSession);
+ public List<ActiveRuleChange> activate(RuleActivation activation) {
+ verifyPermission(UserSession.get());
- DbSession dbSession = myBatis.openSession(false);
+ DbSession dbSession = db.openSession(false);
List<ActiveRuleChange> changes = Lists.newArrayList();
try {
RuleActivationContext context = contextFactory.create(activation.getKey(), dbSession);
ActiveRuleDto activeRule = ActiveRuleDto.createFor(null, null /* TODO */)
.setKey(change.getKey())
.setSeverity(change.getSeverity());
- activeRuleDao.insert(activeRule, dbSession);
+ db.activeRuleDao().insert(activeRule, dbSession);
// TODO insert activeruelparams
} else if (change.getType() == ActiveRuleChange.Type.DEACTIVATED) {
- activeRuleDao.deleteByKey(change.getKey(), dbSession);
+ db.activeRuleDao().deleteByKey(change.getKey(), dbSession);
} else if (change.getType() == ActiveRuleChange.Type.UPDATED) {
/**
* Deactivate a rule on a Quality profile. Does nothing if the rule is not activated.
*/
- public List<ActiveRuleChange> deactivate(ActiveRuleKey key, UserSession userSession) {
- verifyPermission(userSession);
+ public List<ActiveRuleChange> deactivate(ActiveRuleKey key) {
+ verifyPermission(UserSession.get());
throw new UnsupportedOperationException("TODO");
}
- public List<ActiveRuleChange> bulkActivate(BulkRuleActivation activation, UserSession userSession) {
- verifyPermission(userSession);
+ public List<ActiveRuleChange> bulkActivate(BulkRuleActivation activation) {
+ verifyPermission(UserSession.get());
throw new UnsupportedOperationException("TODO");
}
return this;
}
- public RuleActivation setParam(String key, @Nullable String value) {
+ public RuleActivation setParameter(String key, @Nullable String value) {
String sanitizedValue = Strings.emptyToNull(value);
if (value == null) {
parameters.remove(key);
return this;
}
+ public RuleActivation setParameters(Map<String, String> m) {
+ parameters.clear();
+ parameters.putAll(m);
+ return this;
+ }
+
public ActiveRuleKey getKey() {
return key;
}
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDao;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.core.rule.RuleDto;
-import org.sonar.server.rule2.ActiveRuleDao;
-import org.sonar.server.rule2.RuleDao;
+import org.sonar.server.db.DbClient;
import java.util.Collection;
public class RuleActivationContextFactory implements ServerComponent {
- private final ActiveRuleDao activeRuleDao;
- private final RuleDao ruleDao;
- private final QualityProfileDao profileDao;
+ private final DbClient db;
- public RuleActivationContextFactory(ActiveRuleDao activeRuleDao, RuleDao ruleDao, QualityProfileDao profileDao) {
- this.activeRuleDao = activeRuleDao;
- this.ruleDao = ruleDao;
- this.profileDao = profileDao;
+ public RuleActivationContextFactory(DbClient db) {
+ this.db = db;
}
public RuleActivationContext create(ActiveRuleKey key, DbSession session) {
}
private RuleDto initRule(RuleKey ruleKey, RuleActivationContext context, DbSession dbSession) {
- RuleDto rule = ruleDao.getByKey(ruleKey, dbSession);
+ RuleDto rule = db.ruleDao().getByKey(ruleKey, dbSession);
if (rule == null) {
throw new IllegalArgumentException("Rule not found: " + ruleKey);
}
throw new IllegalArgumentException("Rule was removed: " + ruleKey);
}
context.setRule(rule);
- context.setRuleParams(ruleDao.findRuleParamsByRuleKey(rule.getKey(), dbSession));
+ context.setRuleParams(db.ruleDao().findRuleParamsByRuleKey(rule.getKey(), dbSession));
return rule;
}
private QualityProfileDto initProfile(ActiveRuleKey key, RuleActivationContext context, DbSession session, boolean parent) {
- QualityProfileDto profile = profileDao.selectByNameAndLanguage(
+ QualityProfileDto profile = db.qualityProfileDao().selectByNameAndLanguage(
key.qProfile().name(), key.qProfile().lang());
if (profile == null) {
throw new IllegalArgumentException("Quality profile not found: " + key.qProfile());
}
private void initActiveRules(ActiveRuleKey key, RuleActivationContext context, DbSession session, boolean parent) {
- ActiveRuleDto activeRule = activeRuleDao.getByKey(key, session);
+ ActiveRuleDto activeRule = db.activeRuleDao().getByKey(key, session);
Collection<ActiveRuleParamDto> activeRuleParams = null;
if (activeRule != null) {
- context.setActiveRuleParams(activeRuleDao.findParamsByActiveRule(activeRule, session));
+ context.setActiveRuleParams(db.activeRuleDao().findParamsByActiveRule(activeRule, session));
}
if (parent) {
context.setParentActiveRule(activeRule);
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.qualityprofile.ws;
-
-import org.sonar.api.rule.Severity;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.server.qualityprofile.ActiveRuleService;
-
-public class ActivateRuleAction implements RequestHandler {
-
- private final ActiveRuleService service;
-
- public ActivateRuleAction(ActiveRuleService service) {
- this.service = service;
- }
-
- void define(WebService.NewController controller) {
- WebService.NewAction action = controller
- .createAction("activate_rule")
- .setDescription("Activate a rule on a Quality profile")
- .setHandler(this)
- .setPost(true)
- .setSince("4.4");
-
- action.createParam("profile_lang")
- .setDescription("Profile language")
- .setRequired(true)
- .setExampleValue("java");
-
- action.createParam("profile_name")
- .setDescription("Profile name")
- .setRequired(true)
- .setExampleValue("My profile");
-
- action.createParam("rule_repo")
- .setDescription("Rule repository")
- .setRequired(true)
- .setExampleValue("squid");
-
- action.createParam("rule_key")
- .setDescription("Rule key")
- .setRequired(true)
- .setExampleValue("AvoidCycles");
-
- action.createParam("severity")
- .setDescription("Severity")
- .setPossibleValues(Severity.ALL);
-
- action.createParam("params")
- .setDescription("Parameters");
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
-
- }
-}
public class QProfilesWs implements WebService {
private final QProfileRecreateBuiltInAction recreateBuiltInAction;
- private final ActivateRuleAction activateRuleAction;
+ private final RuleActivationActions ruleActivationActions;
- public QProfilesWs(QProfileRecreateBuiltInAction recreateBuiltInAction, ActivateRuleAction activateRuleAction) {
+ public QProfilesWs(QProfileRecreateBuiltInAction recreateBuiltInAction, RuleActivationActions ruleActivationActions) {
this.recreateBuiltInAction = recreateBuiltInAction;
- this.activateRuleAction = activateRuleAction;
+ this.ruleActivationActions = ruleActivationActions;
}
@Override
.setSince("4.4");
recreateBuiltInAction.define(controller);
- activateRuleAction.define(controller);
+ ruleActivationActions.define(controller);
controller.done();
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.qualityprofile.ws;
+
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
+import org.sonar.server.qualityprofile.ActiveRuleService;
+import org.sonar.server.qualityprofile.RuleActivation;
+
+public class RuleActivationActions {
+
+ private final ActiveRuleService service;
+
+ public RuleActivationActions(ActiveRuleService service) {
+ this.service = service;
+ }
+
+ void define(WebService.NewController controller) {
+ defineActivateAction(controller);
+ defineDeactivateAction(controller);
+ }
+
+ private void defineActivateAction(WebService.NewController controller) {
+ WebService.NewAction activate = controller
+ .createAction("activate_rule")
+ .setDescription("Activate a rule on a Quality profile")
+ .setHandler(new RequestHandler() {
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ activate(request, response);
+ }
+ })
+ .setPost(true)
+ .setSince("4.4");
+
+ defineActiveRuleKeyParameters(activate);
+
+ activate.createParam("severity")
+ .setDescription("Severity")
+ .setPossibleValues(Severity.ALL);
+
+ activate.createParam("params")
+ .setDescription("Parameters");
+ }
+
+ private void defineDeactivateAction(WebService.NewController controller) {
+ WebService.NewAction deactivate = controller
+ .createAction("deactivate_rule")
+ .setDescription("Deactivate a rule on a Quality profile")
+ .setHandler(new RequestHandler() {
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ deactivate(request, response);
+ }
+ })
+ .setPost(true)
+ .setSince("4.4");
+ defineActiveRuleKeyParameters(deactivate);
+ }
+
+ private void defineActiveRuleKeyParameters(WebService.NewAction action) {
+ action.createParam("profile_lang")
+ .setDescription("Profile language")
+ .setRequired(true)
+ .setExampleValue("java");
+
+ action.createParam("profile_name")
+ .setDescription("Profile name")
+ .setRequired(true)
+ .setExampleValue("My profile");
+
+ action.createParam("rule_repo")
+ .setDescription("Rule repository")
+ .setRequired(true)
+ .setExampleValue("squid");
+
+ action.createParam("rule_key")
+ .setDescription("Rule key")
+ .setRequired(true)
+ .setExampleValue("AvoidCycles");
+ }
+
+ private void activate(Request request, Response response) throws Exception {
+ ActiveRuleKey key = readKey(request);
+ RuleActivation activation = new RuleActivation(key);
+ activation.setSeverity(request.param("severity"));
+ String params = request.param("params");
+ if (params != null) {
+ activation.setParameters(KeyValueFormat.parse(params));
+ }
+ service.activate(activation);
+ }
+
+ private void deactivate(Request request, Response response) throws Exception {
+ service.deactivate(readKey(request));
+ }
+
+ private ActiveRuleKey readKey(Request request) {
+ return ActiveRuleKey.of(
+ QualityProfileKey.of(request.mandatoryParam("profile_name"), request.mandatoryParam("profile_lang")),
+ RuleKey.of(request.mandatoryParam("rule_repo"), request.mandatoryParam("rule_key")));
+ }
+}
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
+import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRuleKey> {
- private final ActiveRuleDao activeRuleDao;
-
public static enum ActiveRuleField {
OVERRIDE("override"),
INHERITANCE("inheritance"),
}
}
- public ActiveRuleNormalizer(MyBatis mybatis, ActiveRuleDao activeRuleDao) {
- super(mybatis);
- this.activeRuleDao = activeRuleDao;
+ public ActiveRuleNormalizer(DbClient db) {
+ super(db);
}
@Override
public UpdateRequest normalize(ActiveRuleKey key) {
- DbSession dbSession = getMyBatis().openSession(false);
+ DbSession dbSession = db().openSession(false);
try {
- return normalize(activeRuleDao.getByKey(key, dbSession));
+ return normalize(db().activeRuleDao().getByKey(key, dbSession));
} finally {
dbSession.close();
}
XContentBuilder document = jsonBuilder().startObject();
ActiveRuleKey key = rule.getKey();
- if(key == null){
+ if (key == null) {
throw new IllegalStateException("Cannot normalize ActiveRuleDto with null key");
}
import com.google.common.collect.Lists;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
-import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.persistence.DbSession;
import java.util.List;
import java.util.Map;
-public class RuleDao extends BaseDao<RuleMapper, RuleDto, RuleKey> implements BatchComponent, ServerComponent {
+public class RuleDao extends BaseDao<RuleMapper, RuleDto, RuleKey> implements ServerComponent {
public RuleDao() {
super(new RuleIndexDefinition(), RuleMapper.class);
}
@CheckForNull
- public RuleDto getParent(RuleDto rule, DbSession session){
+ public RuleDto getParent(RuleDto rule, DbSession session) {
Preconditions.checkNotNull(rule.getParentId(), "Rule has no persisted parent!");
return mapper(session).selectById(rule.getParentId());
}
return keys;
}
- /** Finder methods for Rules */
+ /**
+ * Finder methods for Rules
+ */
- public List<RuleDto> findByNonManual(DbSession session){
+ public List<RuleDto> findByNonManual(DbSession session) {
return mapper(session).selectNonManual();
}
return ImmutableList.of(mapper(session).selectByName(name));
}
- /** Nested DTO RuleParams */
+ /**
+ * Nested DTO RuleParams
+ */
public void addRuleParam(RuleDto rule, RuleParamDto paramDto, DbSession session) {
Preconditions.checkNotNull(rule.getId(), "Rule id must be set");
paramDto.setRuleId(rule.getId());
System.out.println("paramDto = " + paramDto);
session.enqueue(new EmbeddedIndexAction<RuleKey>(this.getIndexType(), IndexAction.Method.UPDATE, paramDto, rule.getKey()));
- mapper(session).updateParameter(paramDto);
+ mapper(session).updateParameter(paramDto);
return paramDto;
}
session.enqueue(new EmbeddedIndexAction<RuleKey>(this.getIndexType(), IndexAction.Method.DELETE, param, rule.getKey()));
}
- /** Finder methods for RuleParams */
+ /**
+ * Finder methods for RuleParams
+ */
public List<RuleParamDto> findAllRuleParams(DbSession session) {
return mapper(session).selectAllParams();
public List<RuleParamDto> findRuleParamsByRules(List<RuleDto> ruleDtos, DbSession session) {
List<RuleParamDto> ruleParamDtos = new ArrayList<RuleParamDto>();
- for(RuleDto rule:ruleDtos){
+ for (RuleDto rule : ruleDtos) {
ruleParamDtos.addAll(findRuleParamsByRuleKey(rule.getKey(), session));
}
return ruleParamDtos;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.core.cluster.WorkQueue;
public class RuleIndex extends BaseIndex<Rule, RuleQuery, RuleDto, RuleKey> {
- private static final Logger LOG = LoggerFactory.getLogger(RuleIndex.class);
-
public static final Set<String> PUBLIC_FIELDS = ImmutableSet.of(
RuleField.KEY.key(),
RuleField.NAME.key(),
protected XContentBuilder getIndexSettings() throws IOException {
return jsonBuilder().startObject()
.startObject("index")
- .field("number_of_replicas", 0)
- .field("number_of_shards", 3)
- .startObject("mapper")
- .field("dynamic", true)
- .endObject()
- .startObject("analysis")
- .startObject("analyzer")
- .startObject("path_analyzer")
- .field("type", "custom")
- .field("tokenizer", "path_hierarchy")
- .endObject()
- .startObject("sortable")
- .field("type", "custom")
- .field("tokenizer", "keyword")
- .field("filter", "lowercase")
- .endObject()
- .startObject("rule_name")
- .field("type", "custom")
- .field("tokenizer", "standard")
- .array("filter", "lowercase", "rule_name_ngram")
- .endObject()
- .endObject()
- .startObject("filter")
- .startObject("rule_name_ngram")
- .field("type", "nGram")
- .field("min_gram", 3)
- .field("max_gram", 5)
- .array("token_chars", "letter", "digit")
- .endObject()
- .endObject()
- .endObject()
- .endObject()
+ .field("number_of_replicas", 0)
+ .field("number_of_shards", 3)
+ .startObject("mapper")
+ .field("dynamic", true)
+ .endObject()
+ .startObject("analysis")
+ .startObject("analyzer")
+ .startObject("path_analyzer")
+ .field("type", "custom")
+ .field("tokenizer", "path_hierarchy")
+ .endObject()
+ .startObject("sortable")
+ .field("type", "custom")
+ .field("tokenizer", "keyword")
+ .field("filter", "lowercase")
+ .endObject()
+ .startObject("rule_name")
+ .field("type", "custom")
+ .field("tokenizer", "standard")
+ .array("filter", "lowercase", "rule_name_ngram")
+ .endObject()
+ .endObject()
+ .startObject("filter")
+ .startObject("rule_name_ngram")
+ .field("type", "nGram")
+ .field("min_gram", 3)
+ .field("max_gram", 5)
+ .array("token_chars", "letter", "digit")
+ .endObject()
+ .endObject()
+ .endObject()
+ .endObject()
.endObject();
}
.endObject();
mapping.startObject(RuleField.NAME.key())
- .field("type", "multi_field")
- .startObject("fields")
- .startObject(RuleField.NAME.key())
- .field("type", "string")
- .field("index", "analyzed")
- .endObject()
- .startObject("search")
- .field("type", "string")
- .field("index", "analyzed")
- .field("index_analyzer", "rule_name")
- .field("search_analyzer", "standard")
- .endObject()
- .endObject()
+ .field("type", "multi_field")
+ .startObject("fields")
+ .startObject(RuleField.NAME.key())
+ .field("type", "string")
+ .field("index", "analyzed")
+ .endObject()
+ .startObject("search")
+ .field("type", "string")
+ .field("index", "analyzed")
+ .field("index_analyzer", "rule_name")
+ .field("search_analyzer", "standard")
+ .endObject()
+ .endObject()
.endObject();
mapping.startObject(RuleField.ACTIVE.key())
.setIndices(this.getIndexName());
/* Integrate Facets */
- if(options.isFacet()) {
+ if (options.isFacet()) {
this.setFacets(esSearch);
}
/* integrate Query Sort */
- if(query.getSortField() != null){
+ if (query.getSortField() != null) {
FieldSortBuilder sort = SortBuilders.fieldSort(query.getSortField().field().key());
- if(query.isAscendingSort()){
+ if (query.isAscendingSort()) {
sort.order(SortOrder.ASC);
} else {
sort.order(SortOrder.DESC);
}
esSearch.addSort(sort);
- } else if(query.getQueryText() != null && !query.getQueryText().isEmpty()){
+ } else if (query.getQueryText() != null && !query.getQueryText().isEmpty()) {
esSearch.addSort(SortBuilders.scoreSort());
} else {
esSearch.addSort(RuleField.UPDATED_AT.key(), SortOrder.DESC);
/* integrate Option's Fields */
if (options.getFieldsToReturn() != null &&
!options.getFieldsToReturn().isEmpty()) {
- for(String field:options.getFieldsToReturn()) {
+ for (String field : options.getFieldsToReturn()) {
esSearch.addField(field);
}
} else {
qb = QueryBuilders.multiMatchQuery(query.getQueryText(),
"_id",
RuleField.NAME.key(),
- RuleField.NAME.key()+".search",
+ RuleField.NAME.key() + ".search",
RuleField.HTML_DESCRIPTION.key(),
RuleField.KEY.key(),
RuleField.LANGUAGE.key(),
this.addMultiFieldTermFilter(query.getTags(), fb, RuleField.TAGS.key(), RuleField.SYSTEM_TAGS.key());
- if(query.getStatuses() != null && !query.getStatuses().isEmpty()) {
+ if (query.getStatuses() != null && !query.getStatuses().isEmpty()) {
Collection<String> stringStatus = new ArrayList<String>();
for (RuleStatus status : query.getStatuses()) {
stringStatus.add(status.name());
this.addTermFilter(RuleField.STATUS.key(), stringStatus, fb);
}
- if((query.getLanguages() != null && !query.getLanguages().isEmpty()) ||
+ if ((query.getLanguages() != null && !query.getLanguages().isEmpty()) ||
(query.getRepositories() != null && !query.getRepositories().isEmpty()) ||
(query.getSeverities() != null && !query.getSeverities().isEmpty()) ||
(query.getTags() != null && !query.getTags().isEmpty()) ||
}
}
- private void setFacets(SearchRequestBuilder query){
+ private void setFacets(SearchRequestBuilder query) {
//TODO there are no aggregation in 0.9!!! Must use facet...
/* the Lang facet */
@Override
protected Rule getSearchResult(Map<String, Object> response) {
- if(response == null){
+ if (response == null) {
throw new IllegalStateException("Cannot construct Rule with null map!!!");
}
return new RuleDoc(response);
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
+import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
- private final RuleDao ruleDao;
-
public static enum RuleField {
KEY("key"),
REPOSITORY("repo"),
}
}
- public RuleNormalizer(MyBatis myBatis, RuleDao ruleDao) {
- super(myBatis);
- this.ruleDao = ruleDao;
+ public RuleNormalizer(DbClient db) {
+ super(db);
}
@Override
public UpdateRequest normalize(RuleKey key) {
- DbSession dbSession = getMyBatis().openSession(false);
+ DbSession dbSession = db().openSession(false);
try {
- return normalize(ruleDao.getByKey(key, dbSession));
+ return normalize(db().ruleDao().getByKey(key, dbSession));
} finally {
dbSession.close();
}
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
-import org.sonar.core.rule.RuleDao;
-import org.sonar.server.search.Hit;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.search.QueryOptions;
import org.sonar.server.search.Result;
+import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
-import java.util.List;
+import java.util.Set;
/**
* @since 4.4
*/
public class RuleService implements ServerComponent {
- private RuleIndex index;
+ private final RuleIndex index;
+ private final DbClient db;
- public RuleService(RuleIndex index) {
+ public RuleService(RuleIndex index, DbClient db) {
this.index = index;
+ this.db = db;
}
@CheckForNull
public Rule getByKey(RuleKey key) {
- Rule hit = index.getByKey(key);
- if (hit != null) {
- return hit;
- }
- return null;
+ return index.getByKey(key);
}
public RuleQuery newRuleQuery() {
/**
* List all tags
*/
- public List<String> listTags() {
+ public Set<String> listTags() {
throw new UnsupportedOperationException("TODO");
}
+ public void setTags(RuleKey ruleKey, Set<String> tags) {
+ checkAdminPermission(UserSession.get());
+
+ DbSession dbSession = db.openSession(false);
+ try {
+ RuleDto rule = db.ruleDao().getByKey(ruleKey, dbSession);
+ if (rule == null) {
+ throw new NotFoundException(String.format("Rule %s not found", ruleKey));
+ }
+ boolean changed = RuleTagHelper.applyTags(rule, tags);
+ if (changed) {
+ db.ruleDao().update(rule, dbSession);
+ dbSession.commit();
+ }
+ } finally {
+ dbSession.close();
+ }
+ }
+
+ private void checkAdminPermission(UserSession userSession) {
+ userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+ }
+
public RuleService refresh() {
this.index.refresh();
return this;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule2;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+import org.sonar.api.server.rule.RuleTagFormat;
+import org.sonar.core.rule.RuleDto;
+
+import javax.annotation.Nullable;
+import java.util.Set;
+
+class RuleTagHelper {
+
+ private RuleTagHelper() {
+ // only static stuff
+ }
+
+ /**
+ * Validates tags and resolves conflicts between user and system tags.
+ */
+ static boolean applyTags(RuleDto rule, Set<String> tags) {
+ for (String tag : tags) {
+ RuleTagFormat.validate(tag);
+ }
+
+ Set<String> initialTags = rule.getTags();
+ final Set<String> systemTags = rule.getSystemTags();
+ Set<String> withoutSystemTags = Sets.filter(tags, new Predicate<String>() {
+ @Override
+ public boolean apply(@Nullable String input) {
+ return input != null && !systemTags.contains(input);
+ }
+ });
+ rule.setTags(withoutSystemTags);
+ return Sets.difference(initialTags, withoutSystemTags).size() > 0;
+ }
+}
private final SearchAction search;
private final ShowAction show;
private final TagsAction tags;
+ private final SetTagsAction setTags;
- public RulesWebService(SearchAction search, ShowAction show, TagsAction tags) {
+ public RulesWebService(SearchAction search, ShowAction show, TagsAction tags, SetTagsAction setTags) {
this.search = search;
this.show = show;
this.tags = tags;
+ this.setTags = setTags;
}
@Override
search.define(controller);
show.define(controller);
tags.define(controller);
+ setTags.define(controller);
controller.done();
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule2.ws;
+
+import com.google.common.collect.Sets;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.rule2.RuleService;
+
+import java.util.Set;
+
+public class SetTagsAction implements RequestHandler {
+
+ private final RuleService service;
+
+ public SetTagsAction(RuleService service) {
+ this.service = service;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction setTags = controller
+ .createAction("set_tags")
+ .setDescription("Set the tags of a coding rule")
+ .setSince("4.4")
+ .setPost(true)
+ .setHandler(this);
+ setTags
+ .createParam("repo")
+ .setRequired(true)
+ .setDescription("Repository key")
+ .setExampleValue("javascript");
+ setTags
+ .createParam("key")
+ .setRequired(true)
+ .setDescription("Rule key")
+ .setExampleValue("EmptyBlock");
+ setTags
+ .createParam("tags")
+ .setDescription("Comma-separated list of tags. Blank value is used to remove all tags.")
+ .setRequired(true)
+ .setExampleValue("java8,security");
+ }
+
+ @Override
+ public void handle(Request request, Response response) {
+ RuleKey key = RuleKey.of(request.mandatoryParam("repo"), request.mandatoryParam("key"));
+ Set<String> tags = Sets.newHashSet(request.paramAsStrings("tags"));
+ service.setTags(key, tags);
+ }
+}
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.server.rule2.RuleService;
-import java.util.List;
+import java.util.Set;
public class TagsAction implements RequestHandler {
void define(WebService.NewController controller) {
controller
.createAction("tags")
- .setDescription("Search for a collection of relevant rules matching a specified query")
+ .setDescription("List all rule tags")
.setSince("4.4")
.setHandler(this);
}
@Override
public void handle(Request request, Response response) {
- List<String> tags = service.listTags();
+ Set<String> tags = service.listTags();
JsonWriter json = response.newJsonWriter().beginObject();
json.name("tags").beginArray();
for (String tag : tags) {
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.core.db.Dto;
-import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
import java.io.IOException;
import java.io.Serializable;
public abstract class BaseNormalizer<E extends Dto<K>, K extends Serializable> {
- private MyBatis myBatis;
+ private static final Logger LOG = LoggerFactory.getLogger(BaseNormalizer.class);
+
+ private final DbClient db;
- protected BaseNormalizer(MyBatis mybatis) {
- this.myBatis = mybatis;
+ protected BaseNormalizer(DbClient db) {
+ this.db = db;
}
- protected MyBatis getMyBatis() {
- return myBatis;
+ protected DbClient db() {
+ return db;
}
public boolean canNormalize(Class<?> objectClass, Class<?> keyClass) {
public abstract UpdateRequest normalize(E dto);
- private static final Logger LOG = LoggerFactory.getLogger(BaseNormalizer.class);
-
protected void indexField(String field, Object value, XContentBuilder document) {
try {
document.field(field, value);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.db;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.core.qualityprofile.db.QualityProfileDao;
+import org.sonar.server.rule2.ActiveRuleDao;
+import org.sonar.server.rule2.RuleDao;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DbClientTest {
+
+ @Rule
+ public TestDatabase db = new TestDatabase();
+
+ @Test
+ public void facade() throws Exception {
+ MyBatis myBatis = db.myBatis();
+ RuleDao ruleDao = mock(RuleDao.class);
+ ActiveRuleDao activeRuleDao = mock(ActiveRuleDao.class);
+ QualityProfileDao qualityProfileDao = mock(QualityProfileDao.class);
+
+ DbClient client = new DbClient(myBatis, ruleDao, activeRuleDao, qualityProfileDao);
+
+ DbSession dbSession = client.openSession(true);
+ assertThat(dbSession).isNotNull();
+ assertThat(dbSession.getConnection().isClosed()).isFalse();
+ dbSession.close();
+
+ // DAO
+ assertThat(client.ruleDao()).isSameAs(ruleDao);
+ assertThat(client.activeRuleDao()).isSameAs(activeRuleDao);
+ assertThat(client.qualityProfileDao()).isSameAs(qualityProfileDao);
+ }
+}
public void setUp() throws Exception {
tester = new WsTester(new QProfilesWs(
new QProfileRecreateBuiltInAction(qProfileBackup),
- new ActivateRuleAction(mock(ActiveRuleService.class))));
+ new RuleActivationActions(mock(ActiveRuleService.class))));
}
@Test
@Before
public void setUp() {
- controller = new WsTester(new QProfilesWs(new QProfileRecreateBuiltInAction(mock(QProfileBackup.class)), new ActivateRuleAction(mock(ActiveRuleService.class))))
+ controller = new WsTester(new QProfilesWs(new QProfileRecreateBuiltInAction(mock(QProfileBackup.class)), new RuleActivationActions(mock(ActiveRuleService.class))))
.controller("api/qualityprofiles");
}
assertThat(controller).isNotNull();
assertThat(controller.path()).isEqualTo("api/qualityprofiles");
assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(2);
+ assertThat(controller.actions()).hasSize(3);
}
@Test
- public void define_recreate_built_in_action() throws Exception {
+ public void define_recreate_built_action() throws Exception {
WebService.Action restoreProfiles = controller.action("recreate_built_in");
assertThat(restoreProfiles).isNotNull();
assertThat(restoreProfiles.isPost()).isTrue();
}
@Test
- public void define_activate_rule_in_action() throws Exception {
+ public void define_activate_rule_action() throws Exception {
WebService.Action restoreProfiles = controller.action("activate_rule");
assertThat(restoreProfiles).isNotNull();
assertThat(restoreProfiles.isPost()).isTrue();
assertThat(restoreProfiles.params()).hasSize(6);
}
+ @Test
+ public void define_deactivate_rule_action() throws Exception {
+ WebService.Action restoreProfiles = controller.action("deactivate_rule");
+ assertThat(restoreProfiles).isNotNull();
+ assertThat(restoreProfiles.isPost()).isTrue();
+ assertThat(restoreProfiles.params()).hasSize(4);
+ }
+
}
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.utils.DateUtils;
import org.sonar.check.Cardinality;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
public class RuleServiceMediumTest {
@ClassRule
- public static ServerTester tester = new ServerTester()
- .setProperty("sonar.es.http.port","9200");
+ public static ServerTester tester = new ServerTester();
MyBatis myBatis = tester.get(MyBatis.class);
RuleDao dao = tester.get(RuleDao.class);
RuleIndex index = tester.get(RuleIndex.class);
+ RuleService service = tester.get(RuleService.class);
DbSession dbSession;
@Before
// verify that rule is indexed in es
index.refresh();
-
-// Thread.sleep(10000000);
-
-
Rule hit = index.getByKey(ruleKey);
assertThat(hit).isNotNull();
assertThat(hit.key().repository()).isEqualTo(ruleKey.repository());
assertThat(hit.template()).isFalse();
assertThat(hit.tags()).containsOnly("tag1", "tag2");
assertThat(hit.systemTags()).containsOnly("systag1", "systag2");
-
}
@Test
assertThat(hit).isNotNull();
assertThat(hit.key()).isNotNull();
-
RuleService service = tester.get(RuleService.class);
Rule rule = service.getByKey(ruleKey);
assertThat(Iterables.getLast(rule.params(), null).key()).isEqualTo("max");
}
+ @Test
+ @Ignore
+ public void setTags() {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+
+ // insert db
+ RuleKey rule1 = RuleKey.of("javascript", "S001");
+ dao.insert(newRuleDto(rule1)
+ .setTags(Sets.newHashSet("security"))
+ .setSystemTags(Collections.<String>emptySet()),
+ dbSession
+ );
+
+ RuleKey rule2 = RuleKey.of("java", "S001");
+ dao.insert(newRuleDto(rule2)
+ .setTags(Sets.newHashSet("toberemoved"))
+ .setSystemTags(Sets.newHashSet("bug")), dbSession);
+ dbSession.commit();
+
+ service.setTags(rule2, Sets.newHashSet("bug", "security"));
+
+ // verify that tags are indexed in es
+ service.refresh();
+ Set<String> tags = service.listTags();
+ assertThat(tags).containsOnly("security", "java8", "bug");
+ }
+
+ @Test
+ public void setTags_fail_if_rule_does_not_exist() {
+ try {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+ service.setTags(RuleKey.of("java", "S001"), Sets.newHashSet("bug", "security"));
+ fail();
+ } catch (NotFoundException e) {
+ assertThat(e).hasMessage("Rule java:S001 not found");
+ }
+ }
+
+ @Test
+ public void setTags_fail_if_not_permitted() {
+ try {
+ MockUserSession.set();
+ service.setTags(RuleKey.of("java", "S001"), Sets.newHashSet("bug", "security"));
+ fail();
+ } catch (ForbiddenException e) {
+ assertThat(e).hasMessage("Insufficient privileges");
+ }
+ }
+
private RuleDto newRuleDto(RuleKey ruleKey) {
return new RuleDto()
.setRuleKey(ruleKey.rule())
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule2;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.sonar.core.rule.RuleDto;
+
+import java.util.Collections;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
+public class RuleTagHelperTest {
+
+ @Test
+ public void applyTags() throws Exception {
+ RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance"));
+ RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ assertThat(rule.getTags()).containsOnly("java8", "security");
+ }
+
+ @Test
+ public void applyTags_remove_all_existing_tags() throws Exception {
+ RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance"));
+ RuleTagHelper.applyTags(rule, Collections.<String>emptySet());
+ assertThat(rule.getTags()).isEmpty();
+ }
+
+ @Test
+ public void applyTags_validate_format() throws Exception {
+ RuleDto rule = new RuleDto();
+ RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ assertThat(rule.getTags()).containsOnly("java8", "security");
+
+ try {
+ RuleTagHelper.applyTags(rule, Sets.newHashSet("Java Eight"));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage()).startsWith("Tag 'Java Eight' is invalid");
+ }
+ }
+
+ @Test
+ public void applyTags_do_not_duplicate_system_tags() throws Exception {
+ RuleDto rule = new RuleDto()
+ .setTags(Sets.newHashSet("performance"))
+ .setSystemTags(Sets.newHashSet("security"));
+
+ RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+
+ assertThat(rule.getTags()).containsOnly("java8");
+ assertThat(rule.getSystemTags()).containsOnly("security");
+ }
+}
WebService.Controller controller = context.controller("api/rules2");
assertThat(controller).isNotNull();
- assertThat(controller.actions()).hasSize(3);
+ assertThat(controller.actions()).hasSize(4);
assertThat(controller.action("search")).isNotNull();
assertThat(controller.action("show")).isNotNull();
assertThat(controller.action("tags")).isNotNull();
+ assertThat(controller.action("set_tags")).isNotNull();
}
@Test
@Test
public void search_2_rules() throws Exception {
-
DbSession session = tester.get(MyBatis.class).openSession(false);
ruleDao.insert(newRuleDto(RuleKey.of("javascript", "S001")), session);
ruleDao.insert(newRuleDto(RuleKey.of("javascript", "S002")), session);
MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
- System.out.println("request.toString() = " + request.toString());
-
WsTester.Result result = request.execute();
- System.out.println("result.outputAsString() = " + result.outputAsString());
+ //TODO
}