diff options
Diffstat (limited to 'sonar-core/src')
12 files changed, 658 insertions, 178 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java index d3a9ffd0b36..0fbf9f2f6d6 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java @@ -20,31 +20,31 @@ package org.sonar.core.measure; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import org.sonar.api.measures.Metric; +import javax.annotation.Nullable; +import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Set; public class MeasureFilter { // conditions on resources private String baseResourceKey; - private boolean onBaseResourceChildren = false; // only if baseResourceKey is set - private Set<String> resourceScopes = Sets.newHashSet(); - private Set<String> resourceQualifiers = Sets.newHashSet(); - private Set<String> resourceLanguages = Sets.newHashSet(); + private boolean onBaseResourceChildren = false; // only if getBaseResourceKey is set + private List<String> resourceScopes = Lists.newArrayList(); + private List<String> resourceQualifiers = Lists.newArrayList(); + private List<String> resourceLanguages = Lists.newArrayList(); private String resourceName; private Date fromDate = null, toDate = null; private boolean userFavourites = false; // conditions on measures - private List<MeasureFilterValueCondition> measureConditions = Lists.newArrayList(); + private List<MeasureFilterCondition> measureConditions = Lists.newArrayList(); // sort private MeasureFilterSort sort = new MeasureFilterSort(); - public String baseResourceKey() { + public String getBaseResourceKey() { return baseResourceKey; } @@ -62,18 +62,28 @@ public class MeasureFilter { return onBaseResourceChildren; } - public MeasureFilter setResourceScopes(Set<String> resourceScopes) { - this.resourceScopes = resourceScopes; + public MeasureFilter setResourceScopes(@Nullable List<String> l) { + this.resourceScopes = (l != null ? l : Collections.<String>emptyList()); return this; } - public MeasureFilter setResourceQualifiers(String... qualifiers) { - this.resourceQualifiers = Sets.newHashSet(qualifiers); + public MeasureFilter setResourceQualifiers(List<String> l) { + this.resourceQualifiers = (l != null ? l : Collections.<String>emptyList()); return this; } - public MeasureFilter setResourceLanguages(String... languages) { - this.resourceLanguages = Sets.newHashSet(languages); + public MeasureFilter setResourceQualifiers(String... l) { + this.resourceQualifiers = Lists.newArrayList(l); + return this; + } + + public MeasureFilter setResourceLanguages(List<String> l) { + this.resourceLanguages = (l != null ? l : Collections.<String>emptyList()); + return this; + } + + public MeasureFilter setResourceLanguages(String... l) { + this.resourceLanguages = Lists.newArrayList(l); return this; } @@ -82,11 +92,11 @@ public class MeasureFilter { return this; } - public boolean userFavourites() { + public boolean isOnFavourites() { return userFavourites; } - public String resourceName() { + public String getResourceName() { return resourceName; } @@ -95,7 +105,7 @@ public class MeasureFilter { return this; } - public MeasureFilter addCondition(MeasureFilterValueCondition condition) { + public MeasureFilter addCondition(MeasureFilterCondition condition) { this.measureConditions.add(condition); return this; } @@ -111,6 +121,7 @@ public class MeasureFilter { } public MeasureFilter setSortOnMetric(Metric m) { + this.sort.setField(MeasureFilterSort.Field.METRIC); this.sort.setMetric(m); return this; } @@ -130,27 +141,27 @@ public class MeasureFilter { return this; } - public Date fromDate() { + public Date getFromDate() { return fromDate; } - public Date toDate() { + public Date getToDate() { return toDate; } - public Set<String> resourceScopes() { + public List<String> getResourceScopes() { return resourceScopes; } - public Set<String> resourceQualifiers() { + public List<String> getResourceQualifiers() { return resourceQualifiers; } - public Set<String> resourceLanguages() { + public List<String> getResourceLanguages() { return resourceLanguages; } - public List<MeasureFilterValueCondition> measureConditions() { + public List<MeasureFilterCondition> getMeasureConditions() { return measureConditions; } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterValueCondition.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java index 145e7d7bd86..b97ec5f6143 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterValueCondition.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java @@ -21,35 +21,21 @@ package org.sonar.core.measure; import org.sonar.api.measures.Metric; -public class MeasureFilterValueCondition { - - public static enum Operator { - GREATER(">"), GREATER_OR_EQUALS(">="), EQUALS("="), LESS("<"), LESS_OR_EQUALS("<="); - - private String sql; - - private Operator(String sql) { - this.sql = sql; - } - - public String getSql() { - return sql; - } - } +public class MeasureFilterCondition { private final Metric metric; - private final Operator operator; - private final float value; - private int period = -1; + private final String operator; + private final double value; + private Integer period = null; - public MeasureFilterValueCondition(Metric metric, Operator operator, float value) { + public MeasureFilterCondition(Metric metric, String operator, double value) { this.metric = metric; this.operator = operator; this.value = value; } - public MeasureFilterValueCondition setPeriod(int period) { - this.period = (period > 0 ? period : -1); + public MeasureFilterCondition setPeriod(Integer period) { + this.period = period; return this; } @@ -57,7 +43,7 @@ public class MeasureFilterValueCondition { return metric; } - public Operator operator() { + public String operator() { return operator; } @@ -65,20 +51,20 @@ public class MeasureFilterValueCondition { return value; } - public int period() { + public Integer period() { return period; } String valueColumn() { - if (period > 0) { + if (period != null) { return "pm.variation_value_" + period; } return "pm.value"; } - void appendSql(StringBuilder sql) { + void appendSqlCondition(StringBuilder sql) { sql.append(" pm.metric_id="); sql.append(metric.getId()); - sql.append(" AND ").append(valueColumn()).append(operator.getSql()).append(value); + sql.append(" AND ").append(valueColumn()).append(operator).append(value); } } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterContext.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterContext.java new file mode 100644 index 00000000000..5c0ad12b691 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterContext.java @@ -0,0 +1,76 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.measure; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.core.resource.SnapshotDto; + +class MeasureFilterContext { + private Long userId; + private SnapshotDto baseSnapshot; + private String sql; + private String json; + + Long getUserId() { + return userId; + } + + MeasureFilterContext setUserId(Long userId) { + this.userId = userId; + return this; + } + + SnapshotDto getBaseSnapshot() { + return baseSnapshot; + } + + MeasureFilterContext setBaseSnapshot(SnapshotDto baseSnapshot) { + this.baseSnapshot = baseSnapshot; + return this; + } + + String getSql() { + return sql; + } + + MeasureFilterContext setSql(String sql) { + this.sql = sql; + return this; + } + + String getJson() { + return json; + } + + MeasureFilterContext setJson(String json) { + this.json = json; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("json", json) + .append("sql", sql) + .append("user", userId) + .toString(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterDecoder.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterDecoder.java new file mode 100644 index 00000000000..7cf092bed00 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterDecoder.java @@ -0,0 +1,132 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.measure; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.sonar.api.ServerComponent; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.MetricFinder; +import org.sonar.api.utils.DateUtils; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +public class MeasureFilterDecoder implements ServerComponent { + private MetricFinder metricFinder; + private JSONParser parser = new JSONParser(); + + public MeasureFilterDecoder(MetricFinder metricFinder) { + this.metricFinder = metricFinder; + } + + public MeasureFilter decode(String text) throws ParseException { + MeasureFilter filter = new MeasureFilter(); + JSONObject map = (JSONObject) parser.parse(text); + parseResourceConditions(filter, map); + parseMeasureConditions(map, filter); + parseSorting(map, filter); + return filter; + } + + private void parseResourceConditions(MeasureFilter filter, JSONObject map) { + filter.setBaseResourceKey((String) map.get("base")); + if (map.containsKey("onBaseChildren")) { + filter.setOnBaseResourceChildren(((Boolean) map.get("onBaseChildren")).booleanValue()); + } + filter.setResourceScopes((List<String>) map.get("scopes")); + filter.setResourceQualifiers((List<String>) map.get("qualifiers")); + filter.setResourceLanguages((List<String>) map.get("languages")); + filter.setResourceName((String) map.get("name")); + + if (map.containsKey("fromDate")) { + filter.setFromDate(toDate(map, "fromDate")); + } + if (map.containsKey("afterDays")) { + filter.setFromDate(toDays(map, "afterDays")); + } + if (map.containsKey("toDate")) { + filter.setToDate(toDate(map, "toDate")); + } + if (map.containsKey("beforeDays")) { + filter.setToDate(toDays(map, "beforeDays")); + } + if (map.containsKey("favourites")) { + filter.setUserFavourites(((Boolean) map.get("favourites")).booleanValue()); + } + } + + private void parseSorting(JSONObject map, MeasureFilter filter) { + if (map.containsKey("sortAsc")) { + filter.setSortAsc(((Boolean) map.get("sortAsc")).booleanValue()); + } + String s = (String) map.get("sortField"); + if (s != null) { + filter.setSortOn(MeasureFilterSort.Field.valueOf(s)); + } + s = (String) map.get("sortField"); + if (s != null) { + filter.setSortOn(MeasureFilterSort.Field.valueOf((String) map.get("sortField"))); + } + s = (String) map.get("sortMetric"); + if (s != null) { + filter.setSortOnMetric(metricFinder.findByKey(s)); + } + if (map.containsKey("sortPeriod")) { + filter.setSortOnPeriod(((Long) map.get("sortPeriod")).intValue()); + } + } + + private void parseMeasureConditions(JSONObject map, MeasureFilter filter) { + JSONArray conditions = (JSONArray) map.get("conditions"); + if (conditions != null) { + for (Object obj : conditions) { + JSONObject c = (JSONObject) obj; + Metric metric = metricFinder.findByKey((String) c.get("metric")); + String operator = (String) c.get("op"); + Double value = (Double) c.get("val"); + MeasureFilterCondition condition = new MeasureFilterCondition(metric, operator, value); + if (c.containsKey("period")) { + condition.setPeriod(((Long) c.get("period")).intValue()); + } + filter.addCondition(condition); + } + } + } + + private static Date toDate(JSONObject map, String key) { + String date = (String) map.get(key); + if (date != null) { + return DateUtils.parseDate(date); + } + return null; + } + + private static Date toDays(JSONObject map, String key) { + int days = ((Long) map.get(key)).intValue(); + Date date = org.apache.commons.lang.time.DateUtils.truncate(new Date(), Calendar.DATE); + date = org.apache.commons.lang.time.DateUtils.addDays(date, -days); + return date; + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterEngine.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterEngine.java new file mode 100644 index 00000000000..2b5da9a1420 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterEngine.java @@ -0,0 +1,74 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.measure; + +import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.lang.SystemUtils; +import org.json.simple.parser.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.ServerComponent; + +import javax.annotation.Nullable; +import java.util.List; + +public class MeasureFilterEngine implements ServerComponent { + private static final Logger FILTER_LOG = LoggerFactory.getLogger("org.sonar.MEASURE_FILTER"); + + private final MeasureFilterDecoder decoder; + private final MeasureFilterExecutor executor; + + public MeasureFilterEngine(MeasureFilterDecoder decoder, MeasureFilterExecutor executor) { + this.decoder = decoder; + this.executor = executor; + } + + public List<MeasureFilterRow> execute(String filterJson, @Nullable Long userId) throws ParseException { + return execute(filterJson, userId, FILTER_LOG); + } + + @VisibleForTesting + List<MeasureFilterRow> execute(String filterJson, @Nullable Long userId, Logger logger) { + MeasureFilterContext context = new MeasureFilterContext(); + context.setJson(filterJson); + context.setUserId(userId); + try { + long start = System.currentTimeMillis(); + MeasureFilter filter = decoder.decode(filterJson); + List<MeasureFilterRow> rows = executor.execute(filter, context); + log(context, rows, (System.currentTimeMillis() - start), logger); + return rows; + } catch (Exception e) { + throw new IllegalStateException("Fail to execute filter: " + context, e); + } + } + + private void log(MeasureFilterContext context, List<MeasureFilterRow> rows, long durationMs, Logger logger) { + if (logger.isDebugEnabled()) { + StringBuilder log = new StringBuilder(); + log.append(SystemUtils.LINE_SEPARATOR); + log.append(" json: ").append(context.getJson()).append(SystemUtils.LINE_SEPARATOR); + log.append(" sql: ").append(context.getSql()).append(SystemUtils.LINE_SEPARATOR); + log.append("results: ").append(rows.size()).append(" rows in ").append(durationMs).append("ms").append(SystemUtils.LINE_SEPARATOR); + logger.debug(log.toString()); + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterExecutor.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterExecutor.java index eb66a9aa0b4..b529f5a384a 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterExecutor.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterExecutor.java @@ -20,20 +20,17 @@ package org.sonar.core.measure; import org.apache.ibatis.session.SqlSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.api.ServerComponent; import org.sonar.core.persistence.Database; import org.sonar.core.persistence.MyBatis; import org.sonar.core.resource.ResourceDao; -import javax.annotation.Nullable; import java.sql.Connection; +import java.sql.SQLException; import java.util.Collections; import java.util.List; public class MeasureFilterExecutor implements ServerComponent { - private static final Logger FILTER_LOG = LoggerFactory.getLogger("org.sonar.MEASURE_FILTER"); private MyBatis mybatis; private Database database; @@ -45,24 +42,21 @@ public class MeasureFilterExecutor implements ServerComponent { this.resourceDao = resourceDao; } - public List<MeasureFilterRow> execute(MeasureFilter filter, @Nullable Long userId) { + public List<MeasureFilterRow> execute(MeasureFilter filter, MeasureFilterContext context) throws SQLException { List<MeasureFilterRow> rows; SqlSession session = null; try { session = mybatis.openSession(); - MesasureFilterContext context = prepareContext(filter, userId, session); + prepareContext(context, filter, session); if (isValid(filter, context)) { MeasureFilterSql sql = new MeasureFilterSql(database, filter, context); + context.setSql(sql.sql()); Connection connection = session.getConnection(); rows = sql.execute(connection); } else { rows = Collections.emptyList(); } - - } catch (Exception e) { - throw new IllegalStateException(e); - } finally { MyBatis.closeQuietly(session); } @@ -70,19 +64,31 @@ public class MeasureFilterExecutor implements ServerComponent { return rows; } - private MesasureFilterContext prepareContext(MeasureFilter filter, Long userId, SqlSession session) { - MesasureFilterContext context = new MesasureFilterContext(); - context.setUserId(userId); - if (filter.baseResourceKey() != null) { - context.setBaseSnapshot(resourceDao.getLastSnapshot(filter.baseResourceKey(), session)); + + private void prepareContext(MeasureFilterContext context, MeasureFilter filter, SqlSession session) { + if (filter.getBaseResourceKey() != null) { + context.setBaseSnapshot(resourceDao.getLastSnapshot(filter.getBaseResourceKey(), session)); } - return context; } - static boolean isValid(MeasureFilter filter, MesasureFilterContext context) { - return - !(filter.resourceQualifiers().isEmpty() && !filter.userFavourites()) && + static boolean isValid(MeasureFilter filter, MeasureFilterContext context) { + boolean valid = !(filter.isOnBaseResourceChildren() && context.getBaseSnapshot() == null) && - !(filter.userFavourites() && context.getUserId() == null); + !(filter.isOnFavourites() && context.getUserId() == null); + for (MeasureFilterCondition condition : filter.getMeasureConditions()) { + if (condition.period() != null && condition.period() < 1) { + valid = false; + } + if (condition.metric() == null) { + valid = false; + } + } + if (filter.sort().getPeriod() != null && filter.sort().getPeriod() < 1) { + valid = false; + } + if (filter.sort().onMeasures() && filter.sort().metric() == null) { + valid = false; + } + return valid; } } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSort.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSort.java index 3abb3672664..d0e2d53f731 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSort.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSort.java @@ -28,7 +28,7 @@ class MeasureFilterSort { private Field field = Field.NAME; private Metric metric = null; - private int period = -1; + private Integer period = null; private boolean asc = true; MeasureFilterSort() { @@ -43,8 +43,12 @@ class MeasureFilterSort { this.metric = metric; } - void setPeriod(int period) { - this.period = (period > 0 ? period : -1); + Integer getPeriod() { + return period; + } + + void setPeriod(Integer period) { + this.period = period; } void setAsc(boolean asc) { @@ -92,7 +96,7 @@ class MeasureFilterSort { break; case METRIC: if (metric.isNumericType()) { - column = (period > 0 ? "pm.variation_value_" + period : "pm.value"); + column = (period != null ? "pm.variation_value_" + period : "pm.value"); } else { column = "pm.text_value"; } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java index e59708c8467..3952a86396f 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java @@ -39,11 +39,11 @@ class MeasureFilterSql { private final Database database; private final MeasureFilter filter; - private final MesasureFilterContext context; + private final MeasureFilterContext context; private final StringBuilder sql = new StringBuilder(1000); private final List<Date> dateParameters = Lists.newArrayList(); - MeasureFilterSql(Database database, MeasureFilter filter, MesasureFilterContext context) { + MeasureFilterSql(Database database, MeasureFilter filter, MeasureFilterContext context) { this.database = database; this.filter = filter; this.context = context; @@ -71,22 +71,22 @@ class MeasureFilterSql { private void init() { sql.append("SELECT block.id, max(block.rid) rid, max(block.rootid) rootid, max(sortval) sortval"); - for (int index = 0; index < filter.measureConditions().size(); index++) { + for (int index = 0; index < filter.getMeasureConditions().size(); index++) { sql.append(", max(crit_").append(index).append(")"); } sql.append(" FROM ("); appendSortBlock(); - for (int index = 0; index < filter.measureConditions().size(); index++) { - MeasureFilterValueCondition condition = filter.measureConditions().get(index); + for (int index = 0; index < filter.getMeasureConditions().size(); index++) { + MeasureFilterCondition condition = filter.getMeasureConditions().get(index); sql.append(" UNION "); appendConditionBlock(index, condition); } sql.append(") block GROUP BY block.id"); - if (!filter.measureConditions().isEmpty()) { + if (!filter.getMeasureConditions().isEmpty()) { sql.append(" HAVING "); - for (int index = 0; index < filter.measureConditions().size(); index++) { + for (int index = 0; index < filter.getMeasureConditions().size(); index++) { if (index > 0) { sql.append(" AND "); } @@ -101,8 +101,8 @@ class MeasureFilterSql { private void appendSortBlock() { sql.append(" SELECT s.id, s.project_id rid, s.root_project_id rootid, ").append(filter.sort().column()).append(" sortval"); - for (int index = 0; index < filter.measureConditions().size(); index++) { - MeasureFilterValueCondition condition = filter.measureConditions().get(index); + for (int index = 0; index < filter.getMeasureConditions().size(); index++) { + MeasureFilterCondition condition = filter.getMeasureConditions().get(index); sql.append(", ").append(nullSelect(condition.metric())).append(" crit_").append(index); } sql.append(" FROM snapshots s INNER JOIN projects p ON s.project_id=p.id "); @@ -115,14 +115,14 @@ class MeasureFilterSql { appendResourceConditions(); } - private void appendConditionBlock(int conditionIndex, MeasureFilterValueCondition condition) { + private void appendConditionBlock(int conditionIndex, MeasureFilterCondition condition) { sql.append(" SELECT s.id, s.project_id rid, s.root_project_id rootid, null sortval"); - for (int j = 0; j < filter.measureConditions().size(); j++) { + for (int j = 0; j < filter.getMeasureConditions().size(); j++) { sql.append(", "); if (j == conditionIndex) { sql.append(condition.valueColumn()); } else { - sql.append(nullSelect(filter.measureConditions().get(j).metric())); + sql.append(nullSelect(filter.getMeasureConditions().get(j).metric())); } sql.append(" crit_").append(j); } @@ -130,44 +130,46 @@ class MeasureFilterSql { sql.append(" WHERE "); appendResourceConditions(); sql.append(" AND pm.rule_id IS NULL AND pm.rule_priority IS NULL AND pm.characteristic_id IS NULL AND pm.person_id IS NULL AND "); - condition.appendSql(sql); + condition.appendSqlCondition(sql); } private void appendResourceConditions() { sql.append(" s.status='P' AND s.islast=").append(database.getDialect().getTrueSqlValue()); - sql.append(" AND p.copy_resource_id IS NULL "); - if (!filter.resourceQualifiers().isEmpty()) { + if (context.getBaseSnapshot() == null) { + sql.append(" AND p.copy_resource_id IS NULL "); + } + if (!filter.getResourceQualifiers().isEmpty()) { sql.append(" AND s.qualifier IN "); - appendInStatement(filter.resourceQualifiers(), sql); + appendInStatement(filter.getResourceQualifiers(), sql); } - if (!filter.resourceScopes().isEmpty()) { + if (!filter.getResourceScopes().isEmpty()) { sql.append(" AND s.scope IN "); - appendInStatement(filter.resourceScopes(), sql); + appendInStatement(filter.getResourceScopes(), sql); } - if (!filter.resourceLanguages().isEmpty()) { + if (!filter.getResourceLanguages().isEmpty()) { sql.append(" AND p.language IN "); - appendInStatement(filter.resourceLanguages(), sql); + appendInStatement(filter.getResourceLanguages(), sql); } - if (filter.fromDate() != null) { + if (filter.getFromDate() != null) { sql.append(" AND s.created_at >= ? "); - dateParameters.add(new java.sql.Date(filter.fromDate().getTime())); + dateParameters.add(new java.sql.Date(filter.getFromDate().getTime())); } - if (filter.toDate() != null) { + if (filter.getToDate() != null) { sql.append(" AND s.created_at <= ? "); - dateParameters.add(new java.sql.Date(filter.toDate().getTime())); + dateParameters.add(new java.sql.Date(filter.getToDate().getTime())); } - if (filter.userFavourites() && context.getUserId() != null) { + if (filter.isOnFavourites() && context.getUserId() != null) { sql.append(" AND s.project_id IN (SELECT props.resource_id FROM properties props WHERE props.prop_key='favourite' AND props.user_id="); sql.append(context.getUserId()); sql.append(" AND props.resource_id IS NOT NULL) "); } - if (StringUtils.isNotBlank(filter.resourceName())) { + if (StringUtils.isNotBlank(filter.getResourceName())) { sql.append(" AND s.project_id IN (SELECT rindex.resource_id FROM resource_index rindex WHERE rindex.kee like '"); - sql.append(StringEscapeUtils.escapeSql(StringUtils.lowerCase(filter.resourceName()))); + sql.append(StringEscapeUtils.escapeSql(StringUtils.lowerCase(filter.getResourceName()))); sql.append("%'"); - if (!filter.resourceQualifiers().isEmpty()) { + if (!filter.getResourceQualifiers().isEmpty()) { sql.append(" AND rindex.qualifier IN "); - appendInStatement(filter.resourceQualifiers(), sql); + appendInStatement(filter.getResourceQualifiers(), sql); } sql.append(") "); } @@ -178,7 +180,7 @@ class MeasureFilterSql { } else { Long rootSnapshotId = (baseSnapshot.getRootId() != null ? baseSnapshot.getRootId() : baseSnapshot.getId()); sql.append(" AND s.root_snapshot_id=").append(rootSnapshotId); - sql.append(" AND s.path LIKE '").append(baseSnapshot.getPath()).append(baseSnapshot.getId()).append(".%'"); + sql.append(" AND s.path LIKE '").append(StringUtils.defaultString(baseSnapshot.getPath())).append(baseSnapshot.getId()).append(".%'"); } } } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MesasureFilterContext.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterContextTest.java index c5362a3cdba..ffd7fd643e2 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MesasureFilterContext.java +++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterContextTest.java @@ -19,25 +19,23 @@ */ package org.sonar.core.measure; -import org.sonar.core.resource.SnapshotDto; +import org.junit.Test; -public class MesasureFilterContext { - private Long userId; - private SnapshotDto baseSnapshot; +import static org.fest.assertions.Assertions.assertThat; - public Long getUserId() { - return userId; +public class MeasureFilterContextTest { + @Test + public void test_empty_toString() { + MeasureFilterContext context = new MeasureFilterContext(); + assertThat(context.toString()).isNotEmpty(); } - public void setUserId(Long userId) { - this.userId = userId; - } - - public SnapshotDto getBaseSnapshot() { - return baseSnapshot; - } - - public void setBaseSnapshot(SnapshotDto baseSnapshot) { - this.baseSnapshot = baseSnapshot; + @Test + public void test_toString() { + MeasureFilterContext context = new MeasureFilterContext(); + context.setJson("{}"); + context.setSql("SELECT *"); + context.setUserId(50L); + assertThat(context.toString()).isEqualTo("MeasureFilterContext[json={},sql=SELECT *,user=50]"); } } diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDecoderTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDecoderTest.java new file mode 100644 index 00000000000..750cd6667d0 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDecoderTest.java @@ -0,0 +1,121 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.measure; + +import org.json.simple.parser.ParseException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.MetricFinder; + +import java.util.Date; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MeasureFilterDecoderTest { + + private MetricFinder metricFinder; + + @Before + public void before() { + metricFinder = mock(MetricFinder.class); + when(metricFinder.findByKey(anyString())).thenAnswer(new Answer<Metric>() { + public Metric answer(InvocationOnMock invocationOnMock) throws Throwable { + return new Metric((String) invocationOnMock.getArguments()[0]); + } + }); + } + + @Test + public void should_decode() throws ParseException { + String json = "{\"base\": \"org.struts\", \"onBaseChildren\": true, \"scopes\": [\"PRJ\"], " + + "\"qualifiers\": [\"TRK\",\"CLA\"], " + + "\"languages\": [\"java\", \"php\"], \"name\": \"Struts\", \"fromDate\": \"2012-12-25\", " + + "\"toDate\": \"2013-01-31\", " + + "\"favourites\": true, " + + "\"sortAsc\": true, \"sortField\": \"METRIC\", \"sortMetric\": \"ncloc\", \"sortPeriod\":5, " + + "\"conditions\":[{\"metric\":\"lines\", \"op\":\">\", \"val\":123.0}]}"; + + MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json); + + assertThat(filter.getBaseResourceKey()).isEqualTo("org.struts"); + assertThat(filter.isOnBaseResourceChildren()).isTrue(); + assertThat(filter.getResourceScopes()).containsExactly("PRJ"); + assertThat(filter.getResourceQualifiers()).containsExactly("TRK", "CLA"); + assertThat(filter.getResourceLanguages()).containsExactly("java", "php"); + assertThat(filter.getResourceName()).isEqualTo("Struts"); + assertThat(filter.getFromDate().getYear()).isEqualTo(2012 - 1900); + assertThat(filter.getToDate().getYear()).isEqualTo(2013 - 1900); + assertThat(filter.isOnFavourites()).isTrue(); + assertThat(filter.sort().metric().getKey()).isEqualTo("ncloc"); + assertThat(filter.sort().isAsc()).isTrue(); + MeasureFilterCondition condition = filter.getMeasureConditions().get(0); + assertThat(condition.metric().getKey()).isEqualTo("lines"); + assertThat(condition.operator()).isEqualTo(">"); + assertThat(condition.value()).isEqualTo(123.0); + } + + @Test + public void should_set_max_date_by_number_of_days() throws ParseException { + String json = "{\"beforeDays\": 5}"; + + MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json); + + assertThat(filter.getFromDate()).isNull(); + assertThat(filter.getToDate().before(new Date())).isTrue(); + } + + @Test + public void should_set_min_date_by_number_of_days() throws ParseException { + String json = "{\"afterDays\": 5}"; + + MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json); + + assertThat(filter.getToDate()).isNull(); + assertThat(filter.getFromDate().before(new Date())).isTrue(); + } + + @Test + public void test_default_values() throws ParseException { + MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode("{}"); + + assertThat(filter.getBaseResourceKey()).isNull(); + assertThat(filter.isOnBaseResourceChildren()).isFalse(); + assertThat(filter.getResourceScopes()).isEmpty(); + assertThat(filter.getResourceQualifiers()).isEmpty(); + assertThat(filter.getResourceLanguages()).isEmpty(); + assertThat(filter.getResourceName()).isNull(); + assertThat(filter.getFromDate()).isNull(); + assertThat(filter.getToDate()).isNull(); + assertThat(filter.isOnFavourites()).isFalse(); + assertThat(filter.sort().metric()).isNull(); + assertThat(filter.sort().getPeriod()).isNull(); + assertThat(filter.sort().onMeasures()).isFalse(); + assertThat(filter.sort().field()).isEqualTo(MeasureFilterSort.Field.NAME); + assertThat(filter.sort().isAsc()).isTrue(); + assertThat(filter.getMeasureConditions()).isEmpty(); + + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterEngineTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterEngineTest.java new file mode 100644 index 00000000000..b92d173062f --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterEngineTest.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.measure; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Test; +import org.slf4j.Logger; + +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; + +public class MeasureFilterEngineTest { + @Test + public void should_decode_json_and_execute_filter() throws Exception { + MeasureFilterDecoder decoder = mock(MeasureFilterDecoder.class); + MeasureFilter filter = new MeasureFilter(); + when(decoder.decode("{}")).thenReturn(filter); + MeasureFilterExecutor executor = mock(MeasureFilterExecutor.class); + Logger logger = mock(Logger.class); + when(logger.isDebugEnabled()).thenReturn(true); + + MeasureFilterEngine engine = new MeasureFilterEngine(decoder, executor); + + final long userId = 50L; + engine.execute("{}", userId, logger); + verify(executor).execute(refEq(filter), argThat(new BaseMatcher<MeasureFilterContext>() { + public boolean matches(Object o) { + MeasureFilterContext context = (MeasureFilterContext) o; + return "{}".equals(context.getJson()) && context.getUserId() == userId; + } + + public void describeTo(Description description) { + } + })); + verify(logger).debug(anyString()); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterExecutorTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterExecutorTest.java index 75922b5eea2..e2eb14507bf 100644 --- a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterExecutorTest.java +++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterExecutorTest.java @@ -27,6 +27,7 @@ import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.SnapshotDto; +import java.sql.SQLException; import java.util.List; import static org.fest.assertions.Assertions.assertThat; @@ -54,15 +55,15 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void invalid_filter_should_not_return_results() { - MeasureFilter filter = new MeasureFilter(); - // no qualifiers - assertThat(executor.execute(filter, null)).isEmpty(); + public void invalid_filter_should_not_return_results() throws SQLException { + MeasureFilter filter = new MeasureFilter().setUserFavourites(true); + // anonymous user does not have favourites + assertThat(executor.execute(filter, new MeasureFilterContext())).isEmpty(); } @Test public void filter_is_not_valid_if_missing_base_snapshot() { - MesasureFilterContext context = new MesasureFilterContext(); + MeasureFilterContext context = new MeasureFilterContext(); MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setOnBaseResourceChildren(true); assertThat(MeasureFilterExecutor.isValid(filter, context)).isFalse(); @@ -71,8 +72,22 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test + public void filter_is_not_valid_if_condition_on_unknown_metric() { + MeasureFilterContext context = new MeasureFilterContext(); + MeasureFilter filter = new MeasureFilter().addCondition(new MeasureFilterCondition(null, "<", 3.0)); + assertThat(MeasureFilterExecutor.isValid(filter, context)).isFalse(); + } + + @Test + public void filter_is_not_valid_if_sorting_on_unknown_metric() { + MeasureFilterContext context = new MeasureFilterContext(); + MeasureFilter filter = new MeasureFilter().setSortOnMetric(null); + assertThat(MeasureFilterExecutor.isValid(filter, context)).isFalse(); + } + + @Test public void filter_is_not_valid_if_anonymous_favourites() { - MesasureFilterContext context = new MesasureFilterContext(); + MeasureFilterContext context = new MeasureFilterContext(); MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setUserFavourites(true); assertThat(MeasureFilterExecutor.isValid(filter, context)).isFalse(); @@ -81,9 +96,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void projects_without_measure_conditions() { + public void projects_without_measure_conditions() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOn(MeasureFilterSort.Field.LANGUAGE); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); verifyJavaProject(rows.get(0)); @@ -100,9 +115,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_ascending_resource_name() { + public void sort_by_ascending_resource_name() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortAsc(true); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // Big -> Tiny assertThat(rows).hasSize(2); @@ -111,9 +126,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_descending_resource_name() { + public void sort_by_descending_resource_name() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortAsc(false); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // Tiny -> Big assertThat(rows).hasSize(2); @@ -122,9 +137,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_ascending_text_measure() { + public void sort_by_ascending_text_measure() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOnMetric(METRIC_PROFILE); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); verifyPhpProject(rows.get(0));//php way @@ -132,9 +147,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_descending_text_measure() { + public void sort_by_descending_text_measure() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOnMetric(METRIC_PROFILE).setSortAsc(false); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); verifyJavaProject(rows.get(0));// Sonar way @@ -142,18 +157,18 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_missing_text_measure() { + public void sort_by_missing_text_measure() throws SQLException { // the metric 'profile' is not set on files MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortOnMetric(METRIC_PROFILE); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2);//2 files randomly sorted } @Test - public void sort_by_ascending_numeric_measure() { + public void sort_by_ascending_numeric_measure() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortOnMetric(METRIC_LINES); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // Tiny -> Big assertThat(rows).hasSize(2); @@ -162,9 +177,9 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_descending_numeric_measure() { + public void sort_by_descending_numeric_measure() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortOnMetric(METRIC_LINES).setSortAsc(false); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // Big -> Tiny assertThat(rows).hasSize(2); @@ -173,19 +188,19 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_missing_numeric_measure() { + public void sort_by_missing_numeric_measure() throws SQLException { // coverage measures are not computed MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setSortOnMetric(METRIC_COVERAGE); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // 2 files, random order assertThat(rows).hasSize(2); } @Test - public void sort_by_ascending_variation() { + public void sort_by_ascending_variation() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOnMetric(METRIC_LINES).setSortOnPeriod(5); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); verifyJavaProject(rows.get(0));// +400 @@ -193,10 +208,10 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_descending_variation() { + public void sort_by_descending_variation() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK") .setSortOnMetric(METRIC_LINES).setSortOnPeriod(5).setSortAsc(false); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); verifyPhpProject(rows.get(0));// +4900 @@ -204,70 +219,70 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void sort_by_ascending_date() { + public void sort_by_ascending_date() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOn(MeasureFilterSort.Field.DATE); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); verifyJavaProject(rows.get(0));// 2008 verifyPhpProject(rows.get(1));// 2012 } @Test - public void sort_by_descending_date() { + public void sort_by_descending_date() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setSortOn(MeasureFilterSort.Field.DATE).setSortAsc(false); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); verifyPhpProject(rows.get(0));// 2012 verifyJavaProject(rows.get(1));// 2008 } @Test - public void condition_on_numeric_measure() { + public void condition_on_numeric_measure() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA") .setSortOnMetric(METRIC_LINES) - .addCondition(new MeasureFilterValueCondition(METRIC_LINES, MeasureFilterValueCondition.Operator.GREATER, 200)); - List<MeasureFilterRow> rows = executor.execute(filter, null); + .addCondition(new MeasureFilterCondition(METRIC_LINES, ">", 200)); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1); verifyJavaBigFile(rows.get(0)); } @Test - public void condition_on_measure_variation() { + public void condition_on_measure_variation() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK") .setSortOnMetric(METRIC_LINES) - .addCondition(new MeasureFilterValueCondition(METRIC_LINES, MeasureFilterValueCondition.Operator.GREATER, 1000).setPeriod(5)); - List<MeasureFilterRow> rows = executor.execute(filter, null); + .addCondition(new MeasureFilterCondition(METRIC_LINES, ">", 1000).setPeriod(5)); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1); verifyPhpProject(rows.get(0)); } @Test - public void multiple_conditions_on_numeric_measures() { + public void multiple_conditions_on_numeric_measures() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA") .setSortOnMetric(METRIC_LINES) - .addCondition(new MeasureFilterValueCondition(METRIC_LINES, MeasureFilterValueCondition.Operator.GREATER, 2)) - .addCondition(new MeasureFilterValueCondition(METRIC_LINES, MeasureFilterValueCondition.Operator.LESS_OR_EQUALS, 50)); - List<MeasureFilterRow> rows = executor.execute(filter, null); + .addCondition(new MeasureFilterCondition(METRIC_LINES, ">", 2)) + .addCondition(new MeasureFilterCondition(METRIC_LINES, "<=", 50)); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1); verifyJavaTinyFile(rows.get(0)); } @Test - public void filter_by_language() { + public void filter_by_language() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setResourceLanguages("java", "cobol"); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1); verifyJavaProject(rows.get(0)); } @Test - public void filter_by_min_date() { + public void filter_by_min_date() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setFromDate(DateUtils.parseDate("2012-12-13")); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // php has been analyzed in 2012-12-13, whereas java project has been analyzed in 2008 assertThat(rows).hasSize(1); @@ -275,11 +290,11 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void filter_by_range_of_dates() { + public void filter_by_range_of_dates() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK") .setFromDate(DateUtils.parseDate("2007-01-01")) .setToDate(DateUtils.parseDate("2010-01-01")); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); // php has been analyzed in 2012-12-13, whereas java project has been analyzed in 2008 assertThat(rows).hasSize(1); @@ -287,18 +302,18 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void filter_by_resource_name() { + public void filter_by_resource_name() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK").setResourceName("PHP Proj"); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1); verifyPhpProject(rows.get(0)); } @Test - public void filter_by_base_resource() { + public void filter_by_base_resource() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("CLA").setBaseResourceKey("java_project"); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(2); // default sort is on resource name @@ -307,26 +322,26 @@ public class MeasureFilterExecutorTest extends AbstractDaoTestCase { } @Test - public void filter_by_parent_resource() { - MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK", "PAC", "CLA").setBaseResourceKey("java_project").setOnBaseResourceChildren(true); - List<MeasureFilterRow> rows = executor.execute(filter, null); + public void filter_by_parent_resource() throws SQLException { + MeasureFilter filter = new MeasureFilter().setBaseResourceKey("java_project").setOnBaseResourceChildren(true); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).hasSize(1);// the package org.sonar.foo assertThat(rows.get(0).getSnapshotId()).isEqualTo(JAVA_PACKAGE_SNAPSHOT_ID); } @Test - public void filter_by_parent_without_children() { + public void filter_by_parent_without_children() throws SQLException { MeasureFilter filter = new MeasureFilter().setResourceQualifiers("TRK", "PAC", "CLA").setBaseResourceKey("java_project:org.sonar.foo.Big").setOnBaseResourceChildren(true); - List<MeasureFilterRow> rows = executor.execute(filter, null); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext()); assertThat(rows).isEmpty(); } @Test - public void filter_by_user_favourites() { + public void filter_by_user_favourites() throws SQLException { MeasureFilter filter = new MeasureFilter().setUserFavourites(true); - List<MeasureFilterRow> rows = executor.execute(filter, 50L); + List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext().setUserId(50L)); assertThat(rows).hasSize(2); verifyJavaBigFile(rows.get(0)); |