/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.extension.definition;
import static junit.framework.Assert.assertEquals;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.teiid.designer.extension.Constants;
import org.teiid.designer.extension.Factory;
import org.teiid.designer.extension.properties.ModelExtensionPropertyDefinition;
import org.teiid.designer.extension.properties.ModelExtensionPropertyDefinitionImpl;
/**
* ModelExtensionDefinitionWriterTest. This is a round-trip test of the writer and parser. The tests construct a MED, write it
* out, read it back (parser), then compare the resulting MED to the starting MED.
*/
public class ModelExtensionDefinitionWriterTest implements Constants {
private ModelExtensionAssistant assistant;
private ModelExtensionDefinitionWriter writer;
private ModelExtensionDefinitionParser parser;
private InputStream write( ModelExtensionDefinition med ) throws Exception {
return writer.writeAsStream(med);
}
private ModelExtensionDefinition parse( String fileName,
ModelExtensionDefinitionParser parser ) throws Exception {
return parser.parse(new FileInputStream(new File(fileName)), this.assistant);
}
@Before
public void beforeEach() {
this.assistant = Factory.createAssistant();
this.writer = Factory.createWriter();
this.parser = Factory.createParser();
}
@Test
public void shouldWriteBuiltInMeds() throws Exception {
for (String medFileName : BUILT_IN_MEDS) {
ModelExtensionDefinition med = parse(medFileName, this.parser);
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
}
@Test
public void shouldWriteEmptyMed() throws Exception {
// Create a default MED
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteMedNamespacePrefix1() throws Exception {
// Create MED with namespace prefix only
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("myPrefix"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteMedNamespacePrefix2() throws Exception {
// Create MED with namespace prefix containing special chars
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("Wierd<Chars%Here"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteAllHeaderValues() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteAllHeaderValues2() throws Exception {
// Create MED - all header field values set, have html chars
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My<Custom>NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom:yep"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational#1"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 @ Extension Definition"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteExtendedMetaclass1() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Add a single metaclass - with no properties
med.addMetaclass("org.teiid.designer.metamodels.relational.impl.ProcedureImpl"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteExtendedMetaclass2() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Add multiple metaclasses - with no properties
med.addMetaclass("org.teiid.designer.metamodels.relational.impl.ProcedureImpl"); //$NON-NLS-1$
med.addMetaclass("org.teiid.designer.metamodels.relational.impl.BaseTableImpl"); //$NON-NLS-1$
med.addMetaclass("org.teiid.designer.metamodels.relational.impl.ColumnImpl"); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteExtendedMetaclassWProp() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Add single metaclass - with one default property
med.addMetaclass("org.teiid.designer.metamodels.relational.impl.BaseTableImpl"); //$NON-NLS-1$
ModelExtensionPropertyDefinition propDefn = new ModelExtensionPropertyDefinitionImpl(med);
med.addPropertyDefinition("org.teiid.designer.metamodels.relational.impl.BaseTableImpl", propDefn); //$NON-NLS-1$
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteExtendedMetaclassWProps1() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Will extend a single metaclass - with a few properties of different types
med.addMetaclass(TABLE_METACLASS_NAME);
// Factory method creates three different property definitions
for (ModelExtensionPropertyDefinition propDefn : Factory.getTestPropertyDefns(med)) {
med.addPropertyDefinition(TABLE_METACLASS_NAME, propDefn);
}
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
@Test
public void shouldWriteExtendedMetaclassWProps2() throws Exception {
// Create MED - all header field values set
ModelExtensionDefinition med = new ModelExtensionDefinition(this.assistant);
med.setNamespacePrefix("My-Custom-NS"); //$NON-NLS-1$
med.setNamespaceUri("org.teiid.designer.extension.mycustom"); //$NON-NLS-1$
med.setMetamodelUri("http://www.metamatrix.com/metamodels/Relational"); //$NON-NLS-1$
med.setDescription("My Custom 7.4 Extension Definition"); //$NON-NLS-1$
// Will extend a two metaclasses - with a different number of properties on each
med.addMetaclass(TABLE_METACLASS_NAME);
med.addMetaclass(COLUMN_METACLASS_NAME);
// Put three property defns on table
List<ModelExtensionPropertyDefinition> tableDefns = Factory.getTestPropertyDefns(med);
// Put one property defn on column
List<ModelExtensionPropertyDefinition> columnDefns = Factory.getTestPropertyDefns(med);
columnDefns.remove(1); // remove will shift elements, do it twice...
columnDefns.remove(1);
// Add the definitions for BaseTable metaclass
for (ModelExtensionPropertyDefinition propDefn : tableDefns) {
med.addPropertyDefinition(TABLE_METACLASS_NAME, propDefn);
}
// Add the definitions for Column metaclass
for (ModelExtensionPropertyDefinition propDefn : columnDefns) {
med.addPropertyDefinition(COLUMN_METACLASS_NAME, propDefn);
}
// Write it, then read it back into another MED
ModelExtensionDefinition resultMed = roundTrip(med);
assertEquals(med, resultMed);
}
/*
* This will 'round-trip' the MED. It is written out to a temp file, then parsed (read back in). The
* resulting MED is returned.
*/
private ModelExtensionDefinition roundTrip( ModelExtensionDefinition med ) throws Exception {
// Write the incoming MED to a temp file
InputStream stream = write(med);
File outFile = new File(TEMP_MED_FILE_NAME);
writeToFile(stream, outFile);
// Now read the temp file back in, creating a new Med
ModelExtensionDefinition resultMed = parse(TEMP_MED_FILE_NAME, this.parser);
outFile.delete();
return resultMed;
}
private void writeToFile(InputStream inputStream, File file) throws IOException, FileNotFoundException {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
inputStream.close();
out.flush();
out.close();
}
}