package se.bjurr.sbcc;
import static com.atlassian.bitbucket.repository.RefChangeType.DELETE;
import static java.util.regex.Pattern.compile;
import static se.bjurr.sbcc.SbccCommon.getBitbucketEmail;
import static se.bjurr.sbcc.SbccCommon.getBitbucketName;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import com.atlassian.applinks.api.ApplicationLinkService;
import com.atlassian.applinks.api.CredentialsRequiredException;
import com.atlassian.bitbucket.auth.AuthenticationContext;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.repository.RefChange;
import com.atlassian.bitbucket.repository.RefChangeType;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.sal.api.net.ResponseException;
import se.bjurr.sbcc.commits.ChangeSetsService;
import se.bjurr.sbcc.data.SbccChangeSet;
import se.bjurr.sbcc.data.SbccRefChangeVerificationResult;
import se.bjurr.sbcc.data.SbccVerificationResult;
import se.bjurr.sbcc.settings.SbccSettings;
public class RefChangeValidator {
private static Logger logger = Logger.getLogger(RefChangeValidator.class.getName());
private final SbccSettings settings;
private final ChangeSetsService changesetsService;
private final AuthenticationContext bitbucketAuthenticationContext;
private final CommitMessageValidator commitMessageValidator;
private final SbccRenderer sbccRenderer;
private final JqlValidator jqlValidator;
private final Repository fromRepository;
public RefChangeValidator(
Repository fromRepository,
Repository toRepository,
SbccSettings settings,
ChangeSetsService changesetsService,
AuthenticationContext bitbucketAuthenticationContext,
SbccRenderer sbccRenderer,
ApplicationLinkService applicationLinkService,
SbccUserAdminService sbccUserAdminService) {
this.fromRepository = fromRepository;
this.settings = settings;
this.changesetsService = changesetsService;
this.bitbucketAuthenticationContext = bitbucketAuthenticationContext;
this.commitMessageValidator =
new CommitMessageValidator(bitbucketAuthenticationContext, sbccUserAdminService);
this.sbccRenderer = sbccRenderer;
this.jqlValidator = new JqlValidator(applicationLinkService, settings, sbccRenderer);
}
public SbccVerificationResult validateRefChanges(Collection<RefChange> refChanges)
throws IOException, CredentialsRequiredException, ResponseException, ExecutionException {
final SbccVerificationResult refChangeVerificationResult = new SbccVerificationResult();
for (final RefChange refChange : refChanges) {
validateRefChange(
refChangeVerificationResult,
refChange.getType(),
refChange.getRef().getId(),
refChange.getFromHash(),
refChange.getToHash());
}
return refChangeVerificationResult;
}
public void validateRefChange(
final SbccVerificationResult refChangeVerificationResult,
RefChangeType refChangeType,
String refId,
String fromHash,
String toHash)
throws IOException, CredentialsRequiredException, ResponseException, ExecutionException {
logger.fine(
getBitbucketName(bitbucketAuthenticationContext)
+ " "
+ getBitbucketEmail(bitbucketAuthenticationContext)
+ "> RefChange "
+ fromHash
+ " "
+ refId
+ " "
+ toHash
+ " "
+ refChangeType);
if (compile(settings.getBranches().or(".*")).matcher(refId).find()) {
if (refChangeType != DELETE) {
List<SbccChangeSet> refChangeSets =
changesetsService.getNewChangeSets(
settings, fromRepository, refId, refChangeType, fromHash, toHash);
validateRefChange(refChangeVerificationResult, refId, fromHash, toHash, refChangeSets);
}
}
}
public void validateRefChange(
SbccVerificationResult refChangeVerificationResults, PullRequest pullRequest)
throws IOException, CredentialsRequiredException, ResponseException, ExecutionException {
String refId = pullRequest.getFromRef().getId();
String fromHash = pullRequest.getFromRef().getLatestCommit();
String toHash = pullRequest.getToRef().getLatestCommit();
List<SbccChangeSet> refChangeSets = changesetsService.getNewChangeSets(settings, pullRequest);
validateRefChange(refChangeVerificationResults, refId, fromHash, toHash, refChangeSets);
}
private void validateRefChange(
final SbccVerificationResult refChangeVerificationResult,
String refId,
String fromHash,
String toHash,
List<SbccChangeSet> refChangeSets)
throws IOException, CredentialsRequiredException, ResponseException, ExecutionException {
SbccRefChangeVerificationResult refChangeVerificationResults =
validateRefChange(refChangeSets, settings, refId, fromHash, toHash);
if (refChangeVerificationResults.hasReportables()) {
refChangeVerificationResult.add(refChangeVerificationResults);
}
}
private SbccRefChangeVerificationResult validateRefChange(
List<SbccChangeSet> sbccChangeSets,
SbccSettings settings,
String refId,
String fromHash,
String toHash)
throws IOException, CredentialsRequiredException, ResponseException, ExecutionException {
final SbccRefChangeVerificationResult refChangeVerificationResult =
new SbccRefChangeVerificationResult(refId, fromHash, toHash);
refChangeVerificationResult.setBranchValidationResult(validateBranchName(refId));
for (final SbccChangeSet sbccChangeSet : sbccChangeSets) {
sbccRenderer.setSbccChangeSet(sbccChangeSet);
logger.fine(
getBitbucketName(bitbucketAuthenticationContext)
+ " "
+ getBitbucketEmail(bitbucketAuthenticationContext)
+ "> ChangeSet "
+ sbccChangeSet.getId()
+ " "
+ sbccChangeSet.getMessage()
+ " "
+ sbccChangeSet.getCommitter().getEmailAddress()
+ " "
+ sbccChangeSet.getCommitter().getName());
refChangeVerificationResult.setGroupsResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForGroups(settings, sbccChangeSet));
refChangeVerificationResult.addAuthorEmailValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForAuthorEmail(
settings, sbccChangeSet, sbccRenderer));
refChangeVerificationResult.addCommitterEmailValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForCommitterEmail(
settings, sbccChangeSet, sbccRenderer));
refChangeVerificationResult.addAuthorNameValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForAuthorName(settings, sbccChangeSet));
refChangeVerificationResult.addCommitterNameValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForCommitterName(settings, sbccChangeSet));
refChangeVerificationResult.addAuthorEmailInBitbucketValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForAuthorEmailInBitbucket(
settings, sbccChangeSet));
refChangeVerificationResult.addAuthorNameInBitbucketValidationResult(
sbccChangeSet,
commitMessageValidator.validateChangeSetForAuthorNameInBitbucket(
settings, sbccChangeSet));
refChangeVerificationResult.setFailingJql(
sbccChangeSet, jqlValidator.validateJql(sbccChangeSet));
sbccRenderer.setSbccChangeSet(null);
}
return refChangeVerificationResult;
}
private boolean validateBranchName(String branchName) {
return compile(settings.getBranchRejectionRegexp().or(".*")).matcher(branchName).find();
}
}