/*
* 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.convertor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.teiid.core.designer.util.ModelType;
import org.teiid.core.designer.util.StringConstants;
import org.teiid.designer.extension.Constants;
import org.teiid.designer.extension.ExtensionPlugin;
import org.teiid.designer.extension.convertor.MxdConstants.TargetObjectMappings;
import org.teiid.designer.extension.convertor.mxd.DisplayType;
import org.teiid.designer.extension.convertor.mxd.MetaclassType;
import org.teiid.designer.extension.convertor.mxd.ObjectFactory;
import org.teiid.designer.extension.convertor.mxd.PropertyType;
import org.teiid.designer.extension.definition.ModelExtensionDefinition;
import org.teiid.designer.extension.definition.ModelExtensionDefinitionParser;
import org.teiid.designer.runtime.spi.TeiidPropertyDefinition;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
@SuppressWarnings( {"nls", "javadoc"} )
public class TestMxdConvertor implements Constants {
private final MxdConvertor convertor = MxdConvertor.getInstance();
private final ObjectFactory factory = new ObjectFactory();
private enum Tags {
MODEL_EXTENSION("modelExtension"),
MODEL_TYPE("modelType"),
EXT_META_CLASS("extendedMetaclass"),
PROPERTY("property"),
DISPLAY("display"),
DESCRIPTION("description");
private String tag;
private Tags(String tag) {
this.tag = tag;
}
/**
* @return the tag
*/
public String tag() {
return this.tag;
}
}
private final String ODATA_URI = "{http://www.jboss.org/teiiddesigner/ext/odata/2012}";
private final ExpectedProperty JOIN_COLUMN_PROPERTY = new ExpectedProperty("JoinColumn",
TargetObjectMappings.COLUMN,
Boolean.class,
false, true, false, false,
"Join Column",
"On Link tables this property defines the join column");
private final ExpectedProperty COMPLEX_TYPE_PROPERTY = new ExpectedProperty("ComplexType",
TargetObjectMappings.COLUMN,
String.class,
false, true, false, false,
"Complex Type Name", "Name of the Complex Type in EDM");
private final ExpectedProperty COLUMN_GROUP_PROPERTY = new ExpectedProperty("ColumnGroup",
TargetObjectMappings.COLUMN,
String.class,
false, true, false, false,
"Column Group", "Name of the Column Group");
private final ExpectedProperty HTTP_METHOD_PROPERTY = new ExpectedProperty("HttpMethod",
TargetObjectMappings.PROCEDURE,
String.class,
false, true, false, true,
"Http Method", "Http method used for procedure invocation");
private final ExpectedProperty ENTITY_TYPE_PROC_PROPERTY = new ExpectedProperty("EntityType",
TargetObjectMappings.PROCEDURE,
String.class,
false, true, false, true,
"Entity Type Name", "Name of the Entity Type in EDM");
private final ExpectedProperty ENTITY_TYPE_TABLE_PROPERTY = new ExpectedProperty("EntityType",
TargetObjectMappings.TABLE,
String.class,
false, true, false, true,
"Entity Type Name", "Name of the Entity Type in EDM");
private final ExpectedProperty LINK_TABLES_PROPERTY = new ExpectedProperty("LinkTables",
TargetObjectMappings.TABLE,
String.class,
false, true, false, false,
"Link Tables",
"Used to define navigation relationship in many to many case");
/**
* @param metaClass
* @param expProperties
*/
private void checkExpectedValues(MetaclassType metaClass, List<ExpectedProperty> expProperties) {
for (ExpectedProperty expProperty : expProperties) {
boolean foundProp = false;
for (PropertyType property : metaClass.getProperty()) {
if (expProperty.getName().equals(property.getName())) {
foundProp = true;
assertEquals(expProperty.getType().getSimpleName().toLowerCase(), property.getType());
assertEquals(expProperty.isAdvanced(), property.getAdvanced());
assertEquals(expProperty.isIndex(), property.getIndex());
assertEquals(expProperty.isMasked(), property.getMasked());
assertEquals(expProperty.isRequired(), property.getRequired());
assertEquals(1, property.getDisplay().size());
assertEquals(expProperty.getDisplayName(), property.getDisplay().get(0).getValue());
}
}
assertTrue("Failed to match a metaclass property to an expected property", foundProp);
}
}
@Test
public void testFileToMetaClassConversion() throws Exception {
File testFile = new File(ODATA_TRANSLATOR_SOURCE);
Collection<MetaclassType> metaClasses = convertor.read(testFile);
assertNotNull(metaClasses);
assertEquals(3, metaClasses.size());
for (MetaclassType metaClass : metaClasses) {
if (metaClass.getName().equals(TargetObjectMappings.TABLE.getDesignerClass())) {
assertEquals(2, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(ENTITY_TYPE_TABLE_PROPERTY);
expProperties.add(LINK_TABLES_PROPERTY);
checkExpectedValues(metaClass, expProperties);
} else if (metaClass.getName().equals(TargetObjectMappings.PROCEDURE.getDesignerClass())) {
assertEquals(2, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(ENTITY_TYPE_PROC_PROPERTY);
expProperties.add(HTTP_METHOD_PROPERTY);
checkExpectedValues(metaClass, expProperties);
} else if (metaClass.getName().equals(TargetObjectMappings.COLUMN.getDesignerClass())) {
assertEquals(3, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(JOIN_COLUMN_PROPERTY);
expProperties.add(COMPLEX_TYPE_PROPERTY);
expProperties.add(COLUMN_GROUP_PROPERTY);
checkExpectedValues(metaClass, expProperties);
}
}
}
private TeiidPropertyDefinition createTeiidPropertyDefinition(ExpectedProperty expProperty) {
TeiidPropertyDefinition defn = new TeiidPropertyDefinition();
defn.setName(ODATA_URI + expProperty.getName());
defn.setOwner(expProperty.getTarget().getTeiidClass());
defn.setPropertyTypeClassName(expProperty.getType().getCanonicalName());
defn.setAdvanced(expProperty.isAdvanced());
defn.setMasked(expProperty.isMasked());
defn.setRequired(expProperty.isRequired());
defn.setDisplayName(expProperty.getDisplayName());
defn.setDescription(expProperty.getDescription());
return defn;
}
@Test
public void testTranslatorToMetaClassConversion() {
List<TeiidPropertyDefinition> defnCollection = new ArrayList<TeiidPropertyDefinition>();
TeiidPropertyDefinition defn;
defn = createTeiidPropertyDefinition(JOIN_COLUMN_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(COMPLEX_TYPE_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(COLUMN_GROUP_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(HTTP_METHOD_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(ENTITY_TYPE_PROC_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(ENTITY_TYPE_TABLE_PROPERTY);
defnCollection.add(defn);
defn = createTeiidPropertyDefinition(LINK_TABLES_PROPERTY);
defnCollection.add(defn);
Collection<MetaclassType> metaClasses = convertor.read(defnCollection);
assertNotNull(metaClasses);
assertEquals(3, metaClasses.size());
for (MetaclassType metaClass : metaClasses) {
if (metaClass.getName().equals(TargetObjectMappings.TABLE.getDesignerClass())) {
assertEquals(2, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(ENTITY_TYPE_TABLE_PROPERTY);
expProperties.add(LINK_TABLES_PROPERTY);
checkExpectedValues(metaClass, expProperties);
} else if (metaClass.getName().equals(TargetObjectMappings.PROCEDURE.getDesignerClass())) {
assertEquals(2, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(ENTITY_TYPE_PROC_PROPERTY);
expProperties.add(HTTP_METHOD_PROPERTY);
checkExpectedValues(metaClass, expProperties);
} else if (metaClass.getName().equals(TargetObjectMappings.COLUMN.getDesignerClass())) {
assertEquals(3, metaClass.getProperty().size());
List<ExpectedProperty> expProperties = new ArrayList<ExpectedProperty>();
expProperties.add(JOIN_COLUMN_PROPERTY);
expProperties.add(COMPLEX_TYPE_PROPERTY);
expProperties.add(COLUMN_GROUP_PROPERTY);
checkExpectedValues(metaClass, expProperties);
}
}
}
private void checkExpectedValues(PropertyType propertyType, Element propElement) {
String advanced = propElement.getAttribute("advanced");
String required = propElement.getAttribute("required");
String index = propElement.getAttribute("index");
String masked = propElement.getAttribute("masked");
String type = propElement.getAttribute("type");
assertEquals(propertyType.getAdvanced(), Boolean.parseBoolean(advanced));
assertEquals(propertyType.getRequired(), Boolean.parseBoolean(required));
assertEquals(propertyType.getIndex(), index == "" ? true : Boolean.parseBoolean(index));
assertEquals(propertyType.getMasked(), Boolean.parseBoolean(masked));
assertEquals(propertyType.getType(), type);
NodeList displayNodes = propElement.getElementsByTagName("display");
assertEquals(1, displayNodes.getLength());
assertEquals(propertyType.getDisplay().get(0).getValue(), displayNodes.item(0).getTextContent());
NodeList descNodes = propElement.getElementsByTagName("description");
assertEquals(1, descNodes.getLength());
assertEquals(propertyType.getDescription().get(0).getValue(), descNodes.item(0).getTextContent());
}
private PropertyType createMetaClass(final MetaclassType tableMetaClass, ExpectedProperty expProperty) {
PropertyType metaClassProperty = factory.createPropertyType();
metaClassProperty.setName(expProperty.getName());
metaClassProperty.setType(expProperty.getType().getSimpleName().toLowerCase());
metaClassProperty.setAdvanced(expProperty.isAdvanced());
metaClassProperty.setIndex(expProperty.isIndex());
metaClassProperty.setMasked(expProperty.isMasked());
metaClassProperty.setRequired(expProperty.isRequired());
DisplayType displayName = factory.createDisplayType();
displayName.setValue(expProperty.getDisplayName());
metaClassProperty.getDisplay().add(displayName);
DisplayType description = factory.createDisplayType();
description.setValue(expProperty.getDescription());
metaClassProperty.getDescription().add(description);
tableMetaClass.getProperty().add(metaClassProperty);
return metaClassProperty;
}
@Test
public void testMetaClassesToFile() throws Exception {
final MetaclassType tableMetaClass = factory.createMetaclassType();
final MetaclassType procMetaClass = factory.createMetaclassType();
final MetaclassType colMetaClass = factory.createMetaclassType();
tableMetaClass.setName(TargetObjectMappings.TABLE.getDesignerClass());
procMetaClass.setName(TargetObjectMappings.PROCEDURE.getDesignerClass());
colMetaClass.setName(TargetObjectMappings.COLUMN.getDesignerClass());
List<MetaclassType> metaClasses = new ArrayList<MetaclassType>();
metaClasses.add(tableMetaClass);
metaClasses.add(procMetaClass);
metaClasses.add(colMetaClass);
/* @ExtensionMetadataProperty(applicable=Table.class, datatype=String.class, display="Link Tables",
* description="Used to define navigation relationship in many to many case")
* public static final String LINK_TABLES = MetadataFactory.ODATA_URI+"LinkTables"; //$NON-NLS-1$
*/
PropertyType linkTables = createMetaClass(tableMetaClass, LINK_TABLES_PROPERTY);
/* @ExtensionMetadataProperty(applicable=Procedure.class, datatype=String.class, display="Http Method",
* description="Http method used for procedure invocation", required=true)
* public static final String HTTP_METHOD = MetadataFactory.ODATA_URI+"HttpMethod"; //$NON-NLS-1$
*/
PropertyType httpMethod = createMetaClass(procMetaClass, HTTP_METHOD_PROPERTY);
/* @ExtensionMetadataProperty(applicable=Column.class, datatype=Boolean.class, display="Join Column",
* description="On Link tables this property defines the join column")
* public static final String JOIN_COLUMN = MetadataFactory.ODATA_URI+"JoinColumn"; //$NON-NLS-1$
*/
PropertyType joinColumn = createMetaClass(colMetaClass, JOIN_COLUMN_PROPERTY);
/* @ExtensionMetadataProperty(applicable= {Table.class, Procedure.class}, datatype=String.class,
* display="Entity Type Name", description="Name of the Entity Type in EDM", required=true)
* public static final String ENTITY_TYPE = MetadataFactory.ODATA_URI+"EntityType"; //$NON-NLS-1$
*/
// Added to tableMetaClass
PropertyType entityType1 = createMetaClass(tableMetaClass, ENTITY_TYPE_TABLE_PROPERTY);
// Added to procMetaClass
PropertyType entityType2 = createMetaClass(procMetaClass, ENTITY_TYPE_PROC_PROPERTY);
/* @ExtensionMetadataProperty(applicable=Column.class, datatype=String.class, display="Complex Type Name",
* description="Name of the Complex Type in EDM")
* public static final String COMPLEX_TYPE = MetadataFactory.ODATA_URI+"ComplexType"; //$NON-NLS-1$
*/
PropertyType complexType = createMetaClass(colMetaClass, COMPLEX_TYPE_PROPERTY);
/* @ExtensionMetadataProperty(applicable=Column.class, datatype=String.class, display="Column Group",
* description="Name of the Column Group")
* public static final String COLUMN_GROUP = MetadataFactory.ODATA_URI+"ColumnGroup"; //$NON-NLS-1$
*/
PropertyType colGroupType = createMetaClass(colMetaClass, COLUMN_GROUP_PROPERTY);
/* Perform test */
File outputFile = File.createTempFile(this.getClass().getSimpleName(), StringConstants.DOT + StringConstants.XML);
outputFile.deleteOnExit();
FileOutputStream output = new FileOutputStream(outputFile);
convertor.write("odata", ModelType.Type.PHYSICAL, metaClasses, output);
output.close();
InputStream inputStream = new FileInputStream(outputFile);
Reader in = new InputStreamReader(inputStream,"UTF-8");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(in);
is.setEncoding("UTF-8");
Document document = builder.parse(is);
Element docElement = document.getDocumentElement();
assertEquals(Tags.MODEL_EXTENSION.tag(), docElement.getNodeName());
NodeList modelTypes = docElement.getElementsByTagName(Tags.MODEL_TYPE.tag());
assertEquals(1, modelTypes.getLength());
assertEquals(ModelType.Type.PHYSICAL.getName(), modelTypes.item(0).getTextContent());
NodeList metaClassTypes = docElement.getElementsByTagName(Tags.EXT_META_CLASS.tag());
assertEquals(3, metaClassTypes.getLength());
int propertyElementsSeen = 0;
for (int i = 0; i < metaClassTypes.getLength(); i++) {
Node node = metaClassTypes.item(i);
assertTrue(node instanceof Element);
Element metaClassElement = (Element) node;
String targetType = metaClassElement.getAttribute("name");
NodeList propNodes = metaClassElement.getElementsByTagName(Tags.PROPERTY.tag());
assertTrue(propNodes.getLength() > 0);
propertyElementsSeen += propNodes.getLength();
// Property Element
for (int j = 0; j < propNodes.getLength(); ++j) {
Node propNode = propNodes.item(j);
assertTrue(propNode instanceof Element);
Element propElement = (Element) propNode;
String propName = propElement.getAttribute("name");
if (linkTables.getName().equals(propName)) {
checkExpectedValues(linkTables, propElement);
assertEquals(tableMetaClass.getName(), targetType);
} else if (httpMethod.getName().equals(propName)) {
checkExpectedValues(httpMethod, propElement);
assertEquals(procMetaClass.getName(), targetType);
} else if (joinColumn.getName().equals(propName)) {
checkExpectedValues(joinColumn, propElement);
assertEquals(colMetaClass.getName(), targetType);
} else if (entityType1.getName().equals(propName)) {
if (tableMetaClass.getName().equals(targetType))
checkExpectedValues(entityType1, propElement);
else if(procMetaClass.getName().equals(targetType))
checkExpectedValues(entityType2, propElement);
else
fail("entity type 1 or 2 is not targetting table or procedure");
} else if (complexType.getName().equals(propName)) {
checkExpectedValues(complexType, propElement);
assertEquals(colMetaClass.getName(), targetType);
} else if (colGroupType.getName().equals(propName)) {
checkExpectedValues(colGroupType, propElement);
assertEquals(colMetaClass.getName(), targetType);
}
}
}
assertEquals(7, propertyElementsSeen);
/* See if the result parses as expected */
inputStream = new FileInputStream(outputFile);
ModelExtensionDefinitionParser parser = new ModelExtensionDefinitionParser(ExtensionPlugin.getInstance()
.getMedSchema());
ModelExtensionDefinition med = parser.parse(inputStream, ExtensionPlugin.getInstance().createDefaultModelObjectExtensionAssistant());
assertNotNull(med);
for (String err : parser.getErrors()) {
System.out.println("Parser Error: " + err);
}
assertTrue(parser.getErrors().isEmpty());
}
}