Coverage Report - liquibase.changelog.visitor.ValidatingVisitor
 
Classes in this File Line Coverage Branch Coverage Complexity
ValidatingVisitor
63%
41/65
50%
19/38
2.714
 
 1  
 package liquibase.changelog.visitor;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.HashSet;
 5  
 import java.util.List;
 6  
 import java.util.Set;
 7  
 
 8  
 import liquibase.change.Change;
 9  
 import liquibase.changelog.ChangeSet;
 10  
 import liquibase.changelog.DatabaseChangeLog;
 11  
 import liquibase.changelog.RanChangeSet;
 12  
 import liquibase.database.Database;
 13  
 import liquibase.exception.DatabaseException;
 14  
 import liquibase.exception.PreconditionErrorException;
 15  
 import liquibase.exception.PreconditionFailedException;
 16  
 import liquibase.exception.SetupException;
 17  
 import liquibase.exception.ValidationErrors;
 18  
 import liquibase.exception.Warnings;
 19  
 import liquibase.logging.LogFactory;
 20  
 import liquibase.precondition.core.ErrorPrecondition;
 21  
 import liquibase.precondition.core.FailedPrecondition;
 22  
 import liquibase.precondition.core.PreconditionContainer;
 23  
 import liquibase.util.StringUtils;
 24  
 
 25  
 public class ValidatingVisitor implements ChangeSetVisitor {
 26  
 
 27  5
     private List<ChangeSet> invalidMD5Sums = new ArrayList<ChangeSet>();
 28  5
     private List<FailedPrecondition> failedPreconditions = new ArrayList<FailedPrecondition>();
 29  5
     private List<ErrorPrecondition> errorPreconditions = new ArrayList<ErrorPrecondition>();
 30  5
     private Set<ChangeSet> duplicateChangeSets = new HashSet<ChangeSet>();
 31  5
     private List<SetupException> setupExceptions = new ArrayList<SetupException>();
 32  5
     private List<Throwable> changeValidationExceptions = new ArrayList<Throwable>();
 33  5
     private ValidationErrors validationErrors = new ValidationErrors();
 34  5
     private Warnings warnings = new Warnings();
 35  
 
 36  5
     private Set<String> seenChangeSets = new HashSet<String>();
 37  
 
 38  
     private List<RanChangeSet> ranChangeSets;
 39  
     private Database database;
 40  
 
 41  5
     public ValidatingVisitor(List<RanChangeSet> ranChangeSets) {
 42  5
         this.ranChangeSets = ranChangeSets;
 43  5
     }
 44  
 
 45  
     public void validate(Database database, DatabaseChangeLog changeLog) {
 46  2
         this.database = database;
 47  2
         PreconditionContainer preconditions = changeLog.getPreconditions();
 48  
         try {
 49  2
             if (preconditions == null) {
 50  
                 return;
 51  
             }
 52  2
             preconditions.check(database, changeLog, null);
 53  0
         } catch (PreconditionFailedException e) {
 54  0
             LogFactory.getLogger().debug("Precondition Failed: " + e.getMessage(), e);
 55  0
             failedPreconditions.addAll(e.getFailedPreconditions());
 56  0
         } catch (PreconditionErrorException e) {
 57  0
             LogFactory.getLogger().debug("Precondition Error: " + e.getMessage(), e);
 58  0
             errorPreconditions.addAll(e.getErrorPreconditions());
 59  
         } finally {
 60  0
             try {
 61  2
                 database.rollback();
 62  0
             } catch (DatabaseException e) {
 63  0
                 LogFactory.getLogger().warning("Error rolling back after precondition check", e);
 64  2
             }
 65  0
         }
 66  2
     }
 67  
 
 68  
     @Override
 69  
     public Direction getDirection() {
 70  2
         return ChangeSetVisitor.Direction.FORWARD;
 71  
     }
 72  
 
 73  
     @Override
 74  
     public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database) {
 75  7
         for (Change change : changeSet.getChanges()) {
 76  
             try {
 77  5
                 change.init();
 78  1
             } catch (SetupException se) {
 79  1
                 setupExceptions.add(se);
 80  4
             }
 81  
 
 82  5
             warnings.addAll(change.warn(database));
 83  
 
 84  
             try {
 85  5
                 ValidationErrors foundErrors = change.validate(database);
 86  5
                 if (foundErrors != null && foundErrors.hasErrors()) {
 87  1
                     if (changeSet.getOnValidationFail().equals(ChangeSet.ValidationFailOption.MARK_RAN)) {
 88  0
                         LogFactory.getLogger().info(
 89  
                                 "Skipping changeSet " + changeSet + " due to validation error(s): "
 90  
                                         + StringUtils.join(foundErrors.getErrorMessages(), ", "));
 91  0
                         changeSet.setValidationFailed(true);
 92  
                     } else {
 93  1
                         validationErrors.addAll(foundErrors, changeSet);
 94  
                     }
 95  
                 }
 96  0
             } catch (Throwable e) {
 97  0
                 changeValidationExceptions.add(e);
 98  10
             }
 99  
         }
 100  
 
 101  7
         for (RanChangeSet ranChangeSet : ranChangeSets) {
 102  0
             if (ranChangeSet.getId().equalsIgnoreCase(changeSet.getId())
 103  
                     && ranChangeSet.getAuthor().equalsIgnoreCase(changeSet.getAuthor())
 104  
                     && ranChangeSet.getChangeLog().equalsIgnoreCase(changeSet.getFilePath())) {
 105  0
                 if (!changeSet.isCheckSumValid(ranChangeSet.getLastCheckSum())) {
 106  0
                     if (!changeSet.shouldRunOnChange()) {
 107  0
                         invalidMD5Sums.add(changeSet);
 108  
                     }
 109  
                 }
 110  
             }
 111  
         }
 112  
 
 113  7
         String changeSetString = changeSet.toString(false);
 114  7
         if (seenChangeSets.contains(changeSetString)) {
 115  1
             duplicateChangeSets.add(changeSet);
 116  
         } else {
 117  6
             seenChangeSets.add(changeSetString);
 118  
         }
 119  7
     }
 120  
 
 121  
     public List<ChangeSet> getInvalidMD5Sums() {
 122  0
         return invalidMD5Sums;
 123  
     }
 124  
 
 125  
     public List<FailedPrecondition> getFailedPreconditions() {
 126  0
         return failedPreconditions;
 127  
     }
 128  
 
 129  
     public List<ErrorPrecondition> getErrorPreconditions() {
 130  0
         return errorPreconditions;
 131  
     }
 132  
 
 133  
     public Set<ChangeSet> getDuplicateChangeSets() {
 134  1
         return duplicateChangeSets;
 135  
     }
 136  
 
 137  
     public List<SetupException> getSetupExceptions() {
 138  2
         return setupExceptions;
 139  
     }
 140  
 
 141  
     public List<Throwable> getChangeValidationExceptions() {
 142  0
         return changeValidationExceptions;
 143  
     }
 144  
 
 145  
     public ValidationErrors getValidationErrors() {
 146  0
         return validationErrors;
 147  
     }
 148  
 
 149  
     public Warnings getWarnings() {
 150  2
         return warnings;
 151  
     }
 152  
 
 153  
     public boolean validationPassed() {
 154  5
         return invalidMD5Sums.size() == 0 && failedPreconditions.size() == 0 && errorPreconditions.size() == 0
 155  
                 && duplicateChangeSets.size() == 0 && changeValidationExceptions.size() == 0
 156  
                 && setupExceptions.size() == 0 && !validationErrors.hasErrors();
 157  
     }
 158  
 
 159  
     public Database getDatabase() {
 160  0
         return database;
 161  
     }
 162  
 }