mirror of
https://github.com/SonarSource/sonarqube.git
synced 2024-08-03 08:18:00 +02:00
Fix crlf
This commit is contained in:
parent
c6d954e8c3
commit
ee7b180068
2
COPYING
2
COPYING
@ -1,4 +1,4 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
|
@ -6,4 +6,4 @@ tar -cf docs.tar -C target/site/ .
|
||||
|
||||
scp -i ~/.ssh/id_rsa-sonar-keypair -C -r docs.tar root@ec2-75-101-133-159.compute-1.amazonaws.com:/tmp
|
||||
|
||||
ssh -i ~/.ssh/id_rsa-sonar-keypair root@ec2-75-101-133-159.compute-1.amazonaws.com 'tar -xf /tmp/docs.tar -C /vol/www/sonar.codehaus.org/docs'
|
||||
ssh -i ~/.ssh/id_rsa-sonar-keypair root@ec2-75-101-133-159.compute-1.amazonaws.com 'tar -xf /tmp/docs.tar -C /vol/www/sonar.codehaus.org/docs'
|
||||
|
@ -1,71 +1,71 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.sensors;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.api.batch.Decorator;
|
||||
import org.sonar.api.batch.DecoratorContext;
|
||||
import org.sonar.api.batch.DependedUpon;
|
||||
import org.sonar.api.batch.DependsUpon;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.batch.index.ResourcePersister;
|
||||
|
||||
/**
|
||||
* Decorator that currently only closes a review when its corresponding violation has been fixed.
|
||||
*/
|
||||
@DependsUpon("ViolationPersisterDecorator")
|
||||
public class ReviewsDecorator implements Decorator {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ReviewsDecorator.class);
|
||||
|
||||
private ResourcePersister resourcePersister;
|
||||
private DatabaseSession databaseSession;
|
||||
|
||||
public ReviewsDecorator(ResourcePersister resourcePersister, DatabaseSession databaseSession) {
|
||||
this.resourcePersister = resourcePersister;
|
||||
this.databaseSession = databaseSession;
|
||||
}
|
||||
|
||||
public boolean shouldExecuteOnProject(Project project) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void decorate(Resource resource, DecoratorContext context) {
|
||||
Snapshot currentSnapshot = resourcePersister.getSnapshot(resource);
|
||||
if (currentSnapshot != null) {
|
||||
int resourceId = currentSnapshot.getResourceId();
|
||||
int snapshotId = currentSnapshot.getId();
|
||||
Query query = databaseSession.createNativeQuery("UPDATE reviews SET status='closed' " + "WHERE resource_id = " + resourceId
|
||||
+ " AND rule_failure_permanent_id NOT IN " + "(SELECT permanent_id FROM rule_failures WHERE snapshot_id = " + snapshotId + ")");
|
||||
int rowUpdated = query.executeUpdate();
|
||||
LOG.debug("- {} reviews set to 'closed' on resource #{}", rowUpdated, resourceId);
|
||||
databaseSession.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.sensors;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.api.batch.Decorator;
|
||||
import org.sonar.api.batch.DecoratorContext;
|
||||
import org.sonar.api.batch.DependedUpon;
|
||||
import org.sonar.api.batch.DependsUpon;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.batch.index.ResourcePersister;
|
||||
|
||||
/**
|
||||
* Decorator that currently only closes a review when its corresponding violation has been fixed.
|
||||
*/
|
||||
@DependsUpon("ViolationPersisterDecorator")
|
||||
public class ReviewsDecorator implements Decorator {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ReviewsDecorator.class);
|
||||
|
||||
private ResourcePersister resourcePersister;
|
||||
private DatabaseSession databaseSession;
|
||||
|
||||
public ReviewsDecorator(ResourcePersister resourcePersister, DatabaseSession databaseSession) {
|
||||
this.resourcePersister = resourcePersister;
|
||||
this.databaseSession = databaseSession;
|
||||
}
|
||||
|
||||
public boolean shouldExecuteOnProject(Project project) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void decorate(Resource resource, DecoratorContext context) {
|
||||
Snapshot currentSnapshot = resourcePersister.getSnapshot(resource);
|
||||
if (currentSnapshot != null) {
|
||||
int resourceId = currentSnapshot.getResourceId();
|
||||
int snapshotId = currentSnapshot.getId();
|
||||
Query query = databaseSession.createNativeQuery("UPDATE reviews SET status='closed' " + "WHERE resource_id = " + resourceId
|
||||
+ " AND rule_failure_permanent_id NOT IN " + "(SELECT permanent_id FROM rule_failures WHERE snapshot_id = " + snapshotId + ")");
|
||||
int rowUpdated = query.executeUpdate();
|
||||
LOG.debug("- {} reviews set to 'closed' on resource #{}", rowUpdated, resourceId);
|
||||
databaseSession.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,196 +1,196 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.timemachine;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.codehaus.plexus.util.StringInputStream;
|
||||
import org.sonar.api.batch.*;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.SnapshotSource;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RuleFinder;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.components.PastViolationsLoader;
|
||||
import org.sonar.batch.index.ViolationPersister;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@DependsUpon(DecoratorBarriers.END_OF_VIOLATIONS_GENERATION)
|
||||
@DependedUpon("ViolationPersisterDecorator") /* temporary workaround - see NewViolationsDecorator */
|
||||
public class ViolationPersisterDecorator implements Decorator {
|
||||
|
||||
/**
|
||||
* Those chars would be ignored during generation of checksums.
|
||||
*/
|
||||
private static final String SPACE_CHARS = "\t\n\r ";
|
||||
|
||||
private RuleFinder ruleFinder;
|
||||
private PastViolationsLoader pastViolationsLoader;
|
||||
private ViolationPersister violationPersister;
|
||||
|
||||
List<String> checksums = Lists.newArrayList();
|
||||
|
||||
public ViolationPersisterDecorator(RuleFinder ruleFinder, PastViolationsLoader pastViolationsLoader, ViolationPersister violationPersister) {
|
||||
this.ruleFinder = ruleFinder;
|
||||
this.pastViolationsLoader = pastViolationsLoader;
|
||||
this.violationPersister = violationPersister;
|
||||
}
|
||||
|
||||
public boolean shouldExecuteOnProject(Project project) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void decorate(Resource resource, DecoratorContext context) {
|
||||
if (context.getViolations().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Load past violations
|
||||
List<RuleFailureModel> pastViolations = pastViolationsLoader.getPastViolations(resource);
|
||||
// Load current source and calculate checksums
|
||||
checksums = getChecksums(pastViolationsLoader.getSource(resource));
|
||||
// Save violations
|
||||
compareWithPastViolations(context, pastViolations);
|
||||
// Clear cache
|
||||
checksums.clear();
|
||||
}
|
||||
|
||||
private void compareWithPastViolations(DecoratorContext context, List<RuleFailureModel> pastViolations) {
|
||||
Multimap<Rule, RuleFailureModel> pastViolationsByRule = LinkedHashMultimap.create();
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
Rule rule = ruleFinder.findById(pastViolation.getRuleId());
|
||||
pastViolationsByRule.put(rule, pastViolation);
|
||||
}
|
||||
// for each violation, search equivalent past violation
|
||||
for (Violation violation : context.getViolations()) {
|
||||
RuleFailureModel pastViolation = selectPastViolation(violation, pastViolationsByRule);
|
||||
if (pastViolation != null) {
|
||||
// remove violation, since would be updated and shouldn't affect other violations anymore
|
||||
pastViolationsByRule.remove(violation.getRule(), pastViolation);
|
||||
}
|
||||
String checksum = getChecksumForLine(checksums, violation.getLineId());
|
||||
violationPersister.saveViolation(context.getProject(), violation, pastViolation, checksum);
|
||||
}
|
||||
violationPersister.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return checksums, never null
|
||||
*/
|
||||
private List<String> getChecksums(SnapshotSource source) {
|
||||
return source == null || source.getData() == null ? Collections.<String>emptyList() : getChecksums(source.getData());
|
||||
}
|
||||
|
||||
static List<String> getChecksums(String data) {
|
||||
List<String> result = Lists.newArrayList();
|
||||
StringInputStream stream = new StringInputStream(data);
|
||||
try {
|
||||
List<String> lines = IOUtils.readLines(stream);
|
||||
for (String line : lines) {
|
||||
result.add(getChecksum(line));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Unable to calculate checksums", e);
|
||||
|
||||
} finally {
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static String getChecksum(String line) {
|
||||
String reducedLine = StringUtils.replaceChars(line, SPACE_CHARS, "");
|
||||
return DigestUtils.md5Hex(reducedLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return checksum or null if checksum not exists for line
|
||||
*/
|
||||
private String getChecksumForLine(List<String> checksums, Integer line) {
|
||||
if (line == null || line < 1 || line > checksums.size()) {
|
||||
return null;
|
||||
}
|
||||
return checksums.get(line - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation.
|
||||
*/
|
||||
RuleFailureModel selectPastViolation(Violation violation, Multimap<Rule, RuleFailureModel> pastViolationsByRule) {
|
||||
Collection<RuleFailureModel> pastViolations = pastViolationsByRule.get(violation.getRule());
|
||||
if (pastViolations==null || pastViolations.isEmpty()) {
|
||||
// skip violation, if there is no past violations with same rule
|
||||
return null;
|
||||
}
|
||||
String dbFormattedMessage = RuleFailureModel.abbreviateMessage(violation.getMessage());
|
||||
RuleFailureModel found = selectPastViolationUsingLine(violation, dbFormattedMessage, pastViolations);
|
||||
if (found == null) {
|
||||
found = selectPastViolationUsingChecksum(violation, dbFormattedMessage, pastViolations);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation with same message and line.
|
||||
*/
|
||||
private RuleFailureModel selectPastViolationUsingLine(Violation violation, String dbFormattedMessage, Collection<RuleFailureModel> pastViolations) {
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
if (ObjectUtils.equals(violation.getLineId(), pastViolation.getLine()) && StringUtils.equals(dbFormattedMessage, pastViolation.getMessage())) {
|
||||
return pastViolation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation with same message and checksum.
|
||||
*/
|
||||
private RuleFailureModel selectPastViolationUsingChecksum(Violation violation, String dbFormattedMessage, Collection<RuleFailureModel> pastViolations) {
|
||||
String checksum = getChecksumForLine(checksums, violation.getLineId());
|
||||
// skip violation, which not attached to line
|
||||
if (checksum == null) {
|
||||
return null;
|
||||
}
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
String pastChecksum = pastViolation.getChecksum();
|
||||
if (StringUtils.equals(checksum, pastChecksum) && StringUtils.equals(dbFormattedMessage, pastViolation.getMessage())) {
|
||||
return pastViolation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.timemachine;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.codehaus.plexus.util.StringInputStream;
|
||||
import org.sonar.api.batch.*;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.SnapshotSource;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RuleFinder;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.components.PastViolationsLoader;
|
||||
import org.sonar.batch.index.ViolationPersister;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@DependsUpon(DecoratorBarriers.END_OF_VIOLATIONS_GENERATION)
|
||||
@DependedUpon("ViolationPersisterDecorator") /* temporary workaround - see NewViolationsDecorator */
|
||||
public class ViolationPersisterDecorator implements Decorator {
|
||||
|
||||
/**
|
||||
* Those chars would be ignored during generation of checksums.
|
||||
*/
|
||||
private static final String SPACE_CHARS = "\t\n\r ";
|
||||
|
||||
private RuleFinder ruleFinder;
|
||||
private PastViolationsLoader pastViolationsLoader;
|
||||
private ViolationPersister violationPersister;
|
||||
|
||||
List<String> checksums = Lists.newArrayList();
|
||||
|
||||
public ViolationPersisterDecorator(RuleFinder ruleFinder, PastViolationsLoader pastViolationsLoader, ViolationPersister violationPersister) {
|
||||
this.ruleFinder = ruleFinder;
|
||||
this.pastViolationsLoader = pastViolationsLoader;
|
||||
this.violationPersister = violationPersister;
|
||||
}
|
||||
|
||||
public boolean shouldExecuteOnProject(Project project) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void decorate(Resource resource, DecoratorContext context) {
|
||||
if (context.getViolations().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Load past violations
|
||||
List<RuleFailureModel> pastViolations = pastViolationsLoader.getPastViolations(resource);
|
||||
// Load current source and calculate checksums
|
||||
checksums = getChecksums(pastViolationsLoader.getSource(resource));
|
||||
// Save violations
|
||||
compareWithPastViolations(context, pastViolations);
|
||||
// Clear cache
|
||||
checksums.clear();
|
||||
}
|
||||
|
||||
private void compareWithPastViolations(DecoratorContext context, List<RuleFailureModel> pastViolations) {
|
||||
Multimap<Rule, RuleFailureModel> pastViolationsByRule = LinkedHashMultimap.create();
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
Rule rule = ruleFinder.findById(pastViolation.getRuleId());
|
||||
pastViolationsByRule.put(rule, pastViolation);
|
||||
}
|
||||
// for each violation, search equivalent past violation
|
||||
for (Violation violation : context.getViolations()) {
|
||||
RuleFailureModel pastViolation = selectPastViolation(violation, pastViolationsByRule);
|
||||
if (pastViolation != null) {
|
||||
// remove violation, since would be updated and shouldn't affect other violations anymore
|
||||
pastViolationsByRule.remove(violation.getRule(), pastViolation);
|
||||
}
|
||||
String checksum = getChecksumForLine(checksums, violation.getLineId());
|
||||
violationPersister.saveViolation(context.getProject(), violation, pastViolation, checksum);
|
||||
}
|
||||
violationPersister.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return checksums, never null
|
||||
*/
|
||||
private List<String> getChecksums(SnapshotSource source) {
|
||||
return source == null || source.getData() == null ? Collections.<String>emptyList() : getChecksums(source.getData());
|
||||
}
|
||||
|
||||
static List<String> getChecksums(String data) {
|
||||
List<String> result = Lists.newArrayList();
|
||||
StringInputStream stream = new StringInputStream(data);
|
||||
try {
|
||||
List<String> lines = IOUtils.readLines(stream);
|
||||
for (String line : lines) {
|
||||
result.add(getChecksum(line));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Unable to calculate checksums", e);
|
||||
|
||||
} finally {
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static String getChecksum(String line) {
|
||||
String reducedLine = StringUtils.replaceChars(line, SPACE_CHARS, "");
|
||||
return DigestUtils.md5Hex(reducedLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return checksum or null if checksum not exists for line
|
||||
*/
|
||||
private String getChecksumForLine(List<String> checksums, Integer line) {
|
||||
if (line == null || line < 1 || line > checksums.size()) {
|
||||
return null;
|
||||
}
|
||||
return checksums.get(line - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation.
|
||||
*/
|
||||
RuleFailureModel selectPastViolation(Violation violation, Multimap<Rule, RuleFailureModel> pastViolationsByRule) {
|
||||
Collection<RuleFailureModel> pastViolations = pastViolationsByRule.get(violation.getRule());
|
||||
if (pastViolations==null || pastViolations.isEmpty()) {
|
||||
// skip violation, if there is no past violations with same rule
|
||||
return null;
|
||||
}
|
||||
String dbFormattedMessage = RuleFailureModel.abbreviateMessage(violation.getMessage());
|
||||
RuleFailureModel found = selectPastViolationUsingLine(violation, dbFormattedMessage, pastViolations);
|
||||
if (found == null) {
|
||||
found = selectPastViolationUsingChecksum(violation, dbFormattedMessage, pastViolations);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation with same message and line.
|
||||
*/
|
||||
private RuleFailureModel selectPastViolationUsingLine(Violation violation, String dbFormattedMessage, Collection<RuleFailureModel> pastViolations) {
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
if (ObjectUtils.equals(violation.getLineId(), pastViolation.getLine()) && StringUtils.equals(dbFormattedMessage, pastViolation.getMessage())) {
|
||||
return pastViolation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for past violation with same message and checksum.
|
||||
*/
|
||||
private RuleFailureModel selectPastViolationUsingChecksum(Violation violation, String dbFormattedMessage, Collection<RuleFailureModel> pastViolations) {
|
||||
String checksum = getChecksumForLine(checksums, violation.getLineId());
|
||||
// skip violation, which not attached to line
|
||||
if (checksum == null) {
|
||||
return null;
|
||||
}
|
||||
for (RuleFailureModel pastViolation : pastViolations) {
|
||||
String pastChecksum = pastViolation.getChecksum();
|
||||
if (StringUtils.equals(checksum, pastChecksum) && StringUtils.equals(dbFormattedMessage, pastViolation.getMessage())) {
|
||||
return pastViolation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,58 +1,58 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.sensors;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.File;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.utils.DateUtils;
|
||||
import org.sonar.batch.components.PastSnapshot;
|
||||
import org.sonar.batch.components.TimeMachineConfiguration;
|
||||
import org.sonar.batch.index.ResourcePersister;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ReviewsDecoratorTest extends AbstractDbUnitTestCase {
|
||||
|
||||
@Test
|
||||
@Ignore("DBUnit needs Hibernate mapping...")
|
||||
public void shouldSaveConfigurationInSnapshotsTable() throws ParseException {
|
||||
setupData("fixture");
|
||||
|
||||
File resource = new File("Foo");
|
||||
Snapshot snapshot = new Snapshot();
|
||||
snapshot.setId(666);
|
||||
snapshot.setResourceId(111);
|
||||
ResourcePersister persister = mock(ResourcePersister.class);
|
||||
when(persister.getSnapshot(resource)).thenReturn(snapshot);
|
||||
|
||||
ReviewsDecorator reviewsDecorator = new ReviewsDecorator(persister, getSession());
|
||||
reviewsDecorator.decorate(resource, null);
|
||||
|
||||
//checkTables("shouldSaveConfigurationInSnapshotsTable", "snapshots");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.plugins.core.sensors;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.File;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.utils.DateUtils;
|
||||
import org.sonar.batch.components.PastSnapshot;
|
||||
import org.sonar.batch.components.TimeMachineConfiguration;
|
||||
import org.sonar.batch.index.ResourcePersister;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ReviewsDecoratorTest extends AbstractDbUnitTestCase {
|
||||
|
||||
@Test
|
||||
@Ignore("DBUnit needs Hibernate mapping...")
|
||||
public void shouldSaveConfigurationInSnapshotsTable() throws ParseException {
|
||||
setupData("fixture");
|
||||
|
||||
File resource = new File("Foo");
|
||||
Snapshot snapshot = new Snapshot();
|
||||
snapshot.setId(666);
|
||||
snapshot.setResourceId(111);
|
||||
ResourcePersister persister = mock(ResourcePersister.class);
|
||||
when(persister.getSnapshot(resource)).thenReturn(snapshot);
|
||||
|
||||
ReviewsDecorator reviewsDecorator = new ReviewsDecorator(persister, getSession());
|
||||
reviewsDecorator.decorate(resource, null);
|
||||
|
||||
//checkTables("shouldSaveConfigurationInSnapshotsTable", "snapshots");
|
||||
}
|
||||
}
|
||||
|
@ -1,53 +1,53 @@
|
||||
<dataset>
|
||||
|
||||
<snapshots
|
||||
id="11"
|
||||
project_id="555"/>
|
||||
<snapshots
|
||||
id="111"
|
||||
project_id="555"/>
|
||||
<snapshots
|
||||
id="22"
|
||||
project_id="666"/>
|
||||
<snapshots
|
||||
id="222"
|
||||
project_id="666"/>
|
||||
|
||||
<rule_failures
|
||||
id="1"
|
||||
permament_id="1"
|
||||
snapshot_id="11"/>
|
||||
<rule_failures
|
||||
id="2"
|
||||
permament_id="2"
|
||||
snapshot_id="22"/>
|
||||
<rule_failures
|
||||
id="3"
|
||||
permament_id="3"
|
||||
snapshot_id="22"/>
|
||||
<rule_failures
|
||||
id="4"
|
||||
permament_id="1"
|
||||
snapshot_id="111"/>
|
||||
<rule_failures
|
||||
id="5"
|
||||
permament_id="3"
|
||||
snapshot_id="222"/>
|
||||
|
||||
<reviews
|
||||
id="1"
|
||||
status="open"
|
||||
rule_failure_permanent_id="1"
|
||||
resource_id="555"/>
|
||||
<reviews
|
||||
id="2"
|
||||
status="open"
|
||||
rule_failure_permanent_id="2"
|
||||
resource_id="666"/>
|
||||
<reviews
|
||||
id="3"
|
||||
status="open"
|
||||
rule_failure_permanent_id="3"
|
||||
resource_id="666"/>
|
||||
|
||||
<dataset>
|
||||
|
||||
<snapshots
|
||||
id="11"
|
||||
project_id="555"/>
|
||||
<snapshots
|
||||
id="111"
|
||||
project_id="555"/>
|
||||
<snapshots
|
||||
id="22"
|
||||
project_id="666"/>
|
||||
<snapshots
|
||||
id="222"
|
||||
project_id="666"/>
|
||||
|
||||
<rule_failures
|
||||
id="1"
|
||||
permament_id="1"
|
||||
snapshot_id="11"/>
|
||||
<rule_failures
|
||||
id="2"
|
||||
permament_id="2"
|
||||
snapshot_id="22"/>
|
||||
<rule_failures
|
||||
id="3"
|
||||
permament_id="3"
|
||||
snapshot_id="22"/>
|
||||
<rule_failures
|
||||
id="4"
|
||||
permament_id="1"
|
||||
snapshot_id="111"/>
|
||||
<rule_failures
|
||||
id="5"
|
||||
permament_id="3"
|
||||
snapshot_id="222"/>
|
||||
|
||||
<reviews
|
||||
id="1"
|
||||
status="open"
|
||||
rule_failure_permanent_id="1"
|
||||
resource_id="555"/>
|
||||
<reviews
|
||||
id="2"
|
||||
status="open"
|
||||
rule_failure_permanent_id="2"
|
||||
resource_id="666"/>
|
||||
<reviews
|
||||
id="3"
|
||||
status="open"
|
||||
rule_failure_permanent_id="3"
|
||||
resource_id="666"/>
|
||||
|
||||
</dataset>
|
@ -1,2 +1,2 @@
|
||||
set MAVEN_OPTS=-Xmx768m -XX:MaxPermSize=256m
|
||||
mvn clean install -Dtest=false -DfailIfNoTests=false -Ddev
|
||||
mvn clean install -Dtest=false -DfailIfNoTests=false -Ddev
|
||||
|
@ -9,4 +9,4 @@ echo ''
|
||||
echo '-------------------------------------------------'
|
||||
|
||||
# it is recommended to use maven 3 for faster builds
|
||||
mvn clean install -Dtest=false -DfailIfNoTests=false -Ddev
|
||||
mvn clean install -Dtest=false -DfailIfNoTests=false -Ddev
|
||||
|
@ -1,175 +1,175 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.sonar.api.batch.DecoratorContext;
|
||||
import org.sonar.api.batch.Event;
|
||||
import org.sonar.api.batch.SonarIndex;
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.MeasuresFilters;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
|
||||
public class DefaultDecoratorContext implements DecoratorContext {
|
||||
|
||||
private SonarIndex index;
|
||||
private Resource resource;
|
||||
private boolean readOnly = false;
|
||||
|
||||
private List<DecoratorContext> childrenContexts;
|
||||
|
||||
public DefaultDecoratorContext(Resource resource,
|
||||
SonarIndex index,
|
||||
List<DecoratorContext> childrenContexts) {
|
||||
this.index = index;
|
||||
this.resource = resource;
|
||||
this.childrenContexts = childrenContexts;
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext setReadOnly(boolean b) {
|
||||
readOnly = b;
|
||||
childrenContexts = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return index.getProject();
|
||||
}
|
||||
|
||||
public List<DecoratorContext> getChildren() {
|
||||
checkReadOnly("getModules");
|
||||
return childrenContexts;
|
||||
}
|
||||
|
||||
private void checkReadOnly(String methodName) {
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children.");
|
||||
}
|
||||
}
|
||||
|
||||
public <M> M getMeasures(MeasuresFilter<M> filter) {
|
||||
return index.getMeasures(resource, filter);
|
||||
}
|
||||
|
||||
public Measure getMeasure(Metric metric) {
|
||||
return index.getMeasure(resource, metric);
|
||||
}
|
||||
|
||||
public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {
|
||||
List<Measure> result = Lists.newArrayList();
|
||||
for (DecoratorContext childContext : childrenContexts) {
|
||||
Object childResult = childContext.getMeasures(filter);
|
||||
if (childResult != null) {
|
||||
if (childResult instanceof Collection) {
|
||||
result.addAll((Collection) childResult);
|
||||
} else {
|
||||
result.add((Measure) childResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<Measure> getChildrenMeasures(Metric metric) {
|
||||
return getChildrenMeasures(MeasuresFilters.metric(metric));
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public DecoratorContext saveMeasure(Measure measure) {
|
||||
checkReadOnly("saveMeasure");
|
||||
index.addMeasure(resource, measure);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecoratorContext saveMeasure(Metric metric, Double value) {
|
||||
checkReadOnly("saveMeasure");
|
||||
index.addMeasure(resource, new Measure(metric, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public List<Violation> getViolations(ViolationQuery violationQuery) {
|
||||
return index.getViolations(violationQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public List<Violation> getViolations() {
|
||||
return index.getViolations(resource);
|
||||
}
|
||||
|
||||
public Dependency saveDependency(Dependency dependency) {
|
||||
checkReadOnly("addDependency");
|
||||
return index.addDependency(dependency);
|
||||
}
|
||||
|
||||
public Set<Dependency> getDependencies() {
|
||||
return index.getDependencies();
|
||||
}
|
||||
|
||||
public Collection<Dependency> getIncomingDependencies() {
|
||||
return index.getIncomingEdges(resource);
|
||||
}
|
||||
|
||||
public Collection<Dependency> getOutgoingDependencies() {
|
||||
return index.getOutgoingEdges(resource);
|
||||
}
|
||||
|
||||
public List<Event> getEvents() {
|
||||
return index.getEvents(resource);
|
||||
}
|
||||
|
||||
public Event createEvent(String name, String description, String category, Date date) {
|
||||
return index.addEvent(resource, name, description, category, date);
|
||||
}
|
||||
|
||||
public void deleteEvent(Event event) {
|
||||
index.deleteEvent(event);
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {
|
||||
if (violation.getResource() == null) {
|
||||
violation.setResource(resource);
|
||||
}
|
||||
index.addViolation(violation, force);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext saveViolation(Violation violation) {
|
||||
return saveViolation(violation, false);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.sonar.api.batch.DecoratorContext;
|
||||
import org.sonar.api.batch.Event;
|
||||
import org.sonar.api.batch.SonarIndex;
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.MeasuresFilters;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
|
||||
public class DefaultDecoratorContext implements DecoratorContext {
|
||||
|
||||
private SonarIndex index;
|
||||
private Resource resource;
|
||||
private boolean readOnly = false;
|
||||
|
||||
private List<DecoratorContext> childrenContexts;
|
||||
|
||||
public DefaultDecoratorContext(Resource resource,
|
||||
SonarIndex index,
|
||||
List<DecoratorContext> childrenContexts) {
|
||||
this.index = index;
|
||||
this.resource = resource;
|
||||
this.childrenContexts = childrenContexts;
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext setReadOnly(boolean b) {
|
||||
readOnly = b;
|
||||
childrenContexts = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return index.getProject();
|
||||
}
|
||||
|
||||
public List<DecoratorContext> getChildren() {
|
||||
checkReadOnly("getModules");
|
||||
return childrenContexts;
|
||||
}
|
||||
|
||||
private void checkReadOnly(String methodName) {
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children.");
|
||||
}
|
||||
}
|
||||
|
||||
public <M> M getMeasures(MeasuresFilter<M> filter) {
|
||||
return index.getMeasures(resource, filter);
|
||||
}
|
||||
|
||||
public Measure getMeasure(Metric metric) {
|
||||
return index.getMeasure(resource, metric);
|
||||
}
|
||||
|
||||
public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {
|
||||
List<Measure> result = Lists.newArrayList();
|
||||
for (DecoratorContext childContext : childrenContexts) {
|
||||
Object childResult = childContext.getMeasures(filter);
|
||||
if (childResult != null) {
|
||||
if (childResult instanceof Collection) {
|
||||
result.addAll((Collection) childResult);
|
||||
} else {
|
||||
result.add((Measure) childResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<Measure> getChildrenMeasures(Metric metric) {
|
||||
return getChildrenMeasures(MeasuresFilters.metric(metric));
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public DecoratorContext saveMeasure(Measure measure) {
|
||||
checkReadOnly("saveMeasure");
|
||||
index.addMeasure(resource, measure);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecoratorContext saveMeasure(Metric metric, Double value) {
|
||||
checkReadOnly("saveMeasure");
|
||||
index.addMeasure(resource, new Measure(metric, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public List<Violation> getViolations(ViolationQuery violationQuery) {
|
||||
return index.getViolations(violationQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public List<Violation> getViolations() {
|
||||
return index.getViolations(resource);
|
||||
}
|
||||
|
||||
public Dependency saveDependency(Dependency dependency) {
|
||||
checkReadOnly("addDependency");
|
||||
return index.addDependency(dependency);
|
||||
}
|
||||
|
||||
public Set<Dependency> getDependencies() {
|
||||
return index.getDependencies();
|
||||
}
|
||||
|
||||
public Collection<Dependency> getIncomingDependencies() {
|
||||
return index.getIncomingEdges(resource);
|
||||
}
|
||||
|
||||
public Collection<Dependency> getOutgoingDependencies() {
|
||||
return index.getOutgoingEdges(resource);
|
||||
}
|
||||
|
||||
public List<Event> getEvents() {
|
||||
return index.getEvents(resource);
|
||||
}
|
||||
|
||||
public Event createEvent(String name, String description, String category, Date date) {
|
||||
return index.addEvent(resource, name, description, category, date);
|
||||
}
|
||||
|
||||
public void deleteEvent(Event event) {
|
||||
index.deleteEvent(event);
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {
|
||||
if (violation.getResource() == null) {
|
||||
violation.setResource(resource);
|
||||
}
|
||||
index.addViolation(violation, force);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultDecoratorContext saveViolation(Violation violation) {
|
||||
return saveViolation(violation, false);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,88 +1,88 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RuleFinder;
|
||||
import org.sonar.api.rules.Violation;
|
||||
|
||||
public final class ViolationPersister {
|
||||
|
||||
private DatabaseSession session;
|
||||
private ResourcePersister resourcePersister;
|
||||
private RuleFinder ruleFinder;
|
||||
|
||||
public ViolationPersister(DatabaseSession session, ResourcePersister resourcePersister, RuleFinder ruleFinder) {
|
||||
this.session = session;
|
||||
this.resourcePersister = resourcePersister;
|
||||
this.ruleFinder = ruleFinder;
|
||||
}
|
||||
|
||||
void saveViolation(Project project, Violation violation) {
|
||||
saveViolation(project, violation, null, null);
|
||||
}
|
||||
|
||||
public void saveViolation(Project project, Violation violation, RuleFailureModel pastViolation, String checksum) {
|
||||
Snapshot snapshot = resourcePersister.saveResource(project, violation.getResource());
|
||||
|
||||
RuleFailureModel model = createModel(violation);
|
||||
if (pastViolation!=null) {
|
||||
model.setCreatedAt(pastViolation.getCreatedAt());
|
||||
model.setPermanentId(pastViolation.getPermanentId());
|
||||
model.setSwitchedOff(pastViolation.isSwitchedOff());
|
||||
} else {
|
||||
// avoid plugins setting date
|
||||
model.setCreatedAt(snapshot.getCreatedAt());
|
||||
}
|
||||
model.setSnapshotId(snapshot.getId());
|
||||
model.setChecksum(checksum);
|
||||
session.save(model);
|
||||
|
||||
if (model.getPermanentId()==null) {
|
||||
model.setPermanentId(model.getId());
|
||||
session.save(model);
|
||||
}
|
||||
|
||||
// the following fields can have been changed
|
||||
violation.setMessage(model.getMessage());// the message can be changed in the class RuleFailure (truncate + trim)
|
||||
violation.setCreatedAt(model.getCreatedAt());
|
||||
violation.setSwitchedOff(model.isSwitchedOff());
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
session.commit();
|
||||
}
|
||||
|
||||
private RuleFailureModel createModel(Violation violation) {
|
||||
RuleFailureModel model = new RuleFailureModel();
|
||||
Rule rule = ruleFinder.findByKey(violation.getRule().getRepositoryKey(), violation.getRule().getKey());
|
||||
model.setRuleId(rule.getId());
|
||||
model.setPriority(violation.getSeverity());
|
||||
model.setLine(violation.getLineId());
|
||||
model.setMessage(violation.getMessage());
|
||||
model.setCost(violation.getCost());
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RuleFinder;
|
||||
import org.sonar.api.rules.Violation;
|
||||
|
||||
public final class ViolationPersister {
|
||||
|
||||
private DatabaseSession session;
|
||||
private ResourcePersister resourcePersister;
|
||||
private RuleFinder ruleFinder;
|
||||
|
||||
public ViolationPersister(DatabaseSession session, ResourcePersister resourcePersister, RuleFinder ruleFinder) {
|
||||
this.session = session;
|
||||
this.resourcePersister = resourcePersister;
|
||||
this.ruleFinder = ruleFinder;
|
||||
}
|
||||
|
||||
void saveViolation(Project project, Violation violation) {
|
||||
saveViolation(project, violation, null, null);
|
||||
}
|
||||
|
||||
public void saveViolation(Project project, Violation violation, RuleFailureModel pastViolation, String checksum) {
|
||||
Snapshot snapshot = resourcePersister.saveResource(project, violation.getResource());
|
||||
|
||||
RuleFailureModel model = createModel(violation);
|
||||
if (pastViolation!=null) {
|
||||
model.setCreatedAt(pastViolation.getCreatedAt());
|
||||
model.setPermanentId(pastViolation.getPermanentId());
|
||||
model.setSwitchedOff(pastViolation.isSwitchedOff());
|
||||
} else {
|
||||
// avoid plugins setting date
|
||||
model.setCreatedAt(snapshot.getCreatedAt());
|
||||
}
|
||||
model.setSnapshotId(snapshot.getId());
|
||||
model.setChecksum(checksum);
|
||||
session.save(model);
|
||||
|
||||
if (model.getPermanentId()==null) {
|
||||
model.setPermanentId(model.getId());
|
||||
session.save(model);
|
||||
}
|
||||
|
||||
// the following fields can have been changed
|
||||
violation.setMessage(model.getMessage());// the message can be changed in the class RuleFailure (truncate + trim)
|
||||
violation.setCreatedAt(model.getCreatedAt());
|
||||
violation.setSwitchedOff(model.isSwitchedOff());
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
session.commit();
|
||||
}
|
||||
|
||||
private RuleFailureModel createModel(Violation violation) {
|
||||
RuleFailureModel model = new RuleFailureModel();
|
||||
Rule rule = ruleFinder.findByKey(violation.getRule().getRepositoryKey(), violation.getRule().getKey());
|
||||
model.setRuleId(rule.getId());
|
||||
model.setPriority(violation.getSeverity());
|
||||
model.setLine(violation.getLineId());
|
||||
model.setMessage(violation.getMessage());
|
||||
model.setCost(violation.getCost());
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,238 +1,238 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.batch.ResourceFilter;
|
||||
import org.sonar.api.measures.CoreMetrics;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilters;
|
||||
import org.sonar.api.measures.MetricFinder;
|
||||
import org.sonar.api.profiles.RulesProfile;
|
||||
import org.sonar.api.resources.Directory;
|
||||
import org.sonar.api.resources.File;
|
||||
import org.sonar.api.resources.Java;
|
||||
import org.sonar.api.resources.JavaPackage;
|
||||
import org.sonar.api.resources.Language;
|
||||
import org.sonar.api.resources.Library;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Qualifiers;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
import org.sonar.batch.DefaultResourceCreationLock;
|
||||
import org.sonar.batch.ProjectTree;
|
||||
import org.sonar.batch.ResourceFilters;
|
||||
import org.sonar.batch.ViolationFilters;
|
||||
|
||||
public class DefaultIndexTest {
|
||||
|
||||
private DefaultIndex index = null;
|
||||
private DefaultResourceCreationLock lock;
|
||||
private Rule rule;
|
||||
|
||||
@Before
|
||||
public void createIndex() {
|
||||
lock = new DefaultResourceCreationLock();
|
||||
MetricFinder metricFinder = mock(MetricFinder.class);
|
||||
when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
|
||||
|
||||
index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);
|
||||
Project project = new Project("project");
|
||||
|
||||
ResourceFilter filter = new ResourceFilter() {
|
||||
|
||||
public boolean isIgnored(Resource resource) {
|
||||
return StringUtils.containsIgnoreCase(resource.getKey(), "excluded");
|
||||
}
|
||||
};
|
||||
RulesProfile rulesProfile = RulesProfile.create();
|
||||
rule = Rule.create("repoKey", "ruleKey", "Rule");
|
||||
rulesProfile.activateRule(rule, null);
|
||||
index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[] { filter }), new ViolationFilters(), rulesProfile);
|
||||
index.doStart(project);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateUID() {
|
||||
Project project = new Project("my_project");
|
||||
assertThat(DefaultIndex.createUID(project, project), is("my_project"));
|
||||
|
||||
JavaPackage javaPackage = new JavaPackage("org.foo");
|
||||
assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));
|
||||
|
||||
Library library = new Library("junit:junit", "4.7");
|
||||
assertThat(DefaultIndex.createUID(project, library), is("junit:junit"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexParentOfDeprecatedFiles() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
assertThat(index.index(file), is(true));
|
||||
|
||||
Directory reference = new Directory("org/foo");
|
||||
assertThat(index.getResource(reference).getName(), is("org/foo"));
|
||||
assertThat(index.isIndexed(reference, true), is(true));
|
||||
assertThat(index.isExcluded(reference), is(false));
|
||||
assertThat(index.getChildren(reference).size(), is(1));
|
||||
assertThat(index.getParent(reference), is(Project.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexTreeOfResources() {
|
||||
Directory directory = new Directory("org/foo");
|
||||
File file = new File("org/foo/Bar.java");
|
||||
file.setLanguage(Java.INSTANCE);
|
||||
|
||||
assertThat(index.index(directory), is(true));
|
||||
assertThat(index.index(file, directory), is(true));
|
||||
|
||||
File fileRef = new File("org/foo/Bar.java");
|
||||
assertThat(index.getResource(fileRef).getKey(), is("org/foo/Bar.java"));
|
||||
assertThat(index.getResource(fileRef).getLanguage(), is((Language) Java.INSTANCE));
|
||||
assertThat(index.isIndexed(fileRef, true), is(true));
|
||||
assertThat(index.isExcluded(fileRef), is(false));
|
||||
assertThat(index.getChildren(fileRef).size(), is(0));
|
||||
assertThat(index.getParent(fileRef), is(Directory.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexLibraryOutsideProjectTree() {
|
||||
Library lib = new Library("junit", "4.8");
|
||||
assertThat(index.index(lib), is(true));
|
||||
|
||||
Library reference = new Library("junit", "4.8");
|
||||
assertThat(index.getResource(reference).getQualifier(), is(Qualifiers.LIBRARY));
|
||||
assertThat(index.isIndexed(reference, true), is(true));
|
||||
assertThat(index.isExcluded(reference), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotIndexResourceIfParentNotIndexed() {
|
||||
Directory directory = new Directory("org/other");
|
||||
File file = new File("org/foo/Bar.java");
|
||||
|
||||
assertThat(index.index(file, directory), is(false));
|
||||
|
||||
File fileRef = new File("org/foo/Bar.java");
|
||||
assertThat(index.isIndexed(directory, true), is(false));
|
||||
assertThat(index.isIndexed(fileRef, true), is(false));
|
||||
assertThat(index.isExcluded(fileRef), is(false));
|
||||
assertThat(index.getChildren(fileRef).size(), is(0));
|
||||
assertThat(index.getParent(fileRef), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Only a warning is logged when index is locked.
|
||||
*/
|
||||
@Test
|
||||
public void shouldIndexEvenIfLocked() {
|
||||
lock.lock();
|
||||
|
||||
Directory dir = new Directory("org/foo");
|
||||
assertThat(index.index(dir), is(true));
|
||||
assertThat(index.isIndexed(dir, true), is(true));
|
||||
}
|
||||
|
||||
@Test(expected = SonarException.class)
|
||||
public void shouldFailIfIndexingAndLocked() {
|
||||
lock.setFailWhenLocked(true);
|
||||
lock.lock();
|
||||
|
||||
Directory dir = new Directory("org/foo");
|
||||
index.index(dir);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeExcluded() {
|
||||
File file = new File("org/foo/ExcludedBar.java");
|
||||
assertThat(index.index(file), is(false));
|
||||
assertThat(index.isIndexed(file, true), is(true));
|
||||
assertThat(index.isIndexed(file, false), is(false));
|
||||
assertThat(index.isExcluded(file), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexResourceWhenAddingMeasure() {
|
||||
Resource dir = new Directory("org/foo");
|
||||
index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
|
||||
|
||||
assertThat(index.isIndexed(dir, true), is(true));
|
||||
assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));
|
||||
}
|
||||
|
||||
/**
|
||||
* See http://jira.codehaus.org/browse/SONAR-2107
|
||||
*/
|
||||
@Test
|
||||
public void shouldNotFailWhenSavingViolationOnNullRule() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation = Violation.create((Rule) null, file);
|
||||
index.addViolation(violation);
|
||||
|
||||
assertThat(index.getViolations(file).size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViolations() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation1 = Violation.create(rule, file);
|
||||
index.addViolation(violation1);
|
||||
Violation violation2 = Violation.create(rule, file);
|
||||
violation2.setSwitchedOff(true);
|
||||
index.addViolation(violation2);
|
||||
Violation violation3 = Violation.create(rule, file);
|
||||
violation3.setSwitchedOff(true);
|
||||
index.addViolation(violation3);
|
||||
|
||||
assertThat(index.getViolations(file).size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViolationsWithQuery() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation1 = Violation.create(rule, file);
|
||||
index.addViolation(violation1);
|
||||
Violation violation2 = Violation.create(rule, file);
|
||||
violation2.setSwitchedOff(true);
|
||||
index.addViolation(violation2);
|
||||
Violation violation3 = Violation.create(rule, file);
|
||||
violation3.setSwitchedOff(true);
|
||||
index.addViolation(violation3);
|
||||
|
||||
assertThat(index.getViolations(ViolationQuery.create().forResource(file).ignoreSwitchedOff(false)).size(), is(3));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetViolationsWithQueryWithNoResource() {
|
||||
index.getViolations(ViolationQuery.create());
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.batch.ResourceFilter;
|
||||
import org.sonar.api.measures.CoreMetrics;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilters;
|
||||
import org.sonar.api.measures.MetricFinder;
|
||||
import org.sonar.api.profiles.RulesProfile;
|
||||
import org.sonar.api.resources.Directory;
|
||||
import org.sonar.api.resources.File;
|
||||
import org.sonar.api.resources.Java;
|
||||
import org.sonar.api.resources.JavaPackage;
|
||||
import org.sonar.api.resources.Language;
|
||||
import org.sonar.api.resources.Library;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Qualifiers;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
import org.sonar.batch.DefaultResourceCreationLock;
|
||||
import org.sonar.batch.ProjectTree;
|
||||
import org.sonar.batch.ResourceFilters;
|
||||
import org.sonar.batch.ViolationFilters;
|
||||
|
||||
public class DefaultIndexTest {
|
||||
|
||||
private DefaultIndex index = null;
|
||||
private DefaultResourceCreationLock lock;
|
||||
private Rule rule;
|
||||
|
||||
@Before
|
||||
public void createIndex() {
|
||||
lock = new DefaultResourceCreationLock();
|
||||
MetricFinder metricFinder = mock(MetricFinder.class);
|
||||
when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
|
||||
|
||||
index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);
|
||||
Project project = new Project("project");
|
||||
|
||||
ResourceFilter filter = new ResourceFilter() {
|
||||
|
||||
public boolean isIgnored(Resource resource) {
|
||||
return StringUtils.containsIgnoreCase(resource.getKey(), "excluded");
|
||||
}
|
||||
};
|
||||
RulesProfile rulesProfile = RulesProfile.create();
|
||||
rule = Rule.create("repoKey", "ruleKey", "Rule");
|
||||
rulesProfile.activateRule(rule, null);
|
||||
index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[] { filter }), new ViolationFilters(), rulesProfile);
|
||||
index.doStart(project);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateUID() {
|
||||
Project project = new Project("my_project");
|
||||
assertThat(DefaultIndex.createUID(project, project), is("my_project"));
|
||||
|
||||
JavaPackage javaPackage = new JavaPackage("org.foo");
|
||||
assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));
|
||||
|
||||
Library library = new Library("junit:junit", "4.7");
|
||||
assertThat(DefaultIndex.createUID(project, library), is("junit:junit"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexParentOfDeprecatedFiles() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
assertThat(index.index(file), is(true));
|
||||
|
||||
Directory reference = new Directory("org/foo");
|
||||
assertThat(index.getResource(reference).getName(), is("org/foo"));
|
||||
assertThat(index.isIndexed(reference, true), is(true));
|
||||
assertThat(index.isExcluded(reference), is(false));
|
||||
assertThat(index.getChildren(reference).size(), is(1));
|
||||
assertThat(index.getParent(reference), is(Project.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexTreeOfResources() {
|
||||
Directory directory = new Directory("org/foo");
|
||||
File file = new File("org/foo/Bar.java");
|
||||
file.setLanguage(Java.INSTANCE);
|
||||
|
||||
assertThat(index.index(directory), is(true));
|
||||
assertThat(index.index(file, directory), is(true));
|
||||
|
||||
File fileRef = new File("org/foo/Bar.java");
|
||||
assertThat(index.getResource(fileRef).getKey(), is("org/foo/Bar.java"));
|
||||
assertThat(index.getResource(fileRef).getLanguage(), is((Language) Java.INSTANCE));
|
||||
assertThat(index.isIndexed(fileRef, true), is(true));
|
||||
assertThat(index.isExcluded(fileRef), is(false));
|
||||
assertThat(index.getChildren(fileRef).size(), is(0));
|
||||
assertThat(index.getParent(fileRef), is(Directory.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexLibraryOutsideProjectTree() {
|
||||
Library lib = new Library("junit", "4.8");
|
||||
assertThat(index.index(lib), is(true));
|
||||
|
||||
Library reference = new Library("junit", "4.8");
|
||||
assertThat(index.getResource(reference).getQualifier(), is(Qualifiers.LIBRARY));
|
||||
assertThat(index.isIndexed(reference, true), is(true));
|
||||
assertThat(index.isExcluded(reference), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotIndexResourceIfParentNotIndexed() {
|
||||
Directory directory = new Directory("org/other");
|
||||
File file = new File("org/foo/Bar.java");
|
||||
|
||||
assertThat(index.index(file, directory), is(false));
|
||||
|
||||
File fileRef = new File("org/foo/Bar.java");
|
||||
assertThat(index.isIndexed(directory, true), is(false));
|
||||
assertThat(index.isIndexed(fileRef, true), is(false));
|
||||
assertThat(index.isExcluded(fileRef), is(false));
|
||||
assertThat(index.getChildren(fileRef).size(), is(0));
|
||||
assertThat(index.getParent(fileRef), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Only a warning is logged when index is locked.
|
||||
*/
|
||||
@Test
|
||||
public void shouldIndexEvenIfLocked() {
|
||||
lock.lock();
|
||||
|
||||
Directory dir = new Directory("org/foo");
|
||||
assertThat(index.index(dir), is(true));
|
||||
assertThat(index.isIndexed(dir, true), is(true));
|
||||
}
|
||||
|
||||
@Test(expected = SonarException.class)
|
||||
public void shouldFailIfIndexingAndLocked() {
|
||||
lock.setFailWhenLocked(true);
|
||||
lock.lock();
|
||||
|
||||
Directory dir = new Directory("org/foo");
|
||||
index.index(dir);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeExcluded() {
|
||||
File file = new File("org/foo/ExcludedBar.java");
|
||||
assertThat(index.index(file), is(false));
|
||||
assertThat(index.isIndexed(file, true), is(true));
|
||||
assertThat(index.isIndexed(file, false), is(false));
|
||||
assertThat(index.isExcluded(file), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIndexResourceWhenAddingMeasure() {
|
||||
Resource dir = new Directory("org/foo");
|
||||
index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
|
||||
|
||||
assertThat(index.isIndexed(dir, true), is(true));
|
||||
assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));
|
||||
}
|
||||
|
||||
/**
|
||||
* See http://jira.codehaus.org/browse/SONAR-2107
|
||||
*/
|
||||
@Test
|
||||
public void shouldNotFailWhenSavingViolationOnNullRule() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation = Violation.create((Rule) null, file);
|
||||
index.addViolation(violation);
|
||||
|
||||
assertThat(index.getViolations(file).size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViolations() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation1 = Violation.create(rule, file);
|
||||
index.addViolation(violation1);
|
||||
Violation violation2 = Violation.create(rule, file);
|
||||
violation2.setSwitchedOff(true);
|
||||
index.addViolation(violation2);
|
||||
Violation violation3 = Violation.create(rule, file);
|
||||
violation3.setSwitchedOff(true);
|
||||
index.addViolation(violation3);
|
||||
|
||||
assertThat(index.getViolations(file).size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViolationsWithQuery() {
|
||||
File file = new File("org/foo/Bar.java");
|
||||
Violation violation1 = Violation.create(rule, file);
|
||||
index.addViolation(violation1);
|
||||
Violation violation2 = Violation.create(rule, file);
|
||||
violation2.setSwitchedOff(true);
|
||||
index.addViolation(violation2);
|
||||
Violation violation3 = Violation.create(rule, file);
|
||||
violation3.setSwitchedOff(true);
|
||||
index.addViolation(violation3);
|
||||
|
||||
assertThat(index.getViolations(ViolationQuery.create().forResource(file).ignoreSwitchedOff(false)).size(), is(3));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetViolationsWithQueryWithNoResource() {
|
||||
index.getViolations(ViolationQuery.create());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,96 +1,96 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.JavaFile;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RulePriority;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.core.components.DefaultRuleFinder;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ViolationPersisterTest extends AbstractDbUnitTestCase {
|
||||
|
||||
private ViolationPersister violationPersister;
|
||||
private Rule rule1 = Rule.create("checkstyle", "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck", "Check Header");
|
||||
private Rule rule2 = Rule.create("checkstyle", "com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck", "Equals Avoid Null");
|
||||
private JavaFile javaFile = new JavaFile("org.foo.Bar");
|
||||
Project project = new Project("project");
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
setupData("shared");
|
||||
Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
|
||||
ResourcePersister resourcePersister = mock(ResourcePersister.class);
|
||||
when(resourcePersister.saveResource((Project) anyObject(), eq(javaFile))).thenReturn(snapshot);
|
||||
when(resourcePersister.getSnapshot(javaFile)).thenReturn(snapshot);
|
||||
violationPersister = new ViolationPersister(getSession(), resourcePersister, new DefaultRuleFinder(getSessionFactory()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSaveViolations() {
|
||||
Violation violation1a = Violation.create(rule1, javaFile)
|
||||
.setSeverity(RulePriority.CRITICAL).setLineId(20).setCost(55.6)
|
||||
.setMessage("the message");
|
||||
Violation violation1b = Violation.create(rule1, javaFile)
|
||||
.setSeverity(RulePriority.CRITICAL).setLineId(50).setCost(80.0);
|
||||
Violation violation2 = Violation.create(rule2, javaFile)
|
||||
.setSeverity(RulePriority.MINOR);
|
||||
|
||||
violationPersister.saveViolation(project, violation1a);
|
||||
violationPersister.saveViolation(project, violation1b);
|
||||
violationPersister.saveViolation(project, violation2);
|
||||
|
||||
checkTables("shouldInsertViolations", "rule_failures");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCopyPermanentIdFromPastViolation() {
|
||||
RuleFailureModel pastViolation = getSession().getSingleResult(RuleFailureModel.class, "id", 1);
|
||||
|
||||
Violation violation = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation, pastViolation, "line_checksum");
|
||||
|
||||
checkTables("shouldCopyPermanentIdFromPastViolation", "rule_failures");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCopySwitchedOffFromPastViolation() {
|
||||
RuleFailureModel pastViolation1 = getSession().getSingleResult(RuleFailureModel.class, "id", 1);
|
||||
Violation violation1 = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation1, pastViolation1, "line_checksum");
|
||||
|
||||
RuleFailureModel pastViolation2 = getSession().getSingleResult(RuleFailureModel.class, "id", 2);
|
||||
Violation violation2 = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation2, pastViolation2, "line_checksum");
|
||||
|
||||
checkTables("shouldCopySwitchedOffFromPastViolation", "rule_failures");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.batch.index;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.database.model.RuleFailureModel;
|
||||
import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.JavaFile;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.rules.Rule;
|
||||
import org.sonar.api.rules.RulePriority;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.core.components.DefaultRuleFinder;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ViolationPersisterTest extends AbstractDbUnitTestCase {
|
||||
|
||||
private ViolationPersister violationPersister;
|
||||
private Rule rule1 = Rule.create("checkstyle", "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck", "Check Header");
|
||||
private Rule rule2 = Rule.create("checkstyle", "com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck", "Equals Avoid Null");
|
||||
private JavaFile javaFile = new JavaFile("org.foo.Bar");
|
||||
Project project = new Project("project");
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
setupData("shared");
|
||||
Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
|
||||
ResourcePersister resourcePersister = mock(ResourcePersister.class);
|
||||
when(resourcePersister.saveResource((Project) anyObject(), eq(javaFile))).thenReturn(snapshot);
|
||||
when(resourcePersister.getSnapshot(javaFile)).thenReturn(snapshot);
|
||||
violationPersister = new ViolationPersister(getSession(), resourcePersister, new DefaultRuleFinder(getSessionFactory()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSaveViolations() {
|
||||
Violation violation1a = Violation.create(rule1, javaFile)
|
||||
.setSeverity(RulePriority.CRITICAL).setLineId(20).setCost(55.6)
|
||||
.setMessage("the message");
|
||||
Violation violation1b = Violation.create(rule1, javaFile)
|
||||
.setSeverity(RulePriority.CRITICAL).setLineId(50).setCost(80.0);
|
||||
Violation violation2 = Violation.create(rule2, javaFile)
|
||||
.setSeverity(RulePriority.MINOR);
|
||||
|
||||
violationPersister.saveViolation(project, violation1a);
|
||||
violationPersister.saveViolation(project, violation1b);
|
||||
violationPersister.saveViolation(project, violation2);
|
||||
|
||||
checkTables("shouldInsertViolations", "rule_failures");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCopyPermanentIdFromPastViolation() {
|
||||
RuleFailureModel pastViolation = getSession().getSingleResult(RuleFailureModel.class, "id", 1);
|
||||
|
||||
Violation violation = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation, pastViolation, "line_checksum");
|
||||
|
||||
checkTables("shouldCopyPermanentIdFromPastViolation", "rule_failures");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCopySwitchedOffFromPastViolation() {
|
||||
RuleFailureModel pastViolation1 = getSession().getSingleResult(RuleFailureModel.class, "id", 1);
|
||||
Violation violation1 = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation1, pastViolation1, "line_checksum");
|
||||
|
||||
RuleFailureModel pastViolation2 = getSession().getSingleResult(RuleFailureModel.class, "id", 2);
|
||||
Violation violation2 = Violation.create(rule1, javaFile).setSeverity(RulePriority.MAJOR).setMessage("new message");
|
||||
violationPersister.saveViolation(project, violation2, pastViolation2, "line_checksum");
|
||||
|
||||
checkTables("shouldCopySwitchedOffFromPastViolation", "rule_failures");
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
</dataset>
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
</dataset>
|
||||
|
@ -1,26 +1,26 @@
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
</dataset>
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
</dataset>
|
||||
|
@ -1,27 +1,27 @@
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="4" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
</dataset>
|
||||
<dataset>
|
||||
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="4" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="2" MESSAGE="new message" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="line_checksum"/>
|
||||
</dataset>
|
||||
|
@ -1,26 +1,26 @@
|
||||
<dataset>
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="3" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="the message" LINE="20" COST="55.6" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="4" ID="4" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="[null]" LINE="50" COST="80" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="5" ID="5" SNAPSHOT_ID="1000" RULE_ID="31" FAILURE_LEVEL="1" MESSAGE="[null]" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<dataset>
|
||||
<rules_categories id="1" name="Efficiency" description="[null]"/>
|
||||
<rules_categories id="6" name="Usability" description="[null]"/>
|
||||
|
||||
<rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
|
||||
plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
|
||||
plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
|
||||
cardinality="SINGLE" parent_id="[null]"/>
|
||||
|
||||
<projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
|
||||
name="Bar" long_name="org.foo.Bar" description="[null]"
|
||||
enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
|
||||
|
||||
<snapshots 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]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
|
||||
scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
|
||||
status="U" islast="false" depth="3" />
|
||||
|
||||
<rule_failures switched_off="false" permanent_id="1" ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="true" permanent_id="2" ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="3" ID="3" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="the message" LINE="20" COST="55.6" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="4" ID="4" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="[null]" LINE="50" COST="80" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
<rule_failures switched_off="false" permanent_id="5" ID="5" SNAPSHOT_ID="1000" RULE_ID="31" FAILURE_LEVEL="1" MESSAGE="[null]" LINE="[null]" COST="[null]" created_at="2008-11-01 13:58:00.00" checksum="[null]"/>
|
||||
</dataset>
|
@ -1,263 +1,263 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.jpa.session;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
public class JpaDatabaseSession extends DatabaseSession {
|
||||
|
||||
private final DatabaseConnector connector;
|
||||
private EntityManager entityManager = null;
|
||||
private int index = 0;
|
||||
private boolean inTransaction = false;
|
||||
|
||||
public JpaDatabaseSession(DatabaseConnector connector) {
|
||||
this.connector = connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that usage of this method is discouraged, because it allows to construct and execute queries without additional exception handling,
|
||||
* which done in methods of this class.
|
||||
*/
|
||||
public EntityManager getEntityManager() {
|
||||
return entityManager;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
entityManager = connector.createEntityManager();
|
||||
index = 0;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
commit();
|
||||
if (entityManager != null && entityManager.isOpen()) {
|
||||
entityManager.close();
|
||||
entityManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
if (entityManager != null && inTransaction) {
|
||||
if (entityManager.isOpen()) {
|
||||
if (entityManager.getTransaction().getRollbackOnly()) {
|
||||
entityManager.getTransaction().rollback();
|
||||
} else {
|
||||
entityManager.getTransaction().commit();
|
||||
}
|
||||
entityManager.clear();
|
||||
index = 0;
|
||||
}
|
||||
inTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
if (entityManager != null && inTransaction) {
|
||||
entityManager.getTransaction().rollback();
|
||||
inTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T save(T model) {
|
||||
startTransaction();
|
||||
internalSave(model, true);
|
||||
return model;
|
||||
}
|
||||
|
||||
public Object saveWithoutFlush(Object model) {
|
||||
startTransaction();
|
||||
internalSave(model, false);
|
||||
return model;
|
||||
}
|
||||
|
||||
public boolean contains(Object model) {
|
||||
startTransaction();
|
||||
return entityManager.contains(model);
|
||||
}
|
||||
|
||||
public void save(Object... models) {
|
||||
startTransaction();
|
||||
for (Object model : models) {
|
||||
save(model);
|
||||
}
|
||||
}
|
||||
|
||||
private void internalSave(Object model, boolean flushIfNeeded) {
|
||||
try {
|
||||
entityManager.persist(model);
|
||||
} catch (PersistenceException e) {
|
||||
/*
|
||||
* See http://jira.codehaus.org/browse/SONAR-2234
|
||||
* In some cases Hibernate can throw exceptions without meaningful information about context, so we improve them here.
|
||||
*/
|
||||
throw new PersistenceException("Unable to persist : " + model, e);
|
||||
}
|
||||
if (flushIfNeeded && (++index % BATCH_SIZE == 0)) {
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
public Object merge(Object model) {
|
||||
startTransaction();
|
||||
return entityManager.merge(model);
|
||||
}
|
||||
|
||||
public void remove(Object model) {
|
||||
startTransaction();
|
||||
entityManager.remove(model);
|
||||
if (++index % BATCH_SIZE == 0) {
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWithoutFlush(Object model) {
|
||||
startTransaction();
|
||||
entityManager.remove(model);
|
||||
}
|
||||
|
||||
public <T> T reattach(Class<T> entityClass, Object primaryKey) {
|
||||
startTransaction();
|
||||
return entityManager.getReference(entityClass, primaryKey);
|
||||
}
|
||||
|
||||
private void startTransaction() {
|
||||
if (!inTransaction) {
|
||||
entityManager.getTransaction().begin();
|
||||
inTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that not recommended to directly execute {@link Query#getSingleResult()}, because it will bypass exception handling,
|
||||
* which done in {@link #getSingleResult(Query, Object)}.
|
||||
*/
|
||||
public Query createQuery(String hql) {
|
||||
startTransaction();
|
||||
return entityManager.createQuery(hql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query createNativeQuery(String sql) {
|
||||
startTransaction();
|
||||
return entityManager.createNativeQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result or <code>defaultValue</code>, if not found
|
||||
* @throws NonUniqueResultException if more than one result
|
||||
*/
|
||||
public <T> T getSingleResult(Query query, T defaultValue) {
|
||||
/*
|
||||
* See http://jira.codehaus.org/browse/SONAR-2225
|
||||
* By default Hibernate throws NonUniqueResultException without meaningful information about context,
|
||||
* so we improve it here by adding all results in error message.
|
||||
* Note that in some rare situations we can receive too many results, which may lead to OOME,
|
||||
* but actually it will mean that database is corrupted as we don't expect more than one result
|
||||
* and in fact org.hibernate.ejb.QueryImpl#getSingleResult() anyway does loading of several results under the hood.
|
||||
*/
|
||||
List<T> result = query.getResultList();
|
||||
|
||||
if (result.size() == 1) {
|
||||
return result.get(0);
|
||||
|
||||
} else if (result.isEmpty()) {
|
||||
return defaultValue;
|
||||
|
||||
} else {
|
||||
Set<T> uniqueResult = new HashSet<T>(result);
|
||||
if (uniqueResult.size() > 1) {
|
||||
throw new NonUniqueResultException("Expected single result, but got : " + result.toString());
|
||||
} else {
|
||||
return uniqueResult.iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T getEntity(Class<T> entityClass, Object id) {
|
||||
startTransaction();
|
||||
return getEntityManager().find(entityClass, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result or <code>null</code>, if not found
|
||||
* @throws NonUniqueResultException if more than one result
|
||||
*/
|
||||
public <T> T getSingleResult(Class<T> entityClass, Object... criterias) {
|
||||
try {
|
||||
return getSingleResult(getQueryForCriterias(entityClass, true, criterias), (T) null);
|
||||
|
||||
} catch (NonUniqueResultException ex) {
|
||||
NonUniqueResultException e = new NonUniqueResultException("Expected single result for entitiy " + entityClass.getSimpleName()
|
||||
+ " with criterias : " + StringUtils.join(criterias, ","));
|
||||
e.initCause(ex);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> List<T> getResults(Class<T> entityClass, Object... criterias) {
|
||||
return getQueryForCriterias(entityClass, true, criterias).getResultList();
|
||||
}
|
||||
|
||||
public <T> List<T> getResults(Class<T> entityClass) {
|
||||
return getQueryForCriterias(entityClass, false, null).getResultList();
|
||||
}
|
||||
|
||||
private Query getQueryForCriterias(Class<?> entityClass, boolean raiseError, Object... criterias) {
|
||||
if (criterias == null && raiseError) {
|
||||
throw new IllegalStateException("criterias parameter must be provided");
|
||||
}
|
||||
startTransaction();
|
||||
StringBuilder hql = new StringBuilder("SELECT o FROM ").append(entityClass.getSimpleName()).append(" o");
|
||||
if (criterias != null) {
|
||||
hql.append(" WHERE ");
|
||||
Map<String, Object> mappedCriterias = new HashMap<String, Object>();
|
||||
for (int i = 0; i < criterias.length; i += 2) {
|
||||
mappedCriterias.put((String) criterias[i], criterias[i + 1]);
|
||||
}
|
||||
buildCriteriasHQL(hql, mappedCriterias);
|
||||
Query query = getEntityManager().createQuery(hql.toString());
|
||||
|
||||
for (Map.Entry<String, Object> entry : mappedCriterias.entrySet()) {
|
||||
query.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
return getEntityManager().createQuery(hql.toString());
|
||||
}
|
||||
|
||||
private void buildCriteriasHQL(StringBuilder hql, Map<String, Object> mappedCriterias) {
|
||||
for (Iterator<String> i = mappedCriterias.keySet().iterator(); i.hasNext();) {
|
||||
String criteria = i.next();
|
||||
hql.append("o.").append(criteria).append("=:").append(criteria);
|
||||
if (i.hasNext()) {
|
||||
hql.append(" AND ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.jpa.session;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
public class JpaDatabaseSession extends DatabaseSession {
|
||||
|
||||
private final DatabaseConnector connector;
|
||||
private EntityManager entityManager = null;
|
||||
private int index = 0;
|
||||
private boolean inTransaction = false;
|
||||
|
||||
public JpaDatabaseSession(DatabaseConnector connector) {
|
||||
this.connector = connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that usage of this method is discouraged, because it allows to construct and execute queries without additional exception handling,
|
||||
* which done in methods of this class.
|
||||
*/
|
||||
public EntityManager getEntityManager() {
|
||||
return entityManager;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
entityManager = connector.createEntityManager();
|
||||
index = 0;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
commit();
|
||||
if (entityManager != null && entityManager.isOpen()) {
|
||||
entityManager.close();
|
||||
entityManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
if (entityManager != null && inTransaction) {
|
||||
if (entityManager.isOpen()) {
|
||||
if (entityManager.getTransaction().getRollbackOnly()) {
|
||||
entityManager.getTransaction().rollback();
|
||||
} else {
|
||||
entityManager.getTransaction().commit();
|
||||
}
|
||||
entityManager.clear();
|
||||
index = 0;
|
||||
}
|
||||
inTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
if (entityManager != null && inTransaction) {
|
||||
entityManager.getTransaction().rollback();
|
||||
inTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T save(T model) {
|
||||
startTransaction();
|
||||
internalSave(model, true);
|
||||
return model;
|
||||
}
|
||||
|
||||
public Object saveWithoutFlush(Object model) {
|
||||
startTransaction();
|
||||
internalSave(model, false);
|
||||
return model;
|
||||
}
|
||||
|
||||
public boolean contains(Object model) {
|
||||
startTransaction();
|
||||
return entityManager.contains(model);
|
||||
}
|
||||
|
||||
public void save(Object... models) {
|
||||
startTransaction();
|
||||
for (Object model : models) {
|
||||
save(model);
|
||||
}
|
||||
}
|
||||
|
||||
private void internalSave(Object model, boolean flushIfNeeded) {
|
||||
try {
|
||||
entityManager.persist(model);
|
||||
} catch (PersistenceException e) {
|
||||
/*
|
||||
* See http://jira.codehaus.org/browse/SONAR-2234
|
||||
* In some cases Hibernate can throw exceptions without meaningful information about context, so we improve them here.
|
||||
*/
|
||||
throw new PersistenceException("Unable to persist : " + model, e);
|
||||
}
|
||||
if (flushIfNeeded && (++index % BATCH_SIZE == 0)) {
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
public Object merge(Object model) {
|
||||
startTransaction();
|
||||
return entityManager.merge(model);
|
||||
}
|
||||
|
||||
public void remove(Object model) {
|
||||
startTransaction();
|
||||
entityManager.remove(model);
|
||||
if (++index % BATCH_SIZE == 0) {
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWithoutFlush(Object model) {
|
||||
startTransaction();
|
||||
entityManager.remove(model);
|
||||
}
|
||||
|
||||
public <T> T reattach(Class<T> entityClass, Object primaryKey) {
|
||||
startTransaction();
|
||||
return entityManager.getReference(entityClass, primaryKey);
|
||||
}
|
||||
|
||||
private void startTransaction() {
|
||||
if (!inTransaction) {
|
||||
entityManager.getTransaction().begin();
|
||||
inTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that not recommended to directly execute {@link Query#getSingleResult()}, because it will bypass exception handling,
|
||||
* which done in {@link #getSingleResult(Query, Object)}.
|
||||
*/
|
||||
public Query createQuery(String hql) {
|
||||
startTransaction();
|
||||
return entityManager.createQuery(hql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query createNativeQuery(String sql) {
|
||||
startTransaction();
|
||||
return entityManager.createNativeQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result or <code>defaultValue</code>, if not found
|
||||
* @throws NonUniqueResultException if more than one result
|
||||
*/
|
||||
public <T> T getSingleResult(Query query, T defaultValue) {
|
||||
/*
|
||||
* See http://jira.codehaus.org/browse/SONAR-2225
|
||||
* By default Hibernate throws NonUniqueResultException without meaningful information about context,
|
||||
* so we improve it here by adding all results in error message.
|
||||
* Note that in some rare situations we can receive too many results, which may lead to OOME,
|
||||
* but actually it will mean that database is corrupted as we don't expect more than one result
|
||||
* and in fact org.hibernate.ejb.QueryImpl#getSingleResult() anyway does loading of several results under the hood.
|
||||
*/
|
||||
List<T> result = query.getResultList();
|
||||
|
||||
if (result.size() == 1) {
|
||||
return result.get(0);
|
||||
|
||||
} else if (result.isEmpty()) {
|
||||
return defaultValue;
|
||||
|
||||
} else {
|
||||
Set<T> uniqueResult = new HashSet<T>(result);
|
||||
if (uniqueResult.size() > 1) {
|
||||
throw new NonUniqueResultException("Expected single result, but got : " + result.toString());
|
||||
} else {
|
||||
return uniqueResult.iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T getEntity(Class<T> entityClass, Object id) {
|
||||
startTransaction();
|
||||
return getEntityManager().find(entityClass, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result or <code>null</code>, if not found
|
||||
* @throws NonUniqueResultException if more than one result
|
||||
*/
|
||||
public <T> T getSingleResult(Class<T> entityClass, Object... criterias) {
|
||||
try {
|
||||
return getSingleResult(getQueryForCriterias(entityClass, true, criterias), (T) null);
|
||||
|
||||
} catch (NonUniqueResultException ex) {
|
||||
NonUniqueResultException e = new NonUniqueResultException("Expected single result for entitiy " + entityClass.getSimpleName()
|
||||
+ " with criterias : " + StringUtils.join(criterias, ","));
|
||||
e.initCause(ex);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> List<T> getResults(Class<T> entityClass, Object... criterias) {
|
||||
return getQueryForCriterias(entityClass, true, criterias).getResultList();
|
||||
}
|
||||
|
||||
public <T> List<T> getResults(Class<T> entityClass) {
|
||||
return getQueryForCriterias(entityClass, false, null).getResultList();
|
||||
}
|
||||
|
||||
private Query getQueryForCriterias(Class<?> entityClass, boolean raiseError, Object... criterias) {
|
||||
if (criterias == null && raiseError) {
|
||||
throw new IllegalStateException("criterias parameter must be provided");
|
||||
}
|
||||
startTransaction();
|
||||
StringBuilder hql = new StringBuilder("SELECT o FROM ").append(entityClass.getSimpleName()).append(" o");
|
||||
if (criterias != null) {
|
||||
hql.append(" WHERE ");
|
||||
Map<String, Object> mappedCriterias = new HashMap<String, Object>();
|
||||
for (int i = 0; i < criterias.length; i += 2) {
|
||||
mappedCriterias.put((String) criterias[i], criterias[i + 1]);
|
||||
}
|
||||
buildCriteriasHQL(hql, mappedCriterias);
|
||||
Query query = getEntityManager().createQuery(hql.toString());
|
||||
|
||||
for (Map.Entry<String, Object> entry : mappedCriterias.entrySet()) {
|
||||
query.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
return getEntityManager().createQuery(hql.toString());
|
||||
}
|
||||
|
||||
private void buildCriteriasHQL(StringBuilder hql, Map<String, Object> mappedCriterias) {
|
||||
for (Iterator<String> i = mappedCriterias.keySet().iterator(); i.hasNext();) {
|
||||
String criteria = i.next();
|
||||
hql.append("o.").append(criteria).append("=:").append(criteria);
|
||||
if (i.hasNext()) {
|
||||
hql.append(" AND ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,159 +1,159 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.batch;
|
||||
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @since 1.10
|
||||
*/
|
||||
public interface DecoratorContext {
|
||||
|
||||
/**
|
||||
* @return the project in which the decorator is
|
||||
*/
|
||||
Project getProject();
|
||||
|
||||
/**
|
||||
* @return the resource that is currently decorated
|
||||
*/
|
||||
Resource getResource();
|
||||
|
||||
/**
|
||||
* Child contexts are read only
|
||||
*/
|
||||
List<DecoratorContext> getChildren();
|
||||
|
||||
// MEASURES
|
||||
|
||||
/**
|
||||
* Find a measure for the resource
|
||||
*/
|
||||
Measure getMeasure(Metric metric);
|
||||
|
||||
/**
|
||||
* Never return null.
|
||||
*/
|
||||
<M> M getMeasures(MeasuresFilter<M> filter);
|
||||
|
||||
/**
|
||||
* Never return null.
|
||||
*/
|
||||
Collection<Measure> getChildrenMeasures(MeasuresFilter filter);
|
||||
|
||||
/**
|
||||
* @return the resource children measures for the given metric
|
||||
*/
|
||||
Collection<Measure> getChildrenMeasures(Metric metric);
|
||||
|
||||
/**
|
||||
* Add a measure on the current resource. It can not be executed from children contexts.
|
||||
*
|
||||
* @return the same context
|
||||
*/
|
||||
DecoratorContext saveMeasure(Measure measure);
|
||||
|
||||
/**
|
||||
* Add a measure on the current resource. It can not be executed from children contexts.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
DecoratorContext saveMeasure(Metric metric, Double value);
|
||||
|
||||
// DEPENDENCIES
|
||||
|
||||
Dependency saveDependency(Dependency dependency);
|
||||
|
||||
Set<Dependency> getDependencies();
|
||||
|
||||
Collection<Dependency> getIncomingDependencies();
|
||||
|
||||
Collection<Dependency> getOutgoingDependencies();
|
||||
|
||||
// RULES
|
||||
|
||||
/**
|
||||
* Returns the violations that match the {@link ViolationQuery} parameters.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param violationQuery
|
||||
* the request parameters specified as a {@link ViolationQuery}
|
||||
* @return the list of violations that match those parameters
|
||||
*/
|
||||
public abstract List<Violation> getViolations(ViolationQuery violationQuery);
|
||||
|
||||
/**
|
||||
* Returns all the active (= non switched-off) violations found on the current resource.
|
||||
*
|
||||
* @return the list of violations
|
||||
*/
|
||||
List<Violation> getViolations();
|
||||
|
||||
/**
|
||||
* Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
|
||||
*
|
||||
* @since 2.5
|
||||
* @param force allows to force creation of violation even if it was suppressed by {@link org.sonar.api.rules.ViolationFilter}
|
||||
*/
|
||||
DecoratorContext saveViolation(Violation violation, boolean force);
|
||||
|
||||
/**
|
||||
* Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
|
||||
*/
|
||||
DecoratorContext saveViolation(Violation violation);
|
||||
|
||||
// EVENTS
|
||||
|
||||
/**
|
||||
* @return the list of events associated to the current resource
|
||||
*/
|
||||
List<Event> getEvents();
|
||||
|
||||
/**
|
||||
* Creates an event for a given date
|
||||
*
|
||||
* @param name the event name
|
||||
* @param description the event description
|
||||
* @param category the event category
|
||||
* @param date the event date
|
||||
* @return the created event
|
||||
*/
|
||||
Event createEvent(String name, String description, String category, Date date);
|
||||
|
||||
/**
|
||||
* Deletes an event
|
||||
*
|
||||
* @param event the event to delete
|
||||
*/
|
||||
void deleteEvent(Event event);
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.batch;
|
||||
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @since 1.10
|
||||
*/
|
||||
public interface DecoratorContext {
|
||||
|
||||
/**
|
||||
* @return the project in which the decorator is
|
||||
*/
|
||||
Project getProject();
|
||||
|
||||
/**
|
||||
* @return the resource that is currently decorated
|
||||
*/
|
||||
Resource getResource();
|
||||
|
||||
/**
|
||||
* Child contexts are read only
|
||||
*/
|
||||
List<DecoratorContext> getChildren();
|
||||
|
||||
// MEASURES
|
||||
|
||||
/**
|
||||
* Find a measure for the resource
|
||||
*/
|
||||
Measure getMeasure(Metric metric);
|
||||
|
||||
/**
|
||||
* Never return null.
|
||||
*/
|
||||
<M> M getMeasures(MeasuresFilter<M> filter);
|
||||
|
||||
/**
|
||||
* Never return null.
|
||||
*/
|
||||
Collection<Measure> getChildrenMeasures(MeasuresFilter filter);
|
||||
|
||||
/**
|
||||
* @return the resource children measures for the given metric
|
||||
*/
|
||||
Collection<Measure> getChildrenMeasures(Metric metric);
|
||||
|
||||
/**
|
||||
* Add a measure on the current resource. It can not be executed from children contexts.
|
||||
*
|
||||
* @return the same context
|
||||
*/
|
||||
DecoratorContext saveMeasure(Measure measure);
|
||||
|
||||
/**
|
||||
* Add a measure on the current resource. It can not be executed from children contexts.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
DecoratorContext saveMeasure(Metric metric, Double value);
|
||||
|
||||
// DEPENDENCIES
|
||||
|
||||
Dependency saveDependency(Dependency dependency);
|
||||
|
||||
Set<Dependency> getDependencies();
|
||||
|
||||
Collection<Dependency> getIncomingDependencies();
|
||||
|
||||
Collection<Dependency> getOutgoingDependencies();
|
||||
|
||||
// RULES
|
||||
|
||||
/**
|
||||
* Returns the violations that match the {@link ViolationQuery} parameters.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param violationQuery
|
||||
* the request parameters specified as a {@link ViolationQuery}
|
||||
* @return the list of violations that match those parameters
|
||||
*/
|
||||
public abstract List<Violation> getViolations(ViolationQuery violationQuery);
|
||||
|
||||
/**
|
||||
* Returns all the active (= non switched-off) violations found on the current resource.
|
||||
*
|
||||
* @return the list of violations
|
||||
*/
|
||||
List<Violation> getViolations();
|
||||
|
||||
/**
|
||||
* Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
|
||||
*
|
||||
* @since 2.5
|
||||
* @param force allows to force creation of violation even if it was suppressed by {@link org.sonar.api.rules.ViolationFilter}
|
||||
*/
|
||||
DecoratorContext saveViolation(Violation violation, boolean force);
|
||||
|
||||
/**
|
||||
* Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
|
||||
*/
|
||||
DecoratorContext saveViolation(Violation violation);
|
||||
|
||||
// EVENTS
|
||||
|
||||
/**
|
||||
* @return the list of events associated to the current resource
|
||||
*/
|
||||
List<Event> getEvents();
|
||||
|
||||
/**
|
||||
* Creates an event for a given date
|
||||
*
|
||||
* @param name the event name
|
||||
* @param description the event description
|
||||
* @param category the event category
|
||||
* @param date the event date
|
||||
* @return the created event
|
||||
*/
|
||||
Event createEvent(String name, String description, String category, Date date);
|
||||
|
||||
/**
|
||||
* Deletes an event
|
||||
*
|
||||
* @param event the event to delete
|
||||
*/
|
||||
void deleteEvent(Event event);
|
||||
|
||||
}
|
||||
|
@ -1,182 +1,182 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.batch;
|
||||
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.DuplicatedSourceException;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.ProjectLink;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
import org.sonar.graph.DirectedGraphAccessor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class SonarIndex implements DirectedGraphAccessor<Resource, Dependency> {
|
||||
|
||||
/**
|
||||
* Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
|
||||
* If the method resource.getParent() does not return null, then this parent will be indexed too.
|
||||
*
|
||||
* @return false if the resource is excluded
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean index(Resource resource);
|
||||
|
||||
|
||||
/**
|
||||
* Indexes a resource. This method does nothing if the resource is already indexed.
|
||||
*
|
||||
* @param resource the resource to index. Not nullable
|
||||
* @param parentReference a reference to the indexed parent. If null, the resource is indexed as a direct child of project.
|
||||
* @return false if the parent is not indexed or if the resource is excluded
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean index(Resource resource, Resource parentReference);
|
||||
|
||||
/**
|
||||
* Returns true if the referenced resource is excluded. An excluded resource is not indexed.
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean isExcluded(Resource reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean isIndexed(Resource reference, boolean acceptExcluded);
|
||||
|
||||
/**
|
||||
* Search for an indexed resource.
|
||||
*
|
||||
* @param reference the resource reference
|
||||
* @return the indexed resource, null if it's not indexed
|
||||
* @since 1.10. Generic types since 2.6.
|
||||
*/
|
||||
public abstract <R extends Resource> R getResource(R reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract Resource getParent(Resource reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
|
||||
public abstract Collection<Resource> getChildren(Resource reference);
|
||||
|
||||
/**
|
||||
* Save the source code of a file. The file must be have been indexed before.
|
||||
* Note: the source stream is not closed.
|
||||
*
|
||||
* @return false if the resource is excluded or not indexed
|
||||
* @throws org.sonar.api.resources.DuplicatedSourceException
|
||||
* if the source has already been set on this resource
|
||||
*/
|
||||
public abstract void setSource(Resource reference, String source) throws DuplicatedSourceException;
|
||||
|
||||
public abstract Project getProject();
|
||||
|
||||
public final Collection<Resource> getResources() {
|
||||
return getVertices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes the resource.
|
||||
* @return the indexed resource, even if it's excluded
|
||||
* @deprecated since 2.6. Use methods index()
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract Resource addResource(Resource resource);
|
||||
|
||||
public abstract Measure getMeasure(Resource resource, Metric metric);
|
||||
|
||||
public abstract <M> M getMeasures(Resource resource, MeasuresFilter<M> filter);
|
||||
|
||||
/**
|
||||
* Returns the violations that match the {@link ViolationQuery} parameters.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param violationQuery
|
||||
* the request parameters specified as a {@link ViolationQuery}
|
||||
* @return the list of violations that match those parameters
|
||||
*/
|
||||
public abstract List<Violation> getViolations(ViolationQuery violationQuery);
|
||||
|
||||
/**
|
||||
* Returns all the active (= non switched-off) violations found on the given resource. Equivalent to
|
||||
* {@link #getViolations(ViolationQuery)} called with <code>ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true)</code>
|
||||
* as a parameter.
|
||||
*
|
||||
* @since 2.7
|
||||
* @param the
|
||||
* resource on which violations are searched
|
||||
* @return the list of violations
|
||||
*/
|
||||
public final List<Violation> getViolations(Resource resource) {
|
||||
return getViolations(ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public abstract void addViolation(Violation violation, boolean force);
|
||||
|
||||
public final void addViolation(Violation violation) {
|
||||
addViolation(violation, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: the resource is automatically indexed for backward-compatibility, but it should be explictly
|
||||
* indexed before. Next versions will deactivate this automatic indexation.
|
||||
*
|
||||
* @throws SonarException if the metric is unknown.
|
||||
*/
|
||||
public abstract Measure addMeasure(Resource resource, Measure measure);
|
||||
|
||||
public abstract Dependency addDependency(Dependency dependency);
|
||||
|
||||
public abstract Set<Dependency> getDependencies();
|
||||
|
||||
public abstract void addLink(ProjectLink link);
|
||||
|
||||
public abstract void deleteLink(String key);
|
||||
|
||||
public abstract List<Event> getEvents(Resource resource);
|
||||
|
||||
public abstract void deleteEvent(Event event);
|
||||
|
||||
public abstract Event addEvent(Resource resource, String name, String description, String category, Date date);
|
||||
|
||||
public final Collection<Dependency> getOutgoingDependencies(Resource from) {
|
||||
return getOutgoingEdges(from);
|
||||
}
|
||||
|
||||
public final Collection<Dependency> getIncomingDependencies(Resource to) {
|
||||
return getIncomingEdges(to);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.batch;
|
||||
|
||||
import org.sonar.api.design.Dependency;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.MeasuresFilter;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.resources.DuplicatedSourceException;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.ProjectLink;
|
||||
import org.sonar.api.resources.Resource;
|
||||
import org.sonar.api.rules.Violation;
|
||||
import org.sonar.api.violations.ViolationQuery;
|
||||
import org.sonar.graph.DirectedGraphAccessor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class SonarIndex implements DirectedGraphAccessor<Resource, Dependency> {
|
||||
|
||||
/**
|
||||
* Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
|
||||
* If the method resource.getParent() does not return null, then this parent will be indexed too.
|
||||
*
|
||||
* @return false if the resource is excluded
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean index(Resource resource);
|
||||
|
||||
|
||||
/**
|
||||
* Indexes a resource. This method does nothing if the resource is already indexed.
|
||||
*
|
||||
* @param resource the resource to index. Not nullable
|
||||
* @param parentReference a reference to the indexed parent. If null, the resource is indexed as a direct child of project.
|
||||
* @return false if the parent is not indexed or if the resource is excluded
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean index(Resource resource, Resource parentReference);
|
||||
|
||||
/**
|
||||
* Returns true if the referenced resource is excluded. An excluded resource is not indexed.
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean isExcluded(Resource reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract boolean isIndexed(Resource reference, boolean acceptExcluded);
|
||||
|
||||
/**
|
||||
* Search for an indexed resource.
|
||||
*
|
||||
* @param reference the resource reference
|
||||
* @return the indexed resource, null if it's not indexed
|
||||
* @since 1.10. Generic types since 2.6.
|
||||
*/
|
||||
public abstract <R extends Resource> R getResource(R reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
public abstract Resource getParent(Resource reference);
|
||||
|
||||
/**
|
||||
* @since 2.6
|
||||
*/
|
||||
|
||||
public abstract Collection<Resource> getChildren(Resource reference);
|
||||
|
||||
/**
|
||||
* Save the source code of a file. The file must be have been indexed before.
|
||||
* Note: the source stream is not closed.
|
||||
*
|
||||
* @return false if the resource is excluded or not indexed
|
||||
* @throws org.sonar.api.resources.DuplicatedSourceException
|
||||
* if the source has already been set on this resource
|
||||
*/
|
||||
public abstract void setSource(Resource reference, String source) throws DuplicatedSourceException;
|
||||
|
||||
public abstract Project getProject();
|
||||
|
||||
public final Collection<Resource> getResources() {
|
||||
return getVertices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes the resource.
|
||||
* @return the indexed resource, even if it's excluded
|
||||
* @deprecated since 2.6. Use methods index()
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract Resource addResource(Resource resource);
|
||||
|
||||
public abstract Measure getMeasure(Resource resource, Metric metric);
|
||||
|
||||
public abstract <M> M getMeasures(Resource resource, MeasuresFilter<M> filter);
|
||||
|
||||
/**
|
||||
* Returns the violations that match the {@link ViolationQuery} parameters.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param violationQuery
|
||||
* the request parameters specified as a {@link ViolationQuery}
|
||||
* @return the list of violations that match those parameters
|
||||
*/
|
||||
public abstract List<Violation> getViolations(ViolationQuery violationQuery);
|
||||
|
||||
/**
|
||||
* Returns all the active (= non switched-off) violations found on the given resource. Equivalent to
|
||||
* {@link #getViolations(ViolationQuery)} called with <code>ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true)</code>
|
||||
* as a parameter.
|
||||
*
|
||||
* @since 2.7
|
||||
* @param the
|
||||
* resource on which violations are searched
|
||||
* @return the list of violations
|
||||
*/
|
||||
public final List<Violation> getViolations(Resource resource) {
|
||||
return getViolations(ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public abstract void addViolation(Violation violation, boolean force);
|
||||
|
||||
public final void addViolation(Violation violation) {
|
||||
addViolation(violation, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: the resource is automatically indexed for backward-compatibility, but it should be explictly
|
||||
* indexed before. Next versions will deactivate this automatic indexation.
|
||||
*
|
||||
* @throws SonarException if the metric is unknown.
|
||||
*/
|
||||
public abstract Measure addMeasure(Resource resource, Measure measure);
|
||||
|
||||
public abstract Dependency addDependency(Dependency dependency);
|
||||
|
||||
public abstract Set<Dependency> getDependencies();
|
||||
|
||||
public abstract void addLink(ProjectLink link);
|
||||
|
||||
public abstract void deleteLink(String key);
|
||||
|
||||
public abstract List<Event> getEvents(Resource resource);
|
||||
|
||||
public abstract void deleteEvent(Event event);
|
||||
|
||||
public abstract Event addEvent(Resource resource, String name, String description, String category, Date date);
|
||||
|
||||
public final Collection<Dependency> getOutgoingDependencies(Resource from) {
|
||||
return getOutgoingEdges(from);
|
||||
}
|
||||
|
||||
public final Collection<Dependency> getIncomingDependencies(Resource to) {
|
||||
return getIncomingEdges(to);
|
||||
}
|
||||
}
|
||||
|
@ -1,80 +1,80 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.database;
|
||||
|
||||
import org.sonar.api.BatchComponent;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This component should not accessible from plugin API
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
public abstract class DatabaseSession implements BatchComponent {
|
||||
|
||||
|
||||
// IMPORTANT : this value must be the same than the property
|
||||
// hibernate.jdbc.batch_size from /META-INF/persistence.xml (module sonar-database)
|
||||
public static final int BATCH_SIZE = 30;
|
||||
|
||||
|
||||
public abstract EntityManager getEntityManager();
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public abstract void stop();
|
||||
|
||||
public abstract void commit();
|
||||
|
||||
public abstract void rollback();
|
||||
|
||||
public abstract <T> T save(T entity);
|
||||
|
||||
public abstract Object saveWithoutFlush(Object entity);
|
||||
|
||||
public abstract boolean contains(Object entity);
|
||||
|
||||
public abstract void save(Object... entities);
|
||||
|
||||
public abstract Object merge(Object entity);
|
||||
|
||||
public abstract void remove(Object entity);
|
||||
|
||||
public abstract void removeWithoutFlush(Object entity);
|
||||
|
||||
public abstract <T> T reattach(Class<T> entityClass, Object primaryKey);
|
||||
|
||||
public abstract Query createQuery(String hql);
|
||||
|
||||
public abstract Query createNativeQuery(String sql);
|
||||
|
||||
public abstract <T> T getSingleResult(Query query, T defaultValue);
|
||||
|
||||
public abstract <T> T getEntity(Class<T> entityClass, Object id);
|
||||
|
||||
public abstract <T> T getSingleResult(Class<T> entityClass, Object... criterias);
|
||||
|
||||
public abstract <T> List<T> getResults(Class<T> entityClass, Object... criterias);
|
||||
|
||||
public abstract <T> List<T> getResults(Class<T> entityClass);
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.database;
|
||||
|
||||
import org.sonar.api.BatchComponent;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This component should not accessible from plugin API
|
||||
*
|
||||
* @since 1.10
|
||||
*/
|
||||
public abstract class DatabaseSession implements BatchComponent {
|
||||
|
||||
|
||||
// IMPORTANT : this value must be the same than the property
|
||||
// hibernate.jdbc.batch_size from /META-INF/persistence.xml (module sonar-database)
|
||||
public static final int BATCH_SIZE = 30;
|
||||
|
||||
|
||||
public abstract EntityManager getEntityManager();
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public abstract void stop();
|
||||
|
||||
public abstract void commit();
|
||||
|
||||
public abstract void rollback();
|
||||
|
||||
public abstract <T> T save(T entity);
|
||||
|
||||
public abstract Object saveWithoutFlush(Object entity);
|
||||
|
||||
public abstract boolean contains(Object entity);
|
||||
|
||||
public abstract void save(Object... entities);
|
||||
|
||||
public abstract Object merge(Object entity);
|
||||
|
||||
public abstract void remove(Object entity);
|
||||
|
||||
public abstract void removeWithoutFlush(Object entity);
|
||||
|
||||
public abstract <T> T reattach(Class<T> entityClass, Object primaryKey);
|
||||
|
||||
public abstract Query createQuery(String hql);
|
||||
|
||||
public abstract Query createNativeQuery(String sql);
|
||||
|
||||
public abstract <T> T getSingleResult(Query query, T defaultValue);
|
||||
|
||||
public abstract <T> T getEntity(Class<T> entityClass, Object id);
|
||||
|
||||
public abstract <T> T getSingleResult(Class<T> entityClass, Object... criterias);
|
||||
|
||||
public abstract <T> List<T> getResults(Class<T> entityClass, Object... criterias);
|
||||
|
||||
public abstract <T> List<T> getResults(Class<T> entityClass);
|
||||
}
|
||||
|
@ -1,253 +1,253 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.rules;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
|
||||
import org.sonar.api.resources.Resource;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A class that represents a violation. A violation happens when a resource does not respect a defined rule.
|
||||
*/
|
||||
public class Violation {
|
||||
|
||||
private Resource resource;
|
||||
private Rule rule;
|
||||
private String message;
|
||||
private RulePriority severity;
|
||||
private Integer lineId;
|
||||
private Double cost;
|
||||
private Date createdAt;
|
||||
private boolean switchedOff;
|
||||
|
||||
/**
|
||||
* Creates of a violation from a rule. Will need to define the resource later on
|
||||
*
|
||||
* @deprecated since 2.3. Use the factory method create()
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation(Rule rule) {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fully qualified violation
|
||||
*
|
||||
* @param rule
|
||||
* the rule that has been violated
|
||||
* @param resource
|
||||
* the resource the violation should be attached to
|
||||
* @deprecated since 2.3. Use the factory method create()
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation(Rule rule, Resource resource) {
|
||||
this.resource = resource;
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resource the violation applies to
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rule getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rule violated
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setRule(Rule rule) {
|
||||
this.rule = rule;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the violation message
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setLineId(Integer)
|
||||
*/
|
||||
public Integer getLineId() {
|
||||
return lineId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the violation line. Note that numbering starts from 1.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setLineId(Integer lineId) {
|
||||
this.lineId = lineId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public RulePriority getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public Violation setSeverity(RulePriority severity) {
|
||||
this.severity = severity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829
|
||||
*/
|
||||
@Deprecated
|
||||
public RulePriority getPriority() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only
|
||||
*
|
||||
* @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation setPriority(RulePriority priority) {
|
||||
this.severity = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setCost(Double)
|
||||
* @since 2.4
|
||||
*/
|
||||
public Double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost to fix a violation can't be precisely computed without this information. Let's take the following example : a rule forbids to
|
||||
* have methods whose complexity is greater than 10. Without this field "cost", the same violation is created with a method whose
|
||||
* complexity is 15 and a method whose complexity is 100. If the cost to fix one point of complexity is 0.05h, then 15mn is necessary to
|
||||
* fix the method whose complexity is 15, and 3h5mn is required to fix the method whose complexity is 100.
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public Violation setCost(Double d) {
|
||||
this.cost = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public Violation setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches off the current violation. This is a kind of "mute", which means the violation exists but won't be counted as an active
|
||||
* violation (and thus, won't be counted in the total number of violations).
|
||||
*
|
||||
* @since 2.8
|
||||
* @param switchedOff
|
||||
* if true, the violation is considered OFF
|
||||
*/
|
||||
public void setSwitchedOff(boolean switchedOff) {
|
||||
this.switchedOff = switchedOff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells wether this violation is ON or OFF.
|
||||
*
|
||||
* @since 2.8
|
||||
* @return true if the violation has been switched off
|
||||
*/
|
||||
public boolean isSwitchedOff() {
|
||||
return switchedOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( !(obj instanceof Violation)) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
Violation other = (Violation) obj;
|
||||
return new EqualsBuilder().append(rule, other.getRule()).append(resource, other.getResource()).isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37).append(getRule()).append(getResource()).toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this);
|
||||
}
|
||||
|
||||
public static Violation create(ActiveRule activeRule, Resource resource) {
|
||||
return new Violation(activeRule.getRule()).setResource(resource);
|
||||
}
|
||||
|
||||
public static Violation create(Rule rule, Resource resource) {
|
||||
return new Violation(rule).setResource(resource);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.rules;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
|
||||
import org.sonar.api.resources.Resource;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A class that represents a violation. A violation happens when a resource does not respect a defined rule.
|
||||
*/
|
||||
public class Violation {
|
||||
|
||||
private Resource resource;
|
||||
private Rule rule;
|
||||
private String message;
|
||||
private RulePriority severity;
|
||||
private Integer lineId;
|
||||
private Double cost;
|
||||
private Date createdAt;
|
||||
private boolean switchedOff;
|
||||
|
||||
/**
|
||||
* Creates of a violation from a rule. Will need to define the resource later on
|
||||
*
|
||||
* @deprecated since 2.3. Use the factory method create()
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation(Rule rule) {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fully qualified violation
|
||||
*
|
||||
* @param rule
|
||||
* the rule that has been violated
|
||||
* @param resource
|
||||
* the resource the violation should be attached to
|
||||
* @deprecated since 2.3. Use the factory method create()
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation(Rule rule, Resource resource) {
|
||||
this.resource = resource;
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resource the violation applies to
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rule getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rule violated
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setRule(Rule rule) {
|
||||
this.rule = rule;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the violation message
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setLineId(Integer)
|
||||
*/
|
||||
public Integer getLineId() {
|
||||
return lineId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the violation line. Note that numbering starts from 1.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
public Violation setLineId(Integer lineId) {
|
||||
this.lineId = lineId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public RulePriority getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public Violation setSeverity(RulePriority severity) {
|
||||
this.severity = severity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829
|
||||
*/
|
||||
@Deprecated
|
||||
public RulePriority getPriority() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only
|
||||
*
|
||||
* @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829
|
||||
*/
|
||||
@Deprecated
|
||||
public Violation setPriority(RulePriority priority) {
|
||||
this.severity = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setCost(Double)
|
||||
* @since 2.4
|
||||
*/
|
||||
public Double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost to fix a violation can't be precisely computed without this information. Let's take the following example : a rule forbids to
|
||||
* have methods whose complexity is greater than 10. Without this field "cost", the same violation is created with a method whose
|
||||
* complexity is 15 and a method whose complexity is 100. If the cost to fix one point of complexity is 0.05h, then 15mn is necessary to
|
||||
* fix the method whose complexity is 15, and 3h5mn is required to fix the method whose complexity is 100.
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public Violation setCost(Double d) {
|
||||
this.cost = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public Violation setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches off the current violation. This is a kind of "mute", which means the violation exists but won't be counted as an active
|
||||
* violation (and thus, won't be counted in the total number of violations).
|
||||
*
|
||||
* @since 2.8
|
||||
* @param switchedOff
|
||||
* if true, the violation is considered OFF
|
||||
*/
|
||||
public void setSwitchedOff(boolean switchedOff) {
|
||||
this.switchedOff = switchedOff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells wether this violation is ON or OFF.
|
||||
*
|
||||
* @since 2.8
|
||||
* @return true if the violation has been switched off
|
||||
*/
|
||||
public boolean isSwitchedOff() {
|
||||
return switchedOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( !(obj instanceof Violation)) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
Violation other = (Violation) obj;
|
||||
return new EqualsBuilder().append(rule, other.getRule()).append(resource, other.getResource()).isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37).append(getRule()).append(getResource()).toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this);
|
||||
}
|
||||
|
||||
public static Violation create(ActiveRule activeRule, Resource resource) {
|
||||
return new Violation(activeRule.getRule()).setResource(resource);
|
||||
}
|
||||
|
||||
public static Violation create(Rule rule, Resource resource) {
|
||||
return new Violation(rule).setResource(resource);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,89 +1,89 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.violations;
|
||||
|
||||
import org.sonar.api.resources.Resource;
|
||||
|
||||
/**
|
||||
* Class that allows to query the Sonar index about violations.
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public final class ViolationQuery {
|
||||
|
||||
private boolean ignoreSwitchedOff;
|
||||
private Resource resource;
|
||||
|
||||
/**
|
||||
* Use the factory method <code>create()</code>
|
||||
*/
|
||||
ViolationQuery() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ViolationQuery} object.
|
||||
*
|
||||
* @return the new query
|
||||
*/
|
||||
public static ViolationQuery create() {
|
||||
return new ViolationQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if the query should returned switched-off violations or not.
|
||||
*
|
||||
* @param ignore
|
||||
* if true, the query will return only active violations.
|
||||
* @return the current violation query
|
||||
*/
|
||||
public ViolationQuery ignoreSwitchedOff(boolean ignore) {
|
||||
this.ignoreSwitchedOff = ignore;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the query should returned switched-off violations or not.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean ignoreSwitchedOff() {
|
||||
return ignoreSwitchedOff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the resource which violations are search from.
|
||||
*
|
||||
* @param resource
|
||||
* the resource
|
||||
*/
|
||||
public ViolationQuery forResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource which violations are search from.
|
||||
*
|
||||
* @return the resource
|
||||
*/
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 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.api.violations;
|
||||
|
||||
import org.sonar.api.resources.Resource;
|
||||
|
||||
/**
|
||||
* Class that allows to query the Sonar index about violations.
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public final class ViolationQuery {
|
||||
|
||||
private boolean ignoreSwitchedOff;
|
||||
private Resource resource;
|
||||
|
||||
/**
|
||||
* Use the factory method <code>create()</code>
|
||||
*/
|
||||
ViolationQuery() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ViolationQuery} object.
|
||||
*
|
||||
* @return the new query
|
||||
*/
|
||||
public static ViolationQuery create() {
|
||||
return new ViolationQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if the query should returned switched-off violations or not.
|
||||
*
|
||||
* @param ignore
|
||||
* if true, the query will return only active violations.
|
||||
* @return the current violation query
|
||||
*/
|
||||
public ViolationQuery ignoreSwitchedOff(boolean ignore) {
|
||||
this.ignoreSwitchedOff = ignore;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the query should returned switched-off violations or not.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean ignoreSwitchedOff() {
|
||||
return ignoreSwitchedOff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the resource which violations are search from.
|
||||
*
|
||||
* @param resource
|
||||
* the resource
|
||||
*/
|
||||
public ViolationQuery forResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource which violations are search from.
|
||||
*
|
||||
* @return the resource
|
||||
*/
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
@ -1,339 +1,339 @@
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
class ResourceController < ApplicationController
|
||||
|
||||
SECTION=Navigation::SECTION_RESOURCE
|
||||
helper DashboardHelper
|
||||
|
||||
def index
|
||||
@resource = Project.by_key(params[:id])
|
||||
|
||||
if (@resource && has_role?(:user, @resource))
|
||||
params[:layout]='false'
|
||||
@snapshot=@resource.last_snapshot
|
||||
|
||||
load_extensions()
|
||||
|
||||
if @extension
|
||||
if (@extension.getId()=='violations')
|
||||
render_violations()
|
||||
elsif (@extension.getId()=='coverage')
|
||||
render_coverage()
|
||||
elsif (@extension.getId()=='source')
|
||||
render_source()
|
||||
else
|
||||
render_extension()
|
||||
end
|
||||
else
|
||||
render_nothing()
|
||||
end
|
||||
else
|
||||
access_denied
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_extensions
|
||||
@extensions=[]
|
||||
java_facade.getResourceTabs(@resource.scope, @resource.qualifier, @resource.language).each do |tab|
|
||||
tab.getUserRoles().each do |role|
|
||||
if has_role?(role, @resource)
|
||||
@extensions<<tab
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !params[:tab].blank?
|
||||
@extension=@extensions.find{|extension| extension.getId()==params[:tab]}
|
||||
|
||||
elsif !params[:metric].blank?
|
||||
metric=Metric.by_key(params[:metric])
|
||||
@extension=@extensions.find{|extension| extension.getDefaultTabForMetrics().include?(metric.key)}
|
||||
|
||||
end
|
||||
@extension=@extensions.find{|extension| extension.isDefaultTab()} if @extension==nil
|
||||
end
|
||||
|
||||
def load_sources
|
||||
@period = params[:period].to_i unless params[:period].blank?
|
||||
@expanded=(params[:expand]=='true')
|
||||
|
||||
if @snapshot.source
|
||||
source_lines=Java::OrgSonarServerUi::JRubyFacade.new.colorizeCode(@snapshot.source.data, @snapshot.project.language).split("\n")
|
||||
init_scm()
|
||||
|
||||
@lines=[]
|
||||
source_lines.each_with_index do |source, index|
|
||||
line=Line.new(source)
|
||||
@lines<<line
|
||||
|
||||
line.revision=@revisions_by_line[index+1]
|
||||
line.author=@authors_by_line[index+1]
|
||||
|
||||
date_string=@dates_by_line[index+1]
|
||||
line.datetime=(date_string ? Java::OrgSonarApiUtils::DateUtils.parseDateTime(date_string): nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def init_scm
|
||||
@scm_available=(@snapshot.measure('last_commit_datetimes_by_line')!=nil)
|
||||
@authors_by_line=load_distribution('authors_by_line')
|
||||
@revisions_by_line=load_distribution('revisions_by_line')
|
||||
@dates_by_line=load_distribution('last_commit_datetimes_by_line')
|
||||
end
|
||||
|
||||
def load_distribution(metric_key)
|
||||
m=@snapshot.measure(metric_key)
|
||||
m ? m.data_as_line_distribution() : {}
|
||||
end
|
||||
|
||||
def render_coverage
|
||||
load_sources()
|
||||
@display_coverage=true
|
||||
@expandable=(@lines!=nil)
|
||||
if @lines
|
||||
@hits_by_line=load_distribution('coverage_line_hits_data')
|
||||
@conditions_by_line=load_distribution('conditions_by_line')
|
||||
@covered_conditions_by_line=load_distribution('covered_conditions_by_line')
|
||||
|
||||
@hits_by_line.each_pair do |line_id,hits|
|
||||
line=@lines[line_id-1]
|
||||
if line
|
||||
line.hits=hits.to_i
|
||||
line.conditions=@conditions_by_line[line_id].to_i
|
||||
line.covered_conditions=@covered_conditions_by_line[line_id].to_i
|
||||
end
|
||||
end
|
||||
|
||||
if @snapshot.measure('conditions_by_line').nil?
|
||||
# TODO remove this code when branch_coverage_hits_data is fully removed from CoreMetrics
|
||||
deprecated_branches_by_line=load_distribution('branch_coverage_hits_data')
|
||||
deprecated_branches_by_line.each_pair do |line_id,label|
|
||||
line=@lines[line_id-1]
|
||||
if line
|
||||
line.deprecated_conditions_label=label
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
to=(@period ? Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000) : nil)
|
||||
metric=Metric.by_key(params[:coverage_filter]||params[:metric])
|
||||
@coverage_filter=(metric ? metric.key : 'coverage')
|
||||
@filtered=true
|
||||
if ('lines_to_cover'==@coverage_filter || 'coverage'==@coverage_filter || 'line_coverage'==@coverage_filter ||
|
||||
'new_lines_to_cover'==@coverage_filter || 'new_coverage'==@coverage_filter || 'new_line_coverage'==@coverage_filter)
|
||||
@coverage_filter='lines_to_cover'
|
||||
filter_lines{|line| line.hits && line.after(to)}
|
||||
|
||||
elsif 'uncovered_lines'==@coverage_filter || 'new_uncovered_lines'==@coverage_filter
|
||||
@coverage_filter='uncovered_lines'
|
||||
filter_lines{|line| line.hits && line.hits==0 && line.after(to)}
|
||||
|
||||
elsif 'conditions_to_cover'==@coverage_filter || 'branch_coverage'==@coverage_filter ||
|
||||
'new_conditions_to_cover'==@coverage_filter || 'new_branch_coverage'==@coverage_filter
|
||||
@coverage_filter='conditions_to_cover'
|
||||
filter_lines{|line| line.conditions && line.conditions>0 && line.after(to)}
|
||||
|
||||
elsif 'uncovered_conditions'==@coverage_filter || 'new_uncovered_conditions'==@coverage_filter
|
||||
@coverage_filter='uncovered_conditions'
|
||||
filter_lines{|line| line.conditions && line.covered_conditions && line.covered_conditions<line.conditions && line.after(to)}
|
||||
end
|
||||
end
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
|
||||
def render_violations
|
||||
load_sources()
|
||||
@display_violations=true
|
||||
@global_violations=[]
|
||||
@expandable=(@lines!=nil)
|
||||
@filtered=!@expanded
|
||||
|
||||
conditions='switched_off is not true AND snapshot_id=?'
|
||||
values=[@snapshot.id]
|
||||
unless params[:rule].blank?
|
||||
severity=Sonar::RulePriority.id(params[:rule])
|
||||
if severity
|
||||
conditions += ' AND failure_level=?'
|
||||
values<<severity
|
||||
else
|
||||
rule=Rule.by_key_or_id(params[:rule])
|
||||
conditions += ' AND rule_id=?'
|
||||
values<<(rule ? rule.id : -1)
|
||||
end
|
||||
end
|
||||
|
||||
if @period
|
||||
date=@snapshot.period_datetime(@period)
|
||||
if date
|
||||
conditions+=' AND created_at>?'
|
||||
values<<date.advance(:minutes => 1)
|
||||
else
|
||||
conditions+=' AND id=-1'
|
||||
end
|
||||
end
|
||||
|
||||
RuleFailure.find(:all, :include => ['rule', 'reviews' ], :conditions => [conditions] + values, :order => 'failure_level DESC').each do |violation|
|
||||
# sorted by severity => from blocker to info
|
||||
if violation.line && violation.line>0 && @lines
|
||||
@lines[violation.line-1].add_violation(violation)
|
||||
else
|
||||
@global_violations<<violation
|
||||
end
|
||||
# if the permanent_id does not exist, set it to the current id
|
||||
unless violation.permanent_id
|
||||
violation.permanent_id = violation.id
|
||||
violation.save
|
||||
end
|
||||
end
|
||||
|
||||
if !@expanded && @lines
|
||||
filter_lines{|line| line.violations?}
|
||||
end
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
def render_source
|
||||
load_sources()
|
||||
filter_lines_by_date()
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
def filter_lines_by_date
|
||||
if @period
|
||||
@filtered=true
|
||||
to=Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000)
|
||||
if to
|
||||
@lines.each do |line|
|
||||
line.flag_as_hidden() if !line.after(to)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def filter_lines(&block)
|
||||
@lines.each_with_index do |line,index|
|
||||
if yield(line)
|
||||
for i in index-4...index
|
||||
@lines[i].flag_as_highlight_context() if i>=0
|
||||
end
|
||||
line.flag_as_highlighted()
|
||||
for i in index+1..index+4
|
||||
@lines[i].flag_as_highlight_context() if i<@lines.size
|
||||
end
|
||||
else
|
||||
line.flag_as_hidden()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Line
|
||||
attr_accessor :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label
|
||||
|
||||
def initialize(source)
|
||||
@source=source
|
||||
end
|
||||
|
||||
def add_violation(violation)
|
||||
@violations||=[]
|
||||
@violations<<violation
|
||||
@visible=true
|
||||
end
|
||||
|
||||
def violations?
|
||||
@violations && @violations.size>0
|
||||
end
|
||||
|
||||
def violation_severity
|
||||
if @violations && @violations.size>0
|
||||
@violations[0].failure_level
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def after(date)
|
||||
if date && @datetime
|
||||
@datetime.after(date)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def flag_as_highlighted
|
||||
@highlighted=true
|
||||
@hidden=false
|
||||
end
|
||||
|
||||
def flag_as_highlight_context
|
||||
# do not force if highlighted has already been set to true
|
||||
@highlighted=false if @highlighted.nil?
|
||||
@hidden=false
|
||||
end
|
||||
|
||||
def flag_as_hidden
|
||||
# do not force if it has already been flagged as visible
|
||||
if @hidden.nil?
|
||||
@hidden=true
|
||||
@highlighted=false
|
||||
end
|
||||
end
|
||||
|
||||
def hidden?
|
||||
@hidden==true
|
||||
end
|
||||
|
||||
def highlighted?
|
||||
# highlighted if the @highlighted has not been set or has been set to true
|
||||
!hidden? && @highlighted!=false
|
||||
end
|
||||
|
||||
def deprecated_conditions_label=(label)
|
||||
if label
|
||||
@deprecated_conditions_label=label
|
||||
if label=='0%'
|
||||
@conditions=2
|
||||
@covered_conditions=0
|
||||
elsif label=='100%'
|
||||
@conditions=2
|
||||
@covered_conditions=2
|
||||
else
|
||||
@conditions=2
|
||||
@covered_conditions=1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_extension()
|
||||
render :action => 'extension', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
def render_nothing()
|
||||
render :action => 'nothing', :layout => !request.xhr?
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
class ResourceController < ApplicationController
|
||||
|
||||
SECTION=Navigation::SECTION_RESOURCE
|
||||
helper DashboardHelper
|
||||
|
||||
def index
|
||||
@resource = Project.by_key(params[:id])
|
||||
|
||||
if (@resource && has_role?(:user, @resource))
|
||||
params[:layout]='false'
|
||||
@snapshot=@resource.last_snapshot
|
||||
|
||||
load_extensions()
|
||||
|
||||
if @extension
|
||||
if (@extension.getId()=='violations')
|
||||
render_violations()
|
||||
elsif (@extension.getId()=='coverage')
|
||||
render_coverage()
|
||||
elsif (@extension.getId()=='source')
|
||||
render_source()
|
||||
else
|
||||
render_extension()
|
||||
end
|
||||
else
|
||||
render_nothing()
|
||||
end
|
||||
else
|
||||
access_denied
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_extensions
|
||||
@extensions=[]
|
||||
java_facade.getResourceTabs(@resource.scope, @resource.qualifier, @resource.language).each do |tab|
|
||||
tab.getUserRoles().each do |role|
|
||||
if has_role?(role, @resource)
|
||||
@extensions<<tab
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !params[:tab].blank?
|
||||
@extension=@extensions.find{|extension| extension.getId()==params[:tab]}
|
||||
|
||||
elsif !params[:metric].blank?
|
||||
metric=Metric.by_key(params[:metric])
|
||||
@extension=@extensions.find{|extension| extension.getDefaultTabForMetrics().include?(metric.key)}
|
||||
|
||||
end
|
||||
@extension=@extensions.find{|extension| extension.isDefaultTab()} if @extension==nil
|
||||
end
|
||||
|
||||
def load_sources
|
||||
@period = params[:period].to_i unless params[:period].blank?
|
||||
@expanded=(params[:expand]=='true')
|
||||
|
||||
if @snapshot.source
|
||||
source_lines=Java::OrgSonarServerUi::JRubyFacade.new.colorizeCode(@snapshot.source.data, @snapshot.project.language).split("\n")
|
||||
init_scm()
|
||||
|
||||
@lines=[]
|
||||
source_lines.each_with_index do |source, index|
|
||||
line=Line.new(source)
|
||||
@lines<<line
|
||||
|
||||
line.revision=@revisions_by_line[index+1]
|
||||
line.author=@authors_by_line[index+1]
|
||||
|
||||
date_string=@dates_by_line[index+1]
|
||||
line.datetime=(date_string ? Java::OrgSonarApiUtils::DateUtils.parseDateTime(date_string): nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def init_scm
|
||||
@scm_available=(@snapshot.measure('last_commit_datetimes_by_line')!=nil)
|
||||
@authors_by_line=load_distribution('authors_by_line')
|
||||
@revisions_by_line=load_distribution('revisions_by_line')
|
||||
@dates_by_line=load_distribution('last_commit_datetimes_by_line')
|
||||
end
|
||||
|
||||
def load_distribution(metric_key)
|
||||
m=@snapshot.measure(metric_key)
|
||||
m ? m.data_as_line_distribution() : {}
|
||||
end
|
||||
|
||||
def render_coverage
|
||||
load_sources()
|
||||
@display_coverage=true
|
||||
@expandable=(@lines!=nil)
|
||||
if @lines
|
||||
@hits_by_line=load_distribution('coverage_line_hits_data')
|
||||
@conditions_by_line=load_distribution('conditions_by_line')
|
||||
@covered_conditions_by_line=load_distribution('covered_conditions_by_line')
|
||||
|
||||
@hits_by_line.each_pair do |line_id,hits|
|
||||
line=@lines[line_id-1]
|
||||
if line
|
||||
line.hits=hits.to_i
|
||||
line.conditions=@conditions_by_line[line_id].to_i
|
||||
line.covered_conditions=@covered_conditions_by_line[line_id].to_i
|
||||
end
|
||||
end
|
||||
|
||||
if @snapshot.measure('conditions_by_line').nil?
|
||||
# TODO remove this code when branch_coverage_hits_data is fully removed from CoreMetrics
|
||||
deprecated_branches_by_line=load_distribution('branch_coverage_hits_data')
|
||||
deprecated_branches_by_line.each_pair do |line_id,label|
|
||||
line=@lines[line_id-1]
|
||||
if line
|
||||
line.deprecated_conditions_label=label
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
to=(@period ? Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000) : nil)
|
||||
metric=Metric.by_key(params[:coverage_filter]||params[:metric])
|
||||
@coverage_filter=(metric ? metric.key : 'coverage')
|
||||
@filtered=true
|
||||
if ('lines_to_cover'==@coverage_filter || 'coverage'==@coverage_filter || 'line_coverage'==@coverage_filter ||
|
||||
'new_lines_to_cover'==@coverage_filter || 'new_coverage'==@coverage_filter || 'new_line_coverage'==@coverage_filter)
|
||||
@coverage_filter='lines_to_cover'
|
||||
filter_lines{|line| line.hits && line.after(to)}
|
||||
|
||||
elsif 'uncovered_lines'==@coverage_filter || 'new_uncovered_lines'==@coverage_filter
|
||||
@coverage_filter='uncovered_lines'
|
||||
filter_lines{|line| line.hits && line.hits==0 && line.after(to)}
|
||||
|
||||
elsif 'conditions_to_cover'==@coverage_filter || 'branch_coverage'==@coverage_filter ||
|
||||
'new_conditions_to_cover'==@coverage_filter || 'new_branch_coverage'==@coverage_filter
|
||||
@coverage_filter='conditions_to_cover'
|
||||
filter_lines{|line| line.conditions && line.conditions>0 && line.after(to)}
|
||||
|
||||
elsif 'uncovered_conditions'==@coverage_filter || 'new_uncovered_conditions'==@coverage_filter
|
||||
@coverage_filter='uncovered_conditions'
|
||||
filter_lines{|line| line.conditions && line.covered_conditions && line.covered_conditions<line.conditions && line.after(to)}
|
||||
end
|
||||
end
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
|
||||
def render_violations
|
||||
load_sources()
|
||||
@display_violations=true
|
||||
@global_violations=[]
|
||||
@expandable=(@lines!=nil)
|
||||
@filtered=!@expanded
|
||||
|
||||
conditions='switched_off is not true AND snapshot_id=?'
|
||||
values=[@snapshot.id]
|
||||
unless params[:rule].blank?
|
||||
severity=Sonar::RulePriority.id(params[:rule])
|
||||
if severity
|
||||
conditions += ' AND failure_level=?'
|
||||
values<<severity
|
||||
else
|
||||
rule=Rule.by_key_or_id(params[:rule])
|
||||
conditions += ' AND rule_id=?'
|
||||
values<<(rule ? rule.id : -1)
|
||||
end
|
||||
end
|
||||
|
||||
if @period
|
||||
date=@snapshot.period_datetime(@period)
|
||||
if date
|
||||
conditions+=' AND created_at>?'
|
||||
values<<date.advance(:minutes => 1)
|
||||
else
|
||||
conditions+=' AND id=-1'
|
||||
end
|
||||
end
|
||||
|
||||
RuleFailure.find(:all, :include => ['rule', 'reviews' ], :conditions => [conditions] + values, :order => 'failure_level DESC').each do |violation|
|
||||
# sorted by severity => from blocker to info
|
||||
if violation.line && violation.line>0 && @lines
|
||||
@lines[violation.line-1].add_violation(violation)
|
||||
else
|
||||
@global_violations<<violation
|
||||
end
|
||||
# if the permanent_id does not exist, set it to the current id
|
||||
unless violation.permanent_id
|
||||
violation.permanent_id = violation.id
|
||||
violation.save
|
||||
end
|
||||
end
|
||||
|
||||
if !@expanded && @lines
|
||||
filter_lines{|line| line.violations?}
|
||||
end
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
def render_source
|
||||
load_sources()
|
||||
filter_lines_by_date()
|
||||
render :action => 'index', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
|
||||
def filter_lines_by_date
|
||||
if @period
|
||||
@filtered=true
|
||||
to=Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000)
|
||||
if to
|
||||
@lines.each do |line|
|
||||
line.flag_as_hidden() if !line.after(to)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def filter_lines(&block)
|
||||
@lines.each_with_index do |line,index|
|
||||
if yield(line)
|
||||
for i in index-4...index
|
||||
@lines[i].flag_as_highlight_context() if i>=0
|
||||
end
|
||||
line.flag_as_highlighted()
|
||||
for i in index+1..index+4
|
||||
@lines[i].flag_as_highlight_context() if i<@lines.size
|
||||
end
|
||||
else
|
||||
line.flag_as_hidden()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Line
|
||||
attr_accessor :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label
|
||||
|
||||
def initialize(source)
|
||||
@source=source
|
||||
end
|
||||
|
||||
def add_violation(violation)
|
||||
@violations||=[]
|
||||
@violations<<violation
|
||||
@visible=true
|
||||
end
|
||||
|
||||
def violations?
|
||||
@violations && @violations.size>0
|
||||
end
|
||||
|
||||
def violation_severity
|
||||
if @violations && @violations.size>0
|
||||
@violations[0].failure_level
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def after(date)
|
||||
if date && @datetime
|
||||
@datetime.after(date)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def flag_as_highlighted
|
||||
@highlighted=true
|
||||
@hidden=false
|
||||
end
|
||||
|
||||
def flag_as_highlight_context
|
||||
# do not force if highlighted has already been set to true
|
||||
@highlighted=false if @highlighted.nil?
|
||||
@hidden=false
|
||||
end
|
||||
|
||||
def flag_as_hidden
|
||||
# do not force if it has already been flagged as visible
|
||||
if @hidden.nil?
|
||||
@hidden=true
|
||||
@highlighted=false
|
||||
end
|
||||
end
|
||||
|
||||
def hidden?
|
||||
@hidden==true
|
||||
end
|
||||
|
||||
def highlighted?
|
||||
# highlighted if the @highlighted has not been set or has been set to true
|
||||
!hidden? && @highlighted!=false
|
||||
end
|
||||
|
||||
def deprecated_conditions_label=(label)
|
||||
if label
|
||||
@deprecated_conditions_label=label
|
||||
if label=='0%'
|
||||
@conditions=2
|
||||
@covered_conditions=0
|
||||
elsif label=='100%'
|
||||
@conditions=2
|
||||
@covered_conditions=2
|
||||
else
|
||||
@conditions=2
|
||||
@covered_conditions=1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_extension()
|
||||
render :action => 'extension', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
def render_nothing()
|
||||
render :action => 'nothing', :layout => !request.xhr?
|
||||
end
|
||||
end
|
@ -1,263 +1,263 @@
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
|
||||
class ReviewsController < ApplicationController
|
||||
|
||||
SECTION=Navigation::SECTION_HOME
|
||||
|
||||
verify :method => :post, :only => [ :create, :create_comment ], :redirect_to => { :action => :error_not_post }
|
||||
|
||||
def index
|
||||
init_params
|
||||
|
||||
@reviews = []
|
||||
unless params.blank?
|
||||
find_reviews_for_user_query
|
||||
end
|
||||
end
|
||||
|
||||
def list
|
||||
reviews = find_reviews_for_rule_failure params[:rule_failure_permanent_id]
|
||||
render :partial => "list", :locals => { :reviews => reviews }
|
||||
end
|
||||
|
||||
def display_violation
|
||||
violation = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
def form
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
@review = Review.new
|
||||
@review.rule_failure_permanent_id = rule_failure.permanent_id
|
||||
@review_comment = ReviewComment.new
|
||||
@review_comment.review_text = ""
|
||||
if params[:switch_off]
|
||||
@review.review_type = "f-positive"
|
||||
else
|
||||
@review.review_type = Review.default_type
|
||||
end
|
||||
render :partial => "form"
|
||||
end
|
||||
|
||||
def create
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:review][:rule_failure_permanent_id]
|
||||
unless has_rights_to_create? rule_failure
|
||||
render :text => "<b>Cannot create the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review = Review.new(params[:review])
|
||||
@review.user = current_user
|
||||
if params[:assign_to_me]
|
||||
@review.assignee = current_user
|
||||
end
|
||||
@review.title = rule_failure.message
|
||||
@review.status = Review.default_status
|
||||
@review.severity = Sonar::RulePriority.to_s rule_failure.failure_level
|
||||
@review.resource = RuleFailure.find( @review.rule_failure_permanent_id, :include => ['snapshot'] ).snapshot.project
|
||||
@review_comment = ReviewComment.new(params[:review_comment])
|
||||
@review_comment.user = current_user
|
||||
@review.review_comments << @review_comment
|
||||
if @review.valid?
|
||||
if @review.review_type == "f-positive"
|
||||
if rule_failure.get_open_review
|
||||
current_open_review = rule_failure.get_open_review
|
||||
current_open_review.status = "closed"
|
||||
current_open_review.save
|
||||
end
|
||||
rule_failure.switched_off = true
|
||||
rule_failure.save
|
||||
end
|
||||
@review.save
|
||||
@violation = rule_failure
|
||||
end
|
||||
render "create_result"
|
||||
end
|
||||
|
||||
def form_comment
|
||||
@review_comment = ReviewComment.new
|
||||
@review_comment.user = current_user
|
||||
@review_comment.review_id = params[:review_id]
|
||||
@review_comment.review_text = ""
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if params[:update_comment]
|
||||
@update_comment = true
|
||||
@review_comment.review_text = params[:review_text]
|
||||
end
|
||||
render :partial => "form_comment"
|
||||
end
|
||||
|
||||
def create_comment
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
unless has_rights_to_create? rule_failure
|
||||
render :text => "<b>Cannot create the comment</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review_comment = ReviewComment.new(params[:review_comment])
|
||||
@review_comment.user = current_user
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if @review_comment.valid?
|
||||
@review_comment.save
|
||||
# -- TODO : should create a Review#create_comment and put the following logic in it
|
||||
review = @review_comment.review
|
||||
review.updated_at = @review_comment.created_at
|
||||
review.save
|
||||
# -- End of TODO code --
|
||||
@violation = rule_failure
|
||||
end
|
||||
render "create_comment_result"
|
||||
end
|
||||
|
||||
def update_comment
|
||||
review = Review.find params[:review_comment][:review_id]
|
||||
@review_comment = review.review_comments.last
|
||||
unless current_user && current_user.id == @review_comment.user_id
|
||||
render :text => "<b>Cannot modify the comment</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review_comment.review_text = params[:review_comment][:review_text]
|
||||
@review_comment.created_at = DateTime.now
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if @review_comment.valid?
|
||||
@review_comment.save
|
||||
review.updated_at = @review_comment.updated_at
|
||||
review.save
|
||||
@violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
end
|
||||
render "create_comment_result"
|
||||
end
|
||||
|
||||
def form_assign
|
||||
@user_options = add_all_users []
|
||||
@review_id = params[:review_id]
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
render :partial => "form_assign"
|
||||
end
|
||||
|
||||
def assign
|
||||
review = Review.find params[:review_id]
|
||||
unless current_user
|
||||
render :text => "<b>Cannot edit the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
review.assignee = User.find params[:assignee_id]
|
||||
review.save
|
||||
violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
def close_review
|
||||
review = Review.find params[:review_id]
|
||||
unless current_user
|
||||
render :text => "<b>Cannot edit the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
review.status = "closed"
|
||||
review.save
|
||||
violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
## -------------- PRIVATE -------------- ##
|
||||
private
|
||||
|
||||
def init_params
|
||||
@user_names = [["Any", ""]]
|
||||
default_user = [""]
|
||||
if current_user
|
||||
default_user = [current_user.id]
|
||||
end
|
||||
add_all_users @user_names
|
||||
@review_authors = filter_any(params[:review_authors]) || default_user
|
||||
@comment_authors = filter_any(params[:comment_authors]) || default_user
|
||||
@severities = filter_any(params[:severities]) || [""]
|
||||
@statuses = filter_any(params[:statuses]) || ["open"]
|
||||
end
|
||||
|
||||
def add_all_users ( user_options )
|
||||
User.find( :all ).each do |user|
|
||||
userName = user.name
|
||||
if current_user.id == user.id
|
||||
userName = "Me (" + user.name + ")"
|
||||
end
|
||||
user_options << [userName, user.id.to_s]
|
||||
end
|
||||
return user_options
|
||||
end
|
||||
|
||||
def filter_any(array)
|
||||
if array && array.size>1 && array.include?("")
|
||||
array=[""]
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
def find_reviews_for_user_query
|
||||
conditions=[]
|
||||
values={}
|
||||
|
||||
unless @statuses == [""]
|
||||
conditions << "reviews.status in (:statuses)"
|
||||
values[:statuses]=@statuses
|
||||
end
|
||||
unless @severities == [""]
|
||||
conditions << "reviews.severity in (:severities)"
|
||||
values[:severities]=@severities
|
||||
end
|
||||
unless @review_authors == [""]
|
||||
conditions << "reviews.user_id in (:review_authors)"
|
||||
values[:review_authors]=@review_authors
|
||||
end
|
||||
unless @comment_authors == [""]
|
||||
conditions << "review_comments.user_id in (:comment_authors)"
|
||||
values[:comment_authors]=@comment_authors
|
||||
end
|
||||
|
||||
@reviews = Review.find( :all, :order => "created_at DESC", :joins => :review_comments, :conditions => [ conditions.join(" AND "), values] ).uniq
|
||||
end
|
||||
|
||||
def find_reviews_for_rule_failure ( rule_failure_permanent_id )
|
||||
return Review.find :all, :conditions => ['rule_failure_permanent_id=?', rule_failure_permanent_id]
|
||||
end
|
||||
|
||||
def find_last_rule_failure_with_permanent_id ( rule_failure_permanent_id )
|
||||
return RuleFailure.last( :all, :conditions => [ "permanent_id = ?", rule_failure_permanent_id ], :include => ['snapshot'] )
|
||||
end
|
||||
|
||||
def has_rights_to_create? ( rule_failure )
|
||||
return false unless current_user
|
||||
|
||||
project = rule_failure.snapshot.root_project
|
||||
unless has_role?(:user, project)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def error_not_post
|
||||
render :text => "Create actions must use POST method."
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
|
||||
class ReviewsController < ApplicationController
|
||||
|
||||
SECTION=Navigation::SECTION_HOME
|
||||
|
||||
verify :method => :post, :only => [ :create, :create_comment ], :redirect_to => { :action => :error_not_post }
|
||||
|
||||
def index
|
||||
init_params
|
||||
|
||||
@reviews = []
|
||||
unless params.blank?
|
||||
find_reviews_for_user_query
|
||||
end
|
||||
end
|
||||
|
||||
def list
|
||||
reviews = find_reviews_for_rule_failure params[:rule_failure_permanent_id]
|
||||
render :partial => "list", :locals => { :reviews => reviews }
|
||||
end
|
||||
|
||||
def display_violation
|
||||
violation = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
def form
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
@review = Review.new
|
||||
@review.rule_failure_permanent_id = rule_failure.permanent_id
|
||||
@review_comment = ReviewComment.new
|
||||
@review_comment.review_text = ""
|
||||
if params[:switch_off]
|
||||
@review.review_type = "f-positive"
|
||||
else
|
||||
@review.review_type = Review.default_type
|
||||
end
|
||||
render :partial => "form"
|
||||
end
|
||||
|
||||
def create
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:review][:rule_failure_permanent_id]
|
||||
unless has_rights_to_create? rule_failure
|
||||
render :text => "<b>Cannot create the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review = Review.new(params[:review])
|
||||
@review.user = current_user
|
||||
if params[:assign_to_me]
|
||||
@review.assignee = current_user
|
||||
end
|
||||
@review.title = rule_failure.message
|
||||
@review.status = Review.default_status
|
||||
@review.severity = Sonar::RulePriority.to_s rule_failure.failure_level
|
||||
@review.resource = RuleFailure.find( @review.rule_failure_permanent_id, :include => ['snapshot'] ).snapshot.project
|
||||
@review_comment = ReviewComment.new(params[:review_comment])
|
||||
@review_comment.user = current_user
|
||||
@review.review_comments << @review_comment
|
||||
if @review.valid?
|
||||
if @review.review_type == "f-positive"
|
||||
if rule_failure.get_open_review
|
||||
current_open_review = rule_failure.get_open_review
|
||||
current_open_review.status = "closed"
|
||||
current_open_review.save
|
||||
end
|
||||
rule_failure.switched_off = true
|
||||
rule_failure.save
|
||||
end
|
||||
@review.save
|
||||
@violation = rule_failure
|
||||
end
|
||||
render "create_result"
|
||||
end
|
||||
|
||||
def form_comment
|
||||
@review_comment = ReviewComment.new
|
||||
@review_comment.user = current_user
|
||||
@review_comment.review_id = params[:review_id]
|
||||
@review_comment.review_text = ""
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if params[:update_comment]
|
||||
@update_comment = true
|
||||
@review_comment.review_text = params[:review_text]
|
||||
end
|
||||
render :partial => "form_comment"
|
||||
end
|
||||
|
||||
def create_comment
|
||||
rule_failure = find_last_rule_failure_with_permanent_id params[:rule_failure_permanent_id]
|
||||
unless has_rights_to_create? rule_failure
|
||||
render :text => "<b>Cannot create the comment</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review_comment = ReviewComment.new(params[:review_comment])
|
||||
@review_comment.user = current_user
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if @review_comment.valid?
|
||||
@review_comment.save
|
||||
# -- TODO : should create a Review#create_comment and put the following logic in it
|
||||
review = @review_comment.review
|
||||
review.updated_at = @review_comment.created_at
|
||||
review.save
|
||||
# -- End of TODO code --
|
||||
@violation = rule_failure
|
||||
end
|
||||
render "create_comment_result"
|
||||
end
|
||||
|
||||
def update_comment
|
||||
review = Review.find params[:review_comment][:review_id]
|
||||
@review_comment = review.review_comments.last
|
||||
unless current_user && current_user.id == @review_comment.user_id
|
||||
render :text => "<b>Cannot modify the comment</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
@review_comment.review_text = params[:review_comment][:review_text]
|
||||
@review_comment.created_at = DateTime.now
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
if @review_comment.valid?
|
||||
@review_comment.save
|
||||
review.updated_at = @review_comment.updated_at
|
||||
review.save
|
||||
@violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
end
|
||||
render "create_comment_result"
|
||||
end
|
||||
|
||||
def form_assign
|
||||
@user_options = add_all_users []
|
||||
@review_id = params[:review_id]
|
||||
@rule_failure_permanent_id = params[:rule_failure_permanent_id]
|
||||
render :partial => "form_assign"
|
||||
end
|
||||
|
||||
def assign
|
||||
review = Review.find params[:review_id]
|
||||
unless current_user
|
||||
render :text => "<b>Cannot edit the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
review.assignee = User.find params[:assignee_id]
|
||||
review.save
|
||||
violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
def close_review
|
||||
review = Review.find params[:review_id]
|
||||
unless current_user
|
||||
render :text => "<b>Cannot edit the review</b> : access denied."
|
||||
return
|
||||
end
|
||||
|
||||
review.status = "closed"
|
||||
review.save
|
||||
violation = find_last_rule_failure_with_permanent_id review.rule_failure_permanent_id
|
||||
render :partial => "resource/violation", :locals => { :violation => violation }
|
||||
end
|
||||
|
||||
## -------------- PRIVATE -------------- ##
|
||||
private
|
||||
|
||||
def init_params
|
||||
@user_names = [["Any", ""]]
|
||||
default_user = [""]
|
||||
if current_user
|
||||
default_user = [current_user.id]
|
||||
end
|
||||
add_all_users @user_names
|
||||
@review_authors = filter_any(params[:review_authors]) || default_user
|
||||
@comment_authors = filter_any(params[:comment_authors]) || default_user
|
||||
@severities = filter_any(params[:severities]) || [""]
|
||||
@statuses = filter_any(params[:statuses]) || ["open"]
|
||||
end
|
||||
|
||||
def add_all_users ( user_options )
|
||||
User.find( :all ).each do |user|
|
||||
userName = user.name
|
||||
if current_user.id == user.id
|
||||
userName = "Me (" + user.name + ")"
|
||||
end
|
||||
user_options << [userName, user.id.to_s]
|
||||
end
|
||||
return user_options
|
||||
end
|
||||
|
||||
def filter_any(array)
|
||||
if array && array.size>1 && array.include?("")
|
||||
array=[""]
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
def find_reviews_for_user_query
|
||||
conditions=[]
|
||||
values={}
|
||||
|
||||
unless @statuses == [""]
|
||||
conditions << "reviews.status in (:statuses)"
|
||||
values[:statuses]=@statuses
|
||||
end
|
||||
unless @severities == [""]
|
||||
conditions << "reviews.severity in (:severities)"
|
||||
values[:severities]=@severities
|
||||
end
|
||||
unless @review_authors == [""]
|
||||
conditions << "reviews.user_id in (:review_authors)"
|
||||
values[:review_authors]=@review_authors
|
||||
end
|
||||
unless @comment_authors == [""]
|
||||
conditions << "review_comments.user_id in (:comment_authors)"
|
||||
values[:comment_authors]=@comment_authors
|
||||
end
|
||||
|
||||
@reviews = Review.find( :all, :order => "created_at DESC", :joins => :review_comments, :conditions => [ conditions.join(" AND "), values] ).uniq
|
||||
end
|
||||
|
||||
def find_reviews_for_rule_failure ( rule_failure_permanent_id )
|
||||
return Review.find :all, :conditions => ['rule_failure_permanent_id=?', rule_failure_permanent_id]
|
||||
end
|
||||
|
||||
def find_last_rule_failure_with_permanent_id ( rule_failure_permanent_id )
|
||||
return RuleFailure.last( :all, :conditions => [ "permanent_id = ?", rule_failure_permanent_id ], :include => ['snapshot'] )
|
||||
end
|
||||
|
||||
def has_rights_to_create? ( rule_failure )
|
||||
return false unless current_user
|
||||
|
||||
project = rule_failure.snapshot.root_project
|
||||
unless has_role?(:user, project)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def error_not_post
|
||||
render :text => "Create actions must use POST method."
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,72 +1,72 @@
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
class Review < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :assignee, :class_name => "User", :foreign_key => "assignee_id"
|
||||
belongs_to :resource, :class_name => "Project", :foreign_key => "resource_id"
|
||||
has_many :review_comments, :order => "created_at", :dependent => :destroy
|
||||
validates_presence_of :user, :message => "can't be empty"
|
||||
validates_presence_of :title, :message => "can't be empty"
|
||||
validates_presence_of :review_type, :message => "can't be empty"
|
||||
validates_presence_of :status, :message => "can't be empty"
|
||||
|
||||
SEVERITY_INFO = "INFO"
|
||||
SEVERITY_MINOR = "MINOR"
|
||||
SEVERITY_MAJOR = "MAJOR"
|
||||
SEVERITY_CRITICAL = "CRITICAL"
|
||||
SEVERITY_BLOCKER = "BLOCKER"
|
||||
|
||||
TYPE_COMMENTS = "comments"
|
||||
TYPE_FALSE_POSITIVE = "f-positive"
|
||||
|
||||
STATUS_OPEN = "open"
|
||||
STATUS_CLOSED = "closed"
|
||||
|
||||
|
||||
def self.default_severity
|
||||
return SEVERITY_MAJOR
|
||||
end
|
||||
|
||||
def self.default_type
|
||||
return TYPE_COMMENTS
|
||||
end
|
||||
|
||||
def self.default_status
|
||||
return STATUS_OPEN
|
||||
end
|
||||
|
||||
def self.severity_options
|
||||
severity_ops = []
|
||||
severity_ops << ["Info", SEVERITY_INFO]
|
||||
severity_ops << ["Minor", SEVERITY_MINOR]
|
||||
severity_ops << ["Major", SEVERITY_MAJOR]
|
||||
severity_ops << ["Critical", SEVERITY_CRITICAL]
|
||||
severity_ops << ["Blocker", SEVERITY_BLOCKER]
|
||||
return severity_ops
|
||||
end
|
||||
|
||||
def self.status_options
|
||||
status_ops = []
|
||||
status_ops << ["Open", STATUS_OPEN]
|
||||
status_ops << ["Closed", STATUS_CLOSED]
|
||||
return status_ops
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
class Review < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :assignee, :class_name => "User", :foreign_key => "assignee_id"
|
||||
belongs_to :resource, :class_name => "Project", :foreign_key => "resource_id"
|
||||
has_many :review_comments, :order => "created_at", :dependent => :destroy
|
||||
validates_presence_of :user, :message => "can't be empty"
|
||||
validates_presence_of :title, :message => "can't be empty"
|
||||
validates_presence_of :review_type, :message => "can't be empty"
|
||||
validates_presence_of :status, :message => "can't be empty"
|
||||
|
||||
SEVERITY_INFO = "INFO"
|
||||
SEVERITY_MINOR = "MINOR"
|
||||
SEVERITY_MAJOR = "MAJOR"
|
||||
SEVERITY_CRITICAL = "CRITICAL"
|
||||
SEVERITY_BLOCKER = "BLOCKER"
|
||||
|
||||
TYPE_COMMENTS = "comments"
|
||||
TYPE_FALSE_POSITIVE = "f-positive"
|
||||
|
||||
STATUS_OPEN = "open"
|
||||
STATUS_CLOSED = "closed"
|
||||
|
||||
|
||||
def self.default_severity
|
||||
return SEVERITY_MAJOR
|
||||
end
|
||||
|
||||
def self.default_type
|
||||
return TYPE_COMMENTS
|
||||
end
|
||||
|
||||
def self.default_status
|
||||
return STATUS_OPEN
|
||||
end
|
||||
|
||||
def self.severity_options
|
||||
severity_ops = []
|
||||
severity_ops << ["Info", SEVERITY_INFO]
|
||||
severity_ops << ["Minor", SEVERITY_MINOR]
|
||||
severity_ops << ["Major", SEVERITY_MAJOR]
|
||||
severity_ops << ["Critical", SEVERITY_CRITICAL]
|
||||
severity_ops << ["Blocker", SEVERITY_BLOCKER]
|
||||
return severity_ops
|
||||
end
|
||||
|
||||
def self.status_options
|
||||
status_ops = []
|
||||
status_ops << ["Open", STATUS_OPEN]
|
||||
status_ops << ["Closed", STATUS_CLOSED]
|
||||
return status_ops
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,84 +1,84 @@
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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 {library}; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
#
|
||||
|
||||
class RuleFailure < ActiveRecord::Base
|
||||
|
||||
belongs_to :rule
|
||||
belongs_to :snapshot
|
||||
has_many :reviews, :primary_key => "permanent_id", :foreign_key => "rule_failure_permanent_id", :order => "created_at"
|
||||
|
||||
def get_open_review
|
||||
reviews.each do |review|
|
||||
if review.status == "open"
|
||||
return review
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def to_hash_json
|
||||
json = {}
|
||||
json['message'] = message
|
||||
json['line'] = line if line
|
||||
json['priority'] = Sonar::RulePriority.to_s(failure_level).upcase
|
||||
if created_at
|
||||
json['createdAt'] = format_datetime(created_at)
|
||||
end
|
||||
json['rule'] = {
|
||||
:key => rule.key,
|
||||
:name => rule.name
|
||||
}
|
||||
json['resource'] = {
|
||||
:key => snapshot.project.key,
|
||||
:name => snapshot.project.name,
|
||||
:scope => snapshot.project.scope,
|
||||
:qualifier => snapshot.project.qualifier,
|
||||
:language => snapshot.project.language
|
||||
}
|
||||
json
|
||||
end
|
||||
|
||||
def to_xml(xml=Builder::XmlMarkup.new(:indent => 0))
|
||||
xml.violation do
|
||||
xml.message(message)
|
||||
xml.line(line) if line
|
||||
xml.priority(Sonar::RulePriority.to_s(failure_level))
|
||||
if created_at
|
||||
xml.createdAt(format_datetime(created_at))
|
||||
end
|
||||
xml.rule do
|
||||
xml.key(rule.key)
|
||||
xml.name(rule.name)
|
||||
end
|
||||
xml.resource do
|
||||
xml.key(snapshot.project.key)
|
||||
xml.name(snapshot.project.name)
|
||||
xml.scope(snapshot.project.scope)
|
||||
xml.qualifier(snapshot.project.qualifier)
|
||||
xml.language(snapshot.project.language)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def format_datetime(datetime)
|
||||
datetime.strftime("%Y-%m-%dT%H:%M:%S%z")
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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 {library}; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
#
|
||||
|
||||
class RuleFailure < ActiveRecord::Base
|
||||
|
||||
belongs_to :rule
|
||||
belongs_to :snapshot
|
||||
has_many :reviews, :primary_key => "permanent_id", :foreign_key => "rule_failure_permanent_id", :order => "created_at"
|
||||
|
||||
def get_open_review
|
||||
reviews.each do |review|
|
||||
if review.status == "open"
|
||||
return review
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def to_hash_json
|
||||
json = {}
|
||||
json['message'] = message
|
||||
json['line'] = line if line
|
||||
json['priority'] = Sonar::RulePriority.to_s(failure_level).upcase
|
||||
if created_at
|
||||
json['createdAt'] = format_datetime(created_at)
|
||||
end
|
||||
json['rule'] = {
|
||||
:key => rule.key,
|
||||
:name => rule.name
|
||||
}
|
||||
json['resource'] = {
|
||||
:key => snapshot.project.key,
|
||||
:name => snapshot.project.name,
|
||||
:scope => snapshot.project.scope,
|
||||
:qualifier => snapshot.project.qualifier,
|
||||
:language => snapshot.project.language
|
||||
}
|
||||
json
|
||||
end
|
||||
|
||||
def to_xml(xml=Builder::XmlMarkup.new(:indent => 0))
|
||||
xml.violation do
|
||||
xml.message(message)
|
||||
xml.line(line) if line
|
||||
xml.priority(Sonar::RulePriority.to_s(failure_level))
|
||||
if created_at
|
||||
xml.createdAt(format_datetime(created_at))
|
||||
end
|
||||
xml.rule do
|
||||
xml.key(rule.key)
|
||||
xml.name(rule.name)
|
||||
end
|
||||
xml.resource do
|
||||
xml.key(snapshot.project.key)
|
||||
xml.name(snapshot.project.name)
|
||||
xml.scope(snapshot.project.scope)
|
||||
xml.qualifier(snapshot.project.qualifier)
|
||||
xml.language(snapshot.project.language)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def format_datetime(datetime)
|
||||
datetime.strftime("%Y-%m-%dT%H:%M:%S%z")
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,30 +1,30 @@
|
||||
<% form_for :review, @review do |f| %>
|
||||
<%= f.hidden_field :rule_failure_permanent_id -%>
|
||||
<%= f.hidden_field :review_type -%>
|
||||
|
||||
<% if @review.review_type == "f-positive" %>
|
||||
<b>Reason for flagging this violation as a false-positive:</b>
|
||||
<% end %>
|
||||
<%= text_area :review_comment, :review_text,
|
||||
:id => "reviewText", :rows => 8,
|
||||
:style => "width:100%", :onKeyUp => "if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';" -%>
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<%
|
||||
if @review.review_type == "comments"
|
||||
button_text = "Post review"
|
||||
else
|
||||
button_text = "Switch-off violation"
|
||||
end
|
||||
%>
|
||||
<%= submit_to_remote "submit_btn", button_text, :url => { :action => 'create' }, :html => { :id => "submit_btn", :disabled => "true" } -%>
|
||||
|
||||
<a onclick="$('reviewForm<%= @review.rule_failure_permanent_id.to_s -%>').style.display='none';" href="#">Cancel</a>
|
||||
<% if @review.review_type == "comments" %>
|
||||
|
||||
<%= check_box_tag "assign_to_me", "me", true -%> Assign to me
|
||||
<% end %>
|
||||
</div>
|
||||
</div class="clear"></div>
|
||||
<% form_for :review, @review do |f| %>
|
||||
<%= f.hidden_field :rule_failure_permanent_id -%>
|
||||
<%= f.hidden_field :review_type -%>
|
||||
|
||||
<% if @review.review_type == "f-positive" %>
|
||||
<b>Reason for flagging this violation as a false-positive:</b>
|
||||
<% end %>
|
||||
<%= text_area :review_comment, :review_text,
|
||||
:id => "reviewText", :rows => 8,
|
||||
:style => "width:100%", :onKeyUp => "if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';" -%>
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<%
|
||||
if @review.review_type == "comments"
|
||||
button_text = "Post review"
|
||||
else
|
||||
button_text = "Switch-off violation"
|
||||
end
|
||||
%>
|
||||
<%= submit_to_remote "submit_btn", button_text, :url => { :action => 'create' }, :html => { :id => "submit_btn", :disabled => "true" } -%>
|
||||
|
||||
<a onclick="$('reviewForm<%= @review.rule_failure_permanent_id.to_s -%>').style.display='none';" href="#">Cancel</a>
|
||||
<% if @review.review_type == "comments" %>
|
||||
|
||||
<%= check_box_tag "assign_to_me", "me", true -%> Assign to me
|
||||
<% end %>
|
||||
</div>
|
||||
</div class="clear"></div>
|
||||
<% end %>
|
@ -1,28 +1,28 @@
|
||||
<% form_for :review_comment, @review_comment do |f| %>
|
||||
<%= f.hidden_field :review_id %>
|
||||
<%= f.text_area :review_text, :rows => 8,
|
||||
:id => "commentText" + @rule_failure_permanent_id.to_s,
|
||||
:style => "width:100%",
|
||||
:onKeyUp => "if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';" %>
|
||||
<br/>
|
||||
|
||||
<% if @update_comment %>
|
||||
<%= submit_to_remote 'submit_btn', 'Update comment',
|
||||
:url => { :action => 'update_comment',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:html => { :id => "submit_btn" } %>
|
||||
|
||||
<%= link_to_remote 'Cancel',
|
||||
:url => { :action => 'display_violation',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:update => "vId" + @rule_failure_permanent_id.to_s %>
|
||||
<% else %>
|
||||
<%= submit_to_remote 'submit_btn', 'Post comment',
|
||||
:url => { :action => 'create_comment',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:html => { :id => "submit_btn", :disabled => true } %>
|
||||
|
||||
<a onclick="$('reviewForm<%= @rule_failure_permanent_id.to_s -%>').style.display='none'; $('commentAction<%= @rule_failure_permanent_id.to_s -%>').style.display='';" href="#">Cancel</a>
|
||||
<% end %>
|
||||
|
||||
<% form_for :review_comment, @review_comment do |f| %>
|
||||
<%= f.hidden_field :review_id %>
|
||||
<%= f.text_area :review_text, :rows => 8,
|
||||
:id => "commentText" + @rule_failure_permanent_id.to_s,
|
||||
:style => "width:100%",
|
||||
:onKeyUp => "if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';" %>
|
||||
<br/>
|
||||
|
||||
<% if @update_comment %>
|
||||
<%= submit_to_remote 'submit_btn', 'Update comment',
|
||||
:url => { :action => 'update_comment',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:html => { :id => "submit_btn" } %>
|
||||
|
||||
<%= link_to_remote 'Cancel',
|
||||
:url => { :action => 'display_violation',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:update => "vId" + @rule_failure_permanent_id.to_s %>
|
||||
<% else %>
|
||||
<%= submit_to_remote 'submit_btn', 'Post comment',
|
||||
:url => { :action => 'create_comment',
|
||||
:rule_failure_permanent_id => @rule_failure_permanent_id },
|
||||
:html => { :id => "submit_btn", :disabled => true } %>
|
||||
|
||||
<a onclick="$('reviewForm<%= @rule_failure_permanent_id.to_s -%>').style.display='none'; $('commentAction<%= @rule_failure_permanent_id.to_s -%>').style.display='';" href="#">Cancel</a>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
@ -1,65 +1,65 @@
|
||||
<div id="review<%= review.id -%>">
|
||||
<div>
|
||||
<b>Review #<%= review.id -%> - <%= h(review.title) -%></b>
|
||||
<br/>
|
||||
<% if review.assignee %>
|
||||
<i>Assigned to <%= h(review.assignee.name) -%></i>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px; margin-left: 20px">
|
||||
<% unless review.review_comments.blank?
|
||||
last_comment = review.review_comments.last
|
||||
review.review_comments.each do |review_comment|
|
||||
%>
|
||||
<table style="width:100%; margin-bottom: 3px">
|
||||
<tr style="border: solid 1px grey; background-color: #F7F7F7">
|
||||
<td style="width:180px; vertical-align:top; padding: 2px 2px 2px 10px; font-weight: bold">
|
||||
<%= image_tag("user.png") -%> <b><%= h(review_comment.user.name) -%></b>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding: 2px 10px 2px 2px; color: grey; text-align: right; font-style: italic">
|
||||
<%= l review_comment.created_at -%>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="border: solid 1px grey;">
|
||||
<td colspan="2" style="padding: 5px;">
|
||||
<% if review_comment == last_comment %>
|
||||
<div id="lastComment<%= review.id -%>">
|
||||
<%= h(review_comment.review_text) -%>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= h(review_comment.review_text) -%>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<%
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<% if current_user %>
|
||||
<div style="text-align: right; padding: 5px">
|
||||
<% if current_user.id == review.review_comments.last.user_id %>
|
||||
<%= image_tag("pencil.png") -%>
|
||||
<%= link_to_remote "Edit my last comment",
|
||||
:url => { :controller => "reviews", :action => "form_comment",
|
||||
:review_id => review.id,
|
||||
:rule_failure_permanent_id => review.rule_failure_permanent_id,
|
||||
:review_text => review.review_comments.last.review_text,
|
||||
:update_comment => "true" },
|
||||
:update => "lastComment" + review.id.to_s,
|
||||
:complete => "$('commentText" + review.id.to_s + "').focus()" -%>
|
||||
|
||||
<% end %>
|
||||
<%= image_tag("pencil.png") -%>
|
||||
<%= link_to_remote "Add a new comment",
|
||||
:url => { :controller => "reviews", :action => "form_comment", :review_id => review.id, :rule_failure_permanent_id => review.rule_failure_permanent_id },
|
||||
:update => "createComment" + review.id.to_s,
|
||||
:complete => "$('commentText" + review.id.to_s + "').focus()" -%>
|
||||
</div>
|
||||
<div id="createComment<%= review.id -%>"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="review<%= review.id -%>">
|
||||
<div>
|
||||
<b>Review #<%= review.id -%> - <%= h(review.title) -%></b>
|
||||
<br/>
|
||||
<% if review.assignee %>
|
||||
<i>Assigned to <%= h(review.assignee.name) -%></i>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px; margin-left: 20px">
|
||||
<% unless review.review_comments.blank?
|
||||
last_comment = review.review_comments.last
|
||||
review.review_comments.each do |review_comment|
|
||||
%>
|
||||
<table style="width:100%; margin-bottom: 3px">
|
||||
<tr style="border: solid 1px grey; background-color: #F7F7F7">
|
||||
<td style="width:180px; vertical-align:top; padding: 2px 2px 2px 10px; font-weight: bold">
|
||||
<%= image_tag("user.png") -%> <b><%= h(review_comment.user.name) -%></b>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding: 2px 10px 2px 2px; color: grey; text-align: right; font-style: italic">
|
||||
<%= l review_comment.created_at -%>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="border: solid 1px grey;">
|
||||
<td colspan="2" style="padding: 5px;">
|
||||
<% if review_comment == last_comment %>
|
||||
<div id="lastComment<%= review.id -%>">
|
||||
<%= h(review_comment.review_text) -%>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= h(review_comment.review_text) -%>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<%
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<% if current_user %>
|
||||
<div style="text-align: right; padding: 5px">
|
||||
<% if current_user.id == review.review_comments.last.user_id %>
|
||||
<%= image_tag("pencil.png") -%>
|
||||
<%= link_to_remote "Edit my last comment",
|
||||
:url => { :controller => "reviews", :action => "form_comment",
|
||||
:review_id => review.id,
|
||||
:rule_failure_permanent_id => review.rule_failure_permanent_id,
|
||||
:review_text => review.review_comments.last.review_text,
|
||||
:update_comment => "true" },
|
||||
:update => "lastComment" + review.id.to_s,
|
||||
:complete => "$('commentText" + review.id.to_s + "').focus()" -%>
|
||||
|
||||
<% end %>
|
||||
<%= image_tag("pencil.png") -%>
|
||||
<%= link_to_remote "Add a new comment",
|
||||
:url => { :controller => "reviews", :action => "form_comment", :review_id => review.id, :rule_failure_permanent_id => review.rule_failure_permanent_id },
|
||||
:update => "createComment" + review.id.to_s,
|
||||
:complete => "$('commentText" + review.id.to_s + "').focus()" -%>
|
||||
</div>
|
||||
<div id="createComment<%= review.id -%>"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
if @violation
|
||||
page.replace "vId" + @violation.permanent_id.to_s, :partial => "resource/violation", :locals => { :violation => @violation }
|
||||
else
|
||||
page.replace_html "reviewForm" + @rule_failure_permanent_id.to_s, :partial => "form_comment"
|
||||
if @violation
|
||||
page.replace "vId" + @violation.permanent_id.to_s, :partial => "resource/violation", :locals => { :violation => @violation }
|
||||
else
|
||||
page.replace_html "reviewForm" + @rule_failure_permanent_id.to_s, :partial => "form_comment"
|
||||
end
|
@ -1,5 +1,5 @@
|
||||
if @violation
|
||||
page.replace "vId" + @violation.permanent_id.to_s, :partial => "resource/violation", :locals => { :violation => @violation }
|
||||
else
|
||||
page.replace_html "reviewForm" + @review.rule_failure_permanent_id.to_s, :partial => "form"
|
||||
if @violation
|
||||
page.replace "vId" + @violation.permanent_id.to_s, :partial => "resource/violation", :locals => { :violation => @violation }
|
||||
else
|
||||
page.replace_html "reviewForm" + @review.rule_failure_permanent_id.to_s, :partial => "form"
|
||||
end
|
@ -1,54 +1,54 @@
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
|
||||
#
|
||||
# Sonar 2.8
|
||||
#
|
||||
class CreateReview < ActiveRecord::Migration
|
||||
|
||||
def self.up
|
||||
create_table 'reviews' do |t|
|
||||
t.column 'created_at', :datetime
|
||||
t.column 'updated_at', :datetime
|
||||
t.column 'user_id', :integer, :null => true
|
||||
t.column 'assignee_id', :integer, :null => true
|
||||
t.column 'title', :string, :null => true, :limit => 500
|
||||
t.column 'review_type', :string, :null => true, :limit => 10
|
||||
t.column 'status', :string, :null => true, :limit => 10
|
||||
t.column 'severity', :string, :null => true, :limit => 10
|
||||
t.column 'rule_failure_permanent_id', :integer, :null => true
|
||||
t.column 'resource_id', :integer, :null => true
|
||||
t.column 'resource_line', :integer, :null => true
|
||||
end
|
||||
|
||||
create_table 'review_comments' do |t|
|
||||
t.column 'created_at', :datetime
|
||||
t.column 'updated_at', :datetime
|
||||
t.column 'review_id', :integer
|
||||
t.column 'user_id', :integer, :null => true
|
||||
t.column 'review_text', :text, :null => true
|
||||
end
|
||||
|
||||
alter_to_big_primary_key('reviews')
|
||||
alter_to_big_primary_key('review_comments')
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# Sonar, entreprise quality control tool.
|
||||
# Copyright (C) 2008-2011 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
|
||||
#
|
||||
|
||||
#
|
||||
# Sonar 2.8
|
||||
#
|
||||
class CreateReview < ActiveRecord::Migration
|
||||
|
||||
def self.up
|
||||
create_table 'reviews' do |t|
|
||||
t.column 'created_at', :datetime
|
||||
t.column 'updated_at', :datetime
|
||||
t.column 'user_id', :integer, :null => true
|
||||
t.column 'assignee_id', :integer, :null => true
|
||||
t.column 'title', :string, :null => true, :limit => 500
|
||||
t.column 'review_type', :string, :null => true, :limit => 10
|
||||
t.column 'status', :string, :null => true, :limit => 10
|
||||
t.column 'severity', :string, :null => true, :limit => 10
|
||||
t.column 'rule_failure_permanent_id', :integer, :null => true
|
||||
t.column 'resource_id', :integer, :null => true
|
||||
t.column 'resource_line', :integer, :null => true
|
||||
end
|
||||
|
||||
create_table 'review_comments' do |t|
|
||||
t.column 'created_at', :datetime
|
||||
t.column 'updated_at', :datetime
|
||||
t.column 'review_id', :integer
|
||||
t.column 'user_id', :integer, :null => true
|
||||
t.column 'review_text', :text, :null => true
|
||||
end
|
||||
|
||||
alter_to_big_primary_key('reviews')
|
||||
alter_to_big_primary_key('review_comments')
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# NOTE: sonar must be built
|
||||
#
|
||||
@ -6,4 +7,3 @@ cd sonar-application/target/
|
||||
unzip sonar-*.zip
|
||||
cd sonar-*
|
||||
bin/macosx-universal-64/sonar.sh console
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user