/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.odata4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.olingo.client.api.edm.xml.DataServices;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.client.core.edm.ClientCsdlXMLMetadata;
import org.apache.olingo.client.core.edm.xml.ClientCsdlEdmx;
import org.apache.olingo.client.core.serialization.ClientODataDeserializerImpl;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReferentialConstraint;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
import org.apache.olingo.commons.api.edm.provider.CsdlFunction;
import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
import org.apache.olingo.commons.api.edm.provider.CsdlReferentialConstraint;
import org.apache.olingo.commons.api.edm.provider.CsdlReturnType;
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.api.format.ContentType;
import org.junit.Test;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.metadata.Column;
import org.teiid.metadata.ColumnSet;
import org.teiid.metadata.ForeignKey;
import org.teiid.metadata.KeyRecord;
import org.teiid.metadata.ProcedureParameter;
import org.teiid.metadata.KeyRecord.Type;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Procedure;
import org.teiid.metadata.Table;
import org.teiid.query.function.FunctionTree;
import org.teiid.query.function.UDFSource;
import org.teiid.query.metadata.DDLStringVisitor;
import org.teiid.query.metadata.MetadataValidator;
import org.teiid.query.metadata.SystemMetadata;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.query.validator.ValidatorReport;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.WSConnection;
import org.teiid.translator.odata4.ODataExecutionFactory;
import org.teiid.translator.odata4.ODataMetadataProcessor;
import org.teiid.translator.odata4.ODataMetadataProcessor.ODataType;
@SuppressWarnings({"nls", "unused"})
public class TestODataMetadataProcessor {
private ODataExecutionFactory translator;
public static TransformationMetadata getTransformationMetadata(MetadataFactory mf, ODataExecutionFactory ef) throws Exception {
TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(mf.asMetadataStore(), "trippin", new FunctionTree("foo", new UDFSource(ef.getPushDownFunctions())));
ValidatorReport report = new MetadataValidator().validate(metadata.getVdbMetaData(), metadata.getMetadataStore());
if (report.hasItems()) {
throw new RuntimeException(report.getFailureMessage());
}
return metadata;
}
static MetadataFactory tripPinMetadata() throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor() {
protected XMLMetadata getSchema(WSConnection conn) throws TranslatorException {
try {
ClientODataDeserializerImpl deserializer = new ClientODataDeserializerImpl(
false, ContentType.APPLICATION_XML);
XMLMetadata metadata = deserializer.toMetadata(
new FileInputStream(UnitTestUtil.getTestDataFile("trippin.xml")));
return metadata;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
};
Properties props = new Properties();
props.setProperty("schemaNamespace", "Microsoft.OData.SampleService.Models.TripPin");
MetadataFactory mf = new MetadataFactory("vdb", 1, "trippin", SystemMetadata.getInstance().getRuntimeTypeMap(), props, null);
processor.process(mf, null);
// String ddl = DDLStringVisitor.getDDLString(mf.getSchema(), null, null);
// System.out.println(ddl);
return mf;
}
@Test
public void testSchema() throws Exception {
translator = new ODataExecutionFactory();
translator.start();
MetadataFactory mf = tripPinMetadata();
TransformationMetadata metadata = getTransformationMetadata(mf, this.translator);
String ddl = DDLStringVisitor.getDDLString(mf.getSchema(), null, null);
//System.out.println(ddl);
MetadataFactory mf2 = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null);
QueryParser.getQueryParser().parseDDL(mf2, ddl);
Procedure p = mf.getSchema().getProcedure("ResetDataSource");
assertNotNull(p);
assertEquals(0, p.getParameters().size());
}
static CsdlProperty createProperty(String name, EdmPrimitiveTypeKind type) {
return new CsdlProperty().setName(name).setType(type.getFullQualifiedName());
}
static CsdlParameter createParameter(String name, EdmPrimitiveTypeKind type) {
return new CsdlParameter().setName(name).setType(type.getFullQualifiedName());
}
static XMLMetadata buildXmlMetadata(Object... schemaElements) {
final CsdlSchema schema = new CsdlSchema();
schema.setNamespace("namespace");
schema.setEntityContainer(new CsdlEntityContainer());
ArrayList<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
ArrayList<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
ArrayList<CsdlComplexType> complexTypes = new ArrayList<CsdlComplexType>();
ArrayList<CsdlFunctionImport> functionImports = new ArrayList<CsdlFunctionImport>();
ArrayList<CsdlFunction> functions = new ArrayList<CsdlFunction>();
ArrayList<CsdlActionImport> actionImports = new ArrayList<CsdlActionImport>();
ArrayList<CsdlAction> actions = new ArrayList<CsdlAction>();
for (Object obj:schemaElements) {
if (obj instanceof CsdlEntitySet) {
entitySets.add((CsdlEntitySet)obj);
}
else if (obj instanceof CsdlEntityType) {
entityTypes.add((CsdlEntityType)obj);
}
else if (obj instanceof CsdlComplexType) {
complexTypes.add((CsdlComplexType)obj);
} else if (obj instanceof CsdlFunctionImport) {
functionImports.add((CsdlFunctionImport)obj);
} else if (obj instanceof CsdlFunction) {
functions.add((CsdlFunction)obj);
} else if (obj instanceof CsdlActionImport) {
actionImports.add((CsdlActionImport)obj);
} else if (obj instanceof CsdlAction) {
actions.add((CsdlAction)obj);
}
}
schema.setEntityTypes(entityTypes);
schema.setComplexTypes(complexTypes);
schema.setActions(actions);
schema.setFunctions(functions);
schema.getEntityContainer().setEntitySets(entitySets);
schema.getEntityContainer().setFunctionImports(functionImports);
schema.getEntityContainer().setActionImports(actionImports);
ClientCsdlEdmx edmx = new ClientCsdlEdmx();
edmx.setVersion("1.0");
edmx.setDataServices(new DataServices() {
@Override
public List<CsdlSchema> getSchemas() {
return Arrays.asList(schema);
}
@Override
public String getMaxDataServiceVersion() {
return "4.0";
}
@Override
public String getDataServiceVersion() {
return "4.0";
}
});
return new ClientCsdlXMLMetadata(edmx);
}
static CsdlEntitySet createES(String name, String entityType) {
CsdlEntitySet es = new CsdlEntitySet();
es.setName(name);
es.setType(new FullQualifiedName(entityType));
return es;
}
@Test
public void testEnititySet() throws Exception {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "trippin", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null);
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25).setNullable(false));
properties.add(createProperty("dob", EdmPrimitiveTypeKind.DateTimeOffset).setNullable(true));
properties.add(createProperty("ssn", EdmPrimitiveTypeKind.Int64).setNullable(false));
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName("Person");
entityType.setProperties(properties);
entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("ssn")));
CsdlEntitySet es = createES("Persons", "namespace.Person");
XMLMetadata metadata = buildXmlMetadata(es, entityType);
processor.getMetadata(mf, metadata);
assertNotNull(mf.getSchema().getTable("Persons"));
Table person = mf.getSchema().getTable("Persons");
assertEquals(3, person.getColumns().size());
assertNotNull(person.getColumnByName("name"));
assertNotNull(person.getColumnByName("dob"));
assertNotNull(person.getColumnByName("ssn"));
Column name = person.getColumnByName("name");
Column dob = person.getColumnByName("dob");
Column ssn = person.getColumnByName("ssn");
assertEquals("string", name.getDatatype().getRuntimeTypeName());
assertEquals("timestamp", dob.getDatatype().getRuntimeTypeName());
assertEquals("long", ssn.getDatatype().getRuntimeTypeName());
assertTrue(name.getNullType() == NullType.No_Nulls);
assertTrue(dob.getNullType() == NullType.Nullable);
assertTrue(ssn.getNullType() == NullType.No_Nulls);
assertEquals(25, name.getLength());
assertNotNull(person.getPrimaryKey());
assertEquals(1, person.getPrimaryKey().getColumns().size());
assertEquals("ssn", person.getPrimaryKey().getColumns().get(0).getName());
assertTrue(person.getForeignKeys().isEmpty());
}
@Test
public void testEnititySetWithComplexType() throws Exception {
MetadataFactory mf = getEntityWithComplexProperty();
assertEquals(3, mf.getSchema().getTables().size());
assertNotNull(mf.getSchema().getTable("Persons"));
assertNotNull(mf.getSchema().getTable("Persons_address"));
assertNotNull(mf.getSchema().getTable("Persons_secondaddress"));
Table personTable = mf.getSchema().getTable("Persons");
assertEquals(2, personTable.getColumns().size());
assertNotNull(personTable.getPrimaryKey());
Table addressTable = mf.getSchema().getTable("Persons_address");
assertEquals(4, addressTable.getColumns().size());
assertNotNull(addressTable.getColumnByName("ssn"));
assertNotNull(addressTable.getColumnByName("ssn").getProperty(ODataMetadataProcessor.PSEUDO, false));
assertTrue(addressTable.getColumnByName("ssn").isSelectable());
assertEquals(1, addressTable.getForeignKeys().size());
assertEquals("Persons", addressTable.getForeignKeys().get(0).getReferenceTableName());
}
static MetadataFactory getEntityWithComplexProperty()
throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlComplexType address = complexType("Address");
XMLMetadata metadata = buildXmlMetadata(createES("Persons", "namespace.Person"),
buildPersonEntity(address), address);
processor.getMetadata(mf, metadata);
return mf;
}
@Test
public void testMultipleEnititySetWithSameComplexType() throws Exception {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlComplexType address = complexType("Address");
XMLMetadata metadata = buildXmlMetadata(
createES("Persons", "namespace.Person"),
buildPersonEntity(address), address,
createES("Corporate", "namespace.Business"),
buildBusinessEntity(address));
processor.getMetadata(mf, metadata);
assertEquals(5, mf.getSchema().getTables().size());
assertNotNull(mf.getSchema().getTable("Persons"));
assertNotNull(mf.getSchema().getTable("Corporate"));
assertNotNull(mf.getSchema().getTable("Persons_address"));
assertNotNull(mf.getSchema().getTable("Corporate_address"));
Table personTable = mf.getSchema().getTable("Persons");
assertEquals(2, personTable.getColumns().size());
Table personAddress= mf.getSchema().getTable("Persons_address");
assertEquals(4, personAddress.getColumns().size());
ForeignKey fk = personAddress.getForeignKeys().get(0);
assertNotNull(fk.getColumnByName("ssn"));
Table businessTable = mf.getSchema().getTable("Corporate");
assertEquals(1, businessTable.getColumns().size());
Table corporateAddress= mf.getSchema().getTable("Corporate_address");
assertEquals(4, corporateAddress.getColumns().size());
fk = corporateAddress.getForeignKeys().get(0);
assertNotNull(fk.getColumnByName("name"));
}
@Test
public void testOneToOneAssosiation() throws Exception {
MetadataFactory mf = oneToOneRelationMetadata();
Table g1 = mf.getSchema().getTable("G1");
Table g2 = mf.getSchema().getTable("G2");
ForeignKey fk = g2.getForeignKeys().get(0);
assertEquals("one_2_one", fk.getName());
assertNotNull(fk.getColumnByName("e1"));
}
@Test
public void testFunction() throws Exception {
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType("Edm.String");
MetadataFactory mf = functionMetadata("invoke", returnType, null);
Procedure p = mf.getSchema().getProcedure("invoke");
assertNotNull(p);
assertEquals(3, p.getParameters().size());
assertNull(p.getResultSet());
assertNotNull(getReturnParameter(p));
ProcedureParameter pp = getReturnParameter(p);
assertEquals("string", pp.getRuntimeType());
ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.FUNCTION, type);
}
@Test
public void testAction() throws Exception {
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType("Edm.String");
MetadataFactory mf = actionMetadata("invoke", returnType, null);
Procedure p = mf.getSchema().getProcedure("invoke");
assertNotNull(p);
assertEquals(3, p.getParameters().size());
assertNull(p.getResultSet());
assertNotNull(getReturnParameter(p));
ProcedureParameter pp = getReturnParameter(p);
assertEquals("string", pp.getRuntimeType());
ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.ACTION, type);
}
@Test
public void testFunctionReturnPrimitiveCollection() throws Exception {
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType("Edm.String");
returnType.setCollection(true);
MetadataFactory mf = functionMetadata("invoke", returnType, null);
Procedure p = mf.getSchema().getProcedure("invoke");
assertNotNull(p);
assertEquals(3, p.getParameters().size());
assertNull(p.getResultSet());
assertNotNull(getReturnParameter(p));
ProcedureParameter pp = getReturnParameter(p);
assertEquals("string[]", pp.getRuntimeType());
ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.FUNCTION, type);
}
@Test
public void testFunctionReturnComplex() throws Exception {
CsdlComplexType complex = complexType("Address");
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType("namespace.Address");
MetadataFactory mf = functionMetadata("invoke", returnType, complex);
Procedure p = mf.getSchema().getProcedure("invoke");
assertNotNull(p);
assertEquals(2, p.getParameters().size());
assertNotNull(p.getResultSet());
assertNull(getReturnParameter(p));
ColumnSet<Procedure> table = p.getResultSet();
ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.FUNCTION, type);
type = ODataType.valueOf(table.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.COMPLEX, type);
}
@Test
public void testFunctionReturnComplexCollection() throws Exception {
CsdlComplexType complex = complexType("Address");
CsdlReturnType returnType = new CsdlReturnType();
returnType.setType("namespace.Address");
returnType.setCollection(true);
MetadataFactory mf = functionMetadata("invoke", returnType, complex);
Procedure p = mf.getSchema().getProcedure("invoke");
assertNotNull(p);
assertEquals(2, p.getParameters().size());
assertNotNull(p.getResultSet());
assertNull(getReturnParameter(p));
ColumnSet<Procedure> table = p.getResultSet();
ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.FUNCTION, type);
type = ODataType.valueOf(table.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
assertEquals(ODataType.COMPLEX_COLLECTION, type);
}
private ProcedureParameter getReturnParameter(Procedure procedure) {
for (ProcedureParameter pp:procedure.getParameters()) {
if (pp.getType() == ProcedureParameter.Type.ReturnValue) {
return pp;
}
}
return null;
}
static MetadataFactory oneToOneRelationMetadata()
throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlEntityType g1Entity = entityType("g1");
CsdlEntityType g2Entity = entityType("g2");
CsdlNavigationProperty navProperty = new CsdlNavigationProperty();
navProperty.setName("one_2_one");
navProperty.setType("namespace.g2");
navProperty.setNullable(false);
navProperty.setPartner("PartnerPath");
g1Entity.setNavigationProperties(Arrays.asList(navProperty));
CsdlEntitySet g1Set = createES("G1", "namespace.g1");
CsdlEntitySet g2Set = createES("G2", "namespace.g2");
CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding();
navBinding.setPath("one_2_one");
navBinding.setTarget("G2");
g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding));
XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set);
processor.getMetadata(mf, metadata);
return mf;
}
static MetadataFactory functionMetadata(String name, CsdlReturnType returnType, Object other)
throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlFunction func = function(name, returnType);
CsdlFunctionImport funcImport = new CsdlFunctionImport();
funcImport.setFunction(new FullQualifiedName("namespace."+name));
funcImport.setName(name);
XMLMetadata metadata = buildXmlMetadata(funcImport, func, other);
processor.getMetadata(mf, metadata);
return mf;
}
static MetadataFactory actionMetadata(String name, CsdlReturnType returnType, Object other)
throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlAction func = action(name, returnType);
CsdlActionImport funcImport = new CsdlActionImport();
funcImport.setAction(new FullQualifiedName("namespace."+name));
funcImport.setName(name);
XMLMetadata metadata = buildXmlMetadata(funcImport, func, other);
processor.getMetadata(mf, metadata);
return mf;
}
@Test
public void testSelfJoin() throws Exception {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlEntityType g1Entity = entityType("g1");
CsdlNavigationProperty navProperty = new CsdlNavigationProperty();
navProperty.setName("self");
navProperty.setType("Collection(namespace.g1)");
navProperty.setNullable(false);
navProperty.setPartner("PartnerPath");
navProperty.setCollection(true);
g1Entity.setNavigationProperties(Arrays.asList(navProperty));
CsdlEntitySet g1Set = createES("G1", "namespace.g1");
CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding();
navBinding.setPath("self");
navBinding.setTarget("G1");
g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding));
XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set);
processor.getMetadata(mf, metadata);
Table g1 = mf.getSchema().getTable("G1_self");
assertNotNull(g1);
assertEquals("self", g1.getForeignKeys().get(0).getName());
assertNotNull(g1.getForeignKeys().get(0).getColumnByName("G1_e1"));
assertEquals("self", g1.getNameInSource());
}
@Test
public void testOneToManyAssosiation() throws Exception {
MetadataFactory mf = oneToManyRelationMetadata();
Table g1 = mf.getSchema().getTable("G1");
Table g2 = mf.getSchema().getTable("G2");
ForeignKey fk = g2.getForeignKeys().get(0);
assertEquals("one_2_many", fk.getName());
assertNotNull(fk.getColumnByName("e1"));
}
static MetadataFactory oneToManyRelationMetadata() throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlEntityType g1Entity = entityType("g1");
CsdlEntityType g2Entity = multipleKeyEntityType("g2");
CsdlNavigationProperty navProperty = new CsdlNavigationProperty();
navProperty.setName("one_2_many");
navProperty.setType("Collection(namespace.g2)");
navProperty.setNullable(false);
navProperty.setPartner("PartnerPath");
navProperty.setCollection(true);
g1Entity.setNavigationProperties(Arrays.asList(navProperty));
CsdlEntitySet g1Set = createES("G1", "namespace.g1");
CsdlEntitySet g2Set = createES("G2", "namespace.g2");
CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding();
navBinding.setPath("one_2_many");
navBinding.setTarget("G2");
g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding));
XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set);
processor.getMetadata(mf, metadata);
return mf;
}
static MetadataFactory multiplePKMetadata() throws TranslatorException {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlEntityType entityType = multipleKeyEntityType("g1");
CsdlEntitySet entitySet = createES("G1", "namespace.g1");
XMLMetadata metadata = buildXmlMetadata(entityType, entitySet);
processor.getMetadata(mf, metadata);
return mf;
}
private static CsdlEntityType multipleKeyEntityType(String name) {
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("e1", EdmPrimitiveTypeKind.Int32));
properties.add(createProperty("e2", EdmPrimitiveTypeKind.String).setNullable(false));
properties.add(createProperty("e3", EdmPrimitiveTypeKind.String).setNullable(false));
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName(name);
entityType.setProperties(properties);
entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("e1"), new CsdlPropertyRef().setName("e2")));
return entityType;
}
@Test
public void testMultikeyPK() throws Exception {
MetadataFactory mf = multiplePKMetadata();
Table g1 = mf.getSchema().getTable("G1");
assertNotNull(g1.getPrimaryKey().getColumnByName("e1"));
assertNotNull(g1.getPrimaryKey().getColumnByName("e2"));
assertNull(g1.getPrimaryKey().getColumnByName("e3"));
}
@Test
public void testAssosiationWithReferentialContriant() throws Exception {
ODataMetadataProcessor processor = new ODataMetadataProcessor();
MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind",
SystemMetadata.getInstance().getRuntimeTypeMap(),
new Properties(), null);
CsdlEntityType g1Entity = entityType("g1");
g1Entity.getProperties().add(createProperty("g2e2", EdmPrimitiveTypeKind.String));
g1Entity.setKey(Arrays.asList(new CsdlPropertyRef().setName("g2e2")));
CsdlEntityType g2Entity = entityType("g2");
CsdlNavigationProperty navProperty = new CsdlNavigationProperty();
navProperty.setName("one_2_one");
navProperty.setType("namespace.g2");
navProperty.setNullable(false);
navProperty.setPartner("PartnerPath");
navProperty.setReferentialConstraints(Arrays
.asList(new CsdlReferentialConstraint().setProperty("g2e2")
.setReferencedProperty("e2")));
g1Entity.setNavigationProperties(Arrays.asList(navProperty));
CsdlEntitySet g1Set = createES("G1", "namespace.g1");
CsdlEntitySet g2Set = createES("G2", "namespace.g2");
CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding();
navBinding.setPath("one_2_one");
navBinding.setTarget("G2");
g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding));
XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set);
processor.getMetadata(mf, metadata);
Table g1 = mf.getSchema().getTable("G1");
Table g2 = mf.getSchema().getTable("G2");
assertNotNull(g1);
assertNotNull(g2);
ForeignKey fk = g2.getForeignKeys().get(0);
assertEquals("one_2_one", fk.getName());
assertNotNull(fk.getColumnByName("e2"));
assertEquals("g2e2", fk.getReferenceColumns().get(0));
}
static CsdlEntityType entityType(String name) {
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("e1", EdmPrimitiveTypeKind.Int32));
properties.add(createProperty("e2", EdmPrimitiveTypeKind.String).setNullable(false));
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName(name);
entityType.setProperties(properties);
entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("e1")));
return entityType;
}
static CsdlFunction function(String name, CsdlReturnType returnType) {
ArrayList<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
parameters.add(createParameter("e1", EdmPrimitiveTypeKind.Int32));
parameters.add(createParameter("e2", EdmPrimitiveTypeKind.String).setNullable(false));
CsdlFunction function = new CsdlFunction();
function.setName(name);
function.setParameters(parameters);
function.setReturnType(returnType);
return function;
}
static CsdlAction action(String name, CsdlReturnType returnType) {
ArrayList<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
parameters.add(createParameter("e1", EdmPrimitiveTypeKind.Int32));
parameters.add(createParameter("e2", EdmPrimitiveTypeKind.String).setNullable(false));
CsdlAction action = new CsdlAction();
action.setName(name);
action.setParameters(parameters);
action.setReturnType(returnType);
return action;
}
private CsdlEntityType buildBusinessEntity(CsdlComplexType address) {
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25));
properties.add(new CsdlProperty().setName("address").setType(address.getName()));
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName("Business");
entityType.setProperties(properties);
entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("name")));
return entityType;
}
static CsdlEntityType buildPersonEntity(CsdlComplexType address) {
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25));
properties.add(createProperty("ssn", EdmPrimitiveTypeKind.Int64).setNullable(false));
properties.add(new CsdlProperty().setName("address").setType(address.getName()));
properties.add(new CsdlProperty().setName("secondaddress").setType(address.getName()));
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName("Person");
entityType.setProperties(properties);
entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("ssn")));
return entityType;
}
static CsdlComplexType complexType(String name) {
ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>();
properties.add(createProperty("street", EdmPrimitiveTypeKind.String));
properties.add(createProperty("city", EdmPrimitiveTypeKind.String));
properties.add(createProperty("state", EdmPrimitiveTypeKind.String));
CsdlComplexType type = new CsdlComplexType();
type.setName(name).setProperties(properties);
return type;
}
}