diff --git a/source/java/org/alfresco/util/schemacomp/DbObjectVisitor.java b/source/java/org/alfresco/util/schemacomp/DbObjectVisitor.java new file mode 100644 index 0000000000..6f9e946724 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/DbObjectVisitor.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp; + +import org.alfresco.util.schemacomp.model.Column; +import org.alfresco.util.schemacomp.model.DbObject; +import org.alfresco.util.schemacomp.model.ForeignKey; +import org.alfresco.util.schemacomp.model.Index; +import org.alfresco.util.schemacomp.model.PrimaryKey; +import org.alfresco.util.schemacomp.model.Schema; +import org.alfresco.util.schemacomp.model.Sequence; +import org.alfresco.util.schemacomp.model.Table; + +/** + * Defines a visitor that can operate on a DbObject. + * @author Matt Ward + */ +public interface DbObjectVisitor +{ + void visit(DbObject dbObject); +// void visit(Column column); +// void visit(ForeignKey fk); +// void visit(Index index); +// void visit(PrimaryKey pk); +// void visit(Schema schema); +// void visit(Sequence sequence); +// void visit(Table table); +} diff --git a/source/java/org/alfresco/util/schemacomp/DefaultComparisonUtilsTest.java b/source/java/org/alfresco/util/schemacomp/DefaultComparisonUtilsTest.java index 00beeb8d35..f4cee1bd20 100644 --- a/source/java/org/alfresco/util/schemacomp/DefaultComparisonUtilsTest.java +++ b/source/java/org/alfresco/util/schemacomp/DefaultComparisonUtilsTest.java @@ -57,7 +57,7 @@ public class DefaultComparisonUtilsTest public void setUp() { comparisonUtils = new DefaultComparisonUtils(); - ctx = new DiffContext(dialect, differences); + ctx = new DiffContext(dialect, differences, new ArrayList()); } @Test diff --git a/source/java/org/alfresco/util/schemacomp/DiffContext.java b/source/java/org/alfresco/util/schemacomp/DiffContext.java index 438199014d..91f5c201b4 100644 --- a/source/java/org/alfresco/util/schemacomp/DiffContext.java +++ b/source/java/org/alfresco/util/schemacomp/DiffContext.java @@ -18,6 +18,8 @@ */ package org.alfresco.util.schemacomp; +import java.util.List; + import org.hibernate.dialect.Dialect; /** @@ -31,16 +33,17 @@ public class DiffContext { private final Dialect dialect; private final Differences differences; - + private final List validationResults; /** * @param dialect * @param differences */ - public DiffContext(Dialect dialect, Differences differences) + public DiffContext(Dialect dialect, Differences differences, List validationResults) { this.dialect = dialect; this.differences = differences; + this.validationResults = validationResults; } /** @@ -58,4 +61,14 @@ public class DiffContext { return this.differences; } + + /** + * @return the validationResults + */ + public List getValidationResults() + { + return this.validationResults; + } + + } diff --git a/source/java/org/alfresco/util/schemacomp/SchemaCompPackagetTestSuite.java b/source/java/org/alfresco/util/schemacomp/SchemaCompPackagetTestSuite.java new file mode 100644 index 0000000000..ef97b95001 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/SchemaCompPackagetTestSuite.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp; + +import org.alfresco.util.schemacomp.model.ModelTestSuite; +import org.alfresco.util.schemacomp.validator.ValidatorTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite running all the tests in the schemacomp package - and subpackages. + * @author Matt Ward + */ +@RunWith(Suite.class) +@Suite.SuiteClasses( +{ + ModelTestSuite.class, + ValidatorTestSuite.class, + SchemaCompTestSuite.class +}) +public class SchemaCompPackagetTestSuite +{ +} diff --git a/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java b/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java index f2f5bf7a8b..aedff5496c 100644 --- a/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java +++ b/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java @@ -30,7 +30,8 @@ import org.junit.runners.Suite; @Suite.SuiteClasses( { DefaultComparisonUtilsTest.class, - SchemaComparatorTest.class + SchemaComparatorTest.class, + ValidatingVisitorTest.class }) public class SchemaCompTestSuite { diff --git a/source/java/org/alfresco/util/schemacomp/SchemaComparator.java b/source/java/org/alfresco/util/schemacomp/SchemaComparator.java index d20cfbd49e..c3907dcec8 100644 --- a/source/java/org/alfresco/util/schemacomp/SchemaComparator.java +++ b/source/java/org/alfresco/util/schemacomp/SchemaComparator.java @@ -18,6 +18,9 @@ */ package org.alfresco.util.schemacomp; +import java.util.ArrayList; +import java.util.List; + import org.alfresco.util.schemacomp.Result.Strength; import org.alfresco.util.schemacomp.model.Schema; import org.hibernate.dialect.Dialect; @@ -44,22 +47,51 @@ public class SchemaComparator { this.leftSchema = left; this.rightSchema = right; - this.ctx = new DiffContext(dialect, new Differences()); + this.ctx = new DiffContext(dialect, new Differences(), new ArrayList()); } - public void compare() + public void validateAndCompare() + { + validate(); + compare(); + } + + + /** + * Check the left schema against the right schema and record any differences. + */ + private void compare() { - // Check the left schema against the right schema and record any differences. leftSchema.diff(rightSchema, ctx, Strength.ERROR); } + /** + * Validate both schemas. + */ + private void validate() + { + ValidatingVisitor validatingVisitor = new ValidatingVisitor(ctx); + leftSchema.accept(validatingVisitor); + rightSchema.accept(validatingVisitor); + } + + /** * @return the differences */ public Differences getDifferences() { - return this.ctx.getDifferences(); + return ctx.getDifferences(); } + + + /** + * @return the validation results. + */ + public List getValidationResults() + { + return ctx.getValidationResults(); + } } diff --git a/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java b/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java index 006bee5e7e..8d95ea0cd3 100644 --- a/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java +++ b/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java @@ -85,10 +85,11 @@ public class SchemaComparatorTest comparator = new SchemaComparator(left, right, dialect); - comparator.compare(); + comparator.validateAndCompare(); + + dumpDiffs(comparator.getDifferences(), false); + dumpValidation(comparator.getValidationResults()); - dumpDiffs(comparator.getDifferences(), true); - Iterator it = comparator.getDifferences().iterator(); assertHasDifference("left_schema", "left_schema", "right_schema", it.next()); // schema names @@ -136,6 +137,16 @@ public class SchemaComparatorTest } + private void dumpValidation(List validationResults) + { + System.out.println("Validation Results (" + validationResults.size() + ")"); + for (ValidationResult r : validationResults) + { + System.out.println(r); + } + } + + @Test public void canReportWarnings() { @@ -149,10 +160,11 @@ public class SchemaComparatorTest comparator = new SchemaComparator(left, right, dialect); - comparator.compare(); + comparator.validateAndCompare(); dumpDiffs(comparator.getDifferences(), true); - + dumpValidation(comparator.getValidationResults()); + Iterator it = comparator.getDifferences().iterator(); assertHasDifference("left_schema", "left_schema", "right_schema", it.next()); assertNoDifference("left_schema.tbl_example", "tbl_example", it.next()); @@ -233,9 +245,7 @@ public class SchemaComparatorTest assertEquals(value, result.getRight()); } - /** - * @param differences - */ + private void dumpDiffs(Differences differences, boolean showNonDifferences) { System.out.println("Differences (" + differences.size() + ")"); diff --git a/source/java/org/alfresco/util/schemacomp/ValidatingVisitor.java b/source/java/org/alfresco/util/schemacomp/ValidatingVisitor.java new file mode 100644 index 0000000000..7f2e697306 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/ValidatingVisitor.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp; + +import org.alfresco.util.schemacomp.model.DbObject; +import org.alfresco.util.schemacomp.model.Index; +import org.alfresco.util.schemacomp.validator.DbValidator; +import org.alfresco.util.schemacomp.validator.NameValidator; +import org.alfresco.util.schemacomp.validator.NullValidator; + +/** + * Invokes the correct validator for a given DbObject. + * + * @author Matt Ward + */ +public class ValidatingVisitor implements DbObjectVisitor +{ + private DiffContext ctx; + protected NameValidator indexNameValidator = new NameValidator(); + protected NullValidator nullValidator = new NullValidator(); + + public ValidatingVisitor(DiffContext ctx) + { + this.ctx = ctx; + } + + + protected DbValidator getValidatorFor(Class c) + { + if (c.equals(Index.class)) + { + return indexNameValidator; + } + else + { + return nullValidator; + } + } + + @Override + public void visit(DbObject dbObject) + { + DbValidator validator = getValidatorFor(dbObject.getClass()); + validator.validate(dbObject, ctx); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/ValidatingVisitorTest.java b/source/java/org/alfresco/util/schemacomp/ValidatingVisitorTest.java new file mode 100644 index 0000000000..815662c53c --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/ValidatingVisitorTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp; + + +import java.util.ArrayList; +import java.util.Collections; + +import javax.faces.validator.Validator; + +import org.alfresco.util.schemacomp.model.Column; +import org.alfresco.util.schemacomp.model.ForeignKey; +import org.alfresco.util.schemacomp.model.Index; +import org.alfresco.util.schemacomp.model.PrimaryKey; +import org.alfresco.util.schemacomp.model.Schema; +import org.alfresco.util.schemacomp.model.Sequence; +import org.alfresco.util.schemacomp.model.Table; +import org.alfresco.util.schemacomp.validator.DbValidator; +import org.alfresco.util.schemacomp.validator.NameValidator; +import org.alfresco.util.schemacomp.validator.NullValidator; +import org.hibernate.dialect.MySQL5InnoDBDialect; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.validateMockitoUsage; + +/** + * TODO: comment me! + * @author Matt Ward + */ +public class ValidatingVisitorTest +{ + private DiffContext ctx; + private ValidatingVisitor visitor; + + @Before + public void setUp() throws Exception + { + ctx = new DiffContext(new MySQL5InnoDBDialect(), new Differences(), new ArrayList()); + visitor = new ValidatingVisitor(ctx); + } + + @Test + public void canGetCorrectValidator() + { + // Get references to the validator instances to test for + DbValidator nullValidator = visitor.nullValidator; + DbValidator nameValidator = visitor.indexNameValidator; + + assertSame(nullValidator, visitor.getValidatorFor(Column.class)); + assertSame(nullValidator, visitor.getValidatorFor(ForeignKey.class)); + assertSame(nameValidator, visitor.getValidatorFor(Index.class)); + assertSame(nullValidator, visitor.getValidatorFor(PrimaryKey.class)); + assertSame(nullValidator, visitor.getValidatorFor(Schema.class)); + assertSame(nullValidator, visitor.getValidatorFor(Sequence.class)); + assertSame(nullValidator, visitor.getValidatorFor(Table.class)); + } + + @Test + public void canValidate() + { + visitor.indexNameValidator = Mockito.mock(NameValidator.class); + Index index = new Index("index_name", new ArrayList()); + + visitor.visit(index); + + Mockito.verify(visitor.indexNameValidator).validate(index, ctx); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/ValidationResult.java b/source/java/org/alfresco/util/schemacomp/ValidationResult.java new file mode 100644 index 0000000000..fcfdb85b4e --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/ValidationResult.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp; + +/** + * TODO: comment me! + * @author Matt Ward + */ +public class ValidationResult +{ + private Object value; + + /** + * @param value + */ + public ValidationResult(Object value) + { + this.value = value; + } + + /** + * @return the value + */ + public Object getValue() + { + return this.value; + } +} diff --git a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java index 1e49070a5e..cb64ebcefb 100644 --- a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java +++ b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java @@ -18,7 +18,12 @@ */ package org.alfresco.util.schemacomp.model; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import org.alfresco.util.schemacomp.ComparisonUtils; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; diff --git a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java index fda45161a2..d9df932220 100644 --- a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java @@ -23,10 +23,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.inOrder; +import java.util.ArrayList; + +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; import org.alfresco.util.schemacomp.Result.Where; +import org.alfresco.util.schemacomp.ValidationResult; import org.hibernate.dialect.Dialect; import org.junit.Before; import org.junit.Test; @@ -55,7 +59,7 @@ public class AbstractDbObjectTest public void setUp() throws Exception { dbObject = new ConcreteDbObject("the_object"); - ctx = new DiffContext(dialect, differences); + ctx = new DiffContext(dialect, differences, new ArrayList()); } @Test @@ -116,5 +120,10 @@ public class AbstractDbObjectTest Differences differences = ctx.getDifferences(); differences.add(Where.IN_BOTH_BUT_DIFFERENCE, "left", "right"); } + + @Override + public void accept(DbObjectVisitor visitor) + { + } } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Column.java b/source/java/org/alfresco/util/schemacomp/model/Column.java index 7f7b747678..3ef9a8e67a 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Column.java +++ b/source/java/org/alfresco/util/schemacomp/model/Column.java @@ -18,6 +18,7 @@ */ package org.alfresco.util.schemacomp.model; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -113,4 +114,10 @@ public class Column extends AbstractDbObject comparisonUtils.compareSimple(type, rightColumn.type, ctx); comparisonUtils.compareSimple(nullable, rightColumn.nullable, ctx); } + + @Override + public void accept(DbObjectVisitor visitor) + { + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/ColumnTest.java b/source/java/org/alfresco/util/schemacomp/model/ColumnTest.java index 594277ff2e..d6070c731c 100644 --- a/source/java/org/alfresco/util/schemacomp/model/ColumnTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/ColumnTest.java @@ -20,6 +20,8 @@ package org.alfresco.util.schemacomp.model; import org.junit.Before; +import org.junit.Test; +import static org.mockito.Mockito.*; /** * Tests for the Column class. @@ -56,5 +58,13 @@ public class ColumnTest extends DbObjectTestBase inOrder.verify(comparisonUtils).compareSimple(thisColumn.getType(), thatColumn.getType(), ctx); inOrder.verify(comparisonUtils).compareSimple(thisColumn.isNullable(), thatColumn.isNullable(), ctx); } + + @Test + public void acceptVisitor() + { + thisColumn.accept(visitor); + + verify(visitor).visit(thisColumn); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/DbObject.java b/source/java/org/alfresco/util/schemacomp/model/DbObject.java index 5d6d5e9450..d3bc5c2499 100644 --- a/source/java/org/alfresco/util/schemacomp/model/DbObject.java +++ b/source/java/org/alfresco/util/schemacomp/model/DbObject.java @@ -18,6 +18,7 @@ */ package org.alfresco.util.schemacomp.model; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -60,4 +61,13 @@ public interface DbObject * @param ctx The DiffContext */ void diff(DbObject right, DiffContext ctx, Strength strength); + + + /** + * Allows a visitor to be invoked against this DbObject. Implementations should ensure that child + * objects are visited first (by calling accept on them) before invoking the visitor on itself. + * + * @param visitor + */ + void accept(DbObjectVisitor visitor); } diff --git a/source/java/org/alfresco/util/schemacomp/model/DbObjectTestBase.java b/source/java/org/alfresco/util/schemacomp/model/DbObjectTestBase.java index 1a53d4a01a..9fba87cb37 100644 --- a/source/java/org/alfresco/util/schemacomp/model/DbObjectTestBase.java +++ b/source/java/org/alfresco/util/schemacomp/model/DbObjectTestBase.java @@ -18,15 +18,17 @@ */ package org.alfresco.util.schemacomp.model; -import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.*; import java.util.ArrayList; import java.util.List; import org.alfresco.util.schemacomp.ComparisonUtils; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; +import org.alfresco.util.schemacomp.ValidationResult; import org.hibernate.dialect.Dialect; import org.junit.Before; import org.junit.Test; @@ -50,14 +52,15 @@ public abstract class DbObjectTestBase protected InOrder inOrder; protected abstract T getThisObject(); protected abstract T getThatObject(); + protected @Mock DbObjectVisitor visitor; @Before - public void baseSetUp() + public final void baseSetUp() { // Check that the correct calls happened in the correct order. List mocks = getMocksUsedInDiff(); inOrder = inOrder(mocks.toArray()); - ctx = new DiffContext(dialect, differences); + ctx = new DiffContext(dialect, differences, new ArrayList()); } diff --git a/source/java/org/alfresco/util/schemacomp/model/ForeignKey.java b/source/java/org/alfresco/util/schemacomp/model/ForeignKey.java index 853c7126be..a1140b5fe3 100644 --- a/source/java/org/alfresco/util/schemacomp/model/ForeignKey.java +++ b/source/java/org/alfresco/util/schemacomp/model/ForeignKey.java @@ -18,6 +18,7 @@ */ package org.alfresco.util.schemacomp.model; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -145,5 +146,11 @@ public class ForeignKey extends AbstractDbObject comparisonUtils.compareSimple(localColumn, rightFK.localColumn, ctx); comparisonUtils.compareSimple(targetTable, rightFK.targetTable, ctx); comparisonUtils.compareSimple(targetColumn, rightFK.targetColumn, ctx); + } + + @Override + public void accept(DbObjectVisitor visitor) + { + visitor.visit(this); } } diff --git a/source/java/org/alfresco/util/schemacomp/model/ForeignKeyTest.java b/source/java/org/alfresco/util/schemacomp/model/ForeignKeyTest.java index 2cd71bb344..911785f628 100644 --- a/source/java/org/alfresco/util/schemacomp/model/ForeignKeyTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/ForeignKeyTest.java @@ -19,7 +19,10 @@ package org.alfresco.util.schemacomp.model; +import static org.mockito.Mockito.verify; + import org.junit.Before; +import org.junit.Test; /** * Tests for the ForeignKey class. @@ -60,4 +63,12 @@ public class ForeignKeyTest extends DbObjectTestBase inOrder.verify(comparisonUtils).compareSimple(thisFK.getTargetTable(), thatFK.getTargetTable(), ctx); inOrder.verify(comparisonUtils).compareSimple(thisFK.getTargetColumn(), thatFK.getTargetColumn(), ctx); } + + @Test + public void acceptVisitor() + { + thisFK.accept(visitor); + + verify(visitor).visit(thisFK); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Index.java b/source/java/org/alfresco/util/schemacomp/model/Index.java index 4e428b3032..8730506a44 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Index.java +++ b/source/java/org/alfresco/util/schemacomp/model/Index.java @@ -20,6 +20,7 @@ package org.alfresco.util.schemacomp.model; import java.util.List; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -115,4 +116,17 @@ public class Index extends AbstractDbObject Index rightIndex = (Index) right; comparisonUtils.compareSimpleCollections(columnNames, rightIndex.columnNames, ctx, strength); } + + + public void validate(DiffContext ctx) + { + System.out.println("INVALID INDEX, name is not allowed:" + getName()); + } + + + @Override + public void accept(DbObjectVisitor visitor) + { + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/IndexTest.java b/source/java/org/alfresco/util/schemacomp/model/IndexTest.java index 7515be8549..0d56c15029 100644 --- a/source/java/org/alfresco/util/schemacomp/model/IndexTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/IndexTest.java @@ -24,6 +24,7 @@ import org.alfresco.util.schemacomp.Result.Strength; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; +import static org.mockito.Mockito.verify; /** @@ -90,4 +91,13 @@ public class IndexTest extends DbObjectTestBase assertFalse("Indexes should be identified different (different name & different columns)", thisIndex.sameAs(new Index("different_name", Arrays.asList("node_ref", "url")))); } + + + @Test + public void acceptVisitor() + { + thisIndex.accept(visitor); + + verify(visitor).visit(thisIndex); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/PrimaryKey.java b/source/java/org/alfresco/util/schemacomp/model/PrimaryKey.java index 6b4710418b..07637401ef 100644 --- a/source/java/org/alfresco/util/schemacomp/model/PrimaryKey.java +++ b/source/java/org/alfresco/util/schemacomp/model/PrimaryKey.java @@ -20,6 +20,7 @@ package org.alfresco.util.schemacomp.model; import java.util.List; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -92,4 +93,10 @@ public class PrimaryKey extends AbstractDbObject PrimaryKey rightPK = (PrimaryKey) right; comparisonUtils.compareSimpleCollections(columnNames, rightPK.columnNames, ctx, strength); } + + @Override + public void accept(DbObjectVisitor visitor) + { + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/PrimaryKeyTest.java b/source/java/org/alfresco/util/schemacomp/model/PrimaryKeyTest.java index 0408f0d215..232a412c05 100644 --- a/source/java/org/alfresco/util/schemacomp/model/PrimaryKeyTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/PrimaryKeyTest.java @@ -18,10 +18,13 @@ */ package org.alfresco.util.schemacomp.model; +import static org.mockito.Mockito.verify; + import java.util.Arrays; import org.alfresco.util.schemacomp.Result.Strength; import org.junit.Before; +import org.junit.Test; /** @@ -63,4 +66,11 @@ public class PrimaryKeyTest extends DbObjectTestBase Strength.ERROR); } + @Test + public void acceptVisitor() + { + thisPK.accept(visitor); + + verify(visitor).visit(thisPK); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Schema.java b/source/java/org/alfresco/util/schemacomp/model/Schema.java index 441cbec83d..5c886852ce 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Schema.java +++ b/source/java/org/alfresco/util/schemacomp/model/Schema.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -97,4 +98,16 @@ public class Schema extends AbstractDbObject implements Iterable Schema rightSchema = (Schema) right; comparisonUtils.compareCollections(objects, rightSchema.objects, ctx); } + + + @Override + public void accept(DbObjectVisitor visitor) + { + for (DbObject child : objects) + { + child.accept(visitor); + } + + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/SchemaTest.java b/source/java/org/alfresco/util/schemacomp/model/SchemaTest.java index cefe30d417..4089a1dfe8 100644 --- a/source/java/org/alfresco/util/schemacomp/model/SchemaTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/SchemaTest.java @@ -18,8 +18,12 @@ */ package org.alfresco.util.schemacomp.model; +import static org.mockito.Mockito.verify; + import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; /** @@ -59,4 +63,22 @@ public class SchemaTest extends DbObjectTestBase // the DbObjects held in the other schema with its own DbObjects. inOrder.verify(comparisonUtils).compareCollections(left.objects, right.objects, ctx); } + + @Test + public void acceptVisitor() + { + DbObject dbo1 = Mockito.mock(DbObject.class); + left.add(dbo1); + DbObject dbo2 = Mockito.mock(DbObject.class); + left.add(dbo2); + DbObject dbo3 = Mockito.mock(DbObject.class); + left.add(dbo3); + + left.accept(visitor); + + verify(dbo1).accept(visitor); + verify(dbo2).accept(visitor); + verify(dbo3).accept(visitor); + verify(visitor).visit(left); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Sequence.java b/source/java/org/alfresco/util/schemacomp/model/Sequence.java index c6c0a61b3a..dbc6822c11 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Sequence.java +++ b/source/java/org/alfresco/util/schemacomp/model/Sequence.java @@ -18,6 +18,8 @@ */ package org.alfresco.util.schemacomp.model; +import org.alfresco.util.schemacomp.DbObjectVisitor; + /** * Represents a database sequence. @@ -26,5 +28,14 @@ package org.alfresco.util.schemacomp.model; */ public class Sequence extends AbstractDbObject { - // No subclass specific data/behaviour at present. + public Sequence(String name) + { + super(name); + } + + @Override + public void accept(DbObjectVisitor visitor) + { + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/SequenceTest.java b/source/java/org/alfresco/util/schemacomp/model/SequenceTest.java index a53ef1844b..1c1708518d 100644 --- a/source/java/org/alfresco/util/schemacomp/model/SequenceTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/SequenceTest.java @@ -18,6 +18,9 @@ */ package org.alfresco.util.schemacomp.model; +import static org.mockito.Mockito.verify; + +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -25,12 +28,41 @@ import org.junit.Test; * Tests for the Sequence class. * @author Matt Ward */ -public class SequenceTest +public class SequenceTest extends DbObjectTestBase { - @Ignore - @Test - public void noTestsRequired() + private Sequence thisSequence; + private Sequence thatSequence; + + @Before + public void setUp() { - // No functionality over and above AbstractDbObject at present. + thisSequence = new Sequence("this_sequence"); + thatSequence = new Sequence("that_sequence"); + } + + @Test + public void acceptVisitor() + { + thisSequence.accept(visitor); + + verify(visitor).visit(thisSequence); + } + + @Override + protected Sequence getThisObject() + { + return thisSequence; + } + + @Override + protected Sequence getThatObject() + { + return thatSequence; + } + + @Override + protected void doDiffTests() + { + // Nothing extra to diff. } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Table.java b/source/java/org/alfresco/util/schemacomp/model/Table.java index 0a2a5df564..9566dfdee9 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Table.java +++ b/source/java/org/alfresco/util/schemacomp/model/Table.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Differences; import org.alfresco.util.schemacomp.Result.Strength; @@ -185,4 +186,27 @@ public class Table extends AbstractDbObject comparisonUtils.compareCollections(foreignKeys, rightTable.foreignKeys, ctx); comparisonUtils.compareCollections(indexes, rightTable.indexes, ctx); } + + + private List getChildren() + { + List children = new ArrayList(); + children.addAll(columns); + children.add(primaryKey); + children.addAll(foreignKeys); + children.addAll(indexes); + return children; + } + + + @Override + public void accept(DbObjectVisitor visitor) + { + for (DbObject child : getChildren()) + { + child.accept(visitor); + } + + visitor.visit(this); + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/TableTest.java b/source/java/org/alfresco/util/schemacomp/model/TableTest.java index 83ff6e0bec..d0fec058dc 100644 --- a/source/java/org/alfresco/util/schemacomp/model/TableTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/TableTest.java @@ -20,14 +20,21 @@ package org.alfresco.util.schemacomp.model; import static java.util.Arrays.asList; +import static org.mockito.Mockito.verify; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.alfresco.util.schemacomp.Result.Strength; +import org.apache.poi.ss.formula.functions.Columns; import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; /** @@ -40,16 +47,16 @@ public class TableTest extends DbObjectTestBase { private Table table; private Table otherTable; - private Collection columns; + private List columns; private @Mock PrimaryKey primaryKey; - private Collection foreignKeys; - private Collection indexes; + private List foreignKeys; + private List indexes; @Before public void setUp() throws Exception { - columns = asList( + /*columns = asList( new Column("columnA", "VARCHAR2(50)", false), new Column("columnB", "VARCHAR2(100)", false), new Column("columnC", "VARCHAR2(200)", true)); @@ -58,11 +65,31 @@ public class TableTest extends DbObjectTestBase
indexes = asList(new Index("an_index", asList("columnA", "columnC"))); + table = new Table("the_table", columns, primaryKey, foreignKeys, indexes); + otherTable = new Table("the_other_table", columns, primaryKey, foreignKeys, indexes);*/ + + columns = listOfMocks(Column.class, 3); + + foreignKeys = listOfMocks(ForeignKey.class, 1); + + indexes = listOfMocks(Index.class, 1); + table = new Table("the_table", columns, primaryKey, foreignKeys, indexes); otherTable = new Table("the_other_table", columns, primaryKey, foreignKeys, indexes); } + private List listOfMocks(Class c, int size) + { + List list = new ArrayList(size); + for (int i = 0; i < size; i++) + { + list.add((T) Mockito.mock(c)); + } + return list; + } + + @Override protected List getMocksUsedInDiff() { @@ -99,4 +126,31 @@ public class TableTest extends DbObjectTestBase
{ return otherTable; } + + + @Test + public void acceptVisitor() + { + table.setColumns(columns); + table.setForeignKeys(foreignKeys); + table.setIndexes(indexes); + table.setPrimaryKey(primaryKey); + + table.accept(visitor); + + // All the children should be visited + List children = new ArrayList(); + children.addAll(columns); + children.addAll(foreignKeys); + children.addAll(indexes); + children.add(primaryKey); + + for (DbObject child : children) + { + verify(child).accept(visitor); + } + + // The parent itself should be visited + verify(visitor).visit(table); + } } diff --git a/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java b/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java new file mode 100644 index 0000000000..ed6017e1e5 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp.validator; + +import org.alfresco.util.schemacomp.DiffContext; +import org.alfresco.util.schemacomp.model.DbObject; + +/** + * TODO: comment me! + * @author Matt Ward + */ +public interface DbValidator +{ + void validate(DbObject dbo, DiffContext ctx); +} diff --git a/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java b/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java new file mode 100644 index 0000000000..f4dea16dfd --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp.validator; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import org.alfresco.util.schemacomp.DiffContext; +import org.alfresco.util.schemacomp.ValidationResult; +import org.alfresco.util.schemacomp.model.DbObject; +import org.hibernate.dialect.Dialect; + +/** + * Validates the name of a DbObject using a regular expression. A regular expression + * can be supplied for each supported {@link Dialect database dialect}. In addition to + * dialect specific regular expressions, a default may be supplied - comparisons will fall + * back to the default if no specific dialect is matched. + * + * @author Matt Ward + */ +public class NameValidator implements DbValidator +{ + private Map, Pattern> namePatterns = new HashMap, Pattern>(); + private Pattern defaultNamePattern; + + @Override + public void validate(DbObject dbo, DiffContext ctx) + { + String name = dbo.getName(); + + Pattern pattern = namePatterns.get(ctx.getDialect().getClass()); + + ValidationResult result = new ValidationResult(name); + + if (pattern != null && !pattern.matcher(name).matches()) + { + ctx.getValidationResults().add(result); + } + else if (defaultNamePattern != null && !defaultNamePattern.matcher(name).matches()) + { + ctx.getValidationResults().add(result); + } + } + + + /** + * Specify the set of mappings of database dialect to acceptable name patterns. + * + * @param namePatterns + */ + public void setNamePatterns(Map, Pattern> namePatterns) + { + this.namePatterns = namePatterns; + } + + /** + * If during validation, there is no specific name validation pattern for the supplied {@link Dialect} + * then the defaultNamePattern property will be used - if not null. + *

+ * If defaultNamePattern is null then a validation failure will be produced. + * + * @param defaultNamePattern + */ + public void setDefaultNamePattern(Pattern defaultNamePattern) + { + this.defaultNamePattern = defaultNamePattern; + } +} diff --git a/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java b/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java new file mode 100644 index 0000000000..a3e24c229b --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp.validator; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.alfresco.util.schemacomp.DiffContext; +import org.alfresco.util.schemacomp.Differences; +import org.alfresco.util.schemacomp.ValidationResult; +import org.alfresco.util.schemacomp.model.DbObject; +import org.alfresco.util.schemacomp.model.Index; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.Oracle10gDialect; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Tests for the NameValidator class. + * + * @author Matt Ward + */ +public class NameValidatorTest +{ + private NameValidator validator; + private DiffContext ctx; + private List validationResults; + + @Before + public void setUp() throws Exception + { + validator = new NameValidator(); + validationResults = new ArrayList(); + ctx = new DiffContext(new Oracle10gDialect(), new Differences(), validationResults); + } + + @Test + public void canSpecifyDefaultRequiredPattern() + { + validator.setDefaultNamePattern(Pattern.compile("SYS_[A-Z_]+")); + validator.validate(indexForName("SYS_MYINDEX"), ctx); + validator.validate(indexForName("SYS_"), ctx); + validator.validate(indexForName("SYS_MY_INDEX"), ctx); + validator.validate(indexForName("MY_INDEX"), ctx); + + assertEquals(2, validationResults.size()); + assertEquals("SYS_", validationResults.get(0).getValue()); + assertEquals("MY_INDEX", validationResults.get(1).getValue()); + } + + @Test + public void canValidateAgainstPatternForDialect() + { + Map, Pattern> patterns = new HashMap, Pattern>(); + patterns.put(Oracle10gDialect.class, Pattern.compile("ORA_[A-Z_]+")); + validator.setNamePatterns(patterns); + + validator.validate(indexForName("ORA_MYINDEX"), ctx); + validator.validate(indexForName("SYS_MYINDEX"), ctx); + + assertEquals(1, validationResults.size()); + assertEquals("SYS_MYINDEX", validationResults.get(0).getValue()); + } + + + private DbObject indexForName(String name) + { + return new Index(name, new ArrayList()); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/validator/NullValidator.java b/source/java/org/alfresco/util/schemacomp/validator/NullValidator.java new file mode 100644 index 0000000000..4ce49d6b53 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/NullValidator.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp.validator; + +import org.alfresco.util.schemacomp.DiffContext; +import org.alfresco.util.schemacomp.model.DbObject; + +/** + * TODO: comment me! + * @author Matt Ward + */ +public class NullValidator implements DbValidator +{ + @Override + public void validate(DbObject dbo, DiffContext ctx) + { + // Do nothing + } +} diff --git a/source/java/org/alfresco/util/schemacomp/validator/ValidatorTestSuite.java b/source/java/org/alfresco/util/schemacomp/validator/ValidatorTestSuite.java new file mode 100644 index 0000000000..4f54d724c7 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/ValidatorTestSuite.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.util.schemacomp.validator; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses( +{ + NameValidatorTest.class +}) +public class ValidatorTestSuite +{ +}