ALF-10771: adding validation to schema compare tool

Added support to DbObjects to accept visitors
Added ValidatingVisitor to invoke suitable validator on each DbObject
Added NameValidator and NullValidator to operate on DbObject types
Added test suites



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31494 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Matt Ward
2011-10-26 16:01:38 +00:00
parent 7764900451
commit ec302df6ed
33 changed files with 896 additions and 30 deletions

View File

@@ -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;

View File

@@ -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<ValidationResult>());
}
@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)
{
}
}
}

View File

@@ -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);
}
}

View File

@@ -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<Column>
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);
}
}

View File

@@ -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);
}

View File

@@ -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<T extends AbstractDbObject>
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<Object> mocks = getMocksUsedInDiff();
inOrder = inOrder(mocks.toArray());
ctx = new DiffContext(dialect, differences);
ctx = new DiffContext(dialect, differences, new ArrayList<ValidationResult>());
}

View File

@@ -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);
}
}

View File

@@ -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<ForeignKey>
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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<Index>
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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<PrimaryKey>
Strength.ERROR);
}
@Test
public void acceptVisitor()
{
thisPK.accept(visitor);
verify(visitor).visit(thisPK);
}
}

View File

@@ -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<DbObject>
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);
}
}

View File

@@ -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<Schema>
// 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<Sequence>
{
@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.
}
}

View File

@@ -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<DbObject> getChildren()
{
List<DbObject> children = new ArrayList<DbObject>();
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);
}
}

View File

@@ -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<Table>
{
private Table table;
private Table otherTable;
private Collection<Column> columns;
private List<Column> columns;
private @Mock PrimaryKey primaryKey;
private Collection<ForeignKey> foreignKeys;
private Collection<Index> indexes;
private List<ForeignKey> foreignKeys;
private List<Index> 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<Table>
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 <T> List<T> listOfMocks(Class<T> c, int size)
{
List<T> list = new ArrayList<T>(size);
for (int i = 0; i < size; i++)
{
list.add((T) Mockito.mock(c));
}
return list;
}
@Override
protected List<Object> getMocksUsedInDiff()
{
@@ -99,4 +126,31 @@ public class TableTest extends DbObjectTestBase<Table>
{
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<DbObject> children = new ArrayList<DbObject>();
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);
}
}