blob: bc78f6ffa69948f3b02825f5e1d1a41d7e90140e [file] [log] [blame]
/*
* Copyright 2013 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.olingo.odata2.annotation.processor.core.edm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.olingo.odata2.annotation.processor.core.model.Building;
import org.apache.olingo.odata2.annotation.processor.core.model.City;
import org.apache.olingo.odata2.annotation.processor.core.model.Employee;
import org.apache.olingo.odata2.annotation.processor.core.model.Location;
import org.apache.olingo.odata2.annotation.processor.core.model.Manager;
import org.apache.olingo.odata2.annotation.processor.core.model.ModelSharedConstants;
import org.apache.olingo.odata2.annotation.processor.core.model.Photo;
import org.apache.olingo.odata2.annotation.processor.core.model.RefBase;
import org.apache.olingo.odata2.annotation.processor.core.model.Room;
import org.apache.olingo.odata2.annotation.processor.core.model.Team;
import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.edm.FullQualifiedName;
import org.apache.olingo.odata2.api.edm.provider.Association;
import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
import org.apache.olingo.odata2.api.edm.provider.ComplexType;
import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
import org.apache.olingo.odata2.api.edm.provider.EntitySet;
import org.apache.olingo.odata2.api.edm.provider.EntityType;
import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
import org.apache.olingo.odata2.api.edm.provider.Key;
import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
import org.apache.olingo.odata2.api.edm.provider.Property;
import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
import org.apache.olingo.odata2.api.edm.provider.Schema;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.junit.Test;
/**
*
*/
public class AnnotationEdmProviderTest {
private static final String TEST_MODEL_PACKAGE = "org.apache.olingo.odata2.annotation.processor.core.model";
@EdmEntityType
@EdmEntitySet
private static final class GeneratedNamesTestClass {}
@EdmComplexType
private static final class GeneratedNamesComplexTestClass {}
@EdmEntityType(namespace = "MyTestNamespace")
@EdmEntitySet(container = "MyTestContainer")
private static final class DefinedNamesTestClass {}
private final AnnotationEdmProvider aep;
private final Collection<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
public AnnotationEdmProviderTest() throws ODataException {
annotatedClasses.add(RefBase.class);
annotatedClasses.add(Building.class);
annotatedClasses.add(City.class);
annotatedClasses.add(Employee.class);
annotatedClasses.add(Location.class);
annotatedClasses.add(Manager.class);
annotatedClasses.add(Photo.class);
annotatedClasses.add(Room.class);
annotatedClasses.add(Team.class);
aep = new AnnotationEdmProvider(annotatedClasses);
}
@Test
public void defaultNamespaceGeneration() throws ODataException {
Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
localAnnotatedClasses.add(GeneratedNamesTestClass.class);
AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
// validate
EntityType testType = localAep.getEntityType(new FullQualifiedName(
GeneratedNamesTestClass.class.getPackage().getName(),
GeneratedNamesTestClass.class.getSimpleName()));
assertNotNull("Requested entity not found.", testType);
assertEquals("GeneratedNamesTestClass", testType.getName());
assertNull("This should not have a base type", testType.getBaseType());
}
@Test
public void defaultNamespaceGenerationComplexType() throws ODataException {
Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
localAnnotatedClasses.add(GeneratedNamesComplexTestClass.class);
AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
// validate
ComplexType testType = localAep.getComplexType(new FullQualifiedName(
GeneratedNamesComplexTestClass.class.getPackage().getName(),
GeneratedNamesComplexTestClass.class.getSimpleName()));
assertNotNull("Requested entity not found.", testType);
assertEquals("GeneratedNamesComplexTestClass", testType.getName());
assertNull("This should not have a base type", testType.getBaseType());
}
@Test
public void defaultContainerNameGeneration() throws ODataException {
@SuppressWarnings({ "unchecked", "rawtypes" })
AnnotationEdmProvider localAep =
new AnnotationEdmProvider((Collection) Arrays.asList(GeneratedNamesTestClass.class));
EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
assertNotNull(containerInfo);
assertEquals("DefaultContainer", containerInfo.getName());
}
@Test
public void defaultNamespaceDefined() throws ODataException {
Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
localAnnotatedClasses.add(DefinedNamesTestClass.class);
AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
// validate
EntityType testClass = localAep.getEntityType(new FullQualifiedName("MyTestNamespace",
DefinedNamesTestClass.class.getSimpleName()));
assertNotNull("Requested entity not found.", testClass);
assertEquals("DefinedNamesTestClass", testClass.getName());
assertNull("This should not have a base type", testClass.getBaseType());
}
@Test
public void defaultContainerNameDefined() throws ODataException {
@SuppressWarnings({ "unchecked", "rawtypes" })
AnnotationEdmProvider localAep = new AnnotationEdmProvider((Collection) Arrays.asList(DefinedNamesTestClass.class));
EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
assertNotNull(containerInfo);
assertEquals("MyTestContainer", containerInfo.getName());
}
@Test
public void loadAnnotatedClassesFromPackage() throws Exception {
AnnotationEdmProvider localAep = new AnnotationEdmProvider(TEST_MODEL_PACKAGE);
// validate employee
EntityType employee = localAep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
assertEquals("Employee", employee.getName());
final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
assertEquals(1, employeeKeys.size());
assertEquals("EmployeeId", employeeKeys.get(0).getName());
assertEquals(6, employee.getProperties().size());
assertEquals(3, employee.getNavigationProperties().size());
List<Schema> schemas = localAep.getSchemas();
assertEquals(1, schemas.size());
EntityContainerInfo info = localAep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
assertTrue(info.isDefaultEntityContainer());
}
@Test
public void annotationProviderBasic() throws Exception {
assertNotNull(aep);
List<Schema> schemas = aep.getSchemas();
assertEquals(1, schemas.size());
EntityContainerInfo info = aep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
assertTrue(info.isDefaultEntityContainer());
FunctionImport funImp = aep.getFunctionImport(ModelSharedConstants.CONTAINER_1, "NoImport");
assertNull(funImp);
final FullQualifiedName associationFqn = new FullQualifiedName(
ModelSharedConstants.NAMESPACE_1, "NoAssociation");
Association noAssociation = aep.getAssociation(associationFqn);
assertNull(noAssociation);
AssociationSet noAssociationSet = aep.getAssociationSet(
ModelSharedConstants.CONTAINER_1, associationFqn, "NoSrc", "NoSrcEntity");
assertNull(noAssociationSet);
AssociationSet asBuildingRooms = aep.getAssociationSet(
ModelSharedConstants.CONTAINER_1, defaultFqn("BuildingRooms"), "Buildings", "r_Building");
assertNotNull(asBuildingRooms);
assertEquals("Buildings", asBuildingRooms.getEnd1().getEntitySet());
assertEquals("r_Building", asBuildingRooms.getEnd1().getRole());
assertEquals("Rooms", asBuildingRooms.getEnd2().getEntitySet());
assertEquals("r_Room", asBuildingRooms.getEnd2().getRole());
}
@Test
public void annotationProviderGetDefaultContainer() throws Exception {
assertNotNull(aep);
List<Schema> schemas = aep.getSchemas();
assertEquals(1, schemas.size());
EntityContainerInfo info = aep.getEntityContainerInfo(null);
assertTrue(info.isDefaultEntityContainer());
assertEquals(ModelSharedConstants.CONTAINER_1, info.getName());
}
@Test
public void schemaBasic() throws Exception {
assertNotNull(aep);
List<Schema> schemas = aep.getSchemas();
assertEquals(1, schemas.size());
Schema schema = schemas.get(0);
List<EntityContainer> containers = schema.getEntityContainers();
assertEquals(1, containers.size());
EntityContainer container = containers.get(0);
assertEquals(ModelSharedConstants.CONTAINER_1, container.getName());
final List<EntitySet> entitySets = container.getEntitySets();
assertEquals(6, entitySets.size());
List<Association> associations = schema.getAssociations();
assertEquals(4, associations.size());
for (Association association : associations) {
assertNotNull(association.getName());
validateAssociation(association);
}
}
private FullQualifiedName defaultFqn(final String name) {
return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
}
private void validateAssociation(final Association association) {
String name = association.getName();
if (name.equals("r_Employee-r_Room")) {
validateAssociation(association,
"r_Room", EdmMultiplicity.ONE, defaultFqn("Room"),
"r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
} else if (name.equals("BuildingRooms")) {
validateAssociation(association,
"r_Building", EdmMultiplicity.ONE, defaultFqn("Building"),
"r_Room", EdmMultiplicity.MANY, defaultFqn("Room"));
} else if (name.equals("ManagerEmployees")) {
validateAssociation(association,
"r_Manager", EdmMultiplicity.ONE, defaultFqn("Manager"),
"r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
} else if (name.equals("TeamEmployees")) {
validateAssociation(association,
"r_Team", EdmMultiplicity.ONE, defaultFqn("Team"),
"r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
} else {
fail("Got unknown association to validate with name '" + name + "'.");
}
}
private void validateAssociation(final Association association,
final String fromRole, final EdmMultiplicity fromMulti, final FullQualifiedName fromType,
final String toRole, final EdmMultiplicity toMulti, final FullQualifiedName toType) {
AssociationEnd[] ends = new AssociationEnd[] { association.getEnd1(), association.getEnd2() };
for (AssociationEnd associationEnd : ends) {
if (associationEnd.getRole().equals(fromRole)) {
validateAssociationEnd(associationEnd, fromRole, fromMulti, fromType);
} else if (associationEnd.getRole().equals(toRole)) {
validateAssociationEnd(associationEnd, toRole, toMulti, toType);
} else {
fail("Unexpected navigation end '" + associationEnd.getRole()
+ "' for association with name '" + association.getName() + "'.");
}
}
}
private void validateAssociationEnd(final AssociationEnd associationEnd,
final String role, final EdmMultiplicity multiplicity, final FullQualifiedName type) {
assertEquals(role, associationEnd.getRole());
assertEquals(multiplicity, associationEnd.getMultiplicity());
assertEquals(type, associationEnd.getType());
}
@Test
public void entitySetTeams() throws Exception {
// validate teams
EntitySet teams = aep.getEntitySet(ModelSharedConstants.CONTAINER_1, "Teams");
assertEquals(ModelSharedConstants.NAMESPACE_1, teams.getEntityType().getNamespace());
assertEquals("Team", teams.getEntityType().getName());
}
@Test
public void entityTypeEmployee() throws Exception {
// validate employee
EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
assertEquals("Employee", employee.getName());
final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
assertEquals(1, employeeKeys.size());
assertEquals("EmployeeId", employeeKeys.get(0).getName());
assertEquals(6, employee.getProperties().size());
assertEquals(3, employee.getNavigationProperties().size());
Property name = getProperty(employee, "EmployeeName");
assertEquals(Integer.valueOf(20), name.getFacets().getMaxLength());
for (NavigationProperty navigationProperty : employee.getNavigationProperties()) {
if (navigationProperty.getName().equals("ne_Manager")) {
validateNavProperty(navigationProperty, "ManagerEmployees", "r_Employee", "r_Manager");
} else if (navigationProperty.getName().equals("ne_Team")) {
validateNavProperty(navigationProperty, "TeamEmployees", "r_Employee", "r_Team");
} else if (navigationProperty.getName().equals("ne_Room")) {
validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Employee", "r_Room");
} else {
fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
}
}
}
@Test
public void facetsTest() throws Exception {
EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
assertEquals("Employee", employee.getName());
Property name = getProperty(employee, "EmployeeName");
assertEquals(Integer.valueOf(20), name.getFacets().getMaxLength());
assertNull(name.getFacets().getConcurrencyMode());
assertTrue(name.getFacets().isNullable());
Property id = getProperty(employee, "EmployeeId");
assertFalse(id.getFacets().isNullable());
ComplexType city = aep.getComplexType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "c_City"));
Property postalCode = getProperty(city.getProperties(), "PostalCode");
assertEquals(Integer.valueOf(5), postalCode.getFacets().getMaxLength());
EntityType room = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Room"));
Property version = getProperty(room, "Version");
assertEquals(Integer.valueOf(0), version.getFacets().getScale());
assertEquals(Integer.valueOf(0), version.getFacets().getPrecision());
assertEquals(EdmConcurrencyMode.Fixed, version.getFacets().getConcurrencyMode());
}
@Test
public void entityTypeTeam() throws Exception {
// validate team
EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
assertEquals("Team", team.getName());
assertEquals("Base", team.getBaseType().getName());
assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
assertEquals(1, team.getProperties().size());
assertEquals(1, team.getNavigationProperties().size());
NavigationProperty navigationProperty = team.getNavigationProperties().get(0);
validateNavProperty(navigationProperty, "TeamEmployees", "r_Team", "r_Employee");
}
@Test
public void entityTypePhotoWithTwoKeyProperties() throws Exception {
// validate team
EntityType photo = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Photo"));
assertEquals("Photo", photo.getName());
final List<Property> properties = photo.getProperties();
assertEquals(5, properties.size());
assertTrue(containsProperty(properties, "Name"));
assertTrue(containsProperty(properties, "ImageFormat"));
assertTrue(containsProperty(properties, "MimeType"));
assertTrue(containsProperty(properties, "ImageUrl"));
assertTrue(containsProperty(properties, "Image"));
assertFalse(photo.isAbstract());
assertTrue(photo.isHasStream());
Key photoKey = photo.getKey();
List<PropertyRef> keyReferences = photoKey.getKeys();
assertEquals(2, keyReferences.size());
PropertyRef name = getPropertyRef(keyReferences, "Name");
assertEquals("Name", name.getName());
PropertyRef imageFormat = getPropertyRef(keyReferences, "ImageFormat");
assertEquals("ImageFormat", imageFormat.getName());
// assertEquals(0, photo.getNavigationProperties().size());
assertNull(photo.getNavigationProperties());
}
@Test
public void entityTypeAbstractBaseType() throws Exception {
// validate employee
EntityType baseType = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Base"));
assertEquals("Base", baseType.getName());
final List<PropertyRef> keys = baseType.getKey().getKeys();
assertEquals(1, keys.size());
assertEquals("Id", keys.get(0).getName());
assertEquals(2, baseType.getProperties().size());
assertTrue(baseType.isAbstract());
// validate base for team
EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
assertEquals("Team", team.getName());
assertEquals("Base", team.getBaseType().getName());
assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
}
@Test
public void complexTypeLocation() throws Exception {
// validate employee
EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
final List<Property> properties = employee.getProperties();
Property location = null;
for (Property property : properties) {
if (property.getName().equals("Location")) {
location = property;
}
}
assertNotNull(location);
assertEquals("Location", location.getName());
// validate location complex type
ComplexType locationType = aep.getComplexType(
new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "c_Location"));
assertEquals("c_Location", locationType.getName());
assertEquals(2, locationType.getProperties().size());
}
@Test
public void entityTypeRoomWithNavigation() throws Exception {
// validate employee
EntityType room = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Room"));
assertEquals("Room", room.getName());
assertEquals("Base", room.getBaseType().getName());
assertEquals(2, room.getProperties().size());
final List<NavigationProperty> navigationProperties = room.getNavigationProperties();
assertEquals(2, navigationProperties.size());
for (NavigationProperty navigationProperty : navigationProperties) {
if (navigationProperty.getName().equals("nr_Employees")) {
validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Room", "r_Employee");
} else if (navigationProperty.getName().equals("nr_Building")) {
validateNavProperty(navigationProperty, "BuildingRooms", "r_Room", "r_Building");
} else {
fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
}
}
}
private void validateNavProperty(final NavigationProperty navigationProperty, final String name,
final String relationship, final String fromRole, final String toRole) {
if (name != null) {
assertEquals(name, navigationProperty.getName());
}
FullQualifiedName fqn = new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, relationship);
assertEquals("Wrong relationship for navigation property.", fqn, navigationProperty.getRelationship());
assertEquals("Wrong fromRole for navigation property.", fromRole, navigationProperty.getFromRole());
assertEquals("Wrong toRole for navigation property.", toRole, navigationProperty.getToRole());
}
private void validateNavProperty(final NavigationProperty navigationProperty,
final String relationship, final String fromRole, final String toRole) {
validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
}
private boolean containsProperty(final List<Property> properties, final String propertyName) {
return getProperty(properties, propertyName) != null;
}
private Property getProperty(EntityType entity, String propertyName) {
return getProperty(entity.getProperties(), propertyName);
}
private Property getProperty(final List<Property> properties, final String name) {
for (Property property : properties) {
if (name.equals(property.getName())) {
return property;
}
}
fail("Requested property with name '" + name + "' not available.");
return null;
}
private PropertyRef getPropertyRef(final List<PropertyRef> properties, final String name) {
for (PropertyRef property : properties) {
if (name.equals(property.getName())) {
return property;
}
}
return null;
}
}