/** * ***************************************************************************** * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * to you 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.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; 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.annotation.edm.EdmKey; import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty; import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity; import org.apache.olingo.odata2.api.annotation.edm.EdmProperty; import org.apache.olingo.odata2.api.edm.EdmLiteralKind; import org.apache.olingo.odata2.api.edm.EdmMultiplicity; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind; import org.apache.olingo.odata2.api.edm.FullQualifiedName; import org.apache.olingo.odata2.api.exception.ODataException; /** * */ public class AnnotationHelper { public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer"; /** * Compare keys of both instances. * * @param firstInstance * @param secondInstance * @return */ public boolean keyMatch(final Object firstInstance, final Object secondInstance) { if (firstInstance == null || secondInstance == null) { return false; } else if (firstInstance.getClass() != secondInstance.getClass()) { return false; } Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class); Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class); if (firstKeyFields.isEmpty() && secondKeyFields.isEmpty()) { throw new AnnotationRuntimeException("Both object instances does not have EdmKey fields defined [" + "firstClass=" + firstInstance.getClass().getName() + " secondClass=" + secondInstance.getClass().getName() + "]."); } return keyValuesMatch(firstKeyFields, secondKeyFields); } /** * Compare keys of instance with key values in map. * * @param instance * @param keyName2Value * @return */ public boolean keyMatch(final Object instance, final Map<String, Object> keyName2Value) { Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class); return keyValuesMatch(instanceKeyFields, keyName2Value); } private boolean keyValuesMatch(final Map<String, Object> firstKeyValues, final Map<String, Object> secondKeyValues) { if (firstKeyValues.size() != secondKeyValues.size()) { return false; } else if (firstKeyValues.isEmpty()) { throw new AnnotationRuntimeException("No keys given for key value matching."); } else { Set<Map.Entry<String, Object>> entries = firstKeyValues.entrySet(); for (Map.Entry<String, Object> entry : entries) { Object firstKey = entry.getValue(); Object secondKey = secondKeyValues.get(entry.getKey()); if (!isEqual(firstKey, secondKey)) { return false; } } return true; } } private boolean isEqual(final Object firstKey, final Object secondKey) { if (firstKey == null) { return secondKey == null || secondKey.equals(firstKey); } else { return firstKey.equals(secondKey); } } public String extractEntityTypeName(final EdmNavigationProperty enp, final Class<?> fallbackClass) { Class<?> entityTypeClass = enp.toType(); return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass); } public String extractEntityTypeName(final EdmNavigationProperty enp, final Field field) { Class<?> entityTypeClass = enp.toType(); if (entityTypeClass == Object.class) { Class<?> toClass = field.getType(); return extractEntityTypeName((toClass.isArray() || Collection.class.isAssignableFrom(toClass) ? (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : toClass)); } else { return extractEntityTypeName(entityTypeClass); } } /** * Returns <code>NULL</code> if given class is not annotated. If annotated the set entity type name is returned and if * no name is set the default name is generated from the simple class name. * * @param annotatedClass * @return */ public String extractEntityTypeName(final Class<?> annotatedClass) { return extractTypeName(annotatedClass, EdmEntityType.class); } /** * Returns <code>NULL</code> if given class is not annotated. * If annotated the entity set name is returned and if * no name is set a default name is generated based on the simple class name. * * @param annotatedClass * @return */ public String extractEntitySetName(final Class<?> annotatedClass) { if (annotatedClass == Object.class) { return null; } EdmEntitySet entitySet = annotatedClass.getAnnotation(EdmEntitySet.class); if (entitySet == null) { return null; } String name = entitySet.name(); if (name.isEmpty()) { return getCanonicalName(annotatedClass) + "Set"; } return name; } public FullQualifiedName extractEntityTypeFqn(final EdmEntityType type, final Class<?> annotatedClass) { if (type.namespace().isEmpty()) { return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass)); } return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass)); } public FullQualifiedName extractEntityTypeFqn(final Class<?> annotatedClass) { EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class); if (type == null) { return null; } return extractEntityTypeFqn(type, annotatedClass); } public FullQualifiedName extractComplexTypeFqn(final Class<?> annotatedClass) { EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class); if (type == null) { return null; } return extractComplexTypeFqn(type, annotatedClass); } public FullQualifiedName extractComplexTypeFqn(final EdmComplexType type, final Class<?> annotatedClass) { if (type.namespace().isEmpty()) { return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass)); } return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass)); } public String extractComplexTypeName(final Class<?> annotatedClass) { return extractTypeName(annotatedClass, EdmComplexType.class); } public String generateNamespace(final Class<?> annotatedClass) { return annotatedClass.getPackage().getName(); } /** * * * @param <T> must be EdmEntityType or EdmComplexType annotation * @param annotatedClass * @param typeAnnotation * @return null if annotatedClass is not annotated or name set via annotation or generated via * {@link #getCanonicalName(java.lang.Class)} */ private <T extends Annotation> String extractTypeName(final Class<?> annotatedClass, final Class<T> typeAnnotation) { if (annotatedClass == Object.class) { return null; } T type = annotatedClass.getAnnotation(typeAnnotation); if (type == null) { return null; } String name; if (typeAnnotation == EdmEntityType.class) { name = ((EdmEntityType) type).name(); } else if (typeAnnotation == EdmComplexType.class) { name = ((EdmComplexType) type).name(); } else { return null; } if (name.isEmpty()) { return getCanonicalName(annotatedClass); } return name; } /** * Get the set property name from an EdmProperty or EdmNavigationProperty annotation. * * @param field * @return */ public String getPropertyNameFromAnnotation(final Field field) { EdmProperty property = field.getAnnotation(EdmProperty.class); if (property == null) { EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class); if (navProperty == null) { throw new EdmAnnotationException("Given field '" + field + "' has no EdmProperty or EdmNavigationProperty annotation."); } return navProperty.name(); } return property.name(); } public String getPropertyName(final Field field) { String propertyName = getPropertyNameFromAnnotation(field); if (propertyName.isEmpty()) { propertyName = getCanonicalName(field); } return propertyName; } public String extractToRoleName(final EdmNavigationProperty enp, final Field field) { String role = enp.toRole(); if (role.isEmpty()) { role = getCanonicalRoleName(field.getName()); } return role; } public String extractFromRoleEntityName(final Field field) { return extractEntityTypeName(field.getDeclaringClass()); } public String extractToRoleEntityName(final EdmNavigationProperty enp, final Field field) { Class<?> clazz = enp.toType(); if (clazz == Object.class) { if(field.getType().isArray() || Collection.class.isAssignableFrom(field.getType())) { clazz = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; } else { clazz = field.getType(); } } return extractEntityTypeName(clazz); } public String getCanonicalRoleName(String name) { return "r_" + name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1); } public String extractRelationshipName(final EdmNavigationProperty enp, final Field field) { String relationshipName = enp.association(); if (relationshipName.isEmpty()) { final String fromRole = extractFromRoleEntityName(field); final String toRole = extractToRoleEntityName(enp, field); return createCanonicalRelationshipName(fromRole, toRole); } return relationshipName; } public String createCanonicalRelationshipName(String fromRole, String toRole) { if (fromRole.compareTo(toRole) > 0) { return toRole + "_2_" + fromRole; } else { return fromRole + "_2_" + toRole; } } public EdmMultiplicity extractMultiplicity(final EdmNavigationProperty enp, final Field field) { EdmMultiplicity multiplicity = mapMultiplicity(enp.toMultiplicity()); final boolean isCollectionType = field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()); if (multiplicity == EdmMultiplicity.ONE && isCollectionType) { return EdmMultiplicity.MANY; } return multiplicity; } /** * Set key fields based on values in map. * If an key field is not available or <code>NULL</code> in the map * it will be not set as <code>NULL</code> at the instance object. * * @param instance * @param keys * @return */ public <T> T setKeyFields(final T instance, final Map<String, Object> keys) { List<Field> fields = getAnnotatedFields(instance, EdmKey.class); for (Field field : fields) { String propertyName = getPropertyName(field); Object keyValue = keys.get(propertyName); setValueForProperty(instance, propertyName, keyValue); } return instance; } public static final class ODataAnnotationException extends ODataException { private static final long serialVersionUID = 42L; public ODataAnnotationException(final String message) { super(message); } public ODataAnnotationException(final String message, final Exception cause) { super(message, cause); } } public class AnnotatedNavInfo { private final Field fromField; private final Field toField; private final EdmNavigationProperty fromNavigation; private final EdmNavigationProperty toNavigation; public AnnotatedNavInfo(final Field fromField, final Field toField, final EdmNavigationProperty fromNavigation, final EdmNavigationProperty toNavigation) { this.fromField = fromField; this.toField = toField; this.fromNavigation = fromNavigation; this.toNavigation = toNavigation; } public Field getFromField() { return fromField; } public String getFromRoleName() { if(isBiDirectional()) { return extractFromRoleEntityName(toField); } return extractToRoleName(toNavigation, toField); } public Field getToField() { return toField; } public String getToRoleName() { if(isBiDirectional()) { return extractToRoleName(toNavigation, toField); } return extractToRoleName(fromNavigation, fromField); } public EdmMultiplicity getFromMultiplicity() { if(isBiDirectional()) { return EdmMultiplicity.ONE; } return extractMultiplicity(toNavigation, toField); } public EdmMultiplicity getToMultiplicity() { if(isBiDirectional()) { return extractMultiplicity(toNavigation, toField); } return extractMultiplicity(fromNavigation, fromField); } public boolean isBiDirectional() { return fromNavigation == null; } public String getRelationshipName() { String toAssociation = toNavigation.association(); String fromAssociation = ""; if(!isBiDirectional()) { fromAssociation = fromNavigation.association(); } if(fromAssociation.isEmpty() && fromAssociation.equals(toAssociation)) { return createCanonicalRelationshipName(getFromRoleName(), getToRoleName()); } else if(toAssociation.isEmpty()) { return fromAssociation; } else if(!toAssociation.equals(fromAssociation)) { throw new AnnotationRuntimeException("Invalid associations for navigation properties '" + this.toString() + "'"); } return toAssociation; } public String getFromTypeName() { if(isBiDirectional()) { return extractEntityTypeName(toField.getDeclaringClass()); } return extractEntityTypeName(fromField.getDeclaringClass()); } public String getToTypeName() { if(isBiDirectional()) { return extractEntityTypeName(ClassHelper.getFieldType(toField)); } return extractEntityTypeName(toField.getDeclaringClass()); } @Override public String toString() { if(isBiDirectional()) { return "AnnotatedNavInfo{biDirectional = true" + ", toField=" + toField.getName() + ", toNavigation=" + toNavigation.name() + '}'; } return "AnnotatedNavInfo{" + "fromField=" + fromField.getName() + ", toField=" + toField.getName() + ", fromNavigation=" + fromNavigation.name() + ", toNavigation=" + toNavigation.name() + '}'; } } public AnnotatedNavInfo getCommonNavigationInfo(final Class<?> sourceClass, final Class<?> targetClass) { List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class); List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class); if(sourceClass == targetClass) { // special case, actual handled as bi-directional return getCommonNavigationInfoBiDirectional(sourceClass, targetClass); } // first try via association name to get full navigation information for (Field sourceField : sourceFields) { if(ClassHelper.getFieldType(sourceField) == targetClass) { final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class); final String sourceAssociation = extractRelationshipName(sourceNav, sourceField); for (Field targetField : targetFields) { if(ClassHelper.getFieldType(targetField) == sourceClass) { final EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class); final String targetAssociation = extractRelationshipName(targetNav, targetField); if (sourceAssociation.equals(targetAssociation)) { return new AnnotatedNavInfo(sourceField, targetField, sourceNav, targetNav); } } } } } // if nothing was found assume/guess none bi-directional navigation return getCommonNavigationInfoBiDirectional(sourceClass, targetClass); } private AnnotatedNavInfo getCommonNavigationInfoBiDirectional(final Class<?> sourceClass, final Class<?> targetClass) { List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class); String targetEntityTypeName = extractEntityTypeName(targetClass); for (Field sourceField : sourceFields) { final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class); final String navTargetEntityName = extractEntityTypeName(sourceNav, sourceField); if (navTargetEntityName.equals(targetEntityTypeName)) { return new AnnotatedNavInfo(null, sourceField, null, sourceNav); } } return null; } public Class<?> getFieldTypeForProperty(final Class<?> clazz, final String propertyName) throws ODataAnnotationException { if (clazz == null) { return null; } Field field = getFieldForPropertyName(propertyName, clazz, true); if (field == null) { throw new ODataAnnotationException("No field for property '" + propertyName + "' found at class '" + clazz + "'."); } return field.getType(); } public Class<?> getFieldTypeForProperty(final Object instance, final String propertyName) throws ODataAnnotationException { if (instance == null) { return null; } return getFieldTypeForProperty(instance.getClass(), propertyName); } public Object getValueForProperty(final Object instance, final String propertyName) throws ODataAnnotationException { if (instance == null) { return null; } Field field = getFieldForPropertyName(propertyName, instance.getClass(), true); if (field == null) { throw new ODataAnnotationException("No field for property '" + propertyName + "' found at class '" + instance.getClass() + "'."); } return getFieldValue(instance, field); } public void setValueForProperty(final Object instance, final String propertyName, final Object propertyValue) { if (instance != null) { Field field = getFieldForPropertyName(propertyName, instance.getClass(), true); if (field != null) { setFieldValue(instance, field, propertyValue); } } } private Field getFieldForPropertyName(final String propertyName, final Class<?> resultClass, final boolean inherited) { Field[] fields = resultClass.getDeclaredFields(); for (Field field : fields) { EdmProperty property = field.getAnnotation(EdmProperty.class); if (property != null) { if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) { return field; } else if (property.name().equals(propertyName)) { return field; } } } Class<?> superClass = resultClass.getSuperclass(); if (inherited && superClass != Object.class) { return getFieldForPropertyName(propertyName, superClass, true); } return null; } public Object getValueForField(final Object instance, final String fieldName, final Class<? extends Annotation> annotation) { if (instance == null) { return null; } return getValueForField(instance, fieldName, instance.getClass(), annotation, true); } public Object getValueForField(final Object instance, final Class<? extends Annotation> annotation) { if (instance == null) { return null; } return getValueForField(instance, instance.getClass(), annotation, true); } private Object getValueForField(final Object instance, final Class<?> resultClass, final Class<? extends Annotation> annotation, final boolean inherited) { return getValueForField(instance, null, resultClass, annotation, inherited); } public Map<String, Object> getValueForAnnotatedFields(final Object instance, final Class<? extends Annotation> annotation) { return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true); } private Map<String, Object> getValueForAnnotatedFields(final Object instance, final Class<?> resultClass, final Class<? extends Annotation> annotation, final boolean inherited) { if (instance == null) { return null; } Field[] fields = resultClass.getDeclaredFields(); Map<String, Object> fieldName2Value = new HashMap<String, Object>(); for (Field field : fields) { if (field.getAnnotation(annotation) != null) { Object value = getFieldValue(instance, field); final String name = extractPropertyName(field); fieldName2Value.put(name, value); } } Class<?> superClass = resultClass.getSuperclass(); if (inherited && superClass != Object.class) { Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true); fieldName2Value.putAll(tmp); } return fieldName2Value; } private String extractPropertyName(final Field field) { final EdmProperty property = field.getAnnotation(EdmProperty.class); if (property == null || property.name().isEmpty()) { return getCanonicalName(field); } else { return property.name(); } } public void setValueForAnnotatedField(final Object instance, final Class<? extends Annotation> annotation, final Object value) throws ODataAnnotationException { List<Field> fields = getAnnotatedFields(instance, annotation); if (fields.isEmpty()) { throw new ODataAnnotationException("No field found for annotation '" + annotation + "' on instance '" + instance + "'."); } else if (fields.size() > 1) { throw new ODataAnnotationException("More then one field found for annotation '" + annotation + "' on instance '" + instance + "'."); } setFieldValue(instance, fields.get(0), value); } public void setValuesToAnnotatedFields(final Object instance, final Class<? extends Annotation> annotation, final Map<String, Object> fieldName2Value) { List<Field> fields = getAnnotatedFields(instance, annotation); // XXX: refactore for (Field field : fields) { final String canonicalName = getCanonicalName(field); if (fieldName2Value.containsKey(canonicalName)) { Object value = fieldName2Value.get(canonicalName); setFieldValue(instance, field, value); } } } public List<Field> getAnnotatedFields(final Object instance, final Class<? extends Annotation> annotation) { if (instance == null) { return null; } return getAnnotatedFields(instance.getClass(), annotation, true); } public List<Field> getAnnotatedFields(final Class<?> fieldClass, final Class<? extends Annotation> annotation) { return getAnnotatedFields(fieldClass, annotation, true); } /** * * @param resultClass * @param annotation * @param inherited * @return */ private List<Field> getAnnotatedFields(final Class<?> resultClass, final Class<? extends Annotation> annotation, final boolean inherited) { if (resultClass == null) { return null; } Field[] fields = resultClass.getDeclaredFields(); List<Field> annotatedFields = new ArrayList<Field>(); for (Field field : fields) { if (field.getAnnotation(annotation) != null) { annotatedFields.add(field); } } Class<?> superClass = resultClass.getSuperclass(); if (inherited && superClass != Object.class) { List<Field> tmp = getAnnotatedFields(superClass, annotation, true); annotatedFields.addAll(tmp); } return annotatedFields; } private Object getValueForField(final Object instance, final String fieldName, final Class<?> resultClass, final Class<? extends Annotation> annotation, final boolean inherited) { if (instance == null) { return null; } Field[] fields = resultClass.getDeclaredFields(); for (Field field : fields) { if (field.getAnnotation(annotation) != null && (fieldName == null || field.getName().equals(fieldName))) { return getFieldValue(instance, field); } } Class<?> superClass = resultClass.getSuperclass(); if (inherited && superClass != Object.class) { return getValueForField(instance, fieldName, superClass, annotation, true); } return null; } private Object getFieldValue(final Object instance, final Field field) { try { boolean access = field.isAccessible(); field.setAccessible(true); Object value = field.get(instance); field.setAccessible(access); return value; } catch (IllegalArgumentException ex) { // should never happen throw new AnnotationRuntimeException(ex); } catch (IllegalAccessException ex) { // should never happen throw new AnnotationRuntimeException(ex); } } private void setFieldValue(final Object instance, final Field field, final Object value) { try { Object usedValue = value; if (value != null && field.getType() != value.getClass() && value.getClass() == String.class) { usedValue = convert(field, (String) value); } boolean access = field.isAccessible(); field.setAccessible(true); field.set(instance, usedValue); field.setAccessible(access); } catch (IllegalArgumentException ex) { // should never happen throw new AnnotationRuntimeException(ex); } catch (IllegalAccessException ex) { // should never happen throw new AnnotationRuntimeException(ex); } } private Object convert(final Field field, final String propertyValue) { Class<?> fieldClass = field.getType(); try { EdmProperty property = field.getAnnotation(EdmProperty.class); EdmSimpleTypeKind type = mapTypeKind(property.type()); return type.getEdmSimpleTypeInstance().valueOfString(propertyValue, EdmLiteralKind.DEFAULT, null, fieldClass); } catch (EdmSimpleTypeException ex) { throw new AnnotationRuntimeException("Conversion failed for string property [" + propertyValue + "] on field [" + field + "] with error: " + ex.getMessage(), ex); } } public boolean isEdmAnnotated(final Object object) { if (object == null) { return false; } return isEdmAnnotated(object.getClass()); } public boolean isEdmTypeAnnotated(final Class<?> clazz) { boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null; boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null; return isComplexEntity || isEntity; } public boolean isEdmAnnotated(final Class<?> clazz) { if (clazz == null) { return false; } else { final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class); final boolean isEntitySet = null != clazz.getAnnotation(EdmEntitySet.class); final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexType.class); return isEntity || isComplexEntity || isEntitySet; } } public String getCanonicalName(final Field field) { return firstCharToUpperCase(field.getName()); } public String getCanonicalName(final Class<?> clazz) { return firstCharToUpperCase(clazz.getSimpleName()); } private String firstCharToUpperCase(final String content) { if (content == null || content.isEmpty()) { return content; } return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1); } public EdmSimpleTypeKind mapTypeKind(final org.apache.olingo.odata2.api.annotation.edm.EdmType type) { switch (type) { case BINARY: return EdmSimpleTypeKind.Binary; case BOOLEAN: return EdmSimpleTypeKind.Boolean; case BYTE: return EdmSimpleTypeKind.Byte; case COMPLEX: return EdmSimpleTypeKind.Null; case DATE_TIME: return EdmSimpleTypeKind.DateTime; case DATE_TIME_OFFSET: return EdmSimpleTypeKind.DateTimeOffset; case DECIMAL: return EdmSimpleTypeKind.Decimal; case DOUBLE: return EdmSimpleTypeKind.Double; case GUID: return EdmSimpleTypeKind.Guid; case INT16: return EdmSimpleTypeKind.Int16; case INT32: return EdmSimpleTypeKind.Int32; case INT64: return EdmSimpleTypeKind.Int64; case NULL: return EdmSimpleTypeKind.Null; case SBYTE: return EdmSimpleTypeKind.SByte; case SINGLE: return EdmSimpleTypeKind.Single; case STRING: return EdmSimpleTypeKind.String; case TIME: return EdmSimpleTypeKind.Time; default: throw new AnnotationRuntimeException("Unknown type '" + type + "' for mapping to EdmSimpleTypeKind."); } } public EdmMultiplicity mapMultiplicity(final Multiplicity multiplicity) { switch (multiplicity) { case ZERO_OR_ONE: return EdmMultiplicity.ZERO_TO_ONE; case ONE: return EdmMultiplicity.ONE; case MANY: return EdmMultiplicity.MANY; default: throw new AnnotationRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity."); } } /** * */ private static class EdmAnnotationException extends RuntimeException { private static final long serialVersionUID = 42L; public EdmAnnotationException(final String message) { super(message); } } public String getCanonicalNamespace(final Class<?> aClass) { return generateNamespace(aClass); } public String extractContainerName(final Class<?> aClass) { EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class); if (entitySet != null) { String containerName = entitySet.container(); if (!containerName.isEmpty()) { return containerName; } } return DEFAULT_CONTAINER_NAME; } }