ALF-11031: Persist object graph to file

Implemented so that the graph can actually be rendered to XML as a OutputStream, File, Writer.



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31548 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Matt Ward
2011-10-28 16:50:58 +00:00
parent dd9a270ab0
commit 2754a50ab9
9 changed files with 833 additions and 85 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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: <column name="the_column_name"/>
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:
* <pre>
* &lt;tag&gt;content&lt;/tag&gt;
* </pre>
*
* @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<String> columnNames) throws SAXException
{
simpleStartTag("columnnames");
for (String columnName : columnNames)
{
simpleElement("columnname", columnName);
}
simpleEndTag("columnnames");
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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("<column name=\"last_name\">", reader.readLine());
assertEquals(" <type>VARCHAR2(100)</type>", reader.readLine());
assertEquals(" <nullable>true</nullable>", reader.readLine());
assertEquals("</column>", 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("<foreignkey name=\"fk_for_some_table\">", reader.readLine());
assertEquals(" <localcolumn>local_column</localcolumn>", reader.readLine());
assertEquals(" <targettable>target_table</targettable>", reader.readLine());
assertEquals(" <targetcolumn>target_column</targetcolumn>", reader.readLine());
assertEquals("</foreignkey>", 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("<index name=\"index_name\">", reader.readLine());
assertEquals(" <columnnames>", reader.readLine());
assertEquals(" <columnname>first</columnname>", reader.readLine());
assertEquals(" <columnname>second</columnname>", reader.readLine());
assertEquals(" </columnnames>", reader.readLine());
assertEquals("</index>", 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("<primarykey name=\"pk_name\">", reader.readLine());
assertEquals(" <columnnames>", reader.readLine());
assertEquals(" <columnname>first</columnname>", reader.readLine());
assertEquals(" <columnname>second</columnname>", reader.readLine());
assertEquals(" </columnnames>", reader.readLine());
assertEquals("</primarykey>", reader.readLine());
}
@Test
public void transformSchema() throws IOException
{
Collection<Column> columns = columns("one VARCHAR2(100)", "two NUMBER(10)");
PrimaryKey pk = new PrimaryKey(null, "pk_for_my_table", Arrays.asList("id"));
Collection<ForeignKey> fks = fkeys(fk("fk_one", "lc", "tt", "tc"), fk("fk_two", "lc", "tt", "tc"));
Collection<Index> 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("<schema name=\"my_schema\">", reader.readLine());
assertEquals(" <objects>", reader.readLine());
skipUntilEnd(" {table}", reader);
skipUntilEnd(" {table}", reader);
skipUntilEnd(" {sequence}", reader, true);
skipUntilEnd(" {sequence}", reader, true);
skipUntilEnd(" {sequence}", reader, true);
assertEquals(" </objects>", reader.readLine());
assertEquals("</schema>", 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("<sequence name=\"my_sequence\"/>", reader.readLine());
}
@Test
public void transformTable() throws IOException
{
Collection<Column> columns = columns("one VARCHAR2(100)", "two NUMBER(10)");
PrimaryKey pk = new PrimaryKey(null, "pk_for_my_table", Arrays.asList("id"));
Collection<ForeignKey> fks = fkeys(fk("fk_one", "lc", "tt", "tc"), fk("fk_two", "lc", "tt", "tc"));
Collection<Index> 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("<table name=\"my_table\">", reader.readLine());
assertEquals(" <columns>", reader.readLine());
skipUntilEnd(" {column}", reader);
skipUntilEnd(" {column}", reader);
assertEquals(" </columns>", reader.readLine());
skipUntilEnd(" {primarykey}", reader);
assertEquals(" <foreignkeys>", reader.readLine());
skipUntilEnd(" {foreignkey}", reader);
skipUntilEnd(" {foreignkey}", reader);
assertEquals(" </foreignkeys>", reader.readLine());
assertEquals(" <indexes>", reader.readLine());
skipUntilEnd(" {index}", reader);
skipUntilEnd(" {index}", reader);
assertEquals(" </indexes>", reader.readLine());
assertEquals("</table>", 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.
* <p>
* 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 </mytag>
// or if an empty tag is expected
// {mytag} becomes <mytag .../>
if (emptyTag)
{
textToFind = textToFind.trim().
replace("{", "<").
replace("}", "\\s+.*/>");
}
else
{
textToFind = textToFind.trim().
replace("{", "</").
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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", reader.readLine());
}
private void dumpOutput()
{
if (outputDumpEnabled)
{
System.out.println(writer.toString());
}
}
}

View File

@@ -29,10 +29,12 @@ import org.junit.runners.Suite;
@RunWith(Suite.class) @RunWith(Suite.class)
@Suite.SuiteClasses( @Suite.SuiteClasses(
{ {
DbObjectXMLTransformerTest.class,
DbPropertyTest.class, DbPropertyTest.class,
DefaultComparisonUtilsTest.class, DefaultComparisonUtilsTest.class,
SchemaComparatorTest.class, SchemaComparatorTest.class,
ValidatingVisitorTest.class ValidatingVisitorTest.class,
SchemaToXMLTest.class,
}) })
public class SchemaCompTestSuite public class SchemaCompTestSuite
{ {

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<ValidationResult> 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<Column> columns, PrimaryKey primaryKey,
Collection<ForeignKey> foreignKeys, Collection<Index> indexes)
{
return new Table(null, name, columns, primaryKey, foreignKeys, indexes);
}
public static Collection<Column> 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<ForeignKey> 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<Index> 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);
}
}

View File

@@ -19,23 +19,23 @@
package org.alfresco.util.schemacomp; 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.assertEquals;
import static org.junit.Assert.assertSame; import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import org.alfresco.util.schemacomp.Difference.Where; 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.Schema;
import org.alfresco.util.schemacomp.model.Table; import org.alfresco.util.schemacomp.model.Table;
import org.apache.commons.lang.ArrayUtils;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQL5InnoDBDialect; import org.hibernate.dialect.MySQL5InnoDBDialect;
import org.junit.Before; import org.junit.Before;
@@ -137,74 +137,4 @@ public class SchemaComparatorTest
// Table table_in_right does not exist in the left schema // Table table_in_right does not exist in the left schema
} }
private void dumpValidation(List<ValidationResult> 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<Column> 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<ForeignKey> 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<Index> 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);
}
} }

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", reader.readLine());
assertEquals("<schema name=\"alfresco\">", reader.readLine());
assertEquals(" <objects>", reader.readLine());
}
}

