mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -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>
|
||||||
|
* <tag>content</tag>
|
||||||
|
* </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");
|
||||||
|
}
|
||||||
|
}
|
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
92
source/java/org/alfresco/util/schemacomp/SchemaToXML.java
Normal file
92
source/java/org/alfresco/util/schemacomp/SchemaToXML.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user