diff --git a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java index adc33d4eaa..491233efee 100644 --- a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java +++ b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java @@ -19,6 +19,7 @@ package org.alfresco.util.schemacomp; import java.util.Collection; +import java.util.List; import org.alfresco.util.schemacomp.model.Column; import org.alfresco.util.schemacomp.model.DbObject; @@ -27,6 +28,8 @@ 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.Table; +import org.alfresco.util.schemacomp.validator.DbValidator; +import org.apache.poi.hssf.record.DVALRecord; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; @@ -65,21 +68,62 @@ public class DbObjectXMLTransformer // All DbObjects result in an XML element with the DbObject's class name as the tag // and a name attribute corresponding to the value of getName(), // e.g. For an instance of a Column: - String tagName = dbObject.getClass().getSimpleName().toLowerCase(); final AttributesImpl attribs = new AttributesImpl(); - attribs.addAttribute("", "", "name", "CDATA", dbObject.getName()); + attribs.addAttribute("", "", XML.ATTR_NAME, "CDATA", dbObject.getName()); // Add class-specific attributes. addAttributes(dbObject, attribs); + String tagName = dbObject.getClass().getSimpleName().toLowerCase(); xmlOut.startElement("", "", tagName, attribs); // The element's contents can optionally be populated with class-specific content. transformDbObject(dbObject); + // All DbObjects potentially have validator configuration present in the XML. + transformValidators(dbObject.getValidators()); + // Provide the end tag, or close an empty element. xmlOut.endElement("", "", tagName); } + + /** + * @param validators + * @throws SAXException + */ + private void transformValidators(List> validators) throws SAXException + { + if (validators.size() > 0) + { + simpleStartTag(XML.EL_VALIDATORS); + for (DbValidator dbv : validators) + { + final AttributesImpl attribs = new AttributesImpl(); + attribs.addAttribute("", "", XML.ATTR_CLASS, "CDATA", dbv.getClass().getName()); + xmlOut.startElement("", "", XML.EL_VALIDATOR, attribs); + + if (dbv.getPropertyNames().size() > 0) + { + simpleStartTag(XML.EL_PROPERTIES); + for (String propName : dbv.getPropertyNames()) + { + final AttributesImpl propAttrs = new AttributesImpl(); + propAttrs.addAttribute("", "", XML.ATTR_NAME, "CDATA", propName); + xmlOut.startElement("", "", XML.EL_PROPERTY, propAttrs); + String propValue = dbv.getProperty(propName); + char[] chars = propValue.toCharArray(); + xmlOut.characters(chars, 0, chars.length); + simpleEndTag(XML.EL_PROPERTY); + } + simpleEndTag(XML.EL_PROPERTIES); + } + + simpleEndTag(XML.EL_VALIDATOR); + } + simpleEndTag(XML.EL_VALIDATORS); + } + } + /** * Add class-specific attributes. * @@ -91,7 +135,7 @@ public class DbObjectXMLTransformer if (dbObject instanceof Index) { Index index = (Index) dbObject; - attribs.addAttribute("", "", "unique", "CDATA", Boolean.toString(index.isUnique())); + attribs.addAttribute("", "", XML.ATTR_UNIQUE, "CDATA", Boolean.toString(index.isUnique())); } } @@ -127,55 +171,55 @@ public class DbObjectXMLTransformer private void transformSchema(Schema schema) throws SAXException { - simpleStartTag("objects"); + simpleStartTag(XML.EL_OBJECTS); for (DbObject dbo : schema) { output(dbo); } - simpleEndTag("objects"); + simpleEndTag(XML.EL_OBJECTS); } private void transformTable(Table table) throws SAXException { // Output columns - simpleStartTag("columns"); + simpleStartTag(XML.EL_COLUMNS); for (Column column : table.getColumns()) { output(column); } - simpleEndTag("columns"); + simpleEndTag(XML.EL_COLUMNS); // Output primary key output(table.getPrimaryKey()); // Output foreign keys - simpleStartTag("foreignkeys"); + simpleStartTag(XML.EL_FOREIGN_KEYS); for (ForeignKey fk : table.getForeignKeys()) { output(fk); } - simpleEndTag("foreignkeys"); + simpleEndTag(XML.EL_FOREIGN_KEYS); // Output indexes - simpleStartTag("indexes"); + simpleStartTag(XML.EL_INDEXES); for (Index index : table.getIndexes()) { output(index); } - simpleEndTag("indexes"); + simpleEndTag(XML.EL_INDEXES); } private void transformColumn(Column column) throws SAXException { - simpleElement("type", column.getType()); - simpleElement("nullable", Boolean.toString(column.isNullable())); + simpleElement(XML.EL_TYPE, column.getType()); + simpleElement(XML.EL_NULLABLE, Boolean.toString(column.isNullable())); } private void transformForeignKey(ForeignKey fk) throws SAXException { - simpleElement("localcolumn", fk.getLocalColumn()); - simpleElement("targettable", fk.getTargetTable()); - simpleElement("targetcolumn", fk.getTargetColumn()); + simpleElement(XML.EL_LOCAL_COLUMN, fk.getLocalColumn()); + simpleElement(XML.EL_TARGET_TABLE, fk.getTargetTable()); + simpleElement(XML.EL_TARGET_COLUMN, fk.getTargetColumn()); } private void transformIndex(Index index) throws SAXException @@ -219,11 +263,11 @@ public class DbObjectXMLTransformer private void columnNameList(Collection columnNames) throws SAXException { - simpleStartTag("columnnames"); + simpleStartTag(XML.EL_COLUMN_NAMES); for (String columnName : columnNames) { - simpleElement("columnname", columnName); + simpleElement(XML.EL_COLUMN_NAME, columnName); } - simpleEndTag("columnnames"); + simpleEndTag(XML.EL_COLUMN_NAMES); } } diff --git a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java index f0c1cc447a..37cb6459a9 100644 --- a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java +++ b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java @@ -31,8 +31,12 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; @@ -43,12 +47,15 @@ import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; 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; +import org.alfresco.util.schemacomp.validator.DbValidator; +import org.alfresco.util.schemacomp.validator.NameValidator; import org.junit.Before; import org.junit.Test; @@ -248,6 +255,53 @@ public class DbObjectXMLTransformerTest assertEquals("", reader.readLine()); } + + @Test + public void transformObjectWithValidators() throws IOException + { + Collection columns = columns("one VARCHAR2(100)", "two NUMBER(10)"); + PrimaryKey pk = new PrimaryKey(null, "pk_for_my_table", Arrays.asList("id")); + Collection fks = fkeys(fk("fk_one", "lc", "tt", "tc"), fk("fk_two", "lc", "tt", "tc")); + Collection indexes = indexes("index_one col1 col2", "index_two col3 col4"); + + Table table = new Table(null, "my_table", columns, pk, fks, indexes); + + NameValidator nameValidator = new NameValidator(); + nameValidator.setPattern(Pattern.compile("match_me_if_you_can")); + List> validators = new ArrayList>(); + validators.add(nameValidator); + table.setValidators(validators); + + transformer.output(table); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" ", reader.readLine()); + skipUntilEnd(" {column}", reader); + skipUntilEnd(" {column}", reader); + assertEquals(" ", reader.readLine()); + skipUntilEnd(" {primarykey}", reader); + assertEquals(" ", reader.readLine()); + skipUntilEnd(" {foreignkey}", reader); + skipUntilEnd(" {foreignkey}", reader); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + skipUntilEnd(" {index}", reader); + skipUntilEnd(" {index}", reader); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" match_me_if_you_can", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals("
", reader.readLine()); + } + + /** * Ignore lines that are tested elsewhere, e.g. ignore serialized Column objects * in the context of a Table since we only need to know that there was text for a diff --git a/source/java/org/alfresco/util/schemacomp/XML.java b/source/java/org/alfresco/util/schemacomp/XML.java index c324cc6b49..d53075c43b 100644 --- a/source/java/org/alfresco/util/schemacomp/XML.java +++ b/source/java/org/alfresco/util/schemacomp/XML.java @@ -30,9 +30,12 @@ public abstract class XML public static final String EL_SCHEMA = Schema.class.getSimpleName().toLowerCase(); public static final String EL_TABLE = Table.class.getSimpleName().toLowerCase(); public static final String EL_COLUMN = Column.class.getSimpleName().toLowerCase(); + public static final String EL_COLUMNS = "columns"; public static final String EL_PRIMARY_KEY = PrimaryKey.class.getSimpleName().toLowerCase(); public static final String EL_FOREIGN_KEY = ForeignKey.class.getSimpleName().toLowerCase(); + public static final String EL_FOREIGN_KEYS = "foreignkeys"; public static final String EL_INDEX = Index.class.getSimpleName().toLowerCase(); + public static final String EL_INDEXES = "indexes"; public static final String EL_SEQUENCE = Sequence.class.getSimpleName().toLowerCase(); public static final String EL_TYPE = "type"; public static final String EL_NULLABLE = "nullable"; @@ -41,7 +44,13 @@ public abstract class XML public static final String EL_LOCAL_COLUMN = "localcolumn"; public static final String EL_TARGET_COLUMN = "targetcolumn"; public static final String EL_TARGET_TABLE = "targettable"; + public static final String EL_VALIDATORS = "validators"; + public static final String EL_VALIDATOR = "validator"; + public static final String EL_OBJECTS = "objects"; + public static final String EL_PROPERTIES = "properties"; + public static final String EL_PROPERTY = "property"; public static final String ATTR_NAME = "name"; public static final String ATTR_UNIQUE = "unique"; + public static final String ATTR_CLASS = "class"; } diff --git a/source/java/org/alfresco/util/schemacomp/XMLToSchema.java b/source/java/org/alfresco/util/schemacomp/XMLToSchema.java index faaceb80cf..a199eee15b 100644 --- a/source/java/org/alfresco/util/schemacomp/XMLToSchema.java +++ b/source/java/org/alfresco/util/schemacomp/XMLToSchema.java @@ -20,6 +20,8 @@ package org.alfresco.util.schemacomp; import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.Stack; import javax.xml.parsers.SAXParser; @@ -33,6 +35,7 @@ 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.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -47,7 +50,7 @@ public class XMLToSchema extends DefaultHandler private SAXParser parser; private InputStream in; private Schema schema; - private Stack dboStack = new Stack(); + private Stack stack = new Stack(); private String lastTag; private String lastText; @@ -97,43 +100,53 @@ public class XMLToSchema extends DefaultHandler { if (qName.equals(XML.EL_TABLE)) { - Table table = (Table) dboStack.pop(); + Table table = (Table) stack.pop(); schema.add(table); } else if (qName.equals(XML.EL_COLUMN)) { - Column column = (Column) dboStack.pop(); - Table table = (Table) dboStack.peek(); + Column column = (Column) stack.pop(); + Table table = (Table) stack.peek(); table.getColumns().add(column); } else if (qName.equals(XML.EL_PRIMARY_KEY)) { - PrimaryKey pk = (PrimaryKey) dboStack.pop(); - Table table = (Table) dboStack.peek(); + PrimaryKey pk = (PrimaryKey) stack.pop(); + Table table = (Table) stack.peek(); table.setPrimaryKey(pk); } else if (qName.equals(XML.EL_FOREIGN_KEY)) { - ForeignKey fk = (ForeignKey) dboStack.pop(); - Table table = (Table) dboStack.peek(); + ForeignKey fk = (ForeignKey) stack.pop(); + Table table = (Table) stack.peek(); table.getForeignKeys().add(fk); } else if (qName.equals(XML.EL_INDEX)) { - Index index = (Index) dboStack.pop(); - Table table = (Table) dboStack.peek(); + Index index = (Index) stack.pop(); + Table table = (Table) stack.peek(); table.getIndexes().add(index); } else if (qName.equals(XML.EL_SEQUENCE)) { - Sequence seq = (Sequence) dboStack.pop(); + Sequence seq = (Sequence) stack.pop(); schema.add(seq); } + else if (qName.equals(XML.EL_VALIDATOR)) + { + @SuppressWarnings("unchecked") + DbValidator validator = (DbValidator) stack.pop(); + DbObject dbo = (DbObject) stack.peek(); + dbo.getValidators().add(validator); + } + else if (qName.equals(XML.EL_PROPERTY)) + { + //stack.pop(); + } } - - + @SuppressWarnings("unchecked") @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException @@ -146,30 +159,50 @@ public class XMLToSchema extends DefaultHandler } else if (qName.equals(XML.EL_TABLE)) { - dboStack.push(new Table(atts.getValue(XML.ATTR_NAME))); + stack.push(new Table(atts.getValue(XML.ATTR_NAME))); } else if (qName.equals(XML.EL_COLUMN)) { - dboStack.push(new Column(atts.getValue(XML.ATTR_NAME))); + stack.push(new Column(atts.getValue(XML.ATTR_NAME))); } else if (qName.equals(XML.EL_PRIMARY_KEY)) { - dboStack.push(new PrimaryKey(atts.getValue(XML.ATTR_NAME))); + stack.push(new PrimaryKey(atts.getValue(XML.ATTR_NAME))); } else if (qName.equals(XML.EL_FOREIGN_KEY)) { - dboStack.push(new ForeignKey(atts.getValue(XML.ATTR_NAME))); + stack.push(new ForeignKey(atts.getValue(XML.ATTR_NAME))); } else if (qName.equals(XML.EL_INDEX)) { Index index = new Index(atts.getValue(XML.ATTR_NAME)); boolean unique = Boolean.parseBoolean(atts.getValue(XML.ATTR_UNIQUE)); index.setUnique(unique); - dboStack.push(index); + stack.push(index); } else if (qName.equals(XML.EL_SEQUENCE)) { - dboStack.push(new Sequence(atts.getValue(XML.ATTR_NAME))); + stack.push(new Sequence(atts.getValue(XML.ATTR_NAME))); + } + else if (qName.equals(XML.EL_VALIDATOR)) + { + String className = atts.getValue(XML.ATTR_CLASS); + DbValidator validator = null; + try + { + validator = (DbValidator) Class.forName(className).newInstance(); + } + catch (Throwable e) + { + throw new RuntimeException("Couldn't create validator, class: " + className, e); + } + + stack.push(validator); + } + else if (qName.equals(XML.EL_PROPERTY)) + { + String name = atts.getValue(XML.ATTR_NAME); + stack.push(name); } } @@ -182,42 +215,53 @@ public class XMLToSchema extends DefaultHandler { if (lastTag.equals(XML.EL_TYPE)) { - Column column = (Column) dboStack.peek(); + Column column = (Column) stack.peek(); column.setType(lastText); } else if (lastTag.equals(XML.EL_NULLABLE)) { - Column column = (Column) dboStack.peek(); + Column column = (Column) stack.peek(); column.setNullable(Boolean.parseBoolean(lastText)); } else if (lastTag.equals(XML.EL_COLUMN_NAME)) { - if (dboStack.peek() instanceof PrimaryKey) + if (stack.peek() instanceof PrimaryKey) { - PrimaryKey pk = (PrimaryKey) dboStack.peek(); + PrimaryKey pk = (PrimaryKey) stack.peek(); pk.getColumnNames().add(lastText); } - else if (dboStack.peek() instanceof Index) + else if (stack.peek() instanceof Index) { - Index index = (Index) dboStack.peek(); + Index index = (Index) stack.peek(); index.getColumnNames().add(lastText); } } else if (lastTag.equals(XML.EL_LOCAL_COLUMN)) { - ForeignKey fk = (ForeignKey) dboStack.peek(); + ForeignKey fk = (ForeignKey) stack.peek(); fk.setLocalColumn(lastText); } else if (lastTag.equals(XML.EL_TARGET_TABLE)) { - ForeignKey fk = (ForeignKey) dboStack.peek(); + ForeignKey fk = (ForeignKey) stack.peek(); fk.setTargetTable(lastText); } else if (lastTag.equals(XML.EL_TARGET_COLUMN)) { - ForeignKey fk = (ForeignKey) dboStack.peek(); + ForeignKey fk = (ForeignKey) stack.peek(); fk.setTargetColumn(lastText); } + else if (lastTag.equals(XML.EL_PROPERTY)) + { + String propValue = lastText; + String propName = (String) stack.pop(); + if (stack.peek() instanceof DbValidator) + { + @SuppressWarnings("unchecked") + DbValidator validator = (DbValidator) stack.peek(); + validator.setProperty(propName, propValue); + } + } } } } diff --git a/source/java/org/alfresco/util/schemacomp/XMLToSchemaTest.java b/source/java/org/alfresco/util/schemacomp/XMLToSchemaTest.java index 4dc5729dd6..5c3dc6bfe3 100644 --- a/source/java/org/alfresco/util/schemacomp/XMLToSchemaTest.java +++ b/source/java/org/alfresco/util/schemacomp/XMLToSchemaTest.java @@ -28,9 +28,12 @@ import java.io.InputStream; import java.util.Iterator; import org.alfresco.util.schemacomp.model.DbObject; +import org.alfresco.util.schemacomp.model.Index; 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.junit.Before; import org.junit.Test; @@ -89,11 +92,17 @@ public class XMLToSchemaTest assertEquals("nodeRef", table.getForeignKeys().get(0).getTargetColumn()); assertEquals(1, table.getIndexes().size()); - assertEquals("idx_node_by_id", table.getIndexes().get(0).getName()); - assertEquals(true, table.getIndexes().get(0).isUnique()); - assertEquals(2, table.getIndexes().get(0).getColumnNames().size()); - assertEquals("id", table.getIndexes().get(0).getColumnNames().get(0)); - assertEquals("nodeRef", table.getIndexes().get(0).getColumnNames().get(1)); + Index index = table.getIndexes().get(0); + assertEquals("idx_node_by_id", index.getName()); + assertEquals(true, index.isUnique()); + assertEquals(2, index.getColumnNames().size()); + assertEquals("id", index.getColumnNames().get(0)); + assertEquals("nodeRef", index.getColumnNames().get(1)); + assertEquals(1, index.getValidators().size()); + DbValidator validator = index.getValidators().get(0); + assertEquals(NameValidator.class, validator.getClass()); + assertEquals(1, validator.getPropertyNames().size()); + assertEquals("idx_.+", validator.getProperty("pattern")); assertEquals("node_seq", ((Sequence) objects.next()).getName()); assertEquals("person_seq", ((Sequence) objects.next()).getName()); diff --git a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java index 1d0f445b3a..4fad12a408 100644 --- a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java +++ b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObject.java @@ -18,12 +18,17 @@ */ 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.DbProperty; import org.alfresco.util.schemacomp.DefaultComparisonUtils; import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.Result.Strength; import org.alfresco.util.schemacomp.Results; +import org.alfresco.util.schemacomp.validator.DbValidator; /** * Useful base class for many, if not all the {@link DbObject} implementations. @@ -37,6 +42,7 @@ public abstract class AbstractDbObject implements DbObject /** How differences in the name field should be reported */ private Strength nameStrength = Strength.ERROR; protected ComparisonUtils comparisonUtils = new DefaultComparisonUtils(); + private List> validators = new ArrayList>(); /** @@ -203,4 +209,28 @@ public abstract class AbstractDbObject implements DbObject { this.comparisonUtils = comparisonUtils; } + + + @Override + public List> getValidators() + { + return validators; + } + + + /** + * @param validators the validators to set + */ + @Override + public void setValidators(List> validators) + { + if (validators == null) + { + this.validators = Collections.emptyList(); + } + else + { + this.validators = validators; + } + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java index 0832c767f5..1a63ad8536 100644 --- a/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java +++ b/source/java/org/alfresco/util/schemacomp/model/AbstractDbObjectTest.java @@ -24,6 +24,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.inOrder; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DbProperty; @@ -32,6 +34,8 @@ import org.alfresco.util.schemacomp.Difference.Where; import org.alfresco.util.schemacomp.Result.Strength; import org.alfresco.util.schemacomp.Results; import org.alfresco.util.schemacomp.ValidationResult; +import org.alfresco.util.schemacomp.validator.AbstractDbValidator; +import org.alfresco.util.schemacomp.validator.DbValidator; import org.hibernate.dialect.Dialect; import org.junit.Before; import org.junit.Test; @@ -83,8 +87,7 @@ public class AbstractDbObjectTest assertTrue("Logically the same object.", dbObject.sameAs(new ConcreteDbObject("the_name"))); assertTrue("The very same object with non-null name", dbObject.sameAs(dbObject)); } - - + @Test public void diff() { @@ -110,6 +113,25 @@ public class AbstractDbObjectTest } + @SuppressWarnings("unchecked") + @Test + public void canGetValidators() + { + List> validators = dbObject.getValidators(); + assertEquals(0, validators.size()); + + dbObject.setValidators(null); + validators = dbObject.getValidators(); + assertEquals(0, validators.size()); + + dbObject.setValidators(validatorList(new TestValidator1(), new TestValidator2())); + validators = dbObject.getValidators(); + assertEquals(2, validators.size()); + assertEquals(TestValidator1.class, validators.get(0).getClass()); + assertEquals(TestValidator2.class, validators.get(1).getClass()); + } + + /** * Concrete DbObject for testing the AbstractDbObject base class. */ @@ -142,4 +164,27 @@ public class AbstractDbObjectTest return this.someProp; } } + + + private List> validatorList(DbValidator... validators) + { + return Arrays.asList(validators); + } + + + private static class TestValidator extends AbstractDbValidator + { + @Override + public void validate(DbObject reference, DbObject target, DiffContext ctx) + { + } + } + + private static class TestValidator1 extends TestValidator + { + } + + private static class TestValidator2 extends TestValidator + { + } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Column.java b/source/java/org/alfresco/util/schemacomp/model/Column.java index 358f7c2962..3f16abf7f7 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Column.java +++ b/source/java/org/alfresco/util/schemacomp/model/Column.java @@ -21,7 +21,6 @@ package org.alfresco.util.schemacomp.model; import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DbProperty; import org.alfresco.util.schemacomp.DiffContext; -import org.alfresco.util.schemacomp.Results; import org.alfresco.util.schemacomp.Result.Strength; /** @@ -116,7 +115,6 @@ public class Column extends AbstractDbObject @Override protected void doDiff(DbObject right, DiffContext ctx, Strength strength) { - Results differences = ctx.getDifferences(); DbProperty thisTypeProp = new DbProperty(this, "type"); DbProperty thisNullableProp = new DbProperty(this, "nullable"); diff --git a/source/java/org/alfresco/util/schemacomp/model/DbObject.java b/source/java/org/alfresco/util/schemacomp/model/DbObject.java index 4a795f8523..bcf90952de 100644 --- a/source/java/org/alfresco/util/schemacomp/model/DbObject.java +++ b/source/java/org/alfresco/util/schemacomp/model/DbObject.java @@ -18,10 +18,14 @@ */ package org.alfresco.util.schemacomp.model; +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.Results; import org.alfresco.util.schemacomp.Result.Strength; +import org.alfresco.util.schemacomp.validator.DbValidator; /** * All database objects to be modelled for schema comparisons must implement this interface, examples @@ -86,4 +90,20 @@ public interface DbObject * @param parent */ void setParent(DbObject parent); + + + /** + * Retrieve the list of validators associated with this database object. + * + * @see DbValidator + * @return DbValidator List + */ + List> getValidators(); + + /** + * Set/override the validators associated with this database object. + * + * @param validators + */ + void setValidators(List> validators); } diff --git a/source/java/org/alfresco/util/schemacomp/validator/AbstractDbValidator.java b/source/java/org/alfresco/util/schemacomp/validator/AbstractDbValidator.java new file mode 100644 index 0000000000..1a97da8005 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/validator/AbstractDbValidator.java @@ -0,0 +1,54 @@ +/* + * 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.Set; + +import org.alfresco.util.schemacomp.model.DbObject; + +/** + * Base class providing DbValidator support. + * + * @author Matt Ward + */ +public abstract class AbstractDbValidator implements DbValidator +{ + private final Map properties = new HashMap(); + + @Override + public void setProperty(String name, String value) + { + properties.put(name, value); + } + + @Override + public String getProperty(String name) + { + return properties.get(name); + } + + @Override + public Set getPropertyNames() + { + return properties.keySet(); + } + +} diff --git a/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java b/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java index 7bfe1025a7..9253fd57f9 100644 --- a/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java +++ b/source/java/org/alfresco/util/schemacomp/validator/DbValidator.java @@ -18,6 +18,8 @@ */ package org.alfresco.util.schemacomp.validator; +import java.util.Set; + import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.model.DbObject; @@ -27,7 +29,13 @@ import org.alfresco.util.schemacomp.model.DbObject; * * @author Matt Ward */ -public interface DbValidator +public interface DbValidator { - void validate(DbObject reference, DbObject target, DiffContext ctx); + void validate(T reference, T target, DiffContext ctx); + + void setProperty(String name, String value); + + String getProperty(String name); + + Set getPropertyNames(); } diff --git a/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java b/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java index 7e2c637ed0..0493b9cfaf 100644 --- a/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java +++ b/source/java/org/alfresco/util/schemacomp/validator/NameValidator.java @@ -18,8 +18,8 @@ */ package org.alfresco.util.schemacomp.validator; -import java.util.HashMap; -import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import java.util.regex.Pattern; import org.alfresco.util.schemacomp.DbProperty; @@ -36,7 +36,7 @@ import org.hibernate.dialect.Dialect; * * @author Matt Ward */ -public class NameValidator implements DbValidator +public class NameValidator implements DbValidator { private Pattern pattern; @@ -58,4 +58,41 @@ public class NameValidator implements DbValidator { this.pattern = pattern; } + + + public Pattern getPattern() + { + return this.pattern; + } + + + @Override + public void setProperty(String name, String value) + { + if (name.equals("pattern") && value != null) + { + Pattern pattern = Pattern.compile(value); + setPattern(pattern); + } + } + + + @Override + public String getProperty(String name) + { + if (name.equals("pattern") && pattern != null) + { + return pattern.toString(); + } + return null; + } + + + @Override + public Set getPropertyNames() + { + Set props = new TreeSet(); + props.add("pattern"); + return props; + } } diff --git a/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java b/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java index 3ff29a1410..2a7bbfdc13 100644 --- a/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java +++ b/source/java/org/alfresco/util/schemacomp/validator/NameValidatorTest.java @@ -22,7 +22,10 @@ package org.alfresco.util.schemacomp.validator; import static org.junit.Assert.assertEquals; 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; @@ -80,6 +83,14 @@ public class NameValidatorTest } + @Test + public void canSetPatternUsingProperties() + { + validator.setProperty("pattern", "ORA_[A-Z_]+"); + assertEquals("ORA_[A-Z_]+", validator.getPattern().toString()); + } + + private DbObject indexForName(String name) { return new Index(null, 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 index c9c17c9a00..84bab2a378 100644 --- a/source/java/org/alfresco/util/schemacomp/validator/NullValidator.java +++ b/source/java/org/alfresco/util/schemacomp/validator/NullValidator.java @@ -26,7 +26,7 @@ import org.alfresco.util.schemacomp.model.DbObject; * * @author Matt Ward */ -public class NullValidator implements DbValidator +public class NullValidator extends AbstractDbValidator { @Override public void validate(DbObject reference, DbObject target, DiffContext ctx) diff --git a/source/java/org/alfresco/util/schemacomp/xml_to_schema_test.xml b/source/java/org/alfresco/util/schemacomp/xml_to_schema_test.xml index 1cea988710..88f113224f 100644 --- a/source/java/org/alfresco/util/schemacomp/xml_to_schema_test.xml +++ b/source/java/org/alfresco/util/schemacomp/xml_to_schema_test.xml @@ -37,6 +37,13 @@ id nodeRef + + + + idx_.+ + + +