View File

@@ -24,7 +24,6 @@ import java.util.List;
import org.alfresco.util.schemacomp.DbObjectVisitor; import org.alfresco.util.schemacomp.DbObjectVisitor;
import org.alfresco.util.schemacomp.DiffContext; import org.alfresco.util.schemacomp.DiffContext;
import org.alfresco.util.schemacomp.Results;
import org.alfresco.util.schemacomp.Result.Strength; import org.alfresco.util.schemacomp.Result.Strength;
/** /**
@@ -109,11 +108,11 @@ public class Schema extends AbstractDbObject implements Iterable<DbObject>
@Override @Override
public void accept(DbObjectVisitor visitor) public void accept(DbObjectVisitor visitor)
{ {
visitor.visit(this);
for (DbObject child : objects) for (DbObject child : objects)
{ {
child.accept(visitor); child.accept(visitor);
} }
visitor.visit(this);
} }
} }

View File

@@ -220,11 +220,11 @@ public class Table extends AbstractDbObject
@Override @Override
public void accept(DbObjectVisitor visitor) public void accept(DbObjectVisitor visitor)
{ {
visitor.visit(this);
for (DbObject child : getChildren()) for (DbObject child : getChildren())
{ {
child.accept(visitor); child.accept(visitor);
} }
visitor.visit(this);
} }
} }