@@ -20,11 +20,12 @@ | |||
package org.sonar.core.component; | |||
import org.sonar.api.component.Component; | |||
import org.sonar.core.persistence.Dto; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
public class ComponentDto implements Component { | |||
public class ComponentDto extends Dto<String> implements Component { | |||
private Long id; | |||
private String kee; | |||
@@ -114,6 +115,11 @@ public class ComponentDto implements Component { | |||
return this; | |||
} | |||
@Override | |||
public String getKey() { | |||
return kee; | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
@@ -136,4 +142,5 @@ public class ComponentDto implements Component { | |||
public int hashCode() { | |||
return id.hashCode(); | |||
} | |||
} |
@@ -1,56 +0,0 @@ | |||
/* | |||
* 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.core.component.db; | |||
import org.apache.ibatis.session.SqlSession; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.persistence.MyBatis; | |||
import java.util.Collection; | |||
/** | |||
* @since 4.3 | |||
*/ | |||
public class ComponentDao { | |||
private final MyBatis myBatis; | |||
public ComponentDao(MyBatis myBatis) { | |||
this.myBatis = myBatis; | |||
} | |||
public Collection<ComponentDto> selectComponent(ComponentQuery query) { | |||
SqlSession session = myBatis.openSession(false); | |||
try { | |||
return select(query, session); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
} | |||
public Collection<ComponentDto> select(ComponentQuery query, SqlSession session) { | |||
return getMapper(session).selectComponents(query); | |||
} | |||
private ComponentMapper getMapper(SqlSession session) { | |||
return session.getMapper(ComponentMapper.class); | |||
} | |||
} |
@@ -30,5 +30,9 @@ import java.util.Collection; | |||
*/ | |||
public interface ComponentMapper { | |||
ComponentDto selectByKey(String key); | |||
ComponentDto selectById(Long id); | |||
Collection<ComponentDto> selectComponents(@Param("query") ComponentQuery query); | |||
} |
@@ -26,7 +26,6 @@ import org.apache.ibatis.session.SqlSession; | |||
import org.sonar.api.DaoComponent; | |||
import org.sonar.api.component.Component; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.MyBatis; | |||
import javax.annotation.CheckForNull; | |||
@@ -175,11 +174,6 @@ public class ResourceDao implements DaoComponent { | |||
} | |||
} | |||
@CheckForNull | |||
public ComponentDto selectComponentByKey(String key, DbSession session) { | |||
return session.getMapper(ResourceMapper.class).selectComponentByKey(key); | |||
} | |||
@CheckForNull | |||
public Component findByKey(String key) { | |||
ResourceDto resourceDto = getResource(ResourceQuery.create().setKey(key)); |
@@ -61,8 +61,6 @@ public interface ResourceMapper { | |||
List<ComponentDto> selectComponentsByIds(@Param("ids") List<Long> ids); | |||
ComponentDto selectComponentByKey(String key); | |||
/** | |||
* @since 3.6 | |||
*/ |
@@ -5,7 +5,12 @@ | |||
<sql id="componentColumns"> | |||
p.id, | |||
p.kee as kee, | |||
p.qualifier | |||
p.name as name, | |||
p.long_name as longName, | |||
p.qualifier as qualifier, | |||
s.root_project_id as projectId, | |||
p.root_id as subProjectId, | |||
p.path as path | |||
</sql> | |||
<sql id="sortColumn"> | |||
@@ -33,9 +38,30 @@ | |||
</if> | |||
</sql> | |||
<select id="selectByKey" parameterType="String" resultType="Component"> | |||
SELECT <include refid="componentColumns"/> | |||
FROM projects p | |||
INNER JOIN snapshots s on s.project_id=p.id and s.islast=${_true} | |||
<where> | |||
AND p.enabled=${_true} | |||
AND p.kee=#{key} | |||
</where> | |||
</select> | |||
<select id="selectById" parameterType="Long" resultType="Component"> | |||
SELECT <include refid="componentColumns"/> | |||
FROM projects p | |||
INNER JOIN snapshots s on s.project_id=p.id and s.islast=${_true} | |||
<where> | |||
AND p.enabled=${_true} | |||
AND p.id=#{id} | |||
</where> | |||
</select> | |||
<select id="selectComponents" parameterType="map" resultType="Issue"> | |||
select <include refid="componentColumns"/> | |||
from projects p | |||
INNER JOIN snapshots s on s.project_id=p.id and s.islast=${_true} | |||
<include refid="selectQueryConditions"/> | |||
</select> | |||
@@ -179,16 +179,6 @@ | |||
</where> | |||
</select> | |||
<select id="selectComponentByKey" parameterType="String" resultType="Component"> | |||
select <include refid="componentColumns"/> | |||
from projects p | |||
inner join snapshots s on s.project_id=p.id and s.islast=${_true} | |||
<where> | |||
p.enabled=${_true} | |||
and p.kee=#{key} | |||
</where> | |||
</select> | |||
<select id="selectProjectsIncludingNotCompletedOnesByQualifiers" parameterType="map" resultMap="resourceResultMap"> | |||
select * from projects p | |||
<where> |
@@ -1,49 +0,0 @@ | |||
/* | |||
* 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.core.component.db; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.persistence.AbstractDaoTestCase; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class ComponentDaoTest extends AbstractDaoTestCase { | |||
private ComponentDao dao; | |||
@Before | |||
public void createDao() throws Exception { | |||
dao = new ComponentDao(getMyBatis()); | |||
} | |||
@Test | |||
public void should_select_component() { | |||
setupData("selectComponent"); | |||
assertThat(dao.selectComponent(ComponentQuery.create())).hasSize(3); | |||
assertThat(dao.selectComponent(ComponentQuery.create().addIds(1L))).hasSize(1); | |||
assertThat(dao.selectComponent(ComponentQuery.create().addQualifiers(Qualifiers.PROJECT))).hasSize(2); | |||
assertThat(dao.selectComponent(ComponentQuery.create().addQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW))).hasSize(3); | |||
assertThat(dao.selectComponent(ComponentQuery.create().addIds(1L).addQualifiers(Qualifiers.PROJECT))).hasSize(1); | |||
assertThat(dao.selectComponent(ComponentQuery.create().addIds(1L).addQualifiers(Qualifiers.VIEW))).hasSize(0); | |||
} | |||
} |
@@ -213,14 +213,6 @@ public class ResourceDaoTest extends AbstractDaoTestCase { | |||
assertThat(component.path()).isNull(); | |||
} | |||
@Test | |||
public void select_component_by_key() { | |||
setupData("fixture"); | |||
assertThat(dao.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java", session)).isNotNull(); | |||
assertThat(dao.selectComponentByKey("unknown", session)).isNull(); | |||
} | |||
@Test | |||
public void select_components_by_ids_on_huge_number_of_ids() { | |||
setupData("fixture"); |
@@ -1,5 +0,0 @@ | |||
<dataset> | |||
<projects id="1" kee="project1" qualifier="TRK"/> | |||
<projects id="2" kee="project2" qualifier="TRK"/> | |||
<projects id="3" kee="view3" qualifier="VW"/> | |||
</dataset> |
@@ -0,0 +1,85 @@ | |||
/* | |||
* 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.component.persistence; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.apache.ibatis.session.SqlSession; | |||
import org.sonar.api.DaoComponent; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.component.db.ComponentMapper; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.server.db.BaseDao; | |||
import java.util.Collection; | |||
/** | |||
* @since 4.3 | |||
*/ | |||
public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String> implements ServerComponent, DaoComponent { | |||
public ComponentDao() { | |||
this(System2.INSTANCE); | |||
} | |||
@VisibleForTesting | |||
public ComponentDao(System2 system) { | |||
super(ComponentMapper.class, system); | |||
} | |||
public ComponentDto getById(Long id, SqlSession session) { | |||
return getMapper(session).selectById(id); | |||
} | |||
public Collection<ComponentDto> findByQuery(ComponentQuery query, SqlSession session) { | |||
return getMapper(session).selectComponents(query); | |||
} | |||
private ComponentMapper getMapper(SqlSession session) { | |||
return session.getMapper(ComponentMapper.class); | |||
} | |||
@Override | |||
protected ComponentDto doGetByKey(String key, DbSession session) { | |||
return getMapper(session).selectByKey(key); | |||
} | |||
@Override | |||
protected ComponentDto doInsert(ComponentDto item, DbSession session) { | |||
throw new IllegalStateException("Not implemented yet"); | |||
} | |||
@Override | |||
protected ComponentDto doUpdate(ComponentDto item, DbSession session) { | |||
throw new IllegalStateException("Not implemented yet"); | |||
} | |||
@Override | |||
protected void doDeleteByKey(String key, DbSession session) { | |||
throw new IllegalStateException("Not implemented yet"); | |||
} | |||
@Override | |||
public Iterable<String> keysOfRowsUpdatedAfter(long timestamp, DbSession session) { | |||
throw new IllegalStateException("Not implemented yet"); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.component.persistence; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -46,6 +46,7 @@ import org.sonar.core.properties.PropertyQuery; | |||
import org.sonar.core.resource.ResourceDao; | |||
import org.sonar.core.resource.SnapshotDto; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.server.component.persistence.ComponentDao; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.issue.IssueService; | |||
@@ -67,9 +68,6 @@ public class ComponentAppAction implements RequestHandler { | |||
private final DbClient dbClient; | |||
private final ResourceDao resourceDao; | |||
private final PropertiesDao propertiesDao; | |||
private final MeasureDao measureDao; | |||
private final IssueService issueService; | |||
private final Periods periods; | |||
private final Durations durations; | |||
@@ -77,9 +75,6 @@ public class ComponentAppAction implements RequestHandler { | |||
public ComponentAppAction(DbClient dbClient, IssueService issueService, Periods periods, Durations durations, I18n i18n) { | |||
this.dbClient = dbClient; | |||
this.resourceDao = dbClient.getDao(ResourceDao.class); | |||
this.propertiesDao = dbClient.getDao(PropertiesDao.class); | |||
this.measureDao = dbClient.getDao(MeasureDao.class); | |||
this.issueService = issueService; | |||
this.periods = periods; | |||
this.durations = durations; | |||
@@ -112,20 +107,15 @@ public class ComponentAppAction implements RequestHandler { | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
ComponentDto component = resourceDao.selectComponentByKey(fileKey, session); | |||
ComponentDto component = dbClient.getDao(ComponentDao.class).getByKey(fileKey, session); | |||
if (component == null) { | |||
throw new NotFoundException(String.format("Component '%s' does not exists.", fileKey)); | |||
} | |||
Long projectId = component.projectId(); | |||
Long subProjectId = component.subProjectId(); | |||
// projectId and subProjectId can't be null here | |||
if (projectId != null && subProjectId != null) { | |||
appendComponent(json, component, projectId, subProjectId, userSession, session); | |||
appendPermissions(json, component, userSession); | |||
appendPeriods(json, projectId, session); | |||
appendIssuesAggregation(json, component.key(), session); | |||
appendMeasures(json, fileKey, session); | |||
} | |||
appendComponent(json, component, userSession, session); | |||
appendPermissions(json, component, userSession); | |||
appendPeriods(json, component.projectId(), session); | |||
appendIssuesAggregation(json, component.key(), session); | |||
appendMeasures(json, fileKey, session); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
@@ -134,8 +124,8 @@ public class ComponentAppAction implements RequestHandler { | |||
json.close(); | |||
} | |||
private void appendComponent(JsonWriter json, ComponentDto component, Long projectId, Long subProjectId, UserSession userSession, DbSession session) { | |||
List<PropertyDto> propertyDtos = propertiesDao.selectByQuery(PropertyQuery.builder() | |||
private void appendComponent(JsonWriter json, ComponentDto component, UserSession userSession, DbSession session) { | |||
List<PropertyDto> propertyDtos = dbClient.getDao(PropertiesDao.class).selectByQuery(PropertyQuery.builder() | |||
.setKey("favourite") | |||
.setComponentId(component.getId()) | |||
.setUserId(userSession.userId()) | |||
@@ -149,10 +139,10 @@ public class ComponentAppAction implements RequestHandler { | |||
json.prop("name", component.name()); | |||
json.prop("q", component.qualifier()); | |||
Component subProject = componentById(subProjectId, session); | |||
json.prop("subProjectName", subProject.longName()); | |||
Component subProject = componentById(component.subProjectId(), session); | |||
json.prop("subProjectName", subProject != null ? subProject.longName() : null); | |||
Component project = componentById(projectId, session); | |||
Component project = componentById(component.projectId(), session); | |||
json.prop("projectName", project.longName()); | |||
json.prop("fav", isFavourite); | |||
@@ -166,7 +156,7 @@ public class ComponentAppAction implements RequestHandler { | |||
private void appendMeasures(JsonWriter json, String fileKey, DbSession session) { | |||
json.name("measures").beginObject(); | |||
List<MeasureDto> measures = measureDao.findByComponentKeyAndMetricKeys(fileKey, | |||
List<MeasureDto> measures = dbClient.getDao(MeasureDao.class).findByComponentKeyAndMetricKeys(fileKey, | |||
newArrayList(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.VIOLATIONS_KEY, | |||
CoreMetrics.BLOCKER_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY), | |||
session | |||
@@ -187,7 +177,7 @@ public class ComponentAppAction implements RequestHandler { | |||
private void appendPeriods(JsonWriter json, Long projectId, DbSession session) { | |||
json.name("periods").beginArray(); | |||
SnapshotDto snapshotDto = resourceDao.getLastSnapshotByResourceId(projectId, session); | |||
SnapshotDto snapshotDto = dbClient.getDao(ResourceDao.class).getLastSnapshotByResourceId(projectId, session); | |||
if (snapshotDto != null) { | |||
for (int i = 1; i <= 5; i++) { | |||
String mode = snapshotDto.getPeriodMode(i); | |||
@@ -234,7 +224,7 @@ public class ComponentAppAction implements RequestHandler { | |||
@CheckForNull | |||
private Component componentById(@Nullable Long componentId, DbSession session) { | |||
if (componentId != null) { | |||
return resourceDao.findById(componentId, session); | |||
return dbClient.getDao(ComponentDao.class).getById(componentId, session); | |||
} | |||
return null; | |||
} |
@@ -38,7 +38,6 @@ import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.UriReader; | |||
import org.sonar.api.utils.internal.TempFolderCleaner; | |||
import org.sonar.core.component.SnapshotPerspectives; | |||
import org.sonar.core.component.db.ComponentDao; | |||
import org.sonar.core.config.CorePropertyDefinitions; | |||
import org.sonar.core.config.Logback; | |||
import org.sonar.core.i18n.DefaultI18n; | |||
@@ -80,6 +79,7 @@ import org.sonar.server.cluster.LocalNonBlockingWorkQueue; | |||
import org.sonar.server.cluster.LocalQueueWorker; | |||
import org.sonar.server.component.DefaultComponentFinder; | |||
import org.sonar.server.component.DefaultRubyComponentService; | |||
import org.sonar.server.component.persistence.ComponentDao; | |||
import org.sonar.server.component.ws.ComponentAppAction; | |||
import org.sonar.server.component.ws.ComponentsWs; | |||
import org.sonar.server.component.ws.ProjectsWs; | |||
@@ -199,6 +199,7 @@ class ServerComponents { | |||
RuleDao.class, | |||
ActiveRuleDao.class, | |||
MeasureDao.class, | |||
ComponentDao.class, | |||
DbClient.class, | |||
MeasureFilterDao.class | |||
)); |
@@ -31,8 +31,8 @@ import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.api.measures.MetricFinder; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.component.db.ComponentDao; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.core.properties.PropertiesDao; | |||
import org.sonar.core.properties.PropertyDto; | |||
@@ -40,6 +40,7 @@ import org.sonar.core.qualitygate.db.QualityGateConditionDao; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDao; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.component.persistence.ComponentDao; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.BadRequestException.Message; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
@@ -213,16 +214,28 @@ public class QualityGates { | |||
public void associateProject(Long qGateId, Long projectId) { | |||
checkPermission(UserSession.get()); | |||
getNonNullQgate(qGateId); | |||
checkNonNullProject(projectId); | |||
propertiesDao.setProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setResourceId(projectId).setValue(qGateId.toString())); | |||
DbSession session = myBatis.openSession(false); | |||
try { | |||
getNonNullQgate(qGateId); | |||
checkNonNullProject(projectId, session); | |||
propertiesDao.setProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setResourceId(projectId).setValue(qGateId.toString())); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
} | |||
public void dissociateProject(Long qGateId, Long projectId) { | |||
checkPermission(UserSession.get()); | |||
getNonNullQgate(qGateId); | |||
checkNonNullProject(projectId); | |||
propertiesDao.deleteProjectProperty(SONAR_QUALITYGATE_PROPERTY, projectId); | |||
DbSession session = myBatis.openSession(false); | |||
try { | |||
getNonNullQgate(qGateId); | |||
checkNonNullProject(projectId, session); | |||
propertiesDao.deleteProjectProperty(SONAR_QUALITYGATE_PROPERTY, projectId); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
} | |||
public Collection<Metric> gateMetrics() { | |||
@@ -337,8 +350,8 @@ public class QualityGates { | |||
return condition; | |||
} | |||
private void checkNonNullProject(long projectId) { | |||
if (componentDao.selectComponent(ComponentQuery.create().addIds(projectId).addQualifiers(Qualifiers.PROJECT)).isEmpty()) { | |||
private void checkNonNullProject(long projectId, DbSession session) { | |||
if (componentDao.findByQuery(ComponentQuery.create().addIds(projectId).addQualifiers(Qualifiers.PROJECT), session).isEmpty()) { | |||
throw new NotFoundException("There is no project with id=" + projectId); | |||
} | |||
} |
@@ -0,0 +1,94 @@ | |||
/* | |||
* 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.component.persistence; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.persistence.AbstractDaoTestCase; | |||
import org.sonar.core.persistence.DbSession; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class ComponentDaoTest extends AbstractDaoTestCase { | |||
DbSession session; | |||
ComponentDao dao; | |||
@Before | |||
public void createDao() throws Exception { | |||
session = getMyBatis().openSession(false); | |||
dao = new ComponentDao(); | |||
} | |||
@Test | |||
public void get_by_key() { | |||
setupData("shared"); | |||
ComponentDto result = dao.getByKey("org.struts:struts-core:src/org/struts/RequestContext.java", session); | |||
assertThat(result).isNotNull(); | |||
assertThat(result.key()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java"); | |||
assertThat(result.path()).isEqualTo("src/org/struts/RequestContext.java"); | |||
assertThat(result.name()).isEqualTo("RequestContext.java"); | |||
assertThat(result.longName()).isEqualTo("org.struts.RequestContext"); | |||
assertThat(result.qualifier()).isEqualTo("FIL"); | |||
assertThat(result.subProjectId()).isEqualTo(2); | |||
assertThat(result.projectId()).isEqualTo(1); | |||
assertThat(dao.getByKey("unknown", session)).isNull(); | |||
} | |||
@Test | |||
public void get_by_key_on_a_root_project() { | |||
setupData("shared"); | |||
ComponentDto result = dao.getByKey("org.struts:struts", session); | |||
assertThat(result).isNotNull(); | |||
assertThat(result.key()).isEqualTo("org.struts:struts"); | |||
assertThat(result.path()).isNull(); | |||
assertThat(result.name()).isEqualTo("Struts"); | |||
assertThat(result.longName()).isEqualTo("Apache Struts"); | |||
assertThat(result.qualifier()).isEqualTo("TRK"); | |||
assertThat(result.subProjectId()).isNull(); | |||
assertThat(result.projectId()).isEqualTo(1); | |||
} | |||
@Test | |||
public void get_by_id() { | |||
setupData("shared"); | |||
assertThat(dao.getById(4L, session)).isNotNull(); | |||
assertThat(dao.getById(111L, session)).isNull(); | |||
} | |||
@Test | |||
public void find_by_query() { | |||
setupData("shared"); | |||
assertThat(dao.findByQuery(ComponentQuery.create(), session)).hasSize(4); | |||
assertThat(dao.findByQuery(ComponentQuery.create().addIds(1L), session)).hasSize(1); | |||
assertThat(dao.findByQuery(ComponentQuery.create().addQualifiers(Qualifiers.PROJECT), session)).hasSize(1); | |||
assertThat(dao.findByQuery(ComponentQuery.create().addQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE), session)).hasSize(2); | |||
assertThat(dao.findByQuery(ComponentQuery.create().addIds(1L).addQualifiers(Qualifiers.PROJECT), session)).hasSize(1); | |||
assertThat(dao.findByQuery(ComponentQuery.create().addIds(1L).addQualifiers(Qualifiers.MODULE), session)).hasSize(0); | |||
} | |||
} |
@@ -44,6 +44,7 @@ import org.sonar.core.resource.ResourceDao; | |||
import org.sonar.core.resource.SnapshotDto; | |||
import org.sonar.core.rule.RuleDto; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.server.component.persistence.ComponentDao; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.issue.IssueService; | |||
import org.sonar.server.issue.RulesAggregation; | |||
@@ -69,6 +70,9 @@ public class ComponentAppActionTest { | |||
@Mock | |||
DbSession session; | |||
@Mock | |||
ComponentDao componentDao; | |||
@Mock | |||
ResourceDao resourceDao; | |||
@@ -98,13 +102,14 @@ public class ComponentAppActionTest { | |||
public void setUp() throws Exception { | |||
DbClient dbClient = mock(DbClient.class); | |||
when(dbClient.openSession(false)).thenReturn(session); | |||
when(dbClient.getDao(ComponentDao.class)).thenReturn(componentDao); | |||
when(dbClient.getDao(ResourceDao.class)).thenReturn(resourceDao); | |||
when(dbClient.getDao(PropertiesDao.class)).thenReturn(propertiesDao); | |||
when(dbClient.getDao(MeasureDao.class)).thenReturn(measureDao); | |||
when(issueService.findSeveritiesByComponent(COMPONENT_KEY, session)).thenReturn(mock(Multiset.class)); | |||
when(issueService.findRulesByComponent(COMPONENT_KEY, session)).thenReturn(mock(RulesAggregation.class)); | |||
when(measureDao.findByComponentKeyAndMetricKeys(eq(COMPONENT_KEY), anyListOf(String.class), eq(session))).thenReturn(measures); | |||
when(issueService.findSeveritiesByComponent(anyString(), eq(session))).thenReturn(mock(Multiset.class)); | |||
when(issueService.findRulesByComponent(anyString(), eq(session))).thenReturn(mock(RulesAggregation.class)); | |||
when(measureDao.findByComponentKeyAndMetricKeys(anyString(), anyListOf(String.class), eq(session))).thenReturn(measures); | |||
tester = new WsTester(new ComponentsWs(new ComponentAppAction(dbClient, issueService, periods, durations, i18n))); | |||
} | |||
@@ -115,15 +120,29 @@ public class ComponentAppActionTest { | |||
ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(COMPONENT_KEY).setName("Plugin.java") | |||
.setPath("src/main/java/org/sonar/api/Plugin.java").setSubProjectId(5L).setProjectId(1L); | |||
when(resourceDao.selectComponentByKey(COMPONENT_KEY, session)).thenReturn(file); | |||
when(resourceDao.findById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API")); | |||
when(resourceDao.findById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); | |||
when(componentDao.getByKey(COMPONENT_KEY, session)).thenReturn(file); | |||
when(componentDao.getById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API")); | |||
when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); | |||
when(propertiesDao.selectByQuery(any(PropertyQuery.class), eq(session))).thenReturn(newArrayList(new PropertyDto())); | |||
WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY); | |||
request.execute().assertJson(getClass(), "app.json"); | |||
} | |||
@Test | |||
public void app_without_sub_project() throws Exception { | |||
String componentKey = "org.codehaus.sonar:sonar"; | |||
MockUserSession.set().setLogin("john").addComponentPermission(UserRole.CODEVIEWER, componentKey, componentKey); | |||
ComponentDto file = new ComponentDto().setId(1L).setQualifier("TRK").setKey(componentKey).setName("SonarQube").setProjectId(1L); | |||
when(componentDao.getByKey(componentKey, session)).thenReturn(file); | |||
when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); | |||
when(propertiesDao.selectByQuery(any(PropertyQuery.class), eq(session))).thenReturn(newArrayList(new PropertyDto())); | |||
WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", componentKey); | |||
request.execute().assertJson(getClass(), "app_without_sub_project.json"); | |||
} | |||
@Test | |||
public void app_with_measures() throws Exception { | |||
MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY); | |||
@@ -193,9 +212,9 @@ public class ComponentAppActionTest { | |||
private void addProjectSample() { | |||
ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(COMPONENT_KEY).setName("Plugin.java") | |||
.setPath("src/main/java/org/sonar/api/Plugin.java").setSubProjectId(5L).setProjectId(1L); | |||
when(resourceDao.selectComponentByKey(COMPONENT_KEY, session)).thenReturn(file); | |||
when(resourceDao.findById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API")); | |||
when(resourceDao.findById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); | |||
when(componentDao.getByKey(COMPONENT_KEY, session)).thenReturn(file); | |||
when(componentDao.getById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API")); | |||
when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); | |||
} | |||
private void addMeasure(String metricKey, Integer value) { |
@@ -36,7 +36,6 @@ import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.api.measures.MetricFinder; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.component.ComponentQuery; | |||
import org.sonar.core.component.db.ComponentDao; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.MyBatis; | |||
@@ -46,6 +45,7 @@ import org.sonar.core.qualitygate.db.QualityGateConditionDao; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDao; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.component.persistence.ComponentDao; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
@@ -63,33 +63,33 @@ import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.anyLong; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.times; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
import static org.mockito.Mockito.*; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class QualityGatesTest { | |||
@Mock | |||
private QualityGateDao dao; | |||
DbSession session; | |||
@Mock | |||
private QualityGateConditionDao conditionDao; | |||
QualityGateDao dao; | |||
@Mock | |||
private MetricFinder metricFinder; | |||
QualityGateConditionDao conditionDao; | |||
@Mock | |||
private PropertiesDao propertiesDao; | |||
MetricFinder metricFinder; | |||
@Mock | |||
private ComponentDao componentDao; | |||
PropertiesDao propertiesDao; | |||
@Mock | |||
private MyBatis myBatis; | |||
ComponentDao componentDao; | |||
private QualityGates qGates; | |||
@Mock | |||
MyBatis myBatis; | |||
QualityGates qGates; | |||
UserSession authorizedUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); | |||
UserSession unauthenticatedUserSession = MockUserSession.create(); | |||
@@ -97,6 +97,7 @@ public class QualityGatesTest { | |||
@Before | |||
public void initialize() { | |||
when(myBatis.openSession(false)).thenReturn(session); | |||
qGates = new QualityGates(dao, conditionDao, metricFinder, propertiesDao, componentDao, myBatis); | |||
UserSessionTestUtils.setUserSession(authorizedUserSession); | |||
} | |||
@@ -492,10 +493,10 @@ public class QualityGatesTest { | |||
Long qGateId = 42L; | |||
Long projectId = 24L; | |||
when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId)); | |||
when(componentDao.selectComponent(any(ComponentQuery.class))).thenReturn(ImmutableList.of(new ComponentDto().setId(projectId))); | |||
when(componentDao.findByQuery(any(ComponentQuery.class), eq(session))).thenReturn(ImmutableList.of(new ComponentDto().setId(projectId))); | |||
qGates.associateProject(qGateId , projectId); | |||
verify(dao).selectById(qGateId); | |||
verify(componentDao).selectComponent(any(ComponentQuery.class)); | |||
verify(componentDao).findByQuery(any(ComponentQuery.class), eq(session)); | |||
ArgumentCaptor<PropertyDto> propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class); | |||
verify(propertiesDao).setProperty(propertyCaptor.capture()); | |||
PropertyDto property = propertyCaptor.getValue(); | |||
@@ -517,10 +518,10 @@ public class QualityGatesTest { | |||
Long qGateId = 42L; | |||
Long projectId = 24L; | |||
when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId)); | |||
when(componentDao.selectComponent(any(ComponentQuery.class))).thenReturn(ImmutableList.of(new ComponentDto().setId(projectId))); | |||
when(componentDao.findByQuery(any(ComponentQuery.class), eq(session))).thenReturn(ImmutableList.of(new ComponentDto().setId(projectId))); | |||
qGates.dissociateProject(qGateId , projectId); | |||
verify(dao).selectById(qGateId); | |||
verify(componentDao).selectComponent(any(ComponentQuery.class)); | |||
verify(componentDao).findByQuery(any(ComponentQuery.class), eq(session)); | |||
verify(propertiesDao).deleteProjectProperty("sonar.qualitygate", projectId); | |||
} | |||
@@ -0,0 +1,75 @@ | |||
<dataset> | |||
<!-- Struts projects is authorized for all user --> | |||
<group_roles id="1" group_id="[null]" resource_id="1" role="user"/> | |||
<!-- root project --> | |||
<projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" | |||
description="the description" long_name="Apache Struts" | |||
enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"/> | |||
<snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" | |||
status="P" islast="[true]" purge_status="[null]" | |||
period1_mode="[null]" period1_param="[null]" period1_date="[null]" | |||
period2_mode="[null]" period2_param="[null]" period2_date="[null]" | |||
period3_mode="[null]" period3_param="[null]" period3_date="[null]" | |||
period4_mode="[null]" period4_param="[null]" period4_date="[null]" | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" | |||
version="[null]" path=""/> | |||
<snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]" | |||
status="P" islast="[false]" purge_status="[null]" | |||
period1_mode="[null]" period1_param="[null]" period1_date="[null]" | |||
period2_mode="[null]" period2_param="[null]" period2_date="[null]" | |||
period3_mode="[null]" period3_param="[null]" period3_date="[null]" | |||
period4_mode="[null]" period4_param="[null]" period4_date="[null]" | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-01 13:58:00.00" build_date="2008-12-01 13:58:00.00" | |||
version="[null]" path=""/> | |||
<!-- module --> | |||
<projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" | |||
scope="PRJ" qualifier="BRC" long_name="Struts Core" | |||
description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/> | |||
<snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" | |||
status="P" islast="[true]" purge_status="[null]" | |||
period1_mode="[null]" period1_param="[null]" period1_date="[null]" | |||
period2_mode="[null]" period2_param="[null]" period2_date="[null]" | |||
period3_mode="[null]" period3_param="[null]" period3_date="[null]" | |||
period4_mode="[null]" period4_param="[null]" period4_date="[null]" | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" | |||
version="[null]" path="1."/> | |||
<!-- directory --> | |||
<projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" | |||
name="src/org/struts" root_id="2" | |||
description="[null]" | |||
enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"/> | |||
<snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" | |||
status="P" islast="[true]" purge_status="[null]" | |||
period1_mode="[null]" period1_param="[null]" period1_date="[null]" | |||
period2_mode="[null]" period2_param="[null]" period2_date="[null]" | |||
period3_mode="[null]" period3_param="[null]" period3_date="[null]" | |||
period4_mode="[null]" period4_param="[null]" period4_date="[null]" | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" | |||
version="[null]" path="1.2."/> | |||
<!-- file --> | |||
<projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" | |||
name="RequestContext.java" root_id="2" | |||
description="[null]" | |||
enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java"/> | |||
<snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1" | |||
status="P" islast="[true]" purge_status="[null]" | |||
period1_mode="[null]" period1_param="[null]" period1_date="[null]" | |||
period2_mode="[null]" period2_param="[null]" period2_date="[null]" | |||
period3_mode="[null]" period3_param="[null]" period3_date="[null]" | |||
period4_mode="[null]" period4_param="[null]" period4_date="[null]" | |||
period5_mode="[null]" period5_param="[null]" period5_date="[null]" | |||
depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" | |||
version="[null]" path="1.2.3."/> | |||
</dataset> |
@@ -0,0 +1,13 @@ | |||
{ | |||
"key": "org.codehaus.sonar:sonar", | |||
"name": "SonarQube", | |||
"q": "TRK", | |||
"projectName": "SonarQube", | |||
"fav": true, | |||
"canMarkAsFavourite": true, | |||
"canBulkChange": true, | |||
"periods": [], | |||
"severities": [], | |||
"rules": [], | |||
"measures": {} | |||
} |