diff --git a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java new file mode 100644 index 0000000000..f2e431de83 --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformer.java @@ -0,0 +1,211 @@ +/* + * 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.Collection; + +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.Table; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Converts DbObject instances into an XML output stream. + * + * @author Matt Ward + */ +public class DbObjectXMLTransformer +{ + private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl(); + private ContentHandler xmlOut; + + + public DbObjectXMLTransformer(ContentHandler contentHandler) + { + this.xmlOut = contentHandler; + } + + public void output(DbObject dbObject) + { + try + { + attemptOutput(dbObject); + } + catch (SAXException e) + { + throw new RuntimeException("Unable to output " + dbObject, e); + } + } + + private void attemptOutput(DbObject dbObject) throws SAXException + { + // 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()); + xmlOut.startElement("", "", tagName, attribs); + + // The element's contents can optionally be populated with class-specific content. + transformDbObject(dbObject); + + // Provide the end tag, or close an empty element. + xmlOut.endElement("", "", tagName); + } + + private void transformDbObject(DbObject dbObject) throws SAXException + { + if (dbObject instanceof Schema) + { + transformSchema((Schema) dbObject); + } + else if (dbObject instanceof Table) + { + transformTable((Table) dbObject); + } + else if (dbObject instanceof Column) + { + transformColumn((Column) dbObject); + } + else if (dbObject instanceof ForeignKey) + { + transformForeignKey((ForeignKey) dbObject); + } + else if (dbObject instanceof Index) + { + transformIndex((Index) dbObject); + } + else if (dbObject instanceof PrimaryKey) + { + transformPrimaryKey((PrimaryKey) dbObject); + } + } + + + + private void transformSchema(Schema schema) throws SAXException + { + simpleStartTag("objects"); + for (DbObject dbo : schema) + { + output(dbo); + } + simpleEndTag("objects"); + } + + private void transformTable(Table table) throws SAXException + { + // Output columns + simpleStartTag("columns"); + for (Column column : table.getColumns()) + { + output(column); + } + simpleEndTag("columns"); + + // Output primary key + output(table.getPrimaryKey()); + + // Output foreign keys + simpleStartTag("foreignkeys"); + for (ForeignKey fk : table.getForeignKeys()) + { + output(fk); + } + simpleEndTag("foreignkeys"); + + // Output indexes + simpleStartTag("indexes"); + for (Index index : table.getIndexes()) + { + output(index); + } + simpleEndTag("indexes"); + } + + private void transformColumn(Column column) throws SAXException + { + simpleElement("type", column.getType()); + simpleElement("nullable", Boolean.toString(column.isNullable())); + } + + private void transformForeignKey(ForeignKey fk) throws SAXException + { + simpleElement("localcolumn", fk.getLocalColumn()); + simpleElement("targettable", fk.getTargetTable()); + simpleElement("targetcolumn", fk.getTargetColumn()); + } + + private void transformIndex(Index index) throws SAXException + { + columnNameList(index.getColumnNames()); + } + + private void transformPrimaryKey(PrimaryKey pk) throws SAXException + { + columnNameList(pk.getColumnNames()); + } + + + /** + * Create a simple element of the form: + *
+     *    <tag>content</tag>
+     * 
+ * + * @param tag + * @param content + * @throws SAXException + */ + private void simpleElement(String tag, String content) throws SAXException + { + simpleStartTag(tag); + char[] chars = content.toCharArray(); + xmlOut.characters(chars, 0, chars.length); + simpleEndTag(tag); + } + + private void simpleStartTag(String tag) throws SAXException + { + xmlOut.startElement("", "", tag, DbObjectXMLTransformer.EMPTY_ATTRIBUTES); + } + + private void simpleEndTag(String tag) throws SAXException + { + xmlOut.endElement("", "", tag); + } + + private void columnNameList(Collection columnNames) throws SAXException + { + simpleStartTag("columnnames"); + for (String columnName : columnNames) + { + simpleElement("columnname", columnName); + } + simpleEndTag("columnnames"); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java new file mode 100644 index 0000000000..6c11f5c7ad --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/DbObjectXMLTransformerTest.java @@ -0,0 +1,316 @@ +/* + * 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 static org.alfresco.util.schemacomp.SchemaCompTestingUtils.columns; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fk; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fkeys; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.indexes; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collection; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +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.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.junit.Before; +import org.junit.Test; + +import com.sun.star.uno.RuntimeException; + +/** + * Tests for the {@link DbObjectXMLTransformer} class. + * + * @author Matt Ward + */ +public class DbObjectXMLTransformerTest +{ + private DbObjectXMLTransformer transformer; + private TransformerHandler xmlOut; + private Writer writer; + private boolean outputDumpEnabled = true; + + @Before + public void setUp() + { + final SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance(); + try + { + xmlOut = stf.newTransformerHandler(); + } + catch (TransformerConfigurationException error) + { + throw new RuntimeException("Unable to create TransformerHandler.", error); + } + final Transformer t = xmlOut.getTransformer(); + try + { + t.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); + } + catch (final IllegalArgumentException e) + { + // It was worth a try + } + t.setOutputProperty(OutputKeys.INDENT, "yes"); + + writer = new StringWriter(); + xmlOut.setResult(new StreamResult(writer)); + + transformer = new DbObjectXMLTransformer(xmlOut); + } + + + @Test + public void transformColumn() throws IOException + { + Column column = new Column(null, "last_name", "VARCHAR2(100)", true); + + transformer.output(column); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" VARCHAR2(100)", reader.readLine()); + assertEquals(" true", reader.readLine()); + assertEquals("", reader.readLine()); + } + + + @Test + public void transformForeignKey() throws IOException + { + ForeignKey fk = new ForeignKey(null, "fk_for_some_table", + "local_column", "target_table", "target_column"); + + transformer.output(fk); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" local_column", reader.readLine()); + assertEquals(" target_table", reader.readLine()); + assertEquals(" target_column", reader.readLine()); + assertEquals("", reader.readLine()); + } + + + @Test + public void transformIndex() throws IOException + { + Index index = new Index(null, "index_name", Arrays.asList("first", "second")); + + transformer.output(index); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" first", reader.readLine()); + assertEquals(" second", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals("", reader.readLine()); + } + + + @Test + public void transformPrimaryKey() throws IOException + { + PrimaryKey pk = new PrimaryKey(null, "pk_name", Arrays.asList("first", "second")); + + transformer.output(pk); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals(" first", reader.readLine()); + assertEquals(" second", reader.readLine()); + assertEquals(" ", reader.readLine()); + assertEquals("", reader.readLine()); + } + + @Test + public void transformSchema() 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 tableOne = new Table(null, "table_one", columns, pk, fks, indexes); + Table tableTwo = new Table(null, "table_two", columns, pk, fks, indexes); + + Schema schema = new Schema("my_schema"); + schema.add(tableOne); + schema.add(tableTwo); + schema.add(new Sequence(null, "sequence_one")); + schema.add(new Sequence(null, "sequence_two")); + schema.add(new Sequence(null, "sequence_three")); + + transformer.output(schema); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + assertEquals(" ", reader.readLine()); + skipUntilEnd(" {table}", reader); + skipUntilEnd(" {table}", reader); + skipUntilEnd(" {sequence}", reader, true); + skipUntilEnd(" {sequence}", reader, true); + skipUntilEnd(" {sequence}", reader, true); + assertEquals(" ", reader.readLine()); + assertEquals("", reader.readLine()); + } + + @Test + public void transformSequence() throws IOException + { + Sequence sequence = new Sequence(null, "my_sequence"); + + transformer.output(sequence); + + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + dumpOutput(); + assertHasPreamble(reader); + assertEquals("", reader.readLine()); + } + + @Test + public void transformTable() 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); + + 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()); + } + + /** + * 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 + * Column object in the right place - the actual Column text being tested in its own test. + *

+ * Leading and trailing spaces are ignored in the comparison. + * + * @param textToFind + * @param reader + */ + private void skipUntilEnd(String textToFind, BufferedReader reader, boolean emptyTag) + { + // To aid test code clarity, and distinguish between text we're actually + // testing for and text that needs to be ignored... + // {mytag} becomes + // or if an empty tag is expected + // {mytag} becomes + if (emptyTag) + { + textToFind = textToFind.trim(). + replace("{", "<"). + replace("}", "\\s+.*/>"); + } + else + { + textToFind = textToFind.trim(). + replace("{", ""); + } + try + { + String line; + while ((line = reader.readLine()) != null) + { + if (line.trim().matches(textToFind)) + { + return; + } + } + fail("Unable to find text: " + textToFind); + } + catch (IOException error) + { + throw new RuntimeException("Unable to skip text whilst looking for: " + textToFind, error); + } + + } + + private void skipUntilEnd(String textToFind, BufferedReader reader) + { + skipUntilEnd(textToFind, reader, false); + } + + private void assertHasPreamble(BufferedReader reader) throws IOException + { + assertEquals("", reader.readLine()); + } + + private void dumpOutput() + { + if (outputDumpEnabled) + { + System.out.println(writer.toString()); + } + } +} diff --git a/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java b/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java index 9bbadab012..d1bf2312ae 100644 --- a/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java +++ b/source/java/org/alfresco/util/schemacomp/SchemaCompTestSuite.java @@ -29,10 +29,12 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses( { + DbObjectXMLTransformerTest.class, DbPropertyTest.class, DefaultComparisonUtilsTest.class, SchemaComparatorTest.class, - ValidatingVisitorTest.class + ValidatingVisitorTest.class, + SchemaToXMLTest.class, }) public class SchemaCompTestSuite { diff --git a/source/java/org/alfresco/util/schemacomp/SchemaCompTestingUtils.java b/source/java/org/alfresco/util/schemacomp/SchemaCompTestingUtils.java new file mode 100644 index 0000000000..555df4751d --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/SchemaCompTestingUtils.java @@ -0,0 +1,115 @@ +/* + * 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 static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.alfresco.util.schemacomp.Difference.Where; +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.Table; +import org.apache.commons.lang.ArrayUtils; + + +public class SchemaCompTestingUtils +{ + public static void dumpValidation(List validationResults) + { + System.out.println("Validation Results (" + validationResults.size() + ")"); + for (ValidationResult r : validationResults) + { + System.out.println(r); + } + } + + public static void dumpDiffs(Results differences, boolean showNonDifferences) + { + System.out.println("Differences (" + differences.size() + ")"); + for (Difference d : differences) + { + if (d.getWhere() != Where.IN_BOTH_NO_DIFFERENCE || showNonDifferences) + { + System.out.println(d); + } + } + } + + public static Table table(String name) + { + return new Table(null, name, columns("id NUMBER(10)"), pk("pk_" + name, "id"), fkeys(), indexes()); + } + + public static Table table(String name, Collection columns, PrimaryKey primaryKey, + Collection foreignKeys, Collection indexes) + { + return new Table(null, name, columns, primaryKey, foreignKeys, indexes); + } + + public static Collection columns(String... colDefs) + { + assertTrue("Tables must have columns", colDefs.length > 0); + Column[] columns = new Column[colDefs.length]; + + for (int i = 0; i < colDefs.length; i++) + { + String[] parts = colDefs[i].split(" "); + columns[i] = new Column(null, parts[0], parts[1], false); + } + return Arrays.asList(columns); + } + + public static PrimaryKey pk(String name, String... columnNames) + { + assertTrue("No columns specified", columnNames.length > 0); + PrimaryKey pk = new PrimaryKey(null, name, Arrays.asList(columnNames)); + return pk; + } + + public static List fkeys(ForeignKey... fkeys) + { + return Arrays.asList(fkeys); + } + + public static ForeignKey fk(String fkName, String localColumn, String targetTable, String targetColumn) + { + return new ForeignKey(null, fkName, localColumn, targetTable, targetColumn); + } + + /** + * Create collection of indexes using strings of format "name column1 [column2 ... columnN]" + */ + public static Collection indexes(String... indexDefs) + { + Index[] indexes = new Index[indexDefs.length]; + for (int i = 0; i < indexDefs.length; i++) + { + String[] parts = indexDefs[i].split(" "); + String name = parts[0]; + String[] columns = (String[]) ArrayUtils.subarray(parts, 1, parts.length); + indexes[i] = new Index(null, name, Arrays.asList(columns)); + } + return Arrays.asList(indexes); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java b/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java index e65b877afd..a0d9986cd7 100644 --- a/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java +++ b/source/java/org/alfresco/util/schemacomp/SchemaComparatorTest.java @@ -19,23 +19,23 @@ package org.alfresco.util.schemacomp; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.columns; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.dumpDiffs; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.dumpValidation; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fk; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fkeys; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.indexes; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.pk; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.table; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; import java.util.Arrays; -import java.util.Collection; import java.util.Iterator; -import java.util.List; import org.alfresco.util.schemacomp.Difference.Where; -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.Table; -import org.apache.commons.lang.ArrayUtils; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQL5InnoDBDialect; import org.junit.Before; @@ -137,74 +137,4 @@ public class SchemaComparatorTest // Table table_in_right does not exist in the left schema } - - - private void dumpValidation(List validationResults) - { - System.out.println("Validation Results (" + validationResults.size() + ")"); - for (ValidationResult r : validationResults) - { - System.out.println(r); - } - } - - private void dumpDiffs(Results differences, boolean showNonDifferences) - { - System.out.println("Differences (" + differences.size() + ")"); - for (Difference d : differences) - { - if (d.getWhere() != Where.IN_BOTH_NO_DIFFERENCE || showNonDifferences) - { - System.out.println(d); - } - } - } - - private Table table(String name) - { - return new Table(null, name, columns("id NUMBER(10)"), pk("pk_" + name, "id"), fkeys(), indexes()); - } - - private Collection columns(String... colDefs) - { - assertTrue("Tables must have columns", colDefs.length > 0); - Column[] columns = new Column[colDefs.length]; - - for (int i = 0; i < colDefs.length; i++) - { - String[] parts = colDefs[i].split(" "); - columns[i] = new Column(null, parts[0], parts[1], false); - } - return Arrays.asList(columns); - } - - private PrimaryKey pk(String name, String... columnNames) - { - assertTrue("No columns specified", columnNames.length > 0); - PrimaryKey pk = new PrimaryKey(null, name, Arrays.asList(columnNames)); - return pk; - } - - private List fkeys(ForeignKey... fkeys) - { - return Arrays.asList(fkeys); - } - - private ForeignKey fk(String fkName, String localColumn, String targetTable, String targetColumn) - { - return new ForeignKey(null, fkName, localColumn, targetTable, targetColumn); - } - - private Collection indexes(String... indexDefs) - { - Index[] indexes = new Index[indexDefs.length]; - for (int i = 0; i < indexDefs.length; i++) - { - String[] parts = indexDefs[i].split(" "); - String name = parts[0]; - String[] columns = (String[]) ArrayUtils.subarray(parts, 1, parts.length); - indexes[i] = new Index(null, name, Arrays.asList(columns)); - } - return Arrays.asList(indexes); - } } diff --git a/source/java/org/alfresco/util/schemacomp/SchemaToXML.java b/source/java/org/alfresco/util/schemacomp/SchemaToXML.java new file mode 100644 index 0000000000..315c122c1e --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/SchemaToXML.java @@ -0,0 +1,92 @@ +/* + * 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 javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.alfresco.util.schemacomp.model.Schema; +import org.xml.sax.SAXException; + +import com.sun.star.uno.RuntimeException; + +/** + * Converts an in-memory Schema to an XML output stream. + * + * @author Matt Ward + */ +public class SchemaToXML +{ + private TransformerHandler xmlOut; + private Schema schema; + + public SchemaToXML(Schema schema, StreamResult streamResult) + { + final SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance(); + try + { + xmlOut = stf.newTransformerHandler(); + } + catch (TransformerConfigurationException error) + { + throw new RuntimeException("Unable to create TransformerHandler.", error); + } + final Transformer t = xmlOut.getTransformer(); + try + { + t.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); + } + catch (final IllegalArgumentException e) + { + // It was worth a try + } + t.setOutputProperty(OutputKeys.INDENT, "yes"); + xmlOut.setResult(streamResult); + + + this.schema = schema; + } + + + public void execute() + { + try + { + attemptTransformation(); + } + catch (SAXException e) + { + throw new RuntimeException("Unable to complete transformation.", e); + } + } + + private void attemptTransformation() throws SAXException + { + xmlOut.startDocument(); + DbObjectXMLTransformer dboTransformer = new DbObjectXMLTransformer(xmlOut); + dboTransformer.output(schema); + xmlOut.endDocument(); + } + +} diff --git a/source/java/org/alfresco/util/schemacomp/SchemaToXMLTest.java b/source/java/org/alfresco/util/schemacomp/SchemaToXMLTest.java new file mode 100644 index 0000000000..a25ec005ae --- /dev/null +++ b/source/java/org/alfresco/util/schemacomp/SchemaToXMLTest.java @@ -0,0 +1,83 @@ +/* + * 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 static org.alfresco.util.schemacomp.SchemaCompTestingUtils.columns; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fk; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.fkeys; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.indexes; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.pk; +import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.table; +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import javax.xml.transform.stream.StreamResult; + +import org.alfresco.util.schemacomp.model.Schema; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for the SchemaToXML class. + * @author Matt Ward + */ +public class SchemaToXMLTest +{ + @Before + public void setUp() throws Exception + { + } + + @Test + public void canTransformSchemaToXML() throws IOException + { + Writer writer = new StringWriter(); + StreamResult out = new StreamResult(writer); + + Schema schema = new Schema("alfresco"); + + schema.add( + table("node", + columns("id NUMBER(10)", + "nodeRef VARCHAR2(200)", + "name VARCHAR2(150)"), + pk("pk_node", "id"), + fkeys(fk("fk_node_noderef", "nodeRef", "node", "nodeRef")), + indexes("idx_node_by_id id nodeRef")) ); + + SchemaToXML transformer = new SchemaToXML(schema, out); + + transformer.execute(); + + System.out.println(writer.toString()); + + // Check the first couple of lines, details tests of the actual content + // are performed by DbObjectXMLTransformerTest + BufferedReader reader = new BufferedReader(new StringReader(writer.toString())); + assertEquals("", reader.readLine()); + assertEquals("", reader.readLine()); + assertEquals(" ", reader.readLine()); + } +} diff --git a/source/java/org/alfresco/util/schemacomp/model/Schema.java b/source/java/org/alfresco/util/schemacomp/model/Schema.java index aaf2d66162..10ee6ddd6b 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Schema.java +++ b/source/java/org/alfresco/util/schemacomp/model/Schema.java @@ -24,7 +24,6 @@ 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; /** @@ -108,12 +107,12 @@ public class Schema extends AbstractDbObject implements Iterable @Override public void accept(DbObjectVisitor visitor) - { + { + visitor.visit(this); + for (DbObject child : objects) { child.accept(visitor); } - - visitor.visit(this); } } diff --git a/source/java/org/alfresco/util/schemacomp/model/Table.java b/source/java/org/alfresco/util/schemacomp/model/Table.java index b596dfdcd6..65f9d17dbe 100644 --- a/source/java/org/alfresco/util/schemacomp/model/Table.java +++ b/source/java/org/alfresco/util/schemacomp/model/Table.java @@ -220,11 +220,11 @@ public class Table extends AbstractDbObject @Override public void accept(DbObjectVisitor visitor) { + visitor.visit(this); + for (DbObject child : getChildren()) { child.accept(visitor); } - - visitor.visit(this); } }