| /* |
| * 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; |
| } |
| } |