You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2013/12/05 10:15:35 UTC
[01/12] Removed not to merge PoC parts
Updated Branches:
refs/heads/PocEdmAnnotationsExtension a73d1975c -> 12ea18aed
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
deleted file mode 100644
index a277b41..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * *****************************************************************************
- * 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.core.annotation.processor.json;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class JsonWriter {
-
- private final Writer writer;
- private boolean firstProperty = true;
-
- public JsonWriter(Writer writer) {
- this.writer = writer;
- }
-
- public void startCallback(String functionName) {
- try {
- writer.write(encode(functionName) + "(");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void endCallback() {
- try {
- writer.write(");");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void startObject() {
- try {
- firstProperty = true;
- writer.write("{\n");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void endObject() {
- try {
- firstProperty = false;
- writer.write("\n}");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeName(String name) {
- try {
- writer.write("\"" + encode(name) + "\" : ");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void startArray() {
- try {
- writer.write("[\n");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void endArray() {
- try {
- writer.write("\n]");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeSeparator() {
- try {
- writer.write(", ");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeRawString(String value) {
- try {
- writer.write("\"" + value + "\"");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeString(String value) {
- try {
- writer.write("\"" + encode(value) + "\"");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeNull() {
- try {
- writer.write("null");
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- public void writeStringProperty(String name, String value) {
- if (value == null) {
- writeProperty(name, value, false);
- } else {
- writeProperty(name, encode(value), false);
- }
- }
-
- public void writeRawStringProperty(String name, String value) {
- writeProperty(name, value, false);
- }
-
- public void writeRawProperty(String name, String value) {
- writeProperty(name, value, true);
- }
-
- private void writeProperty(String name, String value, boolean raw) {
- if (firstProperty) {
- firstProperty = false;
- } else {
- writeSeparator();
- }
-
- // write content
- this.writeName(name);
- if (value == null) {
- writeNull();
- } else {
- try {
- if (raw) {
- writeRaw(value);
- } else {
- writeString(value);
- }
- } catch (Exception e) {
- writeString("exception for property with name '" + name
- + "' with message '" + e.getMessage()
- + "' and toString '" + value.toString() + "'.");
- }
- }
-
- }
-
- private void writeRaw(String value) {
- try {
- writer.write(value);
- } catch (IOException e) {
- throw new ODataRuntimeException(e.getMessage(), e);
- }
- }
-
- private String encode(String unencoded) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < unencoded.length(); i++) {
- char c = unencoded.charAt(i);
- if (c == '\\') {
- sb.append("\\\\");
- } else if (c == '"') {
- sb.append("\\\"");
- } else if (c == '\n') {
- sb.append("\\n");
- } else if (c == '\r') {
- sb.append("\\r");
- } else if (c == '\f') {
- sb.append("\\f");
- } else if (c == '\b') {
- sb.append("\\b");
- } else if (c == '\t') {
- sb.append("\\t");
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- public void start() {
- writeRaw("{\n\"d\":");
- }
-
- public void finish() {
- writeRaw("\n}");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
new file mode 100644
index 0000000..0c81fb1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
@@ -0,0 +1,726 @@
+/**
+ * *****************************************************************************
+ * 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.core.annotation.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;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+ public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
+
+ /**
+ * Compare keys of both instances.
+ *
+ * @param firstInstance
+ * @param secondInstance
+ * @return
+ */
+ public boolean keyMatch(Object firstInstance, 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);
+
+ return keyValuesMatch(firstKeyFields, secondKeyFields);
+ }
+
+ /**
+ * Compare keys of instance with key values in map.
+ *
+ * @param instance
+ * @param keyName2Value
+ * @return
+ */
+ public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
+ Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
+ return keyValuesMatch(instanceKeyFields, keyName2Value);
+ }
+
+ private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
+ if (firstKeyValues.size() != secondKeyValues.size()) {
+ return false;
+ } 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(Object firstKey, Object secondKey) {
+ if (firstKey == null) {
+ if (secondKey == null) {
+ return true;
+ } else {
+ return secondKey.equals(firstKey);
+ }
+ } else {
+ return firstKey.equals(secondKey);
+ }
+ }
+
+ public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
+ Class<?> entityTypeClass = enp.toType();
+ return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
+ }
+
+ public String extractEntitTypeName(EdmNavigationProperty enp, 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(Class<?> annotatedClass) {
+ return extractTypeName(annotatedClass, EdmEntityType.class);
+ }
+
+ public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
+ if(type.namespace().isEmpty()) {
+ return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
+ }
+ return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
+ }
+
+ public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
+ EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
+ if(type == null) {
+ return null;
+ }
+ return extractEntityTypeFqn(type, annotatedClass);
+ }
+
+ public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
+ EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
+ if(type == null) {
+ return null;
+ }
+ return extractComplexTypeFqn(type, annotatedClass);
+ }
+
+ public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
+ if(type.namespace().isEmpty()) {
+ return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
+ }
+ return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
+ }
+
+ public String extractComplexTypeName(Class<?> annotatedClass) {
+ return extractTypeName(annotatedClass, EdmComplexType.class);
+ }
+
+ public String generateNamespace(Class<?> annotatedClass) {
+ String packageName = annotatedClass.getPackage().getName();
+ return packageName;
+ }
+
+ /**
+ *
+ *
+ * @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(Class<?> annotatedClass, 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(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(Field field) {
+ String propertyName = getPropertyNameFromAnnotation(field);
+ if (propertyName.isEmpty()) {
+ propertyName = getCanonicalName(field);
+ }
+ return propertyName;
+ }
+
+ public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
+ return getCanonicalRole(field.getDeclaringClass());
+ }
+
+ public String extractToRoleName(EdmNavigationProperty enp, Field field) {
+ String role = enp.toRole();
+ if (role.isEmpty()) {
+ role = getCanonicalRole(
+ field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
+ (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
+ }
+ return role;
+ }
+
+ public String getCanonicalRole(Class<?> fallbackClass) {
+ String toRole = extractEntityTypeName(fallbackClass);
+ return "r_" + toRole;
+ }
+
+ public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
+ String relationshipName = enp.association();
+ if (relationshipName.isEmpty()) {
+ final String fromRole = extractFromRoleName(enp, field);
+ final String toRole = extractToRoleName(enp, field);
+ if (fromRole.compareTo(toRole) > 0) {
+ relationshipName = toRole + "-" + fromRole;
+ } else {
+ relationshipName = fromRole + "-" + toRole;
+ }
+ }
+ return relationshipName;
+ }
+
+ public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, 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(T instance, 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 = 1L;
+
+ public ODataAnnotationException(String message) {
+ super(message);
+ }
+ }
+
+
+ public class AnnotatedNavInfo {
+ private final Field fromField;
+ private final Field toField;
+ private final EdmNavigationProperty fromNavigation;
+ private final EdmNavigationProperty toNavigation;
+
+ public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
+ EdmNavigationProperty toNavigation) {
+ this.fromField = fromField;
+ this.toField = toField;
+ this.fromNavigation = fromNavigation;
+ this.toNavigation = toNavigation;
+ }
+
+ public Field getFromField() {
+ return fromField;
+ }
+
+ public Field getToField() {
+ return toField;
+ }
+
+ public EdmMultiplicity getFromMultiplicity() {
+ return getMultiplicity(toNavigation, toField);
+ }
+
+ public EdmMultiplicity getToMultiplicity() {
+ return getMultiplicity(fromNavigation, fromField);
+ }
+
+ public boolean isBiDirectional() {
+ return toNavigation != null;
+ }
+ }
+
+ public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
+ List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
+ List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
+
+ // first try via association name to get full navigation information
+ for (Field sourceField : sourceFields) {
+ final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+ final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
+ for (Field targetField : targetFields) {
+ 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 none bi-directinal navigation
+ String targetEntityTypeName = extractEntityTypeName(targetClass);
+ for (Field sourceField : sourceFields) {
+ final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+ final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
+
+ if (navTargetEntityName.equals(targetEntityTypeName)) {
+ return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
+ }
+ }
+
+ return null;
+ }
+
+ public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+ if (instance == null) {
+ return null;
+ }
+
+ Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+ if (field == null) {
+ throw new ODataAnnotationException("No field for property '" + propertyName
+ + "' found at class '" + instance.getClass() + "'.");
+ }
+ return field.getType();
+ }
+
+ public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+ if (instance == null) {
+ return null;
+ }
+
+ Field field = getFieldForPropertyName(instance, 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(Object instance, String propertyName, Object propertyValue) {
+ if (instance != null) {
+ Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+ if (field != null) {
+ setFieldValue(instance, field, propertyValue);
+ }
+ }
+ }
+
+ private Field getFieldForPropertyName(Object instance, String propertyName,
+ Class<?> resultClass, boolean inherited) {
+ if (instance == null) {
+ return null;
+ }
+
+ 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(instance, propertyName, superClass, true);
+ }
+
+ return null;
+ }
+
+ public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
+ }
+
+ public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getValueForField(instance, instance.getClass(), annotation, true);
+ }
+
+ private Object getValueForField(Object instance, Class<?> resultClass,
+ Class<? extends Annotation> annotation, boolean inherited) {
+ return getValueForField(instance, null, resultClass, annotation, inherited);
+ }
+
+ public Map<String, Object> getValueForAnnotatedFields(Object instance,
+ Class<? extends Annotation> annotation) {
+ return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
+ }
+
+ private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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 EdmProperty property = field.getAnnotation(EdmProperty.class);
+ final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
+ 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;
+ }
+
+ public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, 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(Object instance,
+ Class<? extends Annotation> annotation, 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(Object instance, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getAnnotatedFields(instance.getClass(), annotation, true);
+ }
+
+ public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
+ return getAnnotatedFields(fieldClass, annotation, true);
+ }
+
+ /**
+ *
+ * @param instance
+ * @param resultClass
+ * @param annotation
+ * @param inherited
+ * @return
+ */
+ private List<Field> getAnnotatedFields(Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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(Object instance, String fieldName, Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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(Object instance, 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 ODataRuntimeException(ex);
+ } catch (IllegalAccessException ex) { // should never happen
+ throw new ODataRuntimeException(ex);
+ }
+ }
+
+ private void setFieldValue(Object instance, Field field, 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 ODataRuntimeException(ex);
+ } catch (IllegalAccessException ex) { // should never happen
+ throw new ODataRuntimeException(ex);
+ }
+ }
+
+ public Object convert(Field field, 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 ODataRuntimeException("Conversion failed for string property with error: "
+ + ex.getMessage(), ex);
+ }
+ }
+
+ public boolean isEdmAnnotated(Object object) {
+ if (object == null) {
+ return false;
+ }
+ return isEdmAnnotated(object.getClass());
+ }
+
+ public boolean isEdmTypeAnnotated(Class<?> clazz) {
+ boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
+ boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
+ return isComplexEntity || isEntity;
+ }
+
+ public boolean isEdmAnnotated(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(Field field) {
+ return firstCharToUpperCase(field.getName());
+ }
+
+ public String getCanonicalName(Class<?> clazz) {
+ return firstCharToUpperCase(clazz.getSimpleName());
+ }
+
+ private String firstCharToUpperCase(String content) {
+ if (content == null || content.isEmpty()) {
+ return content;
+ }
+ return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+ }
+
+ public EdmSimpleTypeKind mapTypeKind(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 ODataRuntimeException("Unknown type '" + type
+ + "' for mapping to EdmSimpleTypeKind.");
+ }
+ }
+
+ public EdmMultiplicity mapMultiplicity(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 ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
+ }
+ }
+
+ /**
+ *
+ */
+ private static class EdmAnnotationException extends RuntimeException {
+
+ private static final long serialVersionUID = 42L;
+
+ public EdmAnnotationException(String message) {
+ super(message);
+ }
+ }
+
+ public String getCanonicalNamespace(Class<?> aClass) {
+ return generateNamespace(aClass);
+ }
+
+ public String extractContainerName(Class<?> aClass) {
+ EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+ if(entitySet != null) {
+ String containerName = entitySet.container();
+ if(!containerName.isEmpty()) {
+ return containerName;
+ }
+ }
+ return DEFAULT_CONTAINER_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
new file mode 100644
index 0000000..5e9fcdb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.core.annotation.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+
+ private static final File[] EMPTY_FILE_ARRAY = new File[0];
+
+ private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(CLASSFILE_ENDING);
+ }
+ public static final String CLASSFILE_ENDING = ".class";
+ };
+
+ private static final FileFilter FOLDER_FILTER = new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ };
+
+ public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+ return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+ }
+
+
+ public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+ final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ String folderToScan = packageToScan.replace(".", "/");
+ URL url = classLoader.getResource(folderToScan);
+ if(url == null) {
+ throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+ }
+ File folder = new File(url.getFile());
+ File[] classFiles = folder.listFiles(ff);
+ if(classFiles == null) {
+ classFiles = EMPTY_FILE_ARRAY;
+ }
+
+ List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+ for (File file : classFiles) {
+ String name = file.getName();
+ String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+ try {
+ Class<?> c = classLoader.loadClass(fqn);
+ if (cv.isClassValid(c)) {
+ annotatedClasses.add(c);
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new IllegalArgumentException("Exception during class loading of class '" + fqn +
+ "' with message '" + ex.getMessage() + "'.");
+ }
+ }
+
+ // recursive search
+ File[] subfolders = listSubFolder(folder);
+ for (File file : subfolders) {
+ List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+ annotatedClasses.addAll(subFolderClazzes);
+ }
+ //
+
+ return annotatedClasses;
+ }
+
+ private static File[] listSubFolder(File folder) {
+ File[] subfolders = folder.listFiles(FOLDER_FILTER);
+ if(subfolders == null) {
+ return EMPTY_FILE_ARRAY;
+ }
+ return subfolders;
+ }
+
+ public interface ClassValidator {
+ boolean isClassValid(Class<?> c);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
deleted file mode 100644
index 90a4706..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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.
--->
-<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
- <appender name="console" class="org.apache.log4j.ConsoleAppender">
- <param name="Target" value="System.out" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
- </layout>
- </appender>
-
- <logger name="org.apache.olingo.odata2.ref" additivity="false">
- <level value="trace" />
- <appender-ref ref="console" />
- </logger>
-
- <root>
- <priority value="error" />
- <appender-ref ref="console" />
- </root>
-</log4j:configuration>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
index b132a0b..04dbefc 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
@@ -24,10 +24,10 @@ import org.apache.olingo.odata2.api.edm.FullQualifiedName;
import org.apache.olingo.odata2.api.edm.provider.EntitySet;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
import org.apache.olingo.odata2.core.annotation.model.Building;
import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
deleted file mode 100644
index 3d7b89d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.core.annotation.processor.json;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- *
- */
-public class JsonConsumerTest {
-
- public static final String SIMPLE_TEAM = "{\"d\":{"
- + "\"__metadata\":{\"id\":\"https://localhost/Test.svc/Teams('1')\","
- + "\"uri\":\"https://localhost/Test.svc/Teams('1')\","
- + "\"type\":\"Test.Team\""
- + "},"
- + "\"Id\":\"1\","
- + "\"Name\":\"Team 1\","
- + "\"isScrumTeam\":false}}";
-
- public static final String SIMPLER_TEAM = "{"
- + "\"d\":{"
- + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false"
- + "}}";
-
- @Test
- public void simplerRead() throws Exception {
- InputStream content = encapsulate(SIMPLER_TEAM);
- JsonConsumer jc = new JsonConsumer(content);
- Map<String, String> name2Values = jc.read();
-
-// System.out.println("" + name2Values);
- Assert.assertEquals(3, name2Values.size());
-
- Assert.assertEquals("1", name2Values.get("Id"));
- Assert.assertEquals("Team 1", name2Values.get("Name"));
- Assert.assertEquals("false", name2Values.get("isScrumTeam"));
- }
-
- @Test
- public void simpleRead() throws Exception {
- InputStream content = encapsulate(SIMPLE_TEAM);
- JsonConsumer jc = new JsonConsumer(content);
- Map<String, String> name2Values = jc.read();
-
-// System.out.println("" + name2Values);
- Assert.assertEquals(6, name2Values.size());
-
- Assert.assertEquals("1", name2Values.get("Id"));
- Assert.assertEquals("Team 1", name2Values.get("Name"));
- Assert.assertEquals("false", name2Values.get("isScrumTeam"));
-
- Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_id"));
- Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_uri"));
- Assert.assertEquals("Test.Team", name2Values.get("md_type"));
- }
-
- public static InputStream encapsulate(final String content) {
- try {
- return new ByteArrayInputStream(content.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- // we know that UTF-8 is supported
- throw new RuntimeException("UTF-8 MUST be supported.", e);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/pom.xml b/odata2-edm-annotation/edm-annotation-webref/pom.xml
index 9f4e99f..18ff957 100644
--- a/odata2-edm-annotation/edm-annotation-webref/pom.xml
+++ b/odata2-edm-annotation/edm-annotation-webref/pom.xml
@@ -21,6 +21,10 @@ the License. -->
<relativePath>..</relativePath>
</parent>
+ <properties>
+ <version.slf4j>1.7.1</version.slf4j>
+ </properties>
+
<build>
<finalName>${project.artifactId}</finalName>
<resources>
@@ -88,17 +92,11 @@ the License. -->
<artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-ref-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
-
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
- <version>1.7.1</version>
+ <version>${version.slf4j}</version>
</dependency>
</dependencies>
[04/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
deleted file mode 100644
index 73d1218..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.imageio.ImageIO;
-
-/**
- *
- */
-public class ResourceHelper {
-
- public enum Format {BMP, JPEG, PNG, GIF};
-
- public static byte[] generateImage() {
- return generateImage(Format.PNG);
- }
-
- public static byte[] generateImage(Format format) {
- try {
- int width = 320;
- int height = 320;
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
- WritableRaster raster = image.getRaster();
-
- int mod = format.ordinal() + 2;
- for (int h = 0; h < height; h++) {
- for (int w = 0; w < width; w++) {
- if (((h / 32) + (w / 32)) % mod == 0) {
- raster.setSample(w, h, 0, 0);
- } else {
- raster.setSample(w, h, 0, 1);
- }
- }
- }
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
- ImageIO.write(image, format.name(), out);
- return out.toByteArray();
- } catch (IOException ex) {
- return new byte[0];
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
deleted file mode 100644
index 7c9e486..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Rooms")
-public class Room extends RefBase {
-
- @EdmProperty
- private Integer seats;
- @EdmProperty
- private Integer version;
- @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
- private Building building;
- @EdmNavigationProperty(name = "nr_Employees")
- private List<Employee> employees = new ArrayList<Employee>();
-
- public Room(final int id, final String name) {
- super(id, name);
- }
-
- public void setSeats(final int seats) {
- this.seats = seats;
- }
-
- public int getSeats() {
- return seats;
- }
-
- public void setVersion(final int version) {
- this.version = version;
- }
-
- public int getVersion() {
- return version;
- }
-
- public void setBuilding(final Building building) {
- this.building = building;
- }
-
- public Building getBuilding() {
- return building;
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
deleted file mode 100644
index e9b296f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.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.annotation.edm.EdmType;
-
-/**
-*
-*/
-@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Teams")
-public class Team extends RefBase {
- @EdmProperty(type = EdmType.BOOLEAN)
- private Boolean isScrumTeam;
- @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
- private List<Employee> employees = new ArrayList<Employee>();
-
- public Team() {
- super(-1, null);
- }
-
- public Team(final int id, final String name) {
- super(id, name);
- }
-
- public Boolean isScrumTeam() {
- return isScrumTeam;
- }
-
- public void setScrumTeam(final Boolean isScrumTeam) {
- this.isScrumTeam = isScrumTeam;
- }
-
- public void addEmployee(Employee e) {
- this.employees.add(e);
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/pom.xml b/odata2-edm-annotation/edm-annotation-webref/pom.xml
deleted file mode 100644
index 18ff957..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/pom.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>olingo-odata2-edm-annotation-webref-incubating</artifactId>
- <packaging>war</packaging>
- <name>${project.artifactId}</name>
-
- <parent>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
-
- <properties>
- <version.slf4j>1.7.1</version.slf4j>
- </properties>
-
- <build>
- <finalName>${project.artifactId}</finalName>
- <resources>
- <resource>
- <directory>src/main/version</directory>
- <filtering>true</filtering>
- <targetPath>../${project.build.finalName}/gen</targetPath>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- <resource>
- <directory>target/maven-shared-archive-resources</directory>
- </resource>
- </resources>
-
- <plugins>
- <plugin>
- <groupId>com.sap.research</groupId>
- <artifactId>nwcloud-maven-plugin</artifactId>
- <version>1.0.0.RELEASE</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
-
- </build>
-
- <dependencies>
- <dependency>
- <!-- required because of auto detection of web facet 2.5 -->
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-frontend-jaxrs</artifactId>
- <version>${cxf.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-api-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-core-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>${version.slf4j}</version>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>dev</id>
-
- <build>
- <defaultGoal>cargo:run</defaultGoal>
-
- <plugins>
- <plugin>
- <groupId>org.codehaus.cargo</groupId>
- <artifactId>cargo-maven2-plugin</artifactId>
- <version>1.4.2</version>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
deleted file mode 100644
index 668ac86..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-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.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Buildings")
-public class Building {
- @EdmKey
- @EdmProperty(type = EdmType.INT32)
- private int id;
- @EdmProperty
- private String name;
- @EdmProperty(name = "Image", type = EdmType.BINARY)
- private byte[] image;
- @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
- association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
- private List<Room> rooms = new ArrayList<Room>();
-
- public String getId() {
- return Integer.toString(id);
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setImage(final byte[] byteArray) {
- image = byteArray;
- }
-
- public byte[] getImage() {
- if (image == null) {
- return null;
- } else {
- return image.clone();
- }
- }
-
- public void addRoom(Room room) {
- rooms.add(room);
- }
-
- public List<Room> getRooms() {
- return rooms;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
deleted file mode 100644
index a4d5a56..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
-public class City {
-
- @EdmProperty
- private String postalCode;
- @EdmProperty
- private String cityName;
-
- public City(final String postalCode, final String name) {
- this.postalCode = postalCode;
- cityName = name;
- }
-
- public void setPostalCode(final String postalCode) {
- this.postalCode = postalCode;
- }
-
- public String getPostalCode() {
- return postalCode;
- }
-
- public void setCityName(final String cityName) {
- this.cityName = cityName;
- }
-
- public String getCityName() {
- return cityName;
- }
-
- @Override
- public String toString() {
- return String.format("%s, %s", cityName, postalCode);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
deleted file mode 100644
index 2204ee8..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-
-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.EdmFacets;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Employees")
-public class Employee {
- @EdmKey
- @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
- private String employeeId;
- @EdmProperty(name = "EmployeeName")
- private String employeeName;
- @EdmProperty
- private int age;
- @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
- private Manager manager;
- @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
- private Team team;
- @EdmNavigationProperty(name = "ne_Room")
- private Room room;
- @EdmMediaResourceMimeType
- private String imageType;
- @EdmMediaResourceContent
- private byte[] image;
- @EdmProperty(name = "ImageUrl")
- private String imageUrl;
- @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME,
- facets = @EdmFacets(nullable = true))
- private Calendar entryDate;
- @EdmProperty(name = "Location", facets = @EdmFacets(nullable = false))
- private Location location;
-
- public String getId() {
- return employeeId;
- }
-
- public void setEmployeeName(final String employeeName) {
- this.employeeName = employeeName;
- }
-
- public String getEmployeeName() {
- return employeeName;
- }
-
- public void setAge(final int age) {
- this.age = age;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setManager(final Manager manager) {
- this.manager = manager;
- }
-
- public Manager getManager() {
- return manager;
- }
-
- public void setTeam(final Team team) {
- this.team = team;
- }
-
- public Team getTeam() {
- return team;
- }
-
- public void setRoom(final Room room) {
- this.room = room;
- }
-
- public Room getRoom() {
- return room;
- }
-
- public void setImageUri(final String imageUri) {
- imageUrl = imageUri;
- }
-
- public String getImageUri() {
- return imageUrl;
- }
-
- public void setLocation(final Location location) {
- this.location = location;
- }
-
- public Location getLocation() {
- return location;
- }
-
- public void setEntryDate(final Calendar date) {
- entryDate = date;
- }
-
- public Calendar getEntryDate() {
- return entryDate;
- }
-
- public void setImageType(final String imageType) {
- this.imageType = imageType;
- }
-
- public String getImageType() {
- return imageType;
- }
-
- public void setImage(final byte[] image) {
- this.image = image;
- }
-
- public void setImage(final String imageUrl) {
- image = loadImage(imageUrl);
- }
-
- private static byte[] loadImage(final String imageUrl) {
- return ResourceHelper.loadAsByte(imageUrl);
- }
-
- public byte[] getImage() {
- if (image == null) {
- return null;
- }
- return image.clone();
- }
-
- @Override
- public int hashCode() {
- if (employeeId == null) {
- return 0;
- }
- return employeeId.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
- }
-
- @Override
- public String toString() {
- return "{\"EmployeeId\":\"" + employeeId + "\","
- + "\"EmployeeName\":\"" + employeeName + "\","
- + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
- + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
- + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
- + "\"Location\":"
- + (location == null ? "null" :
- "{\"City\":" + (location.getCity() == null ? "null" :
- "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
- + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
- + "\"Country\":\"" + location.getCountry() + "\"}") + ","
- + "\"Age\":" + age + ","
- + "\"EntryDate\":"
- + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
- + "\"ImageUrl\":\"" + imageUrl + "\"}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
deleted file mode 100644
index 9b0785c..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
-public class Location {
- @EdmProperty
- private String country;
- @EdmProperty
- private City city;
-
- public Location(final String country, final String postalCode, final String cityName) {
- this.country = country;
- city = new City(postalCode, cityName);
- }
-
- public void setCountry(final String country) {
- this.country = country;
- }
-
- public String getCountry() {
- return country;
- }
-
- public void setCity(final City city) {
- this.city = city;
- }
-
- public City getCity() {
- return city;
- }
-
- @Override
- public String toString() {
- return String.format("%s, %s", country, city.toString());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
deleted file mode 100644
index 57e6d78..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-
-/**
- *
- */
-@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Managers")
-public class Manager extends Employee {
-
- @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
- toMultiplicity = Multiplicity.MANY)
- private List<Employee> employees = new ArrayList<Employee>();
-
- public List<Employee> getEmployees() {
- return employees;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
deleted file mode 100644
index ab17fbb..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-public interface ModelSharedConstants {
-
- String NAMESPACE_1 = "RefScenario";
- String CONTAINER_1 = "Container1";
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
deleted file mode 100644
index 52971cd..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.util.Arrays;
-
-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.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Photos")
-public class Photo {
- @EdmKey
- @EdmProperty
- private String name;
- @EdmKey
- @EdmProperty
- private String type;
- @EdmProperty
- @EdmMediaResourceMimeType
- private String mimeType;
- @EdmProperty
- @EdmMediaResourceSource
- private String imageUrl = "http://localhost/someResource.png";
- @EdmProperty(type = EdmType.BINARY)
- @EdmMediaResourceContent
- private byte[] image = ResourceHelper.generateImage();
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(final String type) {
- this.type = type;
- }
-
- public String getImageUri() {
- return imageUrl;
- }
-
- public void setImageUri(final String uri) {
- imageUrl = uri;
- }
-
- public byte[] getImage() {
- return image.clone();
- }
-
- public void setImage(final byte[] image) {
- this.image = image;
- }
-
- public String getImageType() {
- return mimeType;
- }
-
- public void setImageType(final String imageType) {
- this.mimeType = imageType;
- }
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
- hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final Photo other = (Photo) obj;
- if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
- return false;
- }
- if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "{\"Name\":\"" + name + "\","
- + "\"Type\":\"" + type + "\","
- + "\"ImageUrl\":\"" + imageUrl + "\","
- + "\"Image\":\"" + Arrays.toString(image) + "\","
- + "\"MimeType\":\"" + mimeType + "\"";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
deleted file mode 100644
index 727b8c3..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-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.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
-public abstract class RefBase {
- @EdmProperty(name="Name")
- protected String name;
- @EdmProperty(name="Id", type = EdmType.STRING)
- @EdmKey
- protected String id;
-
- public String getName() {
- return name;
- }
-
- public String getId() {
- return id;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setId(int id) {
- this.id = String.valueOf(id);
- }
-
- @Override
- public int hashCode() {
- if(id == null) {
- return -1;
- }
- return id.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final RefBase other = (RefBase) obj;
- if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
- return false;
- }
- if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
- return false;
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
deleted file mode 100644
index 3d2bb88..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.imageio.ImageIO;
-
-/**
- *
- */
-public class ResourceHelper {
-
- public static byte[] loadAsByte(String resource) {
- return load(resource, new byte[0]);
- }
-
- public static byte[] load(String resource, byte[] defaultResult) {
- InputStream instream = null;
- try {
- instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
- if (instream == null) {
- return defaultResult;
- }
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- int b = 0;
- while ((b = instream.read()) != -1) {
- stream.write(b);
- }
-
- return stream.toByteArray();
- } catch (IOException e) {
- throw new RuntimeException(e);
- } finally {
- if(instream != null) {
- try {
- instream.close();
- } catch (IOException ex) { }
- }
- }
- }
-
- public enum Format {BMP, JPEG, PNG, GIF};
-
- public static byte[] generateImage() {
- return generateImage(Format.PNG);
- }
-
- public static byte[] generateImage(Format format) {
- try {
- int width = 320;
- int height = 320;
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
- WritableRaster raster = image.getRaster();
-
- int mod = format.ordinal() + 2;
- for (int h = 0; h < height; h++) {
- for (int w = 0; w < width; w++) {
- if (((h / 32) + (w / 32)) % mod == 0) {
- raster.setSample(w, h, 0, 0);
- } else {
- raster.setSample(w, h, 0, 1);
- }
- }
- }
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
- ImageIO.write(image, format.name(), out);
- return out.toByteArray();
- } catch (IOException ex) {
- return new byte[0];
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
deleted file mode 100644
index 2d9f48e..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Rooms")
-public class Room extends RefBase {
-
- @EdmProperty
- private Integer seats;
- @EdmProperty
- private Integer version;
- @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
- private Building building;
- @EdmNavigationProperty(name = "nr_Employees")
- private List<Employee> employees = new ArrayList<Employee>();
-
- public void setSeats(final int seats) {
- this.seats = seats;
- }
-
- public int getSeats() {
- return seats;
- }
-
- public void setVersion(final int version) {
- this.version = version;
- }
-
- public int getVersion() {
- return version;
- }
-
- public void setBuilding(final Building building) {
- this.building = building;
- }
-
- public Building getBuilding() {
- return building;
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
deleted file mode 100644
index 50d2ad2..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * 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.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.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.annotation.edm.EdmType;
-
-/**
-*
-*/
-@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Teams")
-public class Team extends RefBase {
- @EdmProperty(type = EdmType.BOOLEAN)
- private Boolean isScrumTeam;
- @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
- private List<Employee> employees = new ArrayList<Employee>();
-
- public Boolean isScrumTeam() {
- return isScrumTeam;
- }
-
- public void setScrumTeam(final Boolean isScrumTeam) {
- this.isScrumTeam = isScrumTeam;
- }
-
- public void addEmployee(Employee e) {
- this.employees.add(e);
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
deleted file mode 100644
index 3870119..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * *****************************************************************************
- * 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.ref.annotation.processor;
-
-import java.util.Calendar;
-
-import org.apache.olingo.odata2.api.ODataCallback;
-import org.apache.olingo.odata2.api.ODataDebugCallback;
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.ODataServiceFactory;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.ep.EntityProvider;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
-import org.apache.olingo.odata2.api.processor.ODataErrorContext;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.core.annotation.data.AnnotationInMemoryDs;
-import org.apache.olingo.odata2.core.annotation.data.AnnotationValueAccess;
-import org.apache.olingo.odata2.core.annotation.data.DataStore;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
-import org.apache.olingo.odata2.ref.annotation.model.Building;
-import org.apache.olingo.odata2.ref.annotation.model.Employee;
-import org.apache.olingo.odata2.ref.annotation.model.Location;
-import org.apache.olingo.odata2.ref.annotation.model.Manager;
-import org.apache.olingo.odata2.ref.annotation.model.Photo;
-import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
-import org.apache.olingo.odata2.ref.annotation.model.Room;
-import org.apache.olingo.odata2.ref.annotation.model.Team;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- */
-public class AnnotationPocServiceFactory extends ODataServiceFactory {
-
- private static boolean isInitialized = false;
-
- @Override
- public ODataService createService(final ODataContext context) throws ODataException {
-
- String modelPackage = "org.apache.olingo.odata2.ref.annotation.model";
- AnnotationEdmProvider annotationEdmProvider = new AnnotationEdmProvider(modelPackage);
- AnnotationInMemoryDs annotationScenarioDs = new AnnotationInMemoryDs(modelPackage);
- AnnotationValueAccess annotationValueAccess = new AnnotationValueAccess();
-
- if (!isInitialized) {
- initializeSampleData(annotationScenarioDs);
- isInitialized = true;
- }
-
- // Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
- return createODataSingleProcessorService(annotationEdmProvider,
- new ListsProcessor(annotationScenarioDs, annotationValueAccess));
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
- return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
- ? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
- ? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
- }
-
- /*
- * Helper classes and methods
- */
-
- /**
- *
- */
- private final class ScenarioDebugCallback implements ODataDebugCallback {
-
- @Override
- public boolean isDebugEnabled() {
- return true;
- }
- }
-
- private class ScenarioErrorCallback implements ODataErrorCallback {
-
- private final Logger LOG = LoggerFactory.getLogger(ScenarioErrorCallback.class);
-
- @Override
- public ODataResponse handleError(final ODataErrorContext context) throws ODataApplicationException {
- if (context.getHttpStatus() == HttpStatusCodes.INTERNAL_SERVER_ERROR) {
- LOG.error("Internal Server Error", context.getException());
- }
-
- return EntityProvider.writeErrorDocument(context);
- }
-
- }
-
- private void initializeSampleData(AnnotationInMemoryDs dataSource) throws ODataApplicationException {
- DataStore<Team> teamDs = dataSource.getDataStore(Team.class);
- teamDs.create(createTeam("Team Alpha", true));
- teamDs.create(createTeam("Team Beta", false));
- teamDs.create(createTeam("Team Gamma", false));
- teamDs.create(createTeam("Team Omega", true));
- teamDs.create(createTeam("Team Zeta", true));
-
- DataStore<Building> buildingsDs = dataSource.getDataStore(Building.class);
- Building redBuilding = createBuilding("Red Building");
- buildingsDs.create(redBuilding);
- Building greenBuilding = createBuilding("Green Building");
- buildingsDs.create(greenBuilding);
- Building blueBuilding = createBuilding("Blue Building");
- buildingsDs.create(blueBuilding);
- Building yellowBuilding = createBuilding("Yellow Building");
- buildingsDs.create(yellowBuilding);
-
- DataStore<Photo> photoDs = dataSource.getDataStore(Photo.class);
- photoDs.create(createPhoto("Small picture", ResourceHelper.Format.GIF));
- photoDs.create(createPhoto("Medium picture", ResourceHelper.Format.PNG));
- photoDs.create(createPhoto("Big picture", ResourceHelper.Format.JPEG));
- photoDs.create(createPhoto("Huge picture", ResourceHelper.Format.BMP));
-
- DataStore<Room> roomDs = dataSource.getDataStore(Room.class);
- roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
- roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
- roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
- roomDs.create(createRoom("Big blue room", 40, 1, blueBuilding));
- roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
- roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
-
- DataStore<Employee> employeeDataStore = dataSource.getDataStore(Employee.class);
- employeeDataStore.create(createEmployee("first Employee",
- new Location("Norge", "8392", "Ä"), 42, null,
- photoDs.read().iterator().next().getImage(), photoDs.read().iterator().next().getImageType(),
- "http://localhost/image/first.png",
- null, teamDs.read().iterator().next(), roomDs.read().iterator().next()));
- }
-
- private Employee createEmployee(final String name,
- Location location, final int age, final Calendar date,
- final byte[] image, final String imageType, final String imageUrl,
- Manager manager, Team team, Room room) {
- Employee employee = new Employee();
- employee.setEmployeeName(name);
- employee.setLocation(location);
- employee.setAge(age);
- employee.setEntryDate(date);
- employee.setImage(image);
- employee.setImageType(imageType);
- employee.setImageUri(imageUrl);
- employee.setManager(manager);
- employee.setTeam(team);
- employee.setRoom(room);
- return employee;
- }
-
- private Team createTeam(String teamName, boolean isScrumTeam) {
- Team team = new Team();
- team.setName(teamName);
- team.setScrumTeam(isScrumTeam);
- return team;
- }
-
- private Building createBuilding(String buildingName) {
- Building b = new Building();
- b.setName(buildingName);
- return b;
- }
-
- private Photo createPhoto(String name, ResourceHelper.Format format) {
- Photo p = new Photo();
- p.setName(name);
- p.setImageUri("http://localhost/image/" + name);
- p.setType(format.name());
- p.setImageType("image/" + format.name().toLowerCase());
- p.setImage(ResourceHelper.generateImage(format));
- return p;
- }
-
- private Room createRoom(String name, int seats, int version, Building building) {
- Room r = new Room();
- r.setName(name);
- r.setSeats(seats);
- r.setVersion(version);
- r.setBuilding(building);
-
- building.addRoom(r);
-
- return r;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
deleted file mode 100644
index 90a4706..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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.
--->
-<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
- <appender name="console" class="org.apache.log4j.ConsoleAppender">
- <param name="Target" value="System.out" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
- </layout>
- </appender>
-
- <logger name="org.apache.olingo.odata2.ref" additivity="false">
- <level value="trace" />
- <appender-ref ref="console" />
- </logger>
-
- <root>
- <priority value="error" />
- <appender-ref ref="console" />
- </root>
-</log4j:configuration>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html b/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
deleted file mode 100644
index 6d76d0b..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-
- 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.
-
--->
-
-<table border="1">
-<tr><td>name</td><td>${name}</td></tr>
-<tr><td>version</td><td>${version}</td></tr>
-<tr><td>timestamp</td><td>${timestamp}</td></tr>
-<tr><td>project.build.finalName</td><td>${project.build.finalName}</td></tr>
-</table>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 5f7264c..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- id="WebApp_ID" version="2.5">
- <display-name>org.apache.olingo.odata2.ref.annotations.web</display-name>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <servlet>
- <servlet-name>ReferenceScenarioServlet</servlet-name>
- <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
- <init-param>
- <param-name>javax.ws.rs.Application</param-name>
- <param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
- </init-param>
- <init-param>
- <param-name>org.apache.olingo.odata2.service.factory</param-name>
- <param-value>org.apache.olingo.odata2.ref.annotation.processor.AnnotationPocServiceFactory</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>ReferenceScenarioServlet</servlet-name>
- <url-pattern>/ReferenceScenario.svc/*</url-pattern>
- </servlet-mapping>
-
-</web-app>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
deleted file mode 100644
index 49cf364..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,116 +0,0 @@
-<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8"%>
-<!--
- 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.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>Apache Olingo - OData2 Library</title>
-<style type="text/css">
-body { font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;
- color: blue; background-color: #ffffff; }
-a { color: blue; text-decoration: none; }
-a:focus { outline: thin dotted #4076cb; outline-offset: -1px; }
-a:hover, a:active { outline: 0; }
-a:hover { color: #404a7e; text-decoration: underline; }
-h1, h2, h3, h4, h5, h6 { margin: 9px 0; font-family: inherit; font-weight: bold;
- line-height: 1; color: blue; }
-h1 { font-size: 36px; line-height: 40px; }
-h2 { font-size: 30px; line-height: 40px; }
-h3 { font-size: 24px; line-height: 40px; }
-h4 { font-size: 18px; line-height: 20px; }
-h5 { font-size: 14px; line-height: 20px; }
-h6 { font-size: 12px; line-height: 20px; }
-.logo { float: right; }
-ul { padding: 0; margin: 0 0 9px 25px; }
-ul ul { margin-bottom: 0; }
-li { line-height: 18px; }
-hr { margin: 18px 0;
- border: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; }
-table { border-collapse: collapse; border-spacing: 10px; }
-th, td { border: 1px solid; padding: 20px; }
-.code { font-family: "Courier New", monospace; font-size: 13px; line-height: 18px; }
-</style>
-</head>
-<body>
- <h1>Apache Olingo - OData2 Library</h1>
- <hr />
- <h2>Reference Scenario</h2>
- <table>
- <tr>
- <td valign="top">
- <h3>Service Document and Metadata</h3>
- <ul>
- <li><a href="ReferenceScenario.svc?_wadl" target="_blank">wadl</a></li>
- <li><a href="ReferenceScenario.svc/" target="_blank">service
- document</a></li>
- <li><a href="ReferenceScenario.svc/$metadata" target="_blank">metadata</a></li>
- </ul>
- <h3>EntitySets</h3>
- <ul>
- <li><a href="ReferenceScenario.svc/Employees" target="_blank">Employees</a></li>
- <li><a href="ReferenceScenario.svc/Managers" target="_blank">Managers</a></li>
- <li><a href="ReferenceScenario.svc/Buildings" target="_blank">Buildings</a></li>
- <li><a href="ReferenceScenario.svc/Buildings/?$expand=nb_Rooms"
- target="_blank">Buildings/?$expand=nb_Rooms</a></li>
- <li><a href="ReferenceScenario.svc/Rooms" target="_blank">Rooms</a></li>
- <li><a href="ReferenceScenario.svc/Rooms/?$orderby=Name" target="_blank">Rooms/?$orderby=Name</a></li>
- <li><a href="ReferenceScenario.svc/Photos" target="_blank">Photos</a></li>
- <li><a href="ReferenceScenario.svc/Photos/?$filter=Type%20eq%20'PNG'"
- target="_blank">Photos/?$filter=Type eq 'PNG'</a></li>
- </ul>
- <h3>Entities</h3>
- <ul>
- <li><a href="ReferenceScenario.svc/Employees('1')" target="_blank">Employees('1')</a></li>
- <li><a href="ReferenceScenario.svc/Managers('1')" target="_blank">Managers('1')</a></li>
- <li><a href="ReferenceScenario.svc/Buildings(1)" target="_blank">Buildings(1)</a></li>
- <li><a href="ReferenceScenario.svc/Buildings(1)/nb_Rooms" target="_blank">Buildings(1)/nb_Rooms</a></li>
- <li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
- <li><a href="ReferenceScenario.svc/Rooms('1')/nr_Building" target="_blank">Rooms('1')/nr_Building</a></li>
- <li><a href="ReferenceScenario.svc/Photos(Name='Small%20picture',Type='GIF')"
- target="_blank">Photos(Name='Small%20picture',Type='GIF')</a></li>
- <li><a href="ReferenceScenario.svc/Photos(Name='Big%20picture',Type='JPEG')/$value"
- target="_blank">Photos(Name='Big%20picture',Type='JPEG')/$value</a></li>
- </ul>
- </td>
- <td valign="top">
-
- </td>
- <td valign="bottom">
- <div class="code">
- <%
- String version = "gen/version.html";
- %>
- <%
- try {
- %>
- <jsp:include page='<%=version%>' />
- <%
- } catch (Exception e) {
- %>
- <p>IDE Build</p>
- <%
- }
- %>
- </div>
- </td>
- </tr>
- </table>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/pom.xml b/odata2-edm-annotation/pom.xml
deleted file mode 100644
index 436576f..0000000
--- a/odata2-edm-annotation/pom.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <parent>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-parent-incubating</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
-
- <modules>
- <module>edm-annotation-api</module>
- <module>edm-annotation-core</module>
- <module>edm-annotation-webref</module>
- </modules>
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-lib/odata-ref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/pom.xml b/odata2-lib/odata-ref/pom.xml
index 7b71a66..27cc47c 100644
--- a/odata2-lib/odata-ref/pom.xml
+++ b/odata2-lib/odata-ref/pom.xml
@@ -93,7 +93,7 @@
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
+ <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a195e82..19c21a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
<modules>
<module>odata2-lib</module>
<module>odata2-processor-jpa</module>
- <module>odata2-edm-annotation</module>
+ <module>odata2-annotation-processor</module>
<module>odata2-dist</module>
<module>odata2-sample</module>
</modules>
[07/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
deleted file mode 100644
index 2be5663..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * 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.api.data;
-
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-
-/**
- * Abstract class for implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
- * actual data handling.
- * <br/>
- * Extend this class and implement a DataSourceProcessor if the default implementation
- * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
- */
-public abstract class DataSourceProcessor extends ODataSingleProcessor {
-
- protected final DataSource dataSource;
- protected final ValueAccess valueAccess;
-
- /**
- * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
- * and {@link ValueAccess} (accessing values of data objects).
- *
- * @param dataSource used for accessing the data objects
- * @param valueAccess for accessing the values provided by the data objects
- */
- public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
- this.dataSource = dataSource;
- this.valueAccess = valueAccess;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
deleted file mode 100644
index 685e1b6..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * 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.api.data;
-
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.exception.ODataException;
-
-/**
- * This interface is intended to access values in a Java object.
- */
-public interface ValueAccess {
-
- /**
- * Retrieves the value of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the requested {@link EdmProperty}
- * @return the requested property value
- */
- public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException;
-
- /**
- * Sets the value of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the {@link EdmProperty}
- * @param value the new value of the property
- */
- public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException;
-
- /**
- * Retrieves the Java type of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the requested {@link EdmProperty}
- * @return the requested Java type
- */
- public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException;
-
- /**
- * Retrieves the value defined by a mapping object for the given data object.
- * @param data the Java data object
- * @param mapping the requested {@link EdmMapping}
- * @return the requested value
- */
- public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException;
-
- /**
- * Sets the value defined by a mapping object for the given data object.
- * @param data the Java data object
- * @param mapping the {@link EdmMapping}
- * @param value the new value
- */
- public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/pom.xml b/odata2-edm-annotation/edm-annotation-core/pom.xml
deleted file mode 100644
index 4e408f7..0000000
--- a/odata2-edm-annotation/edm-annotation-core/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
-
- <parent>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-api-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-api-annotation-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-core-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
-
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
deleted file mode 100644
index db03a4c..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- * *****************************************************************************
- * 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.core.annotation.data;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.data.DataSource;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class AnnotationInMemoryDs implements DataSource {
-
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
- private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
- private final boolean persistInMemory;
-
- public AnnotationInMemoryDs(String packageToScan) {
- this(packageToScan, true);
- }
-
- public AnnotationInMemoryDs(String packageToScan, boolean persistInMemory) {
- this.persistInMemory = persistInMemory;
- List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
- @Override
- public boolean isClassValid(Class<?> c) {
- return null != c.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
- }
- });
-
- init(foundClasses);
- }
-
- @SuppressWarnings("unchecked")
- private void init(List<Class<?>> foundClasses) {
- for (Class<?> clz : foundClasses) {
-
- DataStore<Object> dhs = (DataStore<Object>) getDataStore(clz);
- org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet entitySet =
- clz.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
- dataStores.put(entitySet.name(), dhs);
- }
- }
-
- public <T> DataStore<T> getDataStore(Class<T> clazz) {
- return DataStore.createInMemory(clazz, persistInMemory);
- }
-
- @Override
- public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException {
-
- DataStore<Object> holder = getDataStore(entitySet);
- if (holder != null) {
- return new ArrayList<Object>(holder.read());
- }
-
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- @Override
- public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
- throws ODataNotFoundException, EdmException, ODataApplicationException {
-
- DataStore<Object> store = getDataStore(entitySet);
- if (store != null) {
- Object keyInstance = store.createInstance();
- ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
-
- Object result = store.read(keyInstance);
- if (result != null) {
- return result;
- }
- }
-
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- @Override
- public Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
- }
-
- @Override
- public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
- DataStore<?> sourceStore = dataStores.get(sourceEntitySet.getName());
- DataStore<?> targetStore = dataStores.get(targetEntitySet.getName());
-
- AnnotatedNavInfo navInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
- sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
- Field sourceField = navInfo.getFromField();
- if (sourceField == null) {
- throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
- + "', targetStore='" + targetStore + "').");
- }
-
- Object navigationInstance = getValue(sourceField, sourceData);
- List<Object> resultData = new ArrayList<Object>();
- for (Object targetInstance : targetStore.read()) {
- if (navigationInstance instanceof Collection) {
- for (Object object : (Collection<?>) navigationInstance) {
- if (ANNOTATION_HELPER.keyMatch(targetInstance, object)) {
- resultData.add(targetInstance);
- }
- }
- } else if (ANNOTATION_HELPER.keyMatch(targetInstance, navigationInstance)) {
- resultData.add(targetInstance);
- }
- }
-
- if (navInfo.getToMultiplicity() == EdmMultiplicity.MANY) {
- if (targetKeys.isEmpty()) {
- return resultData;
- } else {
- for (Object result : resultData) {
- if (ANNOTATION_HELPER.keyMatch(result, targetKeys)) {
- return result;
- }
- }
- return null;
- }
- } else {
- if (resultData.isEmpty()) {
- return null;
- }
- return resultData.get(0);
- }
- }
-
- @Override
- public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
- Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
- Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
-
- BinaryData db = new BinaryData((byte[]) data, String.valueOf(mimeType));
- return db;
- }
-
- @Override
- public Object newDataObject(EdmEntitySet entitySet)
- throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
- DataStore<Object> dataStore = getDataStore(entitySet);
- if (dataStore != null) {
- return dataStore.createInstance();
- }
-
- throw new ODataRuntimeException("No DataStore found for entitySet with name: " + entitySet.getName());
- }
-
- @Override
- public void writeBinaryData(EdmEntitySet entitySet, Object mediaEntityInstance, BinaryData binaryData)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
- try {
- ANNOTATION_HELPER.setValueForAnnotatedField(
- mediaEntityInstance, EdmMediaResourceContent.class, binaryData.getData());
- ANNOTATION_HELPER.setValueForAnnotatedField(
- mediaEntityInstance, EdmMediaResourceMimeType.class, binaryData.getMimeType());
- } catch (ODataAnnotationException e) {
- throw new ODataRuntimeException("Invalid media resource annotation at entity set '" + entitySet.getName()
- + "' with message '" + e.getMessage() + "'.", e);
- }
- }
-
- /**
- * <p>Updates a single data object identified by the specified entity set and key fields of
- * the data object.</p>
- * @param entitySet the {@link EdmEntitySet} the object must correspond to
- * @param data the data object of the new entity
- * @return updated data object instance
- * @throws org.apache.olingo.odata2.api.exception.ODataNotImplementedException
- * @throws org.apache.olingo.odata2.api.edm.EdmException
- * @throws org.apache.olingo.odata2.api.exception.ODataApplicationException
- */
- public Object updateData(EdmEntitySet entitySet, Object data)
- throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
- DataStore<Object> dataStore = getDataStore(entitySet);
- return dataStore.update(data);
- }
-
- @Override
- public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
- DataStore<Object> dataStore = getDataStore(entitySet);
- Object keyInstance = dataStore.createInstance();
- ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
- dataStore.delete(keyInstance);
- }
-
- @Override
- public void createData(EdmEntitySet entitySet, Object data)
- throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
- DataStore<Object> dataStore = getDataStore(entitySet);
- dataStore.create(data);
- }
-
- @Override
- public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
- }
-
- @Override
- public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceEntity, EdmEntitySet targetEntitySet,
- Map<String, Object> targetEntityValues)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
- // get common data
- DataStore<Object> sourceStore = dataStores.get(sourceEntitySet.getName());
- DataStore<Object> targetStore = dataStores.get(targetEntitySet.getName());
-
- AnnotatedNavInfo commonNavInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
- sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
-
- // get and validate source fields
- Field sourceField = commonNavInfo.getFromField();
- if (sourceField == null) {
- throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
- + "', targetStore='" + targetStore + "').");
- }
-
- // get related target entity
- Object targetEntity = targetStore.createInstance();
- ANNOTATION_HELPER.setKeyFields(targetEntity, targetEntityValues);
- targetEntity = targetStore.read(targetEntity);
-
- // set at source
- setValueAtNavigationField(sourceEntity, sourceField, targetEntity);
- // set at target
- Field targetField = commonNavInfo.getToField();
- if(targetField != null) {
- setValueAtNavigationField(targetEntity, targetField, sourceEntity);
- }
- }
-
- /**
- * Set (Multiplicity != *) or add (Multiplicity == *) <code>value</code> at <code>field</code>
- * of <code>instance</code>.
- *
- * @param instance
- * @param field
- * @param value
- * @throws EdmException
- */
- private void setValueAtNavigationField(Object instance, Field field, Object value)
- throws EdmException {
- Class<?> fieldTypeClass = field.getType();
- if (Collection.class.isAssignableFrom(fieldTypeClass)) {
- @SuppressWarnings("unchecked")
- Collection<Object> collection = (Collection<Object>) ANNOTATION_HELPER.getValueForField(
- instance, field.getName(), EdmNavigationProperty.class);
- if(collection == null) {
- collection = new ArrayList<Object>();
- setValue(instance, field, collection);
- }
- collection.add(value);
- } else if(fieldTypeClass.isArray()) {
- throw new ODataRuntimeException("Write relations for internal used arrays is not supported.");
- } else {
- setValue(instance, field, value);
- }
- }
-
- /**
- * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
- * ODataRuntimeException is thrown.
- * Never returns NULL.
- *
- * @param entitySet for which the corresponding DataStore is returned
- * @return a DataStore object
- * @throws EdmException
- * @throws ODataRuntimeException if no DataStore is found
- */
- private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
- final String name = entitySet.getName();
- DataStore<Object> dataStore = dataStores.get(name);
- if (dataStore == null) {
- throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
- }
- return dataStore;
- }
-
- private Object getValue(Field field, Object instance) {
- try {
- boolean access = field.isAccessible();
- field.setAccessible(true);
- Object value = field.get(instance);
- field.setAccessible(access);
- return value;
- } catch (IllegalArgumentException e) {
- throw new ODataRuntimeException("Error for getting value of field '"
- + field + "' at instance '" + instance + "'.", e);
- } catch (IllegalAccessException e) {
- throw new ODataRuntimeException("Error for getting value of field '"
- + field + "' at instance '" + instance + "'.", e);
- }
- }
-
- private void setValue(Object instance, Field field, Object value) {
- try {
- boolean access = field.isAccessible();
- field.setAccessible(true);
- field.set(instance, value);
- field.setAccessible(access);
- } catch (IllegalArgumentException e) {
- throw new ODataRuntimeException("Error for setting value of field: '"
- + field + "' at instance: '" + instance + "'.", e);
- } catch (IllegalAccessException e) {
- throw new ODataRuntimeException("Error for setting value of field: '"
- + field + "' at instance: '" + instance + "'.", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
deleted file mode 100644
index 14183bf..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.data;
-
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-
-/**
- *
- */
-public class AnnotationValueAccess implements ValueAccess {
- private final AnnotationHelper annotationHelper = new AnnotationHelper();
-
- /**
- * Retrieves the value of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the requested {@link EdmProperty}
- * @return the requested property value
- */
- @Override
- public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
- if(data == null) {
- return null;
- } else if (annotationHelper.isEdmAnnotated(data)) {
- return annotationHelper.getValueForProperty(data, property.getName());
- }
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
- }
-
- /**
- * Sets the value of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the {@link EdmProperty}
- * @param value the new value of the property
- */
- @Override
- public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
- if (annotationHelper.isEdmAnnotated(data)) {
- annotationHelper.setValueForProperty(data, property.getName(), value);
- } else {
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
- }
- }
-
- /**
- * Retrieves the Java type of an EDM property for the given data object.
- * @param data the Java data object
- * @param property the requested {@link EdmProperty}
- * @return the requested Java type
- */
- public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
- if (annotationHelper.isEdmAnnotated(data)) {
- Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
- if (fieldType == null) {
- throw new ODataException("No field type found for property " + property);
- }
- return fieldType;
- }
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
- }
-
- /**
- * Retrieves the value defined by a mapping object for the given data object.
- * @param data the Java data object
- * @param mapping the requested {@link EdmMapping}
- * @return the requested value
- */
- public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
- if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
- return annotationHelper.getValueForProperty(data, mapping.getMediaResourceMimeTypeKey());
- }
- return null;
- }
-
- /**
- * Sets the value defined by a mapping object for the given data object.
- * @param data the Java data object
- * @param mapping the {@link EdmMapping}
- * @param value the new value
- */
- public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
- if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
- annotationHelper.setValueForProperty(data, mapping.getMediaResourceMimeTypeKey(), value);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
deleted file mode 100644
index be3baac..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.data;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-
-/**
- * Data access.
- */
-public class BeanPropertyAccess implements ValueAccess {
-
- @Override
- public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
- return getValue(data, getGetterMethodName(property));
- }
-
- @Override
- public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
- final String methodName = getSetterMethodName(getGetterMethodName(property));
- if (methodName != null) {
- setValue(data, methodName, value);
- }
- }
-
- @Override
- public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
- return getType(data, getGetterMethodName(property));
- }
-
- @Override
- public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
- if (mapping != null && mapping.getMimeType() != null) {
- return getValue(data, mapping.getMimeType());
- }
- return null;
- }
-
- @Override
- public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
- if (mapping != null && mapping.getMimeType() != null) {
- setValue(data, getSetterMethodName(mapping.getMimeType()), value);
- }
- }
-
- private String getGetterMethodName(final EdmProperty property) throws EdmException {
- final String prefix = isBooleanProperty(property) ? "is" : "get";
- final String defaultMethodName = prefix + property.getName();
- return property.getMapping() == null || property.getMapping().getInternalName() == null ?
- defaultMethodName : property.getMapping().getInternalName();
- }
-
- private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
- return property.isSimple()
- && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
- }
-
- private String getSetterMethodName(final String getterMethodName) {
- return getterMethodName.contains(".") ?
- null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
- }
-
- private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
- Object dataObject = data;
-
- for (final String method : methodName.split("\\.", -1)) {
- if (dataObject != null) {
- try {
- dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
- } catch (SecurityException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- } catch (NoSuchMethodException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- } catch (IllegalArgumentException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- } catch (IllegalAccessException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- } catch (InvocationTargetException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- }
- }
- }
-
- return dataObject;
- }
-
- private <T, V> void setValue(final T data, final String methodName, final V value)
- throws ODataNotFoundException {
- try {
- boolean found = false;
- for (final Method method : Arrays.asList(data.getClass().getMethods())) {
- if (method.getName().equals(methodName)) {
- found = true;
- final Class<?> type = method.getParameterTypes()[0];
- if (value == null) {
- if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
- || type.equals(long.class) || type.equals(char.class)) {
- method.invoke(data, 0);
- } else if (type.equals(float.class) || type.equals(double.class)) {
- method.invoke(data, 0.0);
- } else if (type.equals(boolean.class)) {
- method.invoke(data, false);
- } else {
- method.invoke(data, value);
- }
- } else {
- method.invoke(data, value);
- }
- break;
- }
- }
- if (!found) {
- throw new ODataNotFoundException(null);
- }
- } catch (SecurityException e) {
- throw new ODataNotFoundException(null, e);
- } catch (IllegalArgumentException e) {
- throw new ODataNotFoundException(null, e);
- } catch (IllegalAccessException e) {
- throw new ODataNotFoundException(null, e);
- } catch (InvocationTargetException e) {
- throw new ODataNotFoundException(null, e);
- }
- }
-
- private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
- if (data == null) {
- throw new ODataNotFoundException(ODataHttpException.COMMON);
- }
-
- Class<?> type = data.getClass();
- for (final String method : methodName.split("\\.", -1)) {
- try {
- type = type.getMethod(method).getReturnType();
- if (type.isPrimitive()) {
- if (type == boolean.class) {
- type = Boolean.class;
- } else if (type == byte.class) {
- type = Byte.class;
- } else if (type == short.class) {
- type = Short.class;
- } else if (type == int.class) {
- type = Integer.class;
- } else if (type == long.class) {
- type = Long.class;
- } else if (type == float.class) {
- type = Float.class;
- } else if (type == double.class) {
- type = Double.class;
- }
- }
- } catch (final SecurityException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- } catch (final NoSuchMethodException e) {
- throw new ODataNotFoundException(ODataHttpException.COMMON, e);
- }
- }
- return type;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
deleted file mode 100644
index 696ab9a..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.data;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class DataStore<T> {
-
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
- private final List<T> dataStore;
- private final Class<T> dataTypeClass;
-
- private int idCounter = 1;
-
- private static class InMemoryDataStore {
- private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
-
- @SuppressWarnings("unchecked")
- static DataStore<?> getInstance(Class<?> clz, boolean createNewInstance) {
- DataStore<?> ds = c2ds.get(clz);
- if (createNewInstance || ds == null) {
- ds = new DataStore<Object>((Class<Object>) clz);
- c2ds.put(clz, ds);
- }
- return ds;
- }
- }
-
- @SuppressWarnings("unchecked")
- public static <T> DataStore<T> createInMemory(Class<T> clazz) {
- return (DataStore<T>) InMemoryDataStore.getInstance(clazz, true);
- }
-
- @SuppressWarnings("unchecked")
- public static <T> DataStore<T> createInMemory(Class<T> clazz, boolean keepExisting) {
- return (DataStore<T>) InMemoryDataStore.getInstance(clazz, !keepExisting);
- }
-
- private DataStore(List<T> wrapStore, Class<T> clz) {
- dataStore = Collections.synchronizedList(wrapStore);
- dataTypeClass = clz;
- }
-
- private DataStore(Class<T> clz) {
- this(new ArrayList<T>(), clz);
- }
-
- public Class<T> getDataTypeClass() {
- return dataTypeClass;
- }
-
- public String getEntityTypeName() {
- return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
- }
-
- public T createInstance() {
- try {
- return dataTypeClass.newInstance();
- } catch (InstantiationException e) {
- throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
- } catch (IllegalAccessException e) {
- throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
- }
- }
-
- public T read(T obj) {
- List<Object> objKeys = getKeys(obj);
- for (T stored : dataStore) {
- if (objKeys.equals(getKeys(stored))) {
- return stored;
- }
- }
- return null;
- }
-
- public Collection<T> read() {
- return Collections.unmodifiableCollection(dataStore);
- }
-
- public T create(T object) throws DataStoreException {
- synchronized (dataStore) {
- if (read(object) != null || getKeys(object).contains(null)) {
- createKeys(object);
- return this.create(object);
- }
- dataStore.add(object);
- }
- return object;
- }
-
- public T update(T object) {
- synchronized (dataStore) {
- T stored = read(object);
- dataStore.remove(stored);
- dataStore.add(object);
- }
- return object;
- }
-
- public T delete(T object) {
- synchronized (dataStore) {
- T stored = read(object);
- if (stored != null) {
- dataStore.remove(stored);
- }
- return stored;
- }
- }
-
- private List<Object> getKeys(T object) {
- Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
-
- // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable
- List<Object> keyList = new ArrayList<Object>(keys.values());
- return keyList;
- }
-
- private T createKeys(T object) throws DataStoreException {
- List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
- if (fields.isEmpty()) {
- throw new DataStoreException("No EdmKey annotated fields found for class " + object.getClass());
- }
- Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
-
- for (Field field : fields) {
- Object key = createKey(field);
- fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
- }
-
- ANNOTATION_HELPER.setValuesToAnnotatedFields(object, EdmKey.class, fieldName2KeyValue);
-
- return object;
- }
-
- private Object createKey(Field field) {
- Class<?> type = field.getType();
-
- if (type == String.class) {
- return String.valueOf(idCounter++);
- } else if (type == Integer.class || type == int.class) {
- return Integer.valueOf(idCounter++);
- } else if (type == Long.class || type == long.class) {
- return Long.valueOf(idCounter++);
- }
-
- throw new UnsupportedOperationException("Automated key generation for type '" + type
- + "' is not supported (caused on field '" + field + "').");
- }
-
- public static class DataStoreException extends ODataApplicationException {
- private static final long serialVersionUID = 42L;
-
- public DataStoreException(String message) {
- this(message, null);
- }
-
- public DataStoreException(String message, Throwable cause) {
- super(message, Locale.ENGLISH, cause);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
deleted file mode 100644
index 97f5b53..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
+++ /dev/null
@@ -1,773 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.edm;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-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.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
-import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
-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.AssociationSetEnd;
-import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
-import org.apache.olingo.odata2.api.edm.provider.ComplexType;
-import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
-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.edm.provider.SimpleProperty;
-import org.apache.olingo.odata2.api.edm.provider.Using;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- * Provider for the entity data model used in the reference scenario
- *
- */
-public class AnnotationEdmProvider extends EdmProvider {
-
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
- private final List<Class<?>> annotatedClasses;
- private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
- private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
- private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
- private EntityContainer defaultContainer;
-
- public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
-
- this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
- for (Class<?> aClass : annotatedClasses) {
- if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
- this.annotatedClasses.add(aClass);
- }
- }
-
- init();
- }
-
- public AnnotationEdmProvider(String packageToScan) {
- this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
- @Override
- public boolean isClassValid(Class<?> c) {
- return ANNOTATION_HELPER.isEdmAnnotated(c);
- }
- });
-
- init();
- }
-
- private void init() {
- for (Class<?> aClass : annotatedClasses) {
- updateSchema(aClass);
- handleEntityContainer(aClass);
- }
-
- finish();
- }
-
- @Override
- public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
- Schema schema = namespace2Schema.get(edmFQName.getNamespace());
- if (schema != null) {
- List<Association> associations = schema.getAssociations();
- for (Association association : associations) {
- if (association.getName().equals(edmFQName.getName())) {
- return association;
- }
- }
- }
- return null;
- }
-
- @Override
- public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
- String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
- EntityContainer container = name2Container.get(entityContainer);
- if (container != null) {
- List<AssociationSet> associations = container.getAssociationSets();
- for (AssociationSet associationSet : associations) {
- if (associationSet.getAssociation().equals(association)) {
- final AssociationSetEnd endOne = associationSet.getEnd1();
- if (endOne.getRole().equals(sourceEntitySetRole)
- && endOne.getEntitySet().equals(sourceEntitySetName)) {
- return associationSet;
- }
- final AssociationSetEnd endTwo = associationSet.getEnd2();
- if (endTwo.getRole().equals(sourceEntitySetRole)
- && endTwo.getEntitySet().equals(sourceEntitySetName)) {
- return associationSet;
- }
- }
- }
- }
- return null;
- }
-
- @Override
- public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
- Schema schema = namespace2Schema.get(edmFQName.getNamespace());
- if (schema != null) {
- List<ComplexType> complexTypes = schema.getComplexTypes();
- for (ComplexType complexType : complexTypes) {
- if (complexType.getName().equals(edmFQName.getName())) {
- return complexType;
- }
- }
- }
- return null;
- }
-
- @Override
- public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
- EntityContainer container = name2Container.get(name);
- if (container == null) {
- // use default container (if set)
- container = defaultContainer;
- }
- if (container != null) {
- EntityContainerInfo info = new EntityContainerInfo();
- info.setName(container.getName());
- info.setDefaultEntityContainer(container.isDefaultEntityContainer());
- info.setExtendz(container.getExtendz());
- info.setAnnotationAttributes(container.getAnnotationAttributes());
- info.setAnnotationElements(container.getAnnotationElements());
-
- return info;
- }
-
- return null;
- }
-
- @Override
- public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
- EntityContainer container = name2Container.get(entityContainer);
- if (container != null) {
- List<EntitySet> entitySets = container.getEntitySets();
- for (EntitySet entitySet : entitySets) {
- if (entitySet.getName().equals(name)) {
- return entitySet;
- }
- }
- }
-
- return null;
- }
-
- @Override
- public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
- Schema schema = namespace2Schema.get(edmFQName.getNamespace());
- if (schema != null) {
- List<EntityType> complexTypes = schema.getEntityTypes();
- for (EntityType complexType : complexTypes) {
- if (complexType.getName().equals(edmFQName.getName())) {
- return complexType;
- }
- }
- }
- return null;
- }
-
- @Override
- public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
- EntityContainer container = name2Container.get(entityContainer);
- if (container != null) {
- List<FunctionImport> functionImports = container.getFunctionImports();
- for (FunctionImport functionImport : functionImports) {
- if (functionImport.getName().equals(name)) {
- return functionImport;
- }
- }
- }
- return null;
- }
-
- @Override
- public List<Schema> getSchemas() throws ODataException {
- return new ArrayList<Schema>(namespace2Schema.values());
- }
-
- //
- //
- //
- private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
-
- private void updateSchema(Class<?> aClass) {
- EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
- if (et != null) {
- updateSchema(aClass, et);
- }
- EdmComplexType ect = aClass.getAnnotation(EdmComplexType.class);
- if (ect != null) {
- updateSchema(aClass, ect);
- }
- }
-
- private void updateSchema(Class<?> aClass, EdmEntityType et) {
- SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
- TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
- b.addEntityType(typeBuilder.buildEntityType());
- b.addAssociations(typeBuilder.buildAssociations());
- }
-
- private SchemaBuilder getSchemaBuilder(String namespace, Class<?> aClass) {
- String usedNamespace = namespace;
- if(usedNamespace.isEmpty()) {
- usedNamespace = ANNOTATION_HELPER.getCanonicalNamespace(aClass);
- }
- SchemaBuilder builder = namespace2SchemaBuilder.get(usedNamespace);
- if (builder == null) {
- builder = SchemaBuilder.init(usedNamespace);
- namespace2SchemaBuilder.put(usedNamespace, builder);
- }
- return builder;
- }
-
- private void updateSchema(Class<?> aClass, EdmComplexType et) {
- SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
- TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
- b.addComplexType(typeBuilder.buildComplexType());
- }
-
- private void handleEntityContainer(Class<?> aClass) {
- EdmEntityType entityType = aClass.getAnnotation(EdmEntityType.class);
- if (entityType != null) {
- FullQualifiedName typeName = createFqnForEntityType(aClass, entityType);
- String containerName = ANNOTATION_HELPER.extractContainerName(aClass);
- ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
- if (builder == null) {
- builder = ContainerBuilder.init(typeName.getNamespace(), containerName);
- containerName2ContainerBuilder.put(containerName, builder);
- }
- EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
- if (entitySet != null) {
- builder.addEntitySet(createEntitySet(typeName, entitySet));
- }
- }
- }
-
- private EntitySet createEntitySet(FullQualifiedName typeName, EdmEntitySet entitySet) {
- return new EntitySet().setName(entitySet.name()).setEntityType(typeName);
- }
-
- private FullQualifiedName createFqnForEntityType(Class<?> annotatedClass, EdmEntityType entityType) {
- return ANNOTATION_HELPER.extractEntityTypeFqn(annotatedClass);
- }
-
- private void finish() {
- //
- Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
- for (ContainerBuilder containerBuilder : containers) {
- SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
- containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
- final EntityContainer container = containerBuilder.build();
- schemaBuilder.addEntityContainer(container);
- name2Container.put(container.getName(), container);
- if (container.isDefaultEntityContainer()) {
- defaultContainer = container;
- }
- }
- //
- Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
- for (SchemaBuilder schemaBuilder : schemaBuilders) {
- final Schema schema = schemaBuilder.build();
- namespace2Schema.put(schema.getNamespace(), schema);
- }
- }
-
- //
- //
- //
- static class TypeBuilder {
-
- final private String namespace;
- final private String name;
- private boolean isAbstract = false;
- private boolean isMediaResource = false;
- private FullQualifiedName baseEntityType = null;
- private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
- private final List<Property> properties = new ArrayList<Property>();
- private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
- private final List<Association> associations = new ArrayList<Association>();
-
- public TypeBuilder(FullQualifiedName fqn) {
- this.namespace = fqn.getNamespace();
- this.name = fqn.getName();
- }
-
- public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
- return new TypeBuilder(ANNOTATION_HELPER.extractEntityTypeFqn(entity, aClass)).withClass(aClass);
- }
-
- public static TypeBuilder init(EdmComplexType entity, Class<?> aClass) {
- return new TypeBuilder(ANNOTATION_HELPER.extractComplexTypeFqn(entity, aClass)).withClass(aClass);
- }
-
- private TypeBuilder withClass(Class<?> aClass) {
- baseEntityType = createBaseEntityFqn(aClass);
-
- if (Modifier.isAbstract(aClass.getModifiers())) {
- this.isAbstract = true;
- }
-
- Field[] fields = aClass.getDeclaredFields();
- for (Field field : fields) {
- EdmProperty ep = field.getAnnotation(EdmProperty.class);
- if (ep != null) {
- properties.add(createProperty(ep, field, namespace));
- EdmKey eti = field.getAnnotation(EdmKey.class);
- if (eti != null) {
- keyProperties.add(createKeyProperty(ep, field));
- }
- }
- EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
- if (enp != null) {
- final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
- navProperties.add(navProperty);
- Association association = createAssociation(field, navProperty);
- associations.add(association);
- }
- EdmMediaResourceContent emrc = field.getAnnotation(EdmMediaResourceContent.class);
- if (emrc != null) {
- isMediaResource = true;
- }
- }
-
- return this;
- }
-
- public TypeBuilder addProperty(PropertyRef property) {
- keyProperties.add(property);
- return this;
- }
-
- public TypeBuilder addProperty(Property property) {
- properties.add(property);
- return this;
- }
-
- public TypeBuilder addNavigationProperty(NavigationProperty property) {
- navProperties.add(property);
- return this;
- }
-
- public TypeBuilder setAbstract(boolean isAbstract) {
- this.isAbstract = isAbstract;
- return this;
- }
-
- public ComplexType buildComplexType() {
- ComplexType complexType = new ComplexType();
- if (baseEntityType != null) {
- complexType.setBaseType(baseEntityType);
- }
- return complexType.setName(name).setProperties(properties);
- }
-
- public EntityType buildEntityType() {
- EntityType entityType = new EntityType();
- if (baseEntityType != null) {
- entityType.setBaseType(baseEntityType);
- }
- if (!keyProperties.isEmpty()) {
- entityType.setKey(new Key().setKeys(keyProperties));
- }
- if (!navProperties.isEmpty()) {
- entityType.setNavigationProperties(navProperties);
- }
- return entityType.setName(name)
- .setAbstract(isAbstract)
- .setHasStream(isMediaResource)
- .setProperties(properties);
- }
-
- public Collection<Association> buildAssociations() {
- return Collections.unmodifiableCollection(associations);
- }
-
- private PropertyRef createKeyProperty(EdmProperty et, Field field) {
- PropertyRef keyProperty = new PropertyRef();
- String entityName = et.name();
- if (entityName.isEmpty()) {
- entityName = getCanonicalName(field);
- }
- return keyProperty.setName(entityName);
- }
-
- private Property createProperty(EdmProperty ep, Field field, String defaultNamespace) {
- if (isAnnotatedEntity(field.getType())) {
- return createComplexProperty(field, defaultNamespace);
- } else {
- return createSimpleProperty(ep, field);
- }
- }
-
- private Property createSimpleProperty(EdmProperty ep, Field field) {
- SimpleProperty sp = new SimpleProperty();
- String entityName = ANNOTATION_HELPER.getPropertyName(field);
- sp.setName(entityName);
- //
- EdmType type = ep.type();
- if (type == EdmType.NULL) {
- type = getEdmType(field.getType());
- }
- sp.setType(ANNOTATION_HELPER.mapTypeKind(type));
-
- return sp;
- }
-
- private Property createComplexProperty(Field field, String defaultNamespace) {
- ComplexProperty cp = new ComplexProperty();
- // settings from property
- String entityName = ANNOTATION_HELPER.getPropertyName(field);
- cp.setName(entityName);
-
- // settings from related complex entity
- EdmComplexType ece = field.getType().getAnnotation(EdmComplexType.class);
- String complexEntityNamespace = ece.namespace();
- if (complexEntityNamespace.isEmpty()) {
- complexEntityNamespace = defaultNamespace;
- }
- cp.setType(new FullQualifiedName(complexEntityNamespace, ece.name()));
-
- return cp;
- }
-
- private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
- NavigationProperty navProp = new NavigationProperty();
- navProp.setName(ANNOTATION_HELPER.getPropertyName(field));
- String fromRole = ANNOTATION_HELPER.extractFromRoleName(enp, field);
- navProp.setFromRole(fromRole);
-
- String toRole = ANNOTATION_HELPER.extractToRoleName(enp, field);
- navProp.setToRole(toRole);
-
- String relationshipName = ANNOTATION_HELPER.extractRelationshipName(enp, field);
- navProp.setRelationship(new FullQualifiedName(namespace, relationshipName));
-
- return navProp;
- }
-
-// private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
-// if (type == String.class) {
-// return EdmType.String;
-// } else if (type == boolean.class || type == Boolean.class) {
-// return EdmType.Boolean;
-// } else if (type == byte.class || type == Byte.class) {
-// return EdmType.SByte;
-// } else if (type == short.class || type == Short.class) {
-// return EdmType.Int16;
-// } else if (type == int.class || type == Integer.class) {
-// return EdmType.Int32;
-// } else if (type == long.class || type == Long.class) {
-// return EdmType.Int64;
-// } else if (type == double.class || type == Double.class) {
-// return EdmType.Double;
-// } else if (type == float.class || type == Float.class) {
-// return EdmType.Single;
-// } else if (type == BigInteger.class || type == BigDecimal.class) {
-// return EdmType.Decimal;
-// } else if (type == Byte[].class || type == byte[].class) {
-// return EdmType.Binary;
-// } else if (type == Date.class) {
-// return EdmType.DateTime;
-// } else if (type == Calendar.class) {
-// return EdmType.DateTimeOffset;
-// } else if (type == UUID.class) {
-// return EdmType.Guid;
-// } else {
-// throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
-// }
-// }
-
- private EdmType getEdmType(Class<?> type) {
- if (type == String.class) {
- return EdmType.STRING;
- } else if (type == boolean.class || type == Boolean.class) {
- return EdmType.BOOLEAN;
- } else if (type == byte.class || type == Byte.class) {
- return EdmType.SBYTE;
- } else if (type == short.class || type == Short.class) {
- return EdmType.INT16;
- } else if (type == int.class || type == Integer.class) {
- return EdmType.INT32;
- } else if (type == long.class || type == Long.class) {
- return EdmType.INT64;
- } else if (type == double.class || type == Double.class) {
- return EdmType.DOUBLE;
- } else if (type == float.class || type == Float.class) {
- return EdmType.SINGLE;
- } else if (type == BigInteger.class || type == BigDecimal.class) {
- return EdmType.DECIMAL;
- } else if (type == Byte[].class || type == byte[].class) {
- return EdmType.BINARY;
- } else if (type == Date.class) {
- return EdmType.DATE_TIME;
- } else if (type == Calendar.class) {
- return EdmType.DATE_TIME_OFFSET;
- } else if (type == UUID.class) {
- return EdmType.GUID;
- } else {
- throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
- }
- }
-
-
- private Class<?> checkForBaseEntityClass(Class<?> aClass) {
- Class<?> superClass = aClass.getSuperclass();
- if (superClass == Object.class) {
- return null;
- } else {
- EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
- if (edmEntity == null) {
- return checkForBaseEntityClass(superClass);
- } else {
- return superClass;
- }
- }
- }
-
- private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
- Class<?> baseEntityClass = checkForBaseEntityClass(aClass);
- if (baseEntityClass == null) {
- return null;
- }
- return ANNOTATION_HELPER.extractEntityTypeFqn(baseEntityClass);
- }
-
- private Association createAssociation(Field field, NavigationProperty navProperty) {
- Association association = new Association();
- EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
-
- AssociationEnd fromEnd = new AssociationEnd();
- fromEnd.setRole(navProperty.getFromRole());
- String typeName = ANNOTATION_HELPER.extractEntityTypeName(field.getDeclaringClass());
- fromEnd.setType(new FullQualifiedName(namespace, typeName));
- fromEnd.setMultiplicity(EdmMultiplicity.ONE);
- association.setEnd1(fromEnd);
-
- AssociationEnd toEnd = new AssociationEnd();
- toEnd.setRole(navProperty.getToRole());
- String toTypeName = ANNOTATION_HELPER.extractEntitTypeName(navigation, field);
- toEnd.setType(new FullQualifiedName(namespace, toTypeName));
- toEnd.setMultiplicity(ANNOTATION_HELPER.getMultiplicity(navigation, field));
- association.setEnd2(toEnd);
-
- String associationName = navProperty.getRelationship().getName();
- association.setName(associationName);
- return association;
- }
-
- private String getCanonicalName(Field field) {
- return ANNOTATION_HELPER.getCanonicalName(field);
- }
-
- private boolean isAnnotatedEntity(Class<?> clazz) {
- return ANNOTATION_HELPER.isEdmTypeAnnotated(clazz);
- }
- }
-
- static class SchemaBuilder {
-
- final private String namespace;
- // private String alias;
- private final List<Using> usings = new ArrayList<Using>();
- private final List<EntityType> entityTypes = new ArrayList<EntityType>();
- private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
- private final Map<String, Association> name2Associations = new HashMap<String, Association>();
- private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
- private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
- private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
-
- private SchemaBuilder(String namespace) {
- this.namespace = namespace;
- }
-
- public static SchemaBuilder init(String namespace) {
- return new SchemaBuilder(namespace);
- }
-
- public SchemaBuilder addEntityType(EntityType type) {
- entityTypes.add(type);
- return this;
- }
-
- public SchemaBuilder addEntityContainer(EntityContainer container) {
- entityContainers.add(container);
- return this;
- }
-
- public SchemaBuilder addComplexType(ComplexType createEntityType) {
- complexTypes.add(createEntityType);
- return this;
- }
-
- public void addAssociations(Collection<Association> associations) {
- for (Association association : associations) {
- final String relationshipName = association.getName();
- if (name2Associations.containsKey(relationshipName)) {
- association = mergeAssociations(name2Associations.get(relationshipName), association);
- }
- name2Associations.put(relationshipName, association);
- }
- }
-
- private Association mergeAssociations(Association associationOne, Association associationTwo) {
- AssociationEnd oneEnd1 = associationOne.getEnd1();
- AssociationEnd oneEnd2 = associationOne.getEnd2();
- AssociationEnd twoEnd1 = associationTwo.getEnd1();
- AssociationEnd twoEnd2 = associationTwo.getEnd2();
- AssociationEnd[] oneEnds = new AssociationEnd[] { oneEnd1, oneEnd2 };
-
- for (AssociationEnd associationEnd : oneEnds) {
- if (associationEnd.getRole().equals(twoEnd1.getRole())) {
- if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
- associationEnd.setMultiplicity(EdmMultiplicity.MANY);
- }
- } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
- if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
- associationEnd.setMultiplicity(EdmMultiplicity.MANY);
- }
- }
- }
-
- return associationOne;
- }
-
- public Schema build() {
- Schema s = new Schema();
- s.setUsings(usings);
- s.setEntityTypes(entityTypes);
- s.setComplexTypes(complexTypes);
- s.setAssociations(new ArrayList<Association>(name2Associations.values()));
- s.setEntityContainers(entityContainers);
- s.setAnnotationAttributes(annotationAttributes);
- s.setAnnotationElements(annotationElements);
- s.setNamespace(namespace);
- return s;
- }
- }
-
- private static class ContainerBuilder {
-
- final private String name;
- final private String namespace;
- private boolean defaultContainer = true;
- private final List<EntitySet> entitySets = new ArrayList<EntitySet>();
- private final List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
- private final List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
-
- // private Documentation documentation;
-
- private ContainerBuilder(String namespace, String containerName) {
- this.namespace = namespace;
- name = containerName;
- }
-
- public String getNamespace() {
- return namespace;
- }
-
- public static ContainerBuilder init(String namespace, String containerName) {
- return new ContainerBuilder(namespace, containerName);
- }
-
- public ContainerBuilder setDefaultContainer(boolean isDefault) {
- defaultContainer = isDefault;
- return this;
- }
-
- public ContainerBuilder addEntitySet(EntitySet entitySet) {
- entitySets.add(entitySet);
- return this;
- }
-
- public void addAssociationSets(Collection<Association> associations) {
- for (Association association : associations) {
- AssociationSet as = new AssociationSet();
- as.setName(association.getName());
- FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
- as.setAssociation(asAssociationFqn);
-
- AssociationSetEnd asEnd1 = new AssociationSetEnd();
- asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
- asEnd1.setRole(association.getEnd1().getRole());
- as.setEnd1(asEnd1);
-
- AssociationSetEnd asEnd2 = new AssociationSetEnd();
- asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
- asEnd2.setRole(association.getEnd2().getRole());
- as.setEnd2(asEnd2);
-
- associationSets.add(as);
- }
- }
-
- public EntityContainer build() {
- EntityContainer ec = new EntityContainer();
- ec.setName(name);
- ec.setDefaultEntityContainer(defaultContainer);
- ec.setEntitySets(entitySets);
- ec.setAssociationSets(associationSets);
- ec.setFunctionImports(functionImports);
- return ec;
- }
-
- private String getEntitySetName(AssociationEnd end) {
- for (EntitySet entitySet : entitySets) {
- if (entitySet.getEntityType().equals(end.getType())) {
- return entitySet.getName();
- }
- }
- throw new ODataRuntimeException("No entity set found for " + end.getType());
- }
- }
-}
[08/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..73d1218
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ */
+public class ResourceHelper {
+
+ public enum Format {BMP, JPEG, PNG, GIF};
+
+ public static byte[] generateImage() {
+ return generateImage(Format.PNG);
+ }
+
+ public static byte[] generateImage(Format format) {
+ try {
+ int width = 320;
+ int height = 320;
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
+ WritableRaster raster = image.getRaster();
+
+ int mod = format.ordinal() + 2;
+ for (int h = 0; h < height; h++) {
+ for (int w = 0; w < width; w++) {
+ if (((h / 32) + (w / 32)) % mod == 0) {
+ raster.setSample(w, h, 0, 0);
+ } else {
+ raster.setSample(w, h, 0, 1);
+ }
+ }
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+ ImageIO.write(image, format.name(), out);
+ return out.toByteArray();
+ } catch (IOException ex) {
+ return new byte[0];
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
new file mode 100644
index 0000000..7c9e486
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
@@ -0,0 +1,89 @@
+/*
+ * 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.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms")
+public class Room extends RefBase {
+
+ @EdmProperty
+ private Integer seats;
+ @EdmProperty
+ private Integer version;
+ @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
+ private Building building;
+ @EdmNavigationProperty(name = "nr_Employees")
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public Room(final int id, final String name) {
+ super(id, name);
+ }
+
+ public void setSeats(final int seats) {
+ this.seats = seats;
+ }
+
+ public int getSeats() {
+ return seats;
+ }
+
+ public void setVersion(final int version) {
+ this.version = version;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setBuilding(final Building building) {
+ this.building = building;
+ }
+
+ public Building getBuilding() {
+ return building;
+ }
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
new file mode 100644
index 0000000..e9b296f
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.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.annotation.edm.EdmType;
+
+/**
+*
+*/
+@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Teams")
+public class Team extends RefBase {
+ @EdmProperty(type = EdmType.BOOLEAN)
+ private Boolean isScrumTeam;
+ @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public Team() {
+ super(-1, null);
+ }
+
+ public Team(final int id, final String name) {
+ super(id, name);
+ }
+
+ public Boolean isScrumTeam() {
+ return isScrumTeam;
+ }
+
+ public void setScrumTeam(final Boolean isScrumTeam) {
+ this.isScrumTeam = isScrumTeam;
+ }
+
+ public void addEmployee(Employee e) {
+ this.employees.add(e);
+ }
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/pom.xml b/odata2-annotation-processor/annotation-processor-webref/pom.xml
new file mode 100644
index 0000000..9f31106
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>olingo-odata2-annotation-processor-webref-incubating</artifactId>
+ <packaging>war</packaging>
+ <name>${project.artifactId}</name>
+
+ <parent>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <properties>
+ <version.slf4j>1.7.1</version.slf4j>
+ </properties>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+ <resources>
+ <resource>
+ <directory>src/main/version</directory>
+ <filtering>true</filtering>
+ <targetPath>../${project.build.finalName}/gen</targetPath>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ <resource>
+ <directory>target/maven-shared-archive-resources</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>com.sap.research</groupId>
+ <artifactId>nwcloud-maven-plugin</artifactId>
+ <version>1.0.0.RELEASE</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+ <dependencies>
+ <dependency>
+ <!-- required because of auto detection of web facet 2.5 -->
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-api-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-core-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${version.slf4j}</version>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <build>
+ <defaultGoal>cargo:run</defaultGoal>
+
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <version>1.4.2</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
new file mode 100644
index 0000000..668ac86
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+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.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Buildings")
+public class Building {
+ @EdmKey
+ @EdmProperty(type = EdmType.INT32)
+ private int id;
+ @EdmProperty
+ private String name;
+ @EdmProperty(name = "Image", type = EdmType.BINARY)
+ private byte[] image;
+ @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
+ association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
+ private List<Room> rooms = new ArrayList<Room>();
+
+ public String getId() {
+ return Integer.toString(id);
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setImage(final byte[] byteArray) {
+ image = byteArray;
+ }
+
+ public byte[] getImage() {
+ if (image == null) {
+ return null;
+ } else {
+ return image.clone();
+ }
+ }
+
+ public void addRoom(Room room) {
+ rooms.add(room);
+ }
+
+ public List<Room> getRooms() {
+ return rooms;
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
new file mode 100644
index 0000000..a4d5a56
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
+public class City {
+
+ @EdmProperty
+ private String postalCode;
+ @EdmProperty
+ private String cityName;
+
+ public City(final String postalCode, final String name) {
+ this.postalCode = postalCode;
+ cityName = name;
+ }
+
+ public void setPostalCode(final String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setCityName(final String cityName) {
+ this.cityName = cityName;
+ }
+
+ public String getCityName() {
+ return cityName;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s, %s", cityName, postalCode);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
new file mode 100644
index 0000000..2204ee8
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+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.EdmFacets;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Employees")
+public class Employee {
+ @EdmKey
+ @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
+ private String employeeId;
+ @EdmProperty(name = "EmployeeName")
+ private String employeeName;
+ @EdmProperty
+ private int age;
+ @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
+ private Manager manager;
+ @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
+ private Team team;
+ @EdmNavigationProperty(name = "ne_Room")
+ private Room room;
+ @EdmMediaResourceMimeType
+ private String imageType;
+ @EdmMediaResourceContent
+ private byte[] image;
+ @EdmProperty(name = "ImageUrl")
+ private String imageUrl;
+ @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME,
+ facets = @EdmFacets(nullable = true))
+ private Calendar entryDate;
+ @EdmProperty(name = "Location", facets = @EdmFacets(nullable = false))
+ private Location location;
+
+ public String getId() {
+ return employeeId;
+ }
+
+ public void setEmployeeName(final String employeeName) {
+ this.employeeName = employeeName;
+ }
+
+ public String getEmployeeName() {
+ return employeeName;
+ }
+
+ public void setAge(final int age) {
+ this.age = age;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setManager(final Manager manager) {
+ this.manager = manager;
+ }
+
+ public Manager getManager() {
+ return manager;
+ }
+
+ public void setTeam(final Team team) {
+ this.team = team;
+ }
+
+ public Team getTeam() {
+ return team;
+ }
+
+ public void setRoom(final Room room) {
+ this.room = room;
+ }
+
+ public Room getRoom() {
+ return room;
+ }
+
+ public void setImageUri(final String imageUri) {
+ imageUrl = imageUri;
+ }
+
+ public String getImageUri() {
+ return imageUrl;
+ }
+
+ public void setLocation(final Location location) {
+ this.location = location;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public void setEntryDate(final Calendar date) {
+ entryDate = date;
+ }
+
+ public Calendar getEntryDate() {
+ return entryDate;
+ }
+
+ public void setImageType(final String imageType) {
+ this.imageType = imageType;
+ }
+
+ public String getImageType() {
+ return imageType;
+ }
+
+ public void setImage(final byte[] image) {
+ this.image = image;
+ }
+
+ public void setImage(final String imageUrl) {
+ image = loadImage(imageUrl);
+ }
+
+ private static byte[] loadImage(final String imageUrl) {
+ return ResourceHelper.loadAsByte(imageUrl);
+ }
+
+ public byte[] getImage() {
+ if (image == null) {
+ return null;
+ }
+ return image.clone();
+ }
+
+ @Override
+ public int hashCode() {
+ if (employeeId == null) {
+ return 0;
+ }
+ return employeeId.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"EmployeeId\":\"" + employeeId + "\","
+ + "\"EmployeeName\":\"" + employeeName + "\","
+ + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
+ + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
+ + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
+ + "\"Location\":"
+ + (location == null ? "null" :
+ "{\"City\":" + (location.getCity() == null ? "null" :
+ "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
+ + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
+ + "\"Country\":\"" + location.getCountry() + "\"}") + ","
+ + "\"Age\":" + age + ","
+ + "\"EntryDate\":"
+ + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
+ + "\"ImageUrl\":\"" + imageUrl + "\"}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
new file mode 100644
index 0000000..9b0785c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+ @EdmProperty
+ private String country;
+ @EdmProperty
+ private City city;
+
+ public Location(final String country, final String postalCode, final String cityName) {
+ this.country = country;
+ city = new City(postalCode, cityName);
+ }
+
+ public void setCountry(final String country) {
+ this.country = country;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCity(final City city) {
+ this.city = city;
+ }
+
+ public City getCity() {
+ return city;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s, %s", country, city.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
new file mode 100644
index 0000000..57e6d78
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers")
+public class Manager extends Employee {
+
+ @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
+ toMultiplicity = Multiplicity.MANY)
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..ab17fbb
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+public interface ModelSharedConstants {
+
+ String NAMESPACE_1 = "RefScenario";
+ String CONTAINER_1 = "Container1";
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
new file mode 100644
index 0000000..52971cd
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.util.Arrays;
+
+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.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Photos")
+public class Photo {
+ @EdmKey
+ @EdmProperty
+ private String name;
+ @EdmKey
+ @EdmProperty
+ private String type;
+ @EdmProperty
+ @EdmMediaResourceMimeType
+ private String mimeType;
+ @EdmProperty
+ @EdmMediaResourceSource
+ private String imageUrl = "http://localhost/someResource.png";
+ @EdmProperty(type = EdmType.BINARY)
+ @EdmMediaResourceContent
+ private byte[] image = ResourceHelper.generateImage();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public String getImageUri() {
+ return imageUrl;
+ }
+
+ public void setImageUri(final String uri) {
+ imageUrl = uri;
+ }
+
+ public byte[] getImage() {
+ return image.clone();
+ }
+
+ public void setImage(final byte[] image) {
+ this.image = image;
+ }
+
+ public String getImageType() {
+ return mimeType;
+ }
+
+ public void setImageType(final String imageType) {
+ this.mimeType = imageType;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
+ hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Photo other = (Photo) obj;
+ if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+ return false;
+ }
+ if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Name\":\"" + name + "\","
+ + "\"Type\":\"" + type + "\","
+ + "\"ImageUrl\":\"" + imageUrl + "\","
+ + "\"Image\":\"" + Arrays.toString(image) + "\","
+ + "\"MimeType\":\"" + mimeType + "\"";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
new file mode 100644
index 0000000..727b8c3
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+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.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+ @EdmProperty(name="Name")
+ protected String name;
+ @EdmProperty(name="Id", type = EdmType.STRING)
+ @EdmKey
+ protected String id;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setId(int id) {
+ this.id = String.valueOf(id);
+ }
+
+ @Override
+ public int hashCode() {
+ if(id == null) {
+ return -1;
+ }
+ return id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final RefBase other = (RefBase) obj;
+ if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+ return false;
+ }
+ if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
+ return false;
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..3d2bb88
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ */
+public class ResourceHelper {
+
+ public static byte[] loadAsByte(String resource) {
+ return load(resource, new byte[0]);
+ }
+
+ public static byte[] load(String resource, byte[] defaultResult) {
+ InputStream instream = null;
+ try {
+ instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+ if (instream == null) {
+ return defaultResult;
+ }
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ int b = 0;
+ while ((b = instream.read()) != -1) {
+ stream.write(b);
+ }
+
+ return stream.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if(instream != null) {
+ try {
+ instream.close();
+ } catch (IOException ex) { }
+ }
+ }
+ }
+
+ public enum Format {BMP, JPEG, PNG, GIF};
+
+ public static byte[] generateImage() {
+ return generateImage(Format.PNG);
+ }
+
+ public static byte[] generateImage(Format format) {
+ try {
+ int width = 320;
+ int height = 320;
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
+ WritableRaster raster = image.getRaster();
+
+ int mod = format.ordinal() + 2;
+ for (int h = 0; h < height; h++) {
+ for (int w = 0; w < width; w++) {
+ if (((h / 32) + (w / 32)) % mod == 0) {
+ raster.setSample(w, h, 0, 0);
+ } else {
+ raster.setSample(w, h, 0, 1);
+ }
+ }
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+ ImageIO.write(image, format.name(), out);
+ return out.toByteArray();
+ } catch (IOException ex) {
+ return new byte[0];
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
new file mode 100644
index 0000000..2d9f48e
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms")
+public class Room extends RefBase {
+
+ @EdmProperty
+ private Integer seats;
+ @EdmProperty
+ private Integer version;
+ @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
+ private Building building;
+ @EdmNavigationProperty(name = "nr_Employees")
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public void setSeats(final int seats) {
+ this.seats = seats;
+ }
+
+ public int getSeats() {
+ return seats;
+ }
+
+ public void setVersion(final int version) {
+ this.version = version;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setBuilding(final Building building) {
+ this.building = building;
+ }
+
+ public Building getBuilding() {
+ return building;
+ }
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
new file mode 100644
index 0000000..50d2ad2
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.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.annotation.edm.EdmType;
+
+/**
+*
+*/
+@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Teams")
+public class Team extends RefBase {
+ @EdmProperty(type = EdmType.BOOLEAN)
+ private Boolean isScrumTeam;
+ @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public Boolean isScrumTeam() {
+ return isScrumTeam;
+ }
+
+ public void setScrumTeam(final Boolean isScrumTeam) {
+ this.isScrumTeam = isScrumTeam;
+ }
+
+ public void addEmployee(Employee e) {
+ this.employees.add(e);
+ }
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
new file mode 100644
index 0000000..3870119
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
@@ -0,0 +1,202 @@
+/**
+ * *****************************************************************************
+ * 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.ref.annotation.processor;
+
+import java.util.Calendar;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.ODataDebugCallback;
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationValueAccess;
+import org.apache.olingo.odata2.core.annotation.data.DataStore;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
+import org.apache.olingo.odata2.ref.annotation.model.Building;
+import org.apache.olingo.odata2.ref.annotation.model.Employee;
+import org.apache.olingo.odata2.ref.annotation.model.Location;
+import org.apache.olingo.odata2.ref.annotation.model.Manager;
+import org.apache.olingo.odata2.ref.annotation.model.Photo;
+import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
+import org.apache.olingo.odata2.ref.annotation.model.Room;
+import org.apache.olingo.odata2.ref.annotation.model.Team;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class AnnotationPocServiceFactory extends ODataServiceFactory {
+
+ private static boolean isInitialized = false;
+
+ @Override
+ public ODataService createService(final ODataContext context) throws ODataException {
+
+ String modelPackage = "org.apache.olingo.odata2.ref.annotation.model";
+ AnnotationEdmProvider annotationEdmProvider = new AnnotationEdmProvider(modelPackage);
+ AnnotationInMemoryDs annotationScenarioDs = new AnnotationInMemoryDs(modelPackage);
+ AnnotationValueAccess annotationValueAccess = new AnnotationValueAccess();
+
+ if (!isInitialized) {
+ initializeSampleData(annotationScenarioDs);
+ isInitialized = true;
+ }
+
+ // Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
+ return createODataSingleProcessorService(annotationEdmProvider,
+ new ListsProcessor(annotationScenarioDs, annotationValueAccess));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
+ ? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
+ ? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
+ }
+
+ /*
+ * Helper classes and methods
+ */
+
+ /**
+ *
+ */
+ private final class ScenarioDebugCallback implements ODataDebugCallback {
+
+ @Override
+ public boolean isDebugEnabled() {
+ return true;
+ }
+ }
+
+ private class ScenarioErrorCallback implements ODataErrorCallback {
+
+ private final Logger LOG = LoggerFactory.getLogger(ScenarioErrorCallback.class);
+
+ @Override
+ public ODataResponse handleError(final ODataErrorContext context) throws ODataApplicationException {
+ if (context.getHttpStatus() == HttpStatusCodes.INTERNAL_SERVER_ERROR) {
+ LOG.error("Internal Server Error", context.getException());
+ }
+
+ return EntityProvider.writeErrorDocument(context);
+ }
+
+ }
+
+ private void initializeSampleData(AnnotationInMemoryDs dataSource) throws ODataApplicationException {
+ DataStore<Team> teamDs = dataSource.getDataStore(Team.class);
+ teamDs.create(createTeam("Team Alpha", true));
+ teamDs.create(createTeam("Team Beta", false));
+ teamDs.create(createTeam("Team Gamma", false));
+ teamDs.create(createTeam("Team Omega", true));
+ teamDs.create(createTeam("Team Zeta", true));
+
+ DataStore<Building> buildingsDs = dataSource.getDataStore(Building.class);
+ Building redBuilding = createBuilding("Red Building");
+ buildingsDs.create(redBuilding);
+ Building greenBuilding = createBuilding("Green Building");
+ buildingsDs.create(greenBuilding);
+ Building blueBuilding = createBuilding("Blue Building");
+ buildingsDs.create(blueBuilding);
+ Building yellowBuilding = createBuilding("Yellow Building");
+ buildingsDs.create(yellowBuilding);
+
+ DataStore<Photo> photoDs = dataSource.getDataStore(Photo.class);
+ photoDs.create(createPhoto("Small picture", ResourceHelper.Format.GIF));
+ photoDs.create(createPhoto("Medium picture", ResourceHelper.Format.PNG));
+ photoDs.create(createPhoto("Big picture", ResourceHelper.Format.JPEG));
+ photoDs.create(createPhoto("Huge picture", ResourceHelper.Format.BMP));
+
+ DataStore<Room> roomDs = dataSource.getDataStore(Room.class);
+ roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
+ roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
+ roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
+ roomDs.create(createRoom("Big blue room", 40, 1, blueBuilding));
+ roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
+ roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
+
+ DataStore<Employee> employeeDataStore = dataSource.getDataStore(Employee.class);
+ employeeDataStore.create(createEmployee("first Employee",
+ new Location("Norge", "8392", "Ä"), 42, null,
+ photoDs.read().iterator().next().getImage(), photoDs.read().iterator().next().getImageType(),
+ "http://localhost/image/first.png",
+ null, teamDs.read().iterator().next(), roomDs.read().iterator().next()));
+ }
+
+ private Employee createEmployee(final String name,
+ Location location, final int age, final Calendar date,
+ final byte[] image, final String imageType, final String imageUrl,
+ Manager manager, Team team, Room room) {
+ Employee employee = new Employee();
+ employee.setEmployeeName(name);
+ employee.setLocation(location);
+ employee.setAge(age);
+ employee.setEntryDate(date);
+ employee.setImage(image);
+ employee.setImageType(imageType);
+ employee.setImageUri(imageUrl);
+ employee.setManager(manager);
+ employee.setTeam(team);
+ employee.setRoom(room);
+ return employee;
+ }
+
+ private Team createTeam(String teamName, boolean isScrumTeam) {
+ Team team = new Team();
+ team.setName(teamName);
+ team.setScrumTeam(isScrumTeam);
+ return team;
+ }
+
+ private Building createBuilding(String buildingName) {
+ Building b = new Building();
+ b.setName(buildingName);
+ return b;
+ }
+
+ private Photo createPhoto(String name, ResourceHelper.Format format) {
+ Photo p = new Photo();
+ p.setName(name);
+ p.setImageUri("http://localhost/image/" + name);
+ p.setType(format.name());
+ p.setImageType("image/" + format.name().toLowerCase());
+ p.setImage(ResourceHelper.generateImage(format));
+ return p;
+ }
+
+ private Room createRoom(String name, int seats, int version, Building building) {
+ Room r = new Room();
+ r.setName(name);
+ r.setSeats(seats);
+ r.setVersion(version);
+ r.setBuilding(building);
+
+ building.addRoom(r);
+
+ return r;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml b/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
new file mode 100644
index 0000000..90a4706
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
+ </layout>
+ </appender>
+
+ <logger name="org.apache.olingo.odata2.ref" additivity="false">
+ <level value="trace" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <root>
+ <priority value="error" />
+ <appender-ref ref="console" />
+ </root>
+</log4j:configuration>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html b/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
new file mode 100644
index 0000000..6d76d0b
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
@@ -0,0 +1,27 @@
+<!--
+
+ 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.
+
+-->
+
+<table border="1">
+<tr><td>name</td><td>${name}</td></tr>
+<tr><td>version</td><td>${version}</td></tr>
+<tr><td>timestamp</td><td>${timestamp}</td></tr>
+<tr><td>project.build.finalName</td><td>${project.build.finalName}</td></tr>
+</table>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..5f7264c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="WebApp_ID" version="2.5">
+ <display-name>org.apache.olingo.odata2.ref.annotations.web</display-name>
+ <welcome-file-list>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <servlet>
+ <servlet-name>ReferenceScenarioServlet</servlet-name>
+ <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
+ </init-param>
+ <init-param>
+ <param-name>org.apache.olingo.odata2.service.factory</param-name>
+ <param-value>org.apache.olingo.odata2.ref.annotation.processor.AnnotationPocServiceFactory</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>ReferenceScenarioServlet</servlet-name>
+ <url-pattern>/ReferenceScenario.svc/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
new file mode 100644
index 0000000..49cf364
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
@@ -0,0 +1,116 @@
+<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8"%>
+<!--
+ 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>Apache Olingo - OData2 Library</title>
+<style type="text/css">
+body { font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;
+ color: blue; background-color: #ffffff; }
+a { color: blue; text-decoration: none; }
+a:focus { outline: thin dotted #4076cb; outline-offset: -1px; }
+a:hover, a:active { outline: 0; }
+a:hover { color: #404a7e; text-decoration: underline; }
+h1, h2, h3, h4, h5, h6 { margin: 9px 0; font-family: inherit; font-weight: bold;
+ line-height: 1; color: blue; }
+h1 { font-size: 36px; line-height: 40px; }
+h2 { font-size: 30px; line-height: 40px; }
+h3 { font-size: 24px; line-height: 40px; }
+h4 { font-size: 18px; line-height: 20px; }
+h5 { font-size: 14px; line-height: 20px; }
+h6 { font-size: 12px; line-height: 20px; }
+.logo { float: right; }
+ul { padding: 0; margin: 0 0 9px 25px; }
+ul ul { margin-bottom: 0; }
+li { line-height: 18px; }
+hr { margin: 18px 0;
+ border: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; }
+table { border-collapse: collapse; border-spacing: 10px; }
+th, td { border: 1px solid; padding: 20px; }
+.code { font-family: "Courier New", monospace; font-size: 13px; line-height: 18px; }
+</style>
+</head>
+<body>
+ <h1>Apache Olingo - OData2 Library</h1>
+ <hr />
+ <h2>Reference Scenario</h2>
+ <table>
+ <tr>
+ <td valign="top">
+ <h3>Service Document and Metadata</h3>
+ <ul>
+ <li><a href="ReferenceScenario.svc?_wadl" target="_blank">wadl</a></li>
+ <li><a href="ReferenceScenario.svc/" target="_blank">service
+ document</a></li>
+ <li><a href="ReferenceScenario.svc/$metadata" target="_blank">metadata</a></li>
+ </ul>
+ <h3>EntitySets</h3>
+ <ul>
+ <li><a href="ReferenceScenario.svc/Employees" target="_blank">Employees</a></li>
+ <li><a href="ReferenceScenario.svc/Managers" target="_blank">Managers</a></li>
+ <li><a href="ReferenceScenario.svc/Buildings" target="_blank">Buildings</a></li>
+ <li><a href="ReferenceScenario.svc/Buildings/?$expand=nb_Rooms"
+ target="_blank">Buildings/?$expand=nb_Rooms</a></li>
+ <li><a href="ReferenceScenario.svc/Rooms" target="_blank">Rooms</a></li>
+ <li><a href="ReferenceScenario.svc/Rooms/?$orderby=Name" target="_blank">Rooms/?$orderby=Name</a></li>
+ <li><a href="ReferenceScenario.svc/Photos" target="_blank">Photos</a></li>
+ <li><a href="ReferenceScenario.svc/Photos/?$filter=Type%20eq%20'PNG'"
+ target="_blank">Photos/?$filter=Type eq 'PNG'</a></li>
+ </ul>
+ <h3>Entities</h3>
+ <ul>
+ <li><a href="ReferenceScenario.svc/Employees('1')" target="_blank">Employees('1')</a></li>
+ <li><a href="ReferenceScenario.svc/Managers('1')" target="_blank">Managers('1')</a></li>
+ <li><a href="ReferenceScenario.svc/Buildings(1)" target="_blank">Buildings(1)</a></li>
+ <li><a href="ReferenceScenario.svc/Buildings(1)/nb_Rooms" target="_blank">Buildings(1)/nb_Rooms</a></li>
+ <li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
+ <li><a href="ReferenceScenario.svc/Rooms('1')/nr_Building" target="_blank">Rooms('1')/nr_Building</a></li>
+ <li><a href="ReferenceScenario.svc/Photos(Name='Small%20picture',Type='GIF')"
+ target="_blank">Photos(Name='Small%20picture',Type='GIF')</a></li>
+ <li><a href="ReferenceScenario.svc/Photos(Name='Big%20picture',Type='JPEG')/$value"
+ target="_blank">Photos(Name='Big%20picture',Type='JPEG')/$value</a></li>
+ </ul>
+ </td>
+ <td valign="top">
+
+ </td>
+ <td valign="bottom">
+ <div class="code">
+ <%
+ String version = "gen/version.html";
+ %>
+ <%
+ try {
+ %>
+ <jsp:include page='<%=version%>' />
+ <%
+ } catch (Exception e) {
+ %>
+ <p>IDE Build</p>
+ <%
+ }
+ %>
+ </div>
+ </td>
+ </tr>
+ </table>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/pom.xml b/odata2-annotation-processor/pom.xml
new file mode 100644
index 0000000..d763047
--- /dev/null
+++ b/odata2-annotation-processor/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+ <packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+
+ <parent>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-parent-incubating</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modules>
+ <module>annotation-processor-api</module>
+ <module>annotation-processor-core</module>
+ <module>annotation-processor-webref</module>
+ </modules>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/pom.xml b/odata2-edm-annotation/edm-annotation-api/pom.xml
deleted file mode 100644
index 5d697f2..0000000
--- a/odata2-edm-annotation/edm-annotation-api/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0"?>
-<!--
- 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.
--->
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
-
- <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-api-incubating</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
deleted file mode 100644
index 694f199..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * 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.api.data;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-
-/**
- * <p>This interface is intended to make it easier to implement an OData
- * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
- * properties described in the
- * Entity Data Model can be retrieved and set.</p>
- * <p>By obeying these restrictions, data-source implementations get the
- * following advantages:
- * <ul>
- * <li>All system query options can be handled centrally.</li>
- * <li>Following navigation paths must only be done step by step.</li>
- * </ul>
- * </p>
- *
- */
-public interface DataSource {
-
- /**
- * Retrieves the whole data list for the specified entity set.
- * @param entitySet the requested {@link EdmEntitySet}
- * @return the requested data list
- */
- List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Retrieves a single data object for the specified entity set and key.
- * @param entitySet the requested {@link EdmEntitySet}
- * @param keys the entity key as map of key names to key values
- * @return the requested data object
- */
- Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Retrieves data for the specified function import and key.</p>
- * <p>This method is called also for function imports that have defined in
- * their metadata an other HTTP method than <code>GET</code>.</p>
- * @param function the requested {@link EdmFunctionImport}
- * @param parameters the parameters of the function import
- * as map of parameter names to parameter values
- * @param keys the key of the returned entity set, as map of key names to key values,
- * if the return type of the function import is a collection of entities
- * (optional)
- * @return the requested data object, either a list or a single object;
- * if the function import's return type is of type <code>Binary</code>,
- * the returned object(s) must be of type {@link BinaryData}
- */
- Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Retrieves related data for the specified source data, entity set, and key.</p>
- * <p>If the underlying association of the EDM is specified to have target
- * multiplicity '*' and no target key is given, this method returns a list of
- * related data, otherwise it returns a single data object.</p>
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the requested target {@link EdmEntitySet}
- * @param targetKeys the key of the target entity as map of key names to key values
- * (optional)
- * @return the requested releated data object, either a list or a single object
- */
- Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Retrieves the binary data and the MIME type for the media resource
- * associated to the specified media-link entry.
- * @param entitySet the {@link EdmEntitySet} of the media-link entry
- * @param mediaLinkEntryData the data object of the media-link entry
- * @return the binary data and the MIME type of the media resource
- */
- BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Creates and returns a new instance of the requested data-object type.</p>
- * <p>This instance must not be part of the corresponding list and should
- * have empty content, apart from the key and other mandatory properties.
- * However, intermediate objects to access complex properties must not be
- * <code>null</code>.</p>
- * @param entitySet the {@link EdmEntitySet} the object must correspond to
- * @return the new data object
- */
- Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
- ODataApplicationException;
-
- /**
- * Writes the binary data for the media resource associated to the
- * specified media-link entry.
- * @param entitySet the {@link EdmEntitySet} of the media-link entry
- * @param mediaLinkEntryData the data object of the media-link entry
- * @param binaryData the binary data of the media resource along with
- * the MIME type of the binary data
- */
- void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * Deletes a single data object identified by the specified entity set and key.
- * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
- * @param keys the entity key as map of key names to key values
- */
- void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Inserts an instance into the entity list of the specified entity set.</p>
- * <p>If {@link #newDataObject} has not set the key and other mandatory
- * properties already, this method must set them before inserting the
- * instance into the list.</p>
- * @param entitySet the {@link EdmEntitySet} the object must correspond to
- * @param data the data object of the new entity
- */
- void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
- ODataApplicationException;
-
- /**
- * Deletes the relation from the specified source data to a target entity
- * specified by entity set and key.
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the {@link EdmEntitySet} of the target entity
- * @param targetKeys the key of the target entity as map of key names to key values
- * (optional)
- */
- void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Writes a relation from the specified source data to a target entity
- * specified by entity set and key.
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the {@link EdmEntitySet} of the relation target
- * @param targetKeys the key of the target entity as map of key names to key values
- */
- void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Container to store binary data (as byte array) and the associated MIME type.
- */
- public class BinaryData {
- private final byte[] data;
- private final String mimeType;
-
- public BinaryData(final byte[] data, final String mimeType) {
- this.data = data;
- this.mimeType = mimeType;
- }
-
- public byte[] getData() {
- return data;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- @Override
- public String toString() {
- return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
- }
- }
-}
[02/12] git commit: Removed not to merge PoC parts
Posted by mi...@apache.org.
Removed not to merge PoC parts
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/8764e11a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/8764e11a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/8764e11a
Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 8764e11a6d70099a93e2da110fe47ffe06c4baaa
Parents: a73d197
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 08:46:31 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 08:46:31 2013 +0100
----------------------------------------------------------------------
.../api/annotation/edm/ds/EntityCreate.java | 29 -
.../api/annotation/edm/ds/EntityDataSource.java | 31 -
.../api/annotation/edm/ds/EntityDelete.java | 29 -
.../api/annotation/edm/ds/EntityRead.java | 29 -
.../api/annotation/edm/ds/EntitySetRead.java | 29 -
.../api/annotation/edm/ds/EntityUpdate.java | 29 -
.../annotation/data/AnnotationInMemoryDs.java | 8 +-
.../annotation/data/AnnotationValueAccess.java | 2 +-
.../core/annotation/data/DataSourceHolder.java | 212 ------
.../odata2/core/annotation/data/DataStore.java | 2 +-
.../annotation/edm/AnnotationEdmProvider.java | 2 +
.../core/annotation/edm/AnnotationHelper.java | 726 -------------------
.../odata2/core/annotation/edm/ClassHelper.java | 105 ---
.../processor/AnnotationProcessor.java | 309 --------
.../processor/json/EdmAnnotationSerializer.java | 260 -------
.../annotation/processor/json/JsonConsumer.java | 138 ----
.../annotation/processor/json/JsonWriter.java | 204 ------
.../core/annotation/util/AnnotationHelper.java | 726 +++++++++++++++++++
.../core/annotation/util/ClassHelper.java | 105 +++
.../src/main/resources/log4j.xml | 39 -
.../data/AnnotationsInMemoryDsTest.java | 2 +-
.../processor/json/JsonConsumerTest.java | 85 ---
.../edm-annotation-webref/pom.xml | 12 +-
23 files changed, 845 insertions(+), 2268 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
deleted file mode 100644
index 529ee63..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityCreate {
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
deleted file mode 100644
index e21c81f..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface EntityDataSource {
- String name() default "";
- Class<?> entityType();
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
deleted file mode 100644
index f852307..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityDelete {
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
deleted file mode 100644
index 76333ca..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityRead {
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
deleted file mode 100644
index 79cb80c..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntitySetRead {
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
deleted file mode 100644
index 6aea1eb..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityUpdate {
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
index 7c41945..030cc93 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -32,10 +32,10 @@ import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.exception.ODataApplicationException;
import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper.AnnotatedNavInfo;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper.ODataAnnotationException;
-import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
public class AnnotationInMemoryDs implements ListsDataSource {
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
index c29ac39..14183bf 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
@@ -23,7 +23,7 @@ import org.apache.olingo.odata2.api.edm.EdmMapping;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
/**
*
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
deleted file mode 100644
index d4c6f98..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.data;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-
-/**
- *
- */
-public final class DataSourceHolder {
-
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
- private static final Object[] EMPTY_ARRAY = new Object[0];
-
- private final String name;
- private final Object dataSourceInstance;
- private final Class<?> entityTypeClass;
- private Method readMethod;
- private Method createMethod;
- private Method updateMethod;
- private Method deleteMethod;
- private Method readSetMethod;
-
- public DataSourceHolder(Class<?> clz) {
- EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
- entityTypeClass = eds.entityType();
- EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
- if (entityType == null) {
- throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
- }
-
- if (entityType.name().isEmpty()) {
- name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
- } else {
- name = entityType.name();
- }
- dataSourceInstance = createInstance(clz);
- initMethods(clz);
- }
-
- private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
- Method[] methods = clz.getDeclaredMethods();
- for (Method method : methods) {
- EntityRead ec = method.getAnnotation(EntityRead.class);
- if (ec != null) {
- readMethod = method;
- }
- EntityCreate ep = method.getAnnotation(EntityCreate.class);
- if (ep != null) {
- createMethod = method;
- }
- EntityUpdate update = method.getAnnotation(EntityUpdate.class);
- if (update != null) {
- updateMethod = method;
- }
- EntityDelete delete = method.getAnnotation(EntityDelete.class);
- if (delete != null) {
- deleteMethod = method;
- }
- EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
- if (readSet != null) {
- readSetMethod = method;
- }
- }
-
- validateMethods(clz);
- }
-
- private void validateMethods(Class<?> clz) throws IllegalArgumentException {
- //
- if (readMethod == null) {
- throw new IllegalArgumentException("Missing " + EntityRead.class
- + " annotation at " + EntityDataSource.class + " annotated class " + clz);
- }
- if (updateMethod == null) {
- throw new IllegalArgumentException("Missing " + EntityUpdate.class
- + " annotation at " + EntityDataSource.class + " annotated class " + clz);
- }
- if (createMethod == null) {
- throw new IllegalArgumentException("Missing " + EntityCreate.class
- + " annotation at " + EntityDataSource.class + " annotated class " + clz);
- }
-
- if(readSetMethod != null) {
- if(!Collection.class.isAssignableFrom(readSetMethod.getReturnType())) {
- throw new IllegalArgumentException("Read set method must have a return type which is assignable to "
- + Collection.class + " but return type for annotated method " + readSetMethod + " is "
- + readSetMethod.getReturnType());
- }
- }
- }
-
- public Object readEntity(Object[] keyValues) {
- if (readMethod.getParameterTypes().length != keyValues.length) {
- throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
- + Arrays.toString(readMethod.getParameterTypes()) + " given key predicates = "
- + Arrays.toString(keyValues));
- }
-
- return invoke(readMethod, keyValues);
- }
-
- public Object readEntity(List<KeyPredicate> keys) {
- Object[] parameterKeys = mapParameterKeys(readMethod, keys);
- return invoke(readMethod, parameterKeys);
- }
-
- private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
- if(method == null) {
- return EMPTY_ARRAY;
- }
- Class<?>[] pTypes = method.getParameterTypes();
- if (pTypes.length != keys.size()) {
- throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
- + Arrays.toString(pTypes) + " given key predicates = " + keys);
- }
- Object[] parameterKeys = new Object[pTypes.length];
- int i = 0;
- for (KeyPredicate keyPredicate : keys) {
- if (matches(pTypes[i], keyPredicate)) {
- parameterKeys[i] = keyPredicate.getLiteral();
- }
- i++;
- }
- return parameterKeys;
- }
-
- public Object createEntity(Object key) {
- return invoke(createMethod, new Object[]{key});
- }
-
- public Object updateEntity(Object key) {
- return invoke(updateMethod, new Object[]{key});
- }
-
- public Object deleteEntity(List<KeyPredicate> keys) {
- Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
- return invoke(deleteMethod, parameterKeys);
- }
-
- public Collection<?> readEntitySet() {
- return (Collection<?>) invoke(readSetMethod, new Object[0]);
- }
-
- private Object invoke(Method m, Object[] objs) {
- try {
- return m.invoke(dataSourceInstance, objs);
- } catch (Exception ex) {
- return null;
- }
- }
-
- public Object createEntityInstance() {
- return createInstance(this.entityTypeClass);
- }
-
- private static Object createInstance(Class<?> clz) {
- try {
- return clz.newInstance();
- } catch (Exception ex) {
- return null;
- }
- }
-
- public String getEntityName() {
- return this.name;
- }
-
- public Class<?> getEntityTypeClass() {
- return entityTypeClass;
- }
-
- @Override
- public String toString() {
- return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance +
- ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod +
- ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
- }
-
- private boolean matches(Class<?> aClass, KeyPredicate type) {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
index 834e33a..696ab9a 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
@@ -29,7 +29,7 @@ import java.util.Map;
import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
/**
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
index 1b53d58..97f5b53 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -64,6 +64,8 @@ import org.apache.olingo.odata2.api.edm.provider.Schema;
import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
import org.apache.olingo.odata2.api.edm.provider.Using;
import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
/**
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
deleted file mode 100644
index 2b6675f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * *****************************************************************************
- * 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.core.annotation.edm;
-
-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;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationHelper {
-
- public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
-
- /**
- * Compare keys of both instances.
- *
- * @param firstInstance
- * @param secondInstance
- * @return
- */
- public boolean keyMatch(Object firstInstance, 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);
-
- return keyValuesMatch(firstKeyFields, secondKeyFields);
- }
-
- /**
- * Compare keys of instance with key values in map.
- *
- * @param instance
- * @param keyName2Value
- * @return
- */
- public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
- Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
- return keyValuesMatch(instanceKeyFields, keyName2Value);
- }
-
- private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
- if (firstKeyValues.size() != secondKeyValues.size()) {
- return false;
- } 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(Object firstKey, Object secondKey) {
- if (firstKey == null) {
- if (secondKey == null) {
- return true;
- } else {
- return secondKey.equals(firstKey);
- }
- } else {
- return firstKey.equals(secondKey);
- }
- }
-
- public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
- Class<?> entityTypeClass = enp.toType();
- return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
- }
-
- public String extractEntitTypeName(EdmNavigationProperty enp, 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(Class<?> annotatedClass) {
- return extractTypeName(annotatedClass, EdmEntityType.class);
- }
-
- public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
- if(type.namespace().isEmpty()) {
- return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
- }
- return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
- }
-
- public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
- EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
- if(type == null) {
- return null;
- }
- return extractEntityTypeFqn(type, annotatedClass);
- }
-
- public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
- EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
- if(type == null) {
- return null;
- }
- return extractComplexTypeFqn(type, annotatedClass);
- }
-
- public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
- if(type.namespace().isEmpty()) {
- return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
- }
- return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
- }
-
- public String extractComplexTypeName(Class<?> annotatedClass) {
- return extractTypeName(annotatedClass, EdmComplexType.class);
- }
-
- public String generateNamespace(Class<?> annotatedClass) {
- String packageName = annotatedClass.getPackage().getName();
- return packageName;
- }
-
- /**
- *
- *
- * @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(Class<?> annotatedClass, 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(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(Field field) {
- String propertyName = getPropertyNameFromAnnotation(field);
- if (propertyName.isEmpty()) {
- propertyName = getCanonicalName(field);
- }
- return propertyName;
- }
-
- public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
- return getCanonicalRole(field.getDeclaringClass());
- }
-
- public String extractToRoleName(EdmNavigationProperty enp, Field field) {
- String role = enp.toRole();
- if (role.isEmpty()) {
- role = getCanonicalRole(
- field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
- (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
- }
- return role;
- }
-
- public String getCanonicalRole(Class<?> fallbackClass) {
- String toRole = extractEntityTypeName(fallbackClass);
- return "r_" + toRole;
- }
-
- public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
- String relationshipName = enp.association();
- if (relationshipName.isEmpty()) {
- final String fromRole = extractFromRoleName(enp, field);
- final String toRole = extractToRoleName(enp, field);
- if (fromRole.compareTo(toRole) > 0) {
- relationshipName = toRole + "-" + fromRole;
- } else {
- relationshipName = fromRole + "-" + toRole;
- }
- }
- return relationshipName;
- }
-
- public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, 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(T instance, 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 = 1L;
-
- public ODataAnnotationException(String message) {
- super(message);
- }
- }
-
-
- public class AnnotatedNavInfo {
- private final Field fromField;
- private final Field toField;
- private final EdmNavigationProperty fromNavigation;
- private final EdmNavigationProperty toNavigation;
-
- public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
- EdmNavigationProperty toNavigation) {
- this.fromField = fromField;
- this.toField = toField;
- this.fromNavigation = fromNavigation;
- this.toNavigation = toNavigation;
- }
-
- public Field getFromField() {
- return fromField;
- }
-
- public Field getToField() {
- return toField;
- }
-
- public EdmMultiplicity getFromMultiplicity() {
- return getMultiplicity(toNavigation, toField);
- }
-
- public EdmMultiplicity getToMultiplicity() {
- return getMultiplicity(fromNavigation, fromField);
- }
-
- public boolean isBiDirectional() {
- return toNavigation != null;
- }
- }
-
- public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
- List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
- List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
-
- // first try via association name to get full navigation information
- for (Field sourceField : sourceFields) {
- final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
- final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
- for (Field targetField : targetFields) {
- 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 none bi-directinal navigation
- String targetEntityTypeName = extractEntityTypeName(targetClass);
- for (Field sourceField : sourceFields) {
- final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
- final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
-
- if (navTargetEntityName.equals(targetEntityTypeName)) {
- return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
- }
- }
-
- return null;
- }
-
- public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
- if (instance == null) {
- return null;
- }
-
- Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
- if (field == null) {
- throw new ODataAnnotationException("No field for property '" + propertyName
- + "' found at class '" + instance.getClass() + "'.");
- }
- return field.getType();
- }
-
- public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
- if (instance == null) {
- return null;
- }
-
- Field field = getFieldForPropertyName(instance, 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(Object instance, String propertyName, Object propertyValue) {
- if (instance != null) {
- Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
- if (field != null) {
- setFieldValue(instance, field, propertyValue);
- }
- }
- }
-
- private Field getFieldForPropertyName(Object instance, String propertyName,
- Class<?> resultClass, boolean inherited) {
- if (instance == null) {
- return null;
- }
-
- 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(instance, propertyName, superClass, true);
- }
-
- return null;
- }
-
- public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
- }
-
- public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getValueForField(instance, instance.getClass(), annotation, true);
- }
-
- private Object getValueForField(Object instance, Class<?> resultClass,
- Class<? extends Annotation> annotation, boolean inherited) {
- return getValueForField(instance, null, resultClass, annotation, inherited);
- }
-
- public Map<String, Object> getValueForAnnotatedFields(Object instance,
- Class<? extends Annotation> annotation) {
- return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
- }
-
- private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
- Class<? extends Annotation> annotation, 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 EdmProperty property = field.getAnnotation(EdmProperty.class);
- final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
- 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;
- }
-
- public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, 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(Object instance,
- Class<? extends Annotation> annotation, 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(Object instance, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getAnnotatedFields(instance.getClass(), annotation, true);
- }
-
- public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
- return getAnnotatedFields(fieldClass, annotation, true);
- }
-
- /**
- *
- * @param instance
- * @param resultClass
- * @param annotation
- * @param inherited
- * @return
- */
- private List<Field> getAnnotatedFields(Class<?> resultClass,
- Class<? extends Annotation> annotation, 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(Object instance, String fieldName, Class<?> resultClass,
- Class<? extends Annotation> annotation, 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(Object instance, 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 ODataRuntimeException(ex);
- } catch (IllegalAccessException ex) { // should never happen
- throw new ODataRuntimeException(ex);
- }
- }
-
- private void setFieldValue(Object instance, Field field, 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 ODataRuntimeException(ex);
- } catch (IllegalAccessException ex) { // should never happen
- throw new ODataRuntimeException(ex);
- }
- }
-
- public Object convert(Field field, 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 ODataRuntimeException("Conversion failed for string property with error: "
- + ex.getMessage(), ex);
- }
- }
-
- public boolean isEdmAnnotated(Object object) {
- if (object == null) {
- return false;
- }
- return isEdmAnnotated(object.getClass());
- }
-
- public boolean isEdmTypeAnnotated(Class<?> clazz) {
- boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
- boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
- return isComplexEntity || isEntity;
- }
-
- public boolean isEdmAnnotated(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(Field field) {
- return firstCharToUpperCase(field.getName());
- }
-
- public String getCanonicalName(Class<?> clazz) {
- return firstCharToUpperCase(clazz.getSimpleName());
- }
-
- private String firstCharToUpperCase(String content) {
- if (content == null || content.isEmpty()) {
- return content;
- }
- return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
- }
-
- public EdmSimpleTypeKind mapTypeKind(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 ODataRuntimeException("Unknown type '" + type
- + "' for mapping to EdmSimpleTypeKind.");
- }
- }
-
- public EdmMultiplicity mapMultiplicity(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 ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
- }
- }
-
- /**
- *
- */
- private static class EdmAnnotationException extends RuntimeException {
-
- private static final long serialVersionUID = 42L;
-
- public EdmAnnotationException(String message) {
- super(message);
- }
- }
-
- public String getCanonicalNamespace(Class<?> aClass) {
- return generateNamespace(aClass);
- }
-
- public String extractContainerName(Class<?> aClass) {
- EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
- if(entitySet != null) {
- String containerName = entitySet.container();
- if(!containerName.isEmpty()) {
- return containerName;
- }
- }
- return DEFAULT_CONTAINER_NAME;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
deleted file mode 100644
index 2a4c706..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.edm;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- */
-public class ClassHelper {
-
- private static final File[] EMPTY_FILE_ARRAY = new File[0];
-
- private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.endsWith(CLASSFILE_ENDING);
- }
- public static final String CLASSFILE_ENDING = ".class";
- };
-
- private static final FileFilter FOLDER_FILTER = new FileFilter() {
- @Override
- public boolean accept(File pathname) {
- return pathname.isDirectory();
- }
- };
-
- public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
- return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
- }
-
-
- public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
- final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- String folderToScan = packageToScan.replace(".", "/");
- URL url = classLoader.getResource(folderToScan);
- if(url == null) {
- throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
- }
- File folder = new File(url.getFile());
- File[] classFiles = folder.listFiles(ff);
- if(classFiles == null) {
- classFiles = EMPTY_FILE_ARRAY;
- }
-
- List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
- for (File file : classFiles) {
- String name = file.getName();
- String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
- try {
- Class<?> c = classLoader.loadClass(fqn);
- if (cv.isClassValid(c)) {
- annotatedClasses.add(c);
- }
- } catch (ClassNotFoundException ex) {
- throw new IllegalArgumentException("Exception during class loading of class '" + fqn +
- "' with message '" + ex.getMessage() + "'.");
- }
- }
-
- // recursive search
- File[] subfolders = listSubFolder(folder);
- for (File file : subfolders) {
- List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
- annotatedClasses.addAll(subFolderClazzes);
- }
- //
-
- return annotatedClasses;
- }
-
- private static File[] listSubFolder(File folder) {
- File[] subfolders = folder.listFiles(FOLDER_FILTER);
- if(subfolders == null) {
- return EMPTY_FILE_ARRAY;
- }
- return subfolders;
- }
-
- public interface ClassValidator {
- boolean isClassValid(Class<?> c);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
deleted file mode 100644
index b1b8730..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.processor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-import org.apache.olingo.odata2.core.annotation.data.DataSourceHolder;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
-import org.apache.olingo.odata2.core.annotation.processor.json.EdmAnnotationSerializer;
-import org.apache.olingo.odata2.core.annotation.processor.json.JsonConsumer;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationProcessor extends ODataSingleProcessor {
-
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
- private final Map<String, DataSourceHolder> dataSources = new HashMap<String, DataSourceHolder>();
- private ODataContext odataContext;
-
- public AnnotationProcessor(ODataContext context, String packageToScan) {
- odataContext = context;
-
- List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
- @Override
- public boolean isClassValid(Class<?> c) {
- return null != c.getAnnotation(EntityDataSource.class);
- }
- });
-
- init(foundClasses);
- }
-
- private void init(List<Class<?>> foundClasses) {
- for (Class<?> clz : foundClasses) {
- DataSourceHolder dhs = new DataSourceHolder(clz);
- dataSources.put(dhs.getEntityName(), dhs);
- }
- }
-
- @Override
- public ODataResponse readEntity(GetEntityUriInfo uriInfo, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- List<KeyPredicate> keys = uriInfo.getKeyPredicates();
- DataSourceHolder holder = dataSources.get(name);
- if (holder != null) {
- Object result = holder.readEntity(keys);
- if (result != null) {
- return createODataResponse(result, HttpStatusCodes.OK);
- }
- }
-
- return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
- }
-
- @Override
- public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- DataSourceHolder holder = dataSources.get(name);
- if (holder != null) {
- Object result = holder.readEntitySet();
- if (result != null) {
- return createODataResponse(result, HttpStatusCodes.OK);
- }
- }
-
- return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
- }
-
- @Override
- public ODataResponse createEntity(PostUriInfo uriInfo, InputStream content,
- String requestContentType, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- DataSourceHolder dataSource = dataSources.get(name);
- if (dataSource != null) {
- Object instance = createInstanceFromContent(dataSource, content);
-
- Object result = dataSource.createEntity(instance);
- return createODataResponse(result, HttpStatusCodes.CREATED);
- }
-
- return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
- }
-
- @Override
- public ODataResponse deleteEntity(DeleteUriInfo uriInfo, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- DataSourceHolder holder = dataSources.get(name);
- if (holder != null) {
- List<KeyPredicate> keys = uriInfo.getKeyPredicates();
- Object result = holder.deleteEntity(keys);
- if (result != null) {
- return ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
- }
- }
-
- return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
- }
-
- @Override
- public ODataResponse readEntityMedia(GetMediaResourceUriInfo uriInfo, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- List<KeyPredicate> keys = uriInfo.getKeyPredicates();
- Object result = readEntity(name, keys);
- if (result != null) {
- Object content = new AnnotationHelper().getValueForField(result, EdmMediaResourceContent.class);
- Object mimeType = new AnnotationHelper().getValueForField(result, EdmMediaResourceMimeType.class);
- return ODataResponse.status(HttpStatusCodes.OK).entity(content).contentHeader(String.valueOf(mimeType)).build();
- }
-
- return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
- }
-
- private Object readEntity(String entityName, List<KeyPredicate> keys) {
- DataSourceHolder holder = dataSources.get(entityName);
- if (holder != null) {
- return holder.readEntity(keys);
- }
- return null;
- }
-
-
- private ODataResponse createODataResponse(Object result, HttpStatusCodes statusCode) throws ODataException {
-// StringBuilder resultAsString = new StringBuilder("{\"d\":");
-// if (result != null) {
-// resultAsString.append(result.toString());
-// } else {
-// resultAsString.append("NULL");
-// }
-// resultAsString.append("}");
- EdmAnnotationSerializer jsonSerializer =
- new EdmAnnotationSerializer(odataContext.getPathInfo().getServiceRoot().toASCIIString());
- InputStream resultAsString = jsonSerializer.serialize(result);
- return ODataResponse.status(statusCode)
- .contentHeader("application/json")
- .entity(resultAsString).build();
- }
-
- private Object createInstanceFromContent(DataSourceHolder dataSource, InputStream content)
- throws ODataException {
- try {
- Object instance = dataSource.createEntityInstance();
- Map<String, FieldHolder> propName2Field = extractPropertyFields(dataSource.getEntityTypeClass());
- Map<String, String> contentAsMap = JsonConsumer.readContent(content);
- Set<Map.Entry<String, String>> contentEntries = contentAsMap.entrySet();
- for (Map.Entry<String, String> entry : contentEntries) {
- FieldHolder fh = propName2Field.get(entry.getKey());
- if (fh != null) {
- fh.set(instance, entry.getValue());
- }
- }
- return instance;
- } catch (IOException e) {
- throw new ODataRuntimeException("Unexpected IOException with message: " + e.getMessage());
- }
- }
-
- @Override
- public ODataResponse updateEntity(PutMergePatchUriInfo uriInfo, InputStream content,
- String requestContentType, boolean merge, String contentType) throws ODataException {
- final String name = uriInfo.getTargetType().getName();
-
- DataSourceHolder dataSource = dataSources.get(name);
- if (dataSource != null) {
- Object instance = createInstanceFromContent(dataSource, content);
-
- Object result = dataSource.updateEntity(instance);
- return createODataResponse(result, HttpStatusCodes.OK);
- }
-
- return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
- }
-
- private Map<String, FieldHolder> extractPropertyFields(Class<?> typeClass) {
- if (typeClass == null) {
- return Collections.emptyMap();
- }
- EdmEntityType type = typeClass.getAnnotation(EdmEntityType.class);
- if (type == null) {
- return Collections.emptyMap();
- }
-
- //
- Map<String, FieldHolder> name2Fields = new HashMap<String, FieldHolder>();
- Field[] fields = typeClass.getDeclaredFields();
- for (Field field : fields) {
- FieldHolder fh = FieldHolder.create(field);
- name2Fields.put(fh.propertyName, fh);
- }
-
- //
- Class<?> superClass = typeClass.getSuperclass();
- if (superClass != null && superClass.getAnnotation(EdmEntityType.class) != null) {
- name2Fields.putAll(extractPropertyFields(superClass));
- }
- //
-
- return name2Fields;
- }
-
- /**
- *
- */
- static final class FieldHolder {
-
- final String propertyName;
- final Field propertyField;
-
- public FieldHolder(String propertyName, Field propertyField) {
- this.propertyName = propertyName;
- this.propertyField = propertyField;
- }
-
- public static FieldHolder create(Field field) {
- EdmProperty ep = field.getAnnotation(EdmProperty.class);
- String name;
- if (ep != null && !ep.name().isEmpty()) {
- name = ep.name();
- } else {
- name = ANNOTATION_HELPER.getCanonicalName(field);
- }
- return new FieldHolder(name, field);
- }
-
- public void set(Object instance, Object value) {
- set(instance, String.valueOf(value));
- }
-
- public void set(Object instance, String value) {
- try {
- boolean accessible = propertyField.isAccessible();
- if (!accessible) {
- propertyField.setAccessible(true);
- }
-
- //
- Class<?> type = propertyField.getType();
- if (type == Boolean.class || type == boolean.class) {
- propertyField.set(instance, Boolean.valueOf(value));
- } else if (type == Integer.class || type == int.class) {
- propertyField.set(instance, Integer.valueOf(value));
- } else if (type == Long.class || type == long.class) {
- propertyField.set(instance, Integer.valueOf(value));
- } else {
- propertyField.set(instance, value);
- }
- //
-
- if (!accessible) {
- propertyField.setAccessible(false);
- }
- } catch (Exception ex) {
- }
- }
-
- @Override
- public String toString() {
- return "FieldHolder{" + "propertyName=" + propertyName + ", propertyField=" + propertyField + '}';
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
deleted file mode 100644
index 7ae9971..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/**
- * *****************************************************************************
- * 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.core.annotation.processor.json;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-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.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class EdmAnnotationSerializer {
-
- private final String baseUri;
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
- public EdmAnnotationSerializer(String baseUri) {
- this.baseUri = baseUri;
- }
-
- public InputStream serialize(Object obj) {
- byte[] buf = getContent(obj).getBytes();
- InputStream stream = new ByteArrayInputStream(buf);
- return stream;
- }
-
- private String getContent(Object entity) {
- if (entity == null) {
- return "NULL";
- } else if (isConsumable(entity)) {
- try {
- return handleEdmAnnotations(entity);
- } catch (Exception e) {
- throw new ODataRuntimeException("Exception with following message occured: " + e.getMessage(), e);
- }
- } else {
- return entity.toString();
- }
- }
-
- private String handleEdmAnnotations(Object entity)
- throws IllegalArgumentException, IllegalAccessException, IOException {
- //
- Writer writer = new StringWriter();
- JsonWriter json = new JsonWriter(writer);
- json.start();
- writeObject(entity, json);
- json.finish();
- writer.close();
- //
- return writer.toString();
- }
-
- private void writeObject(Object entity, JsonWriter json) throws IllegalAccessException {
- if (entity.getClass().isArray()) {
- List<Object> entities = Arrays.asList(entity);
- writeCollection(entities, json);
- } else if (Collection.class.isAssignableFrom(entity.getClass())) {
- Collection<Object> entities = (Collection<Object>) entity;
- writeCollection(entities, json);
- } else {
- writeSingleObject(entity, json);
- }
- }
-
- private void writeCollection(Collection<Object> entities, JsonWriter json) throws IllegalAccessException {
- json.startObject();
- json.writeName("results");
- json.startArray();
- boolean writeSeperator = false;
- for (Object object : entities) {
- if (writeSeperator) {
- json.writeSeparator();
- } else {
- writeSeperator = true;
- }
- writeSingleObject(object, json);
- }
- json.endArray();
- json.endObject();
- }
-
- private void writeSingleObject(Object entity, JsonWriter json) throws IllegalAccessException {
- List<Field> fields = getAllFields(entity.getClass());
- json.startObject();
- for (Field field : fields) {
- boolean written = writeEdmProperty(entity, json, field);
- if (!written) {
- writeEdmNavigationProperty(entity, json, field);
- }
- }
- json.endObject();
- }
-
- private boolean writeEdmNavigationProperty(Object entity, JsonWriter json, Field field)
- throws IllegalArgumentException, IllegalAccessException {
- EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
- EdmEntitySet entitySet = entity.getClass().getAnnotation(EdmEntitySet.class);
- if (navProperty != null) {
- field.setAccessible(true);
- Object keyValue = extractEdmKey(entity);
- json.writeStringProperty("uri", baseUri + entitySet.name() + "('" + keyValue.toString() + "')"
- + "/" + navProperty.association());
- return true;
- }
- return false;
- }
-
- private boolean writeEdmProperty(Object entity, JsonWriter json, Field field) throws IllegalAccessException {
- EdmProperty property = field.getAnnotation(EdmProperty.class);
- if (property != null) {
- field.setAccessible(true);
- Object fieldValue = field.get(entity);
- String name = getName(property, field);
- EdmSimpleTypeKind defaultType = getDefaultSimpleTypeKind(field, property);
- try {
- String value = defaultType.getEdmSimpleTypeInstance().valueToString(fieldValue, EdmLiteralKind.JSON, null);
- write(defaultType, name, value, json);
- } catch (EdmSimpleTypeException e) {
- throw new IllegalArgumentException("Illegal argument for valueToString for EdmSimpleType = '"
- + property.type() + "' with message = '" + e.getMessage() + "'.");
- }
- return true;
- }
- return false;
- }
-
- public void write(EdmSimpleTypeKind kind, String name, String value, JsonWriter jsonStreamWriter) {
- switch (kind) {
- case String:
- jsonStreamWriter.writeStringProperty(name, value);
- break;
- case Boolean:
- case Byte:
- case SByte:
- case Int16:
- case Int32:
- jsonStreamWriter.writeRawProperty(name, value);
- break;
- case DateTime:
- case DateTimeOffset:
- // Although JSON escaping is (and should be) done in the JSON
- // serializer, we backslash-escape the forward slash here explicitly
- // because it is not required to escape it in JSON but in OData.
- jsonStreamWriter.writeRawStringProperty(name, value == null ? null : value.replace("/", "\\/"));
- break;
- default:
- jsonStreamWriter.writeRawStringProperty(name, value);
- break;
- }
- }
-
- private EdmSimpleTypeKind getDefaultSimpleTypeKind(Field field, EdmProperty property) {
- final EdmType type = property.type();
- if (type == EdmType.NULL) {
- Class<?> fieldType = field.getType();
- if (fieldType == String.class) {
- return EdmSimpleTypeKind.String;
- } else if (fieldType == Long.class) {
- return EdmSimpleTypeKind.Int64;
- } else if (fieldType == Integer.class) {
- return EdmSimpleTypeKind.Int32;
- }
- }
- return ANNOTATION_HELPER.mapTypeKind(type);
- }
-
- private Class<?> getType(EdmProperty property) {
- EdmSimpleTypeKind type = ANNOTATION_HELPER.mapTypeKind(property.type());
- Class<?> defaultType = type.getEdmSimpleTypeInstance().getDefaultType();
- return defaultType;
- }
-
- private Object extractEdmKey(Object value) throws IllegalArgumentException, IllegalAccessException {
- Field idField = getFieldWithAnnotation(value.getClass(), EdmKey.class);
- if (idField == null) {
- return "NULL";
- }
- idField.setAccessible(true);
- return idField.get(value);
- }
-
- private Field getFieldWithAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
-
- Field[] fields = clazz.getDeclaredFields();
- for (Field field : fields) {
- if (field.getAnnotation(annotationClazz) != null) {
- return field;
- }
- }
-
- Class<?> superclass = clazz.getSuperclass();
- if (superclass != Object.class) {
- return getFieldWithAnnotation(superclass, annotationClazz);
- }
-
- return null;
- }
-
- private List<Field> getAllFields(Class<?> clazz) {
- Field[] fields = clazz.getDeclaredFields();
- List<Field> allFields = new ArrayList<Field>(Arrays.asList(fields));
-
- final Class<?> superclass = clazz.getSuperclass();
- if (superclass != Object.class) {
- allFields.addAll(getAllFields(superclass));
- }
-
- return allFields;
- }
-
- private boolean isConsumable(Object entity) {
- if (entity == null) {
- return false;
- } else if (ANNOTATION_HELPER.isEdmAnnotated(entity)) {
- return true;
- } else if (entity.getClass().isArray() || entity.getClass().isAssignableFrom(Collection.class)) {
- return true;
- } else if (Collection.class.isAssignableFrom(entity.getClass())) {
- return true;
- }
- return false;
- }
-
- private String getName(EdmProperty property, Field field) {
- String name = property.name();
- if (name.isEmpty()) {
- name = ANNOTATION_HELPER.getCanonicalName(field);
- }
- return name;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
deleted file mode 100644
index 265484d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.processor.json;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.olingo.odata2.core.ep.util.FormatJson;
-
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-
-/**
- *
- */
-public class JsonConsumer {
-
- private final JsonReader reader;
- private final Map<String, String> properties;
-
- public JsonConsumer(InputStream content) {
- reader = new JsonReader(new InputStreamReader(content));
- properties = new HashMap<String, String>();
- }
-
- public static Map<String, String> readContent(InputStream content) throws IOException {
- JsonConsumer jc = new JsonConsumer(content);
- return jc.read();
- }
-
- public Map<String, String> read() throws IOException {
-
- reader.beginObject();
- String nextName = reader.nextName();
- if (FormatJson.D.equals(nextName)) {
- reader.beginObject();
- readEntryContent();
- reader.endObject();
- } else {
- handleName(nextName);
- readEntryContent();
- }
- reader.endObject();
-
- return properties;
- }
-
- private void readEntryContent() throws IOException {
- while (reader.hasNext()) {
- final String name = reader.nextName();
- handleName(name);
- }
- }
-
- private void handleName(final String name) throws IOException {
- if (FormatJson.METADATA.equals(name)) {
- readMetadata();
- } else {
- readPropertyValue(name);
- }
- }
-
- private void readPropertyValue(final String name) throws IOException {
- final JsonToken tokenType = reader.peek();
- final String value;
-
- switch (tokenType) {
- case STRING:
- value = reader.nextString();
- break;
- case BOOLEAN:
- value = String.valueOf(reader.nextBoolean());
- break;
- case NULL:
- reader.nextNull();
- default:
- value = null;
- }
-
- properties.put(name, value);
- }
-
- private void readMetadata() throws IOException {
- reader.beginObject();
-
- while (reader.hasNext()) {
- String name = reader.nextName();
-
- if (FormatJson.PROPERTIES.equals(name)) {
- reader.skipValue();
- continue;
- }
-
- String value = reader.nextString();
- if (FormatJson.ID.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.URI.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.TYPE.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.ETAG.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.EDIT_MEDIA.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.MEDIA_SRC.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.MEDIA_ETAG.equals(name)) {
- properties.put("md_" + name, value);
- } else if (FormatJson.CONTENT_TYPE.equals(name)) {
- properties.put("md_" + name, value);
- } else {
- throw new IllegalStateException("Unknown metadata");
- }
- }
-
- reader.endObject();
- }
-
-}
[09/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
new file mode 100644
index 0000000..0c81fb1
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
@@ -0,0 +1,726 @@
+/**
+ * *****************************************************************************
+ * 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.core.annotation.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;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+ public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
+
+ /**
+ * Compare keys of both instances.
+ *
+ * @param firstInstance
+ * @param secondInstance
+ * @return
+ */
+ public boolean keyMatch(Object firstInstance, 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);
+
+ return keyValuesMatch(firstKeyFields, secondKeyFields);
+ }
+
+ /**
+ * Compare keys of instance with key values in map.
+ *
+ * @param instance
+ * @param keyName2Value
+ * @return
+ */
+ public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
+ Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
+ return keyValuesMatch(instanceKeyFields, keyName2Value);
+ }
+
+ private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
+ if (firstKeyValues.size() != secondKeyValues.size()) {
+ return false;
+ } 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(Object firstKey, Object secondKey) {
+ if (firstKey == null) {
+ if (secondKey == null) {
+ return true;
+ } else {
+ return secondKey.equals(firstKey);
+ }
+ } else {
+ return firstKey.equals(secondKey);
+ }
+ }
+
+ public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
+ Class<?> entityTypeClass = enp.toType();
+ return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
+ }
+
+ public String extractEntitTypeName(EdmNavigationProperty enp, 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(Class<?> annotatedClass) {
+ return extractTypeName(annotatedClass, EdmEntityType.class);
+ }
+
+ public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
+ if(type.namespace().isEmpty()) {
+ return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
+ }
+ return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
+ }
+
+ public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
+ EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
+ if(type == null) {
+ return null;
+ }
+ return extractEntityTypeFqn(type, annotatedClass);
+ }
+
+ public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
+ EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
+ if(type == null) {
+ return null;
+ }
+ return extractComplexTypeFqn(type, annotatedClass);
+ }
+
+ public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
+ if(type.namespace().isEmpty()) {
+ return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
+ }
+ return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
+ }
+
+ public String extractComplexTypeName(Class<?> annotatedClass) {
+ return extractTypeName(annotatedClass, EdmComplexType.class);
+ }
+
+ public String generateNamespace(Class<?> annotatedClass) {
+ String packageName = annotatedClass.getPackage().getName();
+ return packageName;
+ }
+
+ /**
+ *
+ *
+ * @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(Class<?> annotatedClass, 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(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(Field field) {
+ String propertyName = getPropertyNameFromAnnotation(field);
+ if (propertyName.isEmpty()) {
+ propertyName = getCanonicalName(field);
+ }
+ return propertyName;
+ }
+
+ public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
+ return getCanonicalRole(field.getDeclaringClass());
+ }
+
+ public String extractToRoleName(EdmNavigationProperty enp, Field field) {
+ String role = enp.toRole();
+ if (role.isEmpty()) {
+ role = getCanonicalRole(
+ field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
+ (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
+ }
+ return role;
+ }
+
+ public String getCanonicalRole(Class<?> fallbackClass) {
+ String toRole = extractEntityTypeName(fallbackClass);
+ return "r_" + toRole;
+ }
+
+ public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
+ String relationshipName = enp.association();
+ if (relationshipName.isEmpty()) {
+ final String fromRole = extractFromRoleName(enp, field);
+ final String toRole = extractToRoleName(enp, field);
+ if (fromRole.compareTo(toRole) > 0) {
+ relationshipName = toRole + "-" + fromRole;
+ } else {
+ relationshipName = fromRole + "-" + toRole;
+ }
+ }
+ return relationshipName;
+ }
+
+ public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, 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(T instance, 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 = 1L;
+
+ public ODataAnnotationException(String message) {
+ super(message);
+ }
+ }
+
+
+ public class AnnotatedNavInfo {
+ private final Field fromField;
+ private final Field toField;
+ private final EdmNavigationProperty fromNavigation;
+ private final EdmNavigationProperty toNavigation;
+
+ public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
+ EdmNavigationProperty toNavigation) {
+ this.fromField = fromField;
+ this.toField = toField;
+ this.fromNavigation = fromNavigation;
+ this.toNavigation = toNavigation;
+ }
+
+ public Field getFromField() {
+ return fromField;
+ }
+
+ public Field getToField() {
+ return toField;
+ }
+
+ public EdmMultiplicity getFromMultiplicity() {
+ return getMultiplicity(toNavigation, toField);
+ }
+
+ public EdmMultiplicity getToMultiplicity() {
+ return getMultiplicity(fromNavigation, fromField);
+ }
+
+ public boolean isBiDirectional() {
+ return toNavigation != null;
+ }
+ }
+
+ public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
+ List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
+ List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
+
+ // first try via association name to get full navigation information
+ for (Field sourceField : sourceFields) {
+ final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+ final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
+ for (Field targetField : targetFields) {
+ 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 none bi-directinal navigation
+ String targetEntityTypeName = extractEntityTypeName(targetClass);
+ for (Field sourceField : sourceFields) {
+ final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+ final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
+
+ if (navTargetEntityName.equals(targetEntityTypeName)) {
+ return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
+ }
+ }
+
+ return null;
+ }
+
+ public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+ if (instance == null) {
+ return null;
+ }
+
+ Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+ if (field == null) {
+ throw new ODataAnnotationException("No field for property '" + propertyName
+ + "' found at class '" + instance.getClass() + "'.");
+ }
+ return field.getType();
+ }
+
+ public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+ if (instance == null) {
+ return null;
+ }
+
+ Field field = getFieldForPropertyName(instance, 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(Object instance, String propertyName, Object propertyValue) {
+ if (instance != null) {
+ Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+ if (field != null) {
+ setFieldValue(instance, field, propertyValue);
+ }
+ }
+ }
+
+ private Field getFieldForPropertyName(Object instance, String propertyName,
+ Class<?> resultClass, boolean inherited) {
+ if (instance == null) {
+ return null;
+ }
+
+ 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(instance, propertyName, superClass, true);
+ }
+
+ return null;
+ }
+
+ public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
+ }
+
+ public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getValueForField(instance, instance.getClass(), annotation, true);
+ }
+
+ private Object getValueForField(Object instance, Class<?> resultClass,
+ Class<? extends Annotation> annotation, boolean inherited) {
+ return getValueForField(instance, null, resultClass, annotation, inherited);
+ }
+
+ public Map<String, Object> getValueForAnnotatedFields(Object instance,
+ Class<? extends Annotation> annotation) {
+ return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
+ }
+
+ private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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 EdmProperty property = field.getAnnotation(EdmProperty.class);
+ final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
+ 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;
+ }
+
+ public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, 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(Object instance,
+ Class<? extends Annotation> annotation, 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(Object instance, Class<? extends Annotation> annotation) {
+ if (instance == null) {
+ return null;
+ }
+ return getAnnotatedFields(instance.getClass(), annotation, true);
+ }
+
+ public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
+ return getAnnotatedFields(fieldClass, annotation, true);
+ }
+
+ /**
+ *
+ * @param instance
+ * @param resultClass
+ * @param annotation
+ * @param inherited
+ * @return
+ */
+ private List<Field> getAnnotatedFields(Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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(Object instance, String fieldName, Class<?> resultClass,
+ Class<? extends Annotation> annotation, 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(Object instance, 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 ODataRuntimeException(ex);
+ } catch (IllegalAccessException ex) { // should never happen
+ throw new ODataRuntimeException(ex);
+ }
+ }
+
+ private void setFieldValue(Object instance, Field field, 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 ODataRuntimeException(ex);
+ } catch (IllegalAccessException ex) { // should never happen
+ throw new ODataRuntimeException(ex);
+ }
+ }
+
+ public Object convert(Field field, 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 ODataRuntimeException("Conversion failed for string property with error: "
+ + ex.getMessage(), ex);
+ }
+ }
+
+ public boolean isEdmAnnotated(Object object) {
+ if (object == null) {
+ return false;
+ }
+ return isEdmAnnotated(object.getClass());
+ }
+
+ public boolean isEdmTypeAnnotated(Class<?> clazz) {
+ boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
+ boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
+ return isComplexEntity || isEntity;
+ }
+
+ public boolean isEdmAnnotated(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(Field field) {
+ return firstCharToUpperCase(field.getName());
+ }
+
+ public String getCanonicalName(Class<?> clazz) {
+ return firstCharToUpperCase(clazz.getSimpleName());
+ }
+
+ private String firstCharToUpperCase(String content) {
+ if (content == null || content.isEmpty()) {
+ return content;
+ }
+ return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+ }
+
+ public EdmSimpleTypeKind mapTypeKind(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 ODataRuntimeException("Unknown type '" + type
+ + "' for mapping to EdmSimpleTypeKind.");
+ }
+ }
+
+ public EdmMultiplicity mapMultiplicity(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 ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
+ }
+ }
+
+ /**
+ *
+ */
+ private static class EdmAnnotationException extends RuntimeException {
+
+ private static final long serialVersionUID = 42L;
+
+ public EdmAnnotationException(String message) {
+ super(message);
+ }
+ }
+
+ public String getCanonicalNamespace(Class<?> aClass) {
+ return generateNamespace(aClass);
+ }
+
+ public String extractContainerName(Class<?> aClass) {
+ EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+ if(entitySet != null) {
+ String containerName = entitySet.container();
+ if(!containerName.isEmpty()) {
+ return containerName;
+ }
+ }
+ return DEFAULT_CONTAINER_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
new file mode 100644
index 0000000..5e9fcdb
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.core.annotation.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+
+ private static final File[] EMPTY_FILE_ARRAY = new File[0];
+
+ private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(CLASSFILE_ENDING);
+ }
+ public static final String CLASSFILE_ENDING = ".class";
+ };
+
+ private static final FileFilter FOLDER_FILTER = new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ };
+
+ public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+ return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+ }
+
+
+ public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+ final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ String folderToScan = packageToScan.replace(".", "/");
+ URL url = classLoader.getResource(folderToScan);
+ if(url == null) {
+ throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+ }
+ File folder = new File(url.getFile());
+ File[] classFiles = folder.listFiles(ff);
+ if(classFiles == null) {
+ classFiles = EMPTY_FILE_ARRAY;
+ }
+
+ List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+ for (File file : classFiles) {
+ String name = file.getName();
+ String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+ try {
+ Class<?> c = classLoader.loadClass(fqn);
+ if (cv.isClassValid(c)) {
+ annotatedClasses.add(c);
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new IllegalArgumentException("Exception during class loading of class '" + fqn +
+ "' with message '" + ex.getMessage() + "'.");
+ }
+ }
+
+ // recursive search
+ File[] subfolders = listSubFolder(folder);
+ for (File file : subfolders) {
+ List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+ annotatedClasses.addAll(subFolderClazzes);
+ }
+ //
+
+ return annotatedClasses;
+ }
+
+ private static File[] listSubFolder(File folder) {
+ File[] subfolders = folder.listFiles(FOLDER_FILTER);
+ if(subfolders == null) {
+ return EMPTY_FILE_ARRAY;
+ }
+ return subfolders;
+ }
+
+ public interface ClassValidator {
+ boolean isClassValid(Class<?> c);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
new file mode 100644
index 0000000..04dbefc
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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.core.annotation.data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ *
+ */
+public class AnnotationsInMemoryDsTest {
+
+ private final AnnotationInMemoryDs datasource;
+ private AnnotationEdmProvider edmProvider;
+ private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
+
+ public AnnotationsInMemoryDsTest() {
+ datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
+ edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
+ }
+
+ @Test
+ public void createSimpleEntity() throws Exception {
+ EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+
+ Building building = new Building();
+ building.setName("Common Building");
+ datasource.createData(edmEntitySet, building);
+
+ Map<String, Object> keys = new HashMap<String, Object>();
+ keys.put("Id", "1");
+
+ Building read = (Building) datasource.readData(edmEntitySet, keys);
+ Assert.assertEquals("Common Building", read.getName());
+ Assert.assertEquals("1", read.getId());
+ }
+
+
+ @Test
+ public void createSimpleEntityWithOwnKey() throws Exception {
+ EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+
+ Building building = new Building();
+ building.setName("Common Building");
+ AnnotationHelper ah = new AnnotationHelper();
+ ah.setValueForProperty(building, "Id", "42");
+ datasource.createData(edmEntitySet, building);
+
+ Map<String, Object> keys = new HashMap<String, Object>();
+ keys.put("Id", "42");
+
+ Building read = (Building) datasource.readData(edmEntitySet, keys);
+ Assert.assertEquals("Common Building", read.getName());
+ Assert.assertEquals("42", read.getId());
+ }
+
+ @Test
+ public void createSimpleEntityWithDuplicateKey() throws Exception {
+ EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+ AnnotationHelper ah = new AnnotationHelper();
+
+ Building building = new Building();
+ building.setName("Common Building");
+ ah.setValueForProperty(building, "Id", "42");
+ datasource.createData(edmEntitySet, building);
+ //
+ Building buildingDuplicate = new Building();
+ buildingDuplicate.setName("Duplicate Building");
+ ah.setValueForProperty(buildingDuplicate, "Id", "42");
+ datasource.createData(edmEntitySet, buildingDuplicate);
+
+ Map<String, Object> keys42 = new HashMap<String, Object>();
+ keys42.put("Id", "42");
+ Building read42 = (Building) datasource.readData(edmEntitySet, keys42);
+ Assert.assertEquals("Common Building", read42.getName());
+ Assert.assertEquals("42", read42.getId());
+
+ Map<String, Object> keys = new HashMap<String, Object>();
+ keys.put("Id", "1");
+ Building read = (Building) datasource.readData(edmEntitySet, keys);
+ Assert.assertEquals("Duplicate Building", read.getName());
+ Assert.assertEquals("1", read.getId());
+}
+
+
+ @Test
+ public void createEntityTwoKeys() throws Exception {
+ EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
+
+ Photo photo = new Photo();
+ photo.setName("BigPicture");
+ photo.setType("PNG");
+ photo.setImageUri("https://localhost/image.png");
+ photo.setImageType("image/png");
+ datasource.createData(edmEntitySet, photo);
+
+ Map<String, Object> keys = new HashMap<String, Object>();
+ keys.put("ImageFormat", "PNG");
+ keys.put("Name", "BigPicture");
+
+ Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+ Assert.assertEquals("BigPicture", read.getName());
+ Assert.assertEquals("PNG", read.getType());
+ Assert.assertEquals("image/png", read.getImageType());
+ Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+ }
+
+ @Test
+ // @Ignore("Rethink update method")
+ public void createAndUpdateEntityTwoKeys() throws Exception {
+ EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
+
+ Photo photo = new Photo();
+ final String nameKeyValue = "BigPicture";
+ final String typeKeyValue = "PNG";
+ photo.setName(nameKeyValue);
+ photo.setType(typeKeyValue);
+ photo.setImageUri("https://localhost/image.png");
+ photo.setImageType("image/png");
+ datasource.createData(edmEntitySet, photo);
+
+ Map<String, Object> keys = new HashMap<String, Object>();
+ keys.put("Name", "BigPicture");
+ keys.put("ImageFormat", "PNG");
+
+ Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+ Assert.assertEquals("BigPicture", read.getName());
+ Assert.assertEquals("PNG", read.getType());
+ Assert.assertEquals("image/png", read.getImageType());
+ Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+
+ // update
+ Photo updatedPhoto = new Photo();
+ updatedPhoto.setName(nameKeyValue);
+ updatedPhoto.setType(typeKeyValue);
+ updatedPhoto.setImageUri("https://localhost/image.jpg");
+ updatedPhoto.setImageType("image/jpg");
+ datasource.updateData(edmEntitySet, updatedPhoto);
+
+ Map<String, Object> updatedKeys = new HashMap<String, Object>();
+ updatedKeys.put("Name", nameKeyValue);
+ updatedKeys.put("ImageFormat", typeKeyValue);
+
+ Photo readUpdated = (Photo) datasource.readData(edmEntitySet, updatedKeys);
+ Assert.assertEquals("BigPicture", readUpdated.getName());
+ Assert.assertEquals("PNG", readUpdated.getType());
+ Assert.assertEquals("image/jpg", readUpdated.getImageType());
+ Assert.assertEquals("https://localhost/image.jpg", readUpdated.getImageUri());
+ }
+
+ private EdmEntitySet createMockedEdmEntitySet(String entitySetName) throws ODataException {
+ EntitySet entitySet = edmProvider.getEntitySet(DEFAULT_CONTAINER, entitySetName);
+ FullQualifiedName entityType = entitySet.getEntityType();
+
+ EdmEntitySet edmEntitySet = Mockito.mock(EdmEntitySet.class);
+ Mockito.when(edmEntitySet.getName()).thenReturn(entitySetName);
+ EdmEntityType edmEntityType = Mockito.mock(EdmEntityType.class);
+ Mockito.when(edmEntitySet.getEntityType()).thenReturn(edmEntityType);
+ Mockito.when(edmEntityType.getName()).thenReturn(entityType.getName());
+
+ return edmEntitySet;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
new file mode 100644
index 0000000..494a090
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
@@ -0,0 +1,463 @@
+/*
+ * 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.core.annotation.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.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.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.apache.olingo.odata2.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.City;
+import org.apache.olingo.odata2.core.annotation.model.Employee;
+import org.apache.olingo.odata2.core.annotation.model.Location;
+import org.apache.olingo.odata2.core.annotation.model.Manager;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.model.RefBase;
+import org.apache.olingo.odata2.core.annotation.model.Room;
+import org.apache.olingo.odata2.core.annotation.model.Team;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class AnnotationEdmProviderTest {
+
+ @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() {
+ 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("org.apache.olingo.odata2.core.annotation.model");
+
+ // 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(String name) {
+ return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
+ }
+
+ private void validateAssociation(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(Association association,
+ String fromRole, EdmMultiplicity fromMulti, FullQualifiedName fromType,
+ String toRole, EdmMultiplicity toMulti, 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(AssociationEnd associationEnd,
+ String role, EdmMultiplicity multiplicity, 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());
+
+ 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 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(NavigationProperty navigationProperty, String name,
+ String relationship, String fromRole, 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(NavigationProperty navigationProperty,
+ String relationship, String fromRole, String toRole) {
+ validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
+ }
+
+ private boolean containsProperty(List<Property> properties, String propertyName) {
+ return getProperty(properties, propertyName) != null;
+ }
+
+ private Property getProperty(List<Property> properties, String name) {
+ for (Property property : properties) {
+ if(name.equals(property.getName())) {
+ return property;
+ }
+ }
+ return null;
+ }
+
+ private PropertyRef getPropertyRef(List<PropertyRef> properties, String name) {
+ for (PropertyRef property : properties) {
+ if(name.equals(property.getName())) {
+ return property;
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
new file mode 100644
index 0000000..737b5e2
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+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.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Buildings")
+public class Building {
+ @EdmKey
+ @EdmProperty(type = EdmType.INT32)
+ private String id;
+ @EdmProperty
+ private String name;
+ @EdmProperty(name = "Image", type = EdmType.BINARY)
+ private byte[] image;
+ @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
+ association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
+ private List<Room> rooms = new ArrayList<Room>();
+
+ public Building() {}
+
+ public String getId() {
+ return id;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setImage(final byte[] byteArray) {
+ image = byteArray;
+ }
+
+ public byte[] getImage() {
+ if (image == null) {
+ return null;
+ } else {
+ return image.clone();
+ }
+ }
+
+ public List<Room> getRooms() {
+ return rooms;
+ }
+
+ @Override
+ public int hashCode() {
+ return id == null ? 0 : id.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
new file mode 100644
index 0000000..7b866a3
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+
+/**
+ *
+ */
+@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
+public class City {
+
+ @EdmProperty
+ private String postalCode;
+ @EdmProperty
+ private String cityName;
+
+ public City(final String postalCode, final String name) {
+ this.postalCode = postalCode;
+ cityName = name;
+ }
+
+ public void setPostalCode(final String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setCityName(final String cityName) {
+ this.cityName = cityName;
+ }
+
+ public String getCityName() {
+ return cityName;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s, %s", cityName, postalCode);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
new file mode 100644
index 0000000..63b8a76
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+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.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Employees")
+public class Employee {
+ @EdmKey
+ @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
+ private String employeeId;
+ @EdmProperty(name = "EmployeeName")
+ private String employeeName;
+ @EdmProperty
+ private int age;
+ @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
+ private Manager manager;
+ @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
+ private Team team;
+ @EdmNavigationProperty(name = "ne_Room")
+ private Room room;
+ @EdmMediaResourceMimeType
+ private String imageType;
+ @EdmMediaResourceContent
+ private byte[] image;
+ @EdmProperty(name = "ImageUrl")
+ private String imageUrl;
+ @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME)
+ private Calendar entryDate;
+ @EdmProperty(name = "Location")
+ private Location location;
+
+ public Employee(final String employeeId, final String name) {
+ this.employeeId = employeeId;
+ setEmployeeName(name);
+ }
+
+ public String getId() {
+ return employeeId;
+ }
+
+ public void setEmployeeName(final String employeeName) {
+ this.employeeName = employeeName;
+ }
+
+ public String getEmployeeName() {
+ return employeeName;
+ }
+
+ public void setAge(final int age) {
+ this.age = age;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setManager(final Manager manager) {
+ this.manager = manager;
+ }
+
+ public Manager getManager() {
+ return manager;
+ }
+
+ public void setTeam(final Team team) {
+ this.team = team;
+ }
+
+ public Team getTeam() {
+ return team;
+ }
+
+ public void setRoom(final Room room) {
+ this.room = room;
+ }
+
+ public Room getRoom() {
+ return room;
+ }
+
+ public void setImageUri(final String imageUri) {
+ imageUrl = imageUri;
+ }
+
+ public String getImageUri() {
+ return imageUrl;
+ }
+
+ public void setLocation(final Location location) {
+ this.location = location;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public void setEntryDate(final Calendar date) {
+ entryDate = date;
+ }
+
+ public Calendar getEntryDate() {
+ return entryDate;
+ }
+
+ public void setImageType(final String imageType) {
+ this.imageType = imageType;
+ }
+
+ public String getImageType() {
+ return imageType;
+ }
+
+ public void setImage(final byte[] image) {
+ this.image = image;
+ }
+
+ public byte[] getImage() {
+ if (image == null) {
+ return null;
+ }
+ return image.clone();
+ }
+
+ @Override
+ public int hashCode() {
+ if (employeeId == null) {
+ return 0;
+ }
+ return employeeId.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return this == obj
+ || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"EmployeeId\":\"" + employeeId + "\","
+ + "\"EmployeeName\":\"" + employeeName + "\","
+ + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
+ + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
+ + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
+ + "\"Location\":"
+ + (location == null ? "null" :
+ "{\"City\":" + (location.getCity() == null ? "null" :
+ "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
+ + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
+ + "\"Country\":\"" + location.getCountry() + "\"}") + ","
+ + "\"Age\":" + age + ","
+ + "\"EntryDate\":"
+ + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
+ + "\"ImageUrl\":\"" + imageUrl + "\"}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
new file mode 100644
index 0000000..7f3f082
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+
+/**
+ *
+ */
+@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+ @EdmProperty
+ private String country;
+ @EdmProperty
+ private City city;
+
+ public Location(final String country, final String postalCode, final String cityName) {
+ this.country = country;
+ city = new City(postalCode, cityName);
+ }
+
+ public void setCountry(final String country) {
+ this.country = country;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCity(final City city) {
+ this.city = city;
+ }
+
+ public City getCity() {
+ return city;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s, %s", country, city.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
new file mode 100644
index 0000000..e3edbd0
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers")
+public class Manager extends Employee {
+
+ @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
+ toMultiplicity = Multiplicity.MANY)
+ private List<Employee> employees = new ArrayList<Employee>();
+
+ public Manager(final String id, final String name) {
+ super(id, name);
+ }
+
+ public List<Employee> getEmployees() {
+ return employees;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..1d44498
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+public interface ModelSharedConstants {
+
+ String NAMESPACE_1 = "RefScenario";
+ String CONTAINER_1 = "DefaultContainer";
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
new file mode 100644
index 0000000..520216a
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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.core.annotation.model;
+
+import java.util.Arrays;
+
+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.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Photos")
+public class Photo {
+ @EdmProperty
+ @EdmKey
+ private String name;
+ @EdmProperty(name = "ImageFormat")
+ @EdmKey
+ private String type;
+ @EdmProperty
+ @EdmMediaResourceMimeType
+ private String mimeType;
+ @EdmProperty
+ @EdmMediaResourceSource
+ private String imageUrl = "http://localhost/someResource.png";
+ @EdmProperty(type = EdmType.BINARY)
+ @EdmMediaResourceContent
+ private byte[] image = ResourceHelper.generateImage();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public String getImageUri() {
+ return imageUrl;
+ }
+
+ public void setImageUri(final String uri) {
+ imageUrl = uri;
+ }
+
+ public byte[] getImage() {
+ return image.clone();
+ }
+
+ public void setImage(final byte[] image) {
+ this.image = image;
+ }
+
+ public String getImageType() {
+ return mimeType;
+ }
+
+ public void setImageType(final String imageType) {
+ this.mimeType = imageType;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
+ hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Photo other = (Photo) obj;
+ if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+ return false;
+ }
+ if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "{\"Name\":\"" + name + "\","
+ + "\"Type\":\"" + type + "\","
+ + "\"ImageUrl\":\"" + imageUrl + "\","
+ + "\"Image\":\"" + Arrays.toString(image) + "\","
+ + "\"MimeType\":\"" + mimeType + "\"";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
new file mode 100644
index 0000000..6f3002f
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.annotation.model;
+
+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.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+ @EdmProperty(name="Name")
+ protected String name;
+ @EdmProperty(name="Id", type = EdmType.STRING)
+ @EdmKey
+ protected int id;
+
+ public RefBase(int id, String name) {
+ this.name = name;
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getId() {
+ return Integer.toString(id);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
[05/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
deleted file mode 100644
index 0c81fb1..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * *****************************************************************************
- * 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.core.annotation.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;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationHelper {
-
- public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
-
- /**
- * Compare keys of both instances.
- *
- * @param firstInstance
- * @param secondInstance
- * @return
- */
- public boolean keyMatch(Object firstInstance, 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);
-
- return keyValuesMatch(firstKeyFields, secondKeyFields);
- }
-
- /**
- * Compare keys of instance with key values in map.
- *
- * @param instance
- * @param keyName2Value
- * @return
- */
- public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
- Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
- return keyValuesMatch(instanceKeyFields, keyName2Value);
- }
-
- private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
- if (firstKeyValues.size() != secondKeyValues.size()) {
- return false;
- } 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(Object firstKey, Object secondKey) {
- if (firstKey == null) {
- if (secondKey == null) {
- return true;
- } else {
- return secondKey.equals(firstKey);
- }
- } else {
- return firstKey.equals(secondKey);
- }
- }
-
- public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
- Class<?> entityTypeClass = enp.toType();
- return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
- }
-
- public String extractEntitTypeName(EdmNavigationProperty enp, 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(Class<?> annotatedClass) {
- return extractTypeName(annotatedClass, EdmEntityType.class);
- }
-
- public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
- if(type.namespace().isEmpty()) {
- return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
- }
- return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
- }
-
- public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
- EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
- if(type == null) {
- return null;
- }
- return extractEntityTypeFqn(type, annotatedClass);
- }
-
- public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
- EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
- if(type == null) {
- return null;
- }
- return extractComplexTypeFqn(type, annotatedClass);
- }
-
- public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
- if(type.namespace().isEmpty()) {
- return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
- }
- return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
- }
-
- public String extractComplexTypeName(Class<?> annotatedClass) {
- return extractTypeName(annotatedClass, EdmComplexType.class);
- }
-
- public String generateNamespace(Class<?> annotatedClass) {
- String packageName = annotatedClass.getPackage().getName();
- return packageName;
- }
-
- /**
- *
- *
- * @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(Class<?> annotatedClass, 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(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(Field field) {
- String propertyName = getPropertyNameFromAnnotation(field);
- if (propertyName.isEmpty()) {
- propertyName = getCanonicalName(field);
- }
- return propertyName;
- }
-
- public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
- return getCanonicalRole(field.getDeclaringClass());
- }
-
- public String extractToRoleName(EdmNavigationProperty enp, Field field) {
- String role = enp.toRole();
- if (role.isEmpty()) {
- role = getCanonicalRole(
- field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
- (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
- }
- return role;
- }
-
- public String getCanonicalRole(Class<?> fallbackClass) {
- String toRole = extractEntityTypeName(fallbackClass);
- return "r_" + toRole;
- }
-
- public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
- String relationshipName = enp.association();
- if (relationshipName.isEmpty()) {
- final String fromRole = extractFromRoleName(enp, field);
- final String toRole = extractToRoleName(enp, field);
- if (fromRole.compareTo(toRole) > 0) {
- relationshipName = toRole + "-" + fromRole;
- } else {
- relationshipName = fromRole + "-" + toRole;
- }
- }
- return relationshipName;
- }
-
- public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, 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(T instance, 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 = 1L;
-
- public ODataAnnotationException(String message) {
- super(message);
- }
- }
-
-
- public class AnnotatedNavInfo {
- private final Field fromField;
- private final Field toField;
- private final EdmNavigationProperty fromNavigation;
- private final EdmNavigationProperty toNavigation;
-
- public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
- EdmNavigationProperty toNavigation) {
- this.fromField = fromField;
- this.toField = toField;
- this.fromNavigation = fromNavigation;
- this.toNavigation = toNavigation;
- }
-
- public Field getFromField() {
- return fromField;
- }
-
- public Field getToField() {
- return toField;
- }
-
- public EdmMultiplicity getFromMultiplicity() {
- return getMultiplicity(toNavigation, toField);
- }
-
- public EdmMultiplicity getToMultiplicity() {
- return getMultiplicity(fromNavigation, fromField);
- }
-
- public boolean isBiDirectional() {
- return toNavigation != null;
- }
- }
-
- public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
- List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
- List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
-
- // first try via association name to get full navigation information
- for (Field sourceField : sourceFields) {
- final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
- final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
- for (Field targetField : targetFields) {
- 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 none bi-directinal navigation
- String targetEntityTypeName = extractEntityTypeName(targetClass);
- for (Field sourceField : sourceFields) {
- final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
- final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
-
- if (navTargetEntityName.equals(targetEntityTypeName)) {
- return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
- }
- }
-
- return null;
- }
-
- public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
- if (instance == null) {
- return null;
- }
-
- Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
- if (field == null) {
- throw new ODataAnnotationException("No field for property '" + propertyName
- + "' found at class '" + instance.getClass() + "'.");
- }
- return field.getType();
- }
-
- public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
- if (instance == null) {
- return null;
- }
-
- Field field = getFieldForPropertyName(instance, 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(Object instance, String propertyName, Object propertyValue) {
- if (instance != null) {
- Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
- if (field != null) {
- setFieldValue(instance, field, propertyValue);
- }
- }
- }
-
- private Field getFieldForPropertyName(Object instance, String propertyName,
- Class<?> resultClass, boolean inherited) {
- if (instance == null) {
- return null;
- }
-
- 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(instance, propertyName, superClass, true);
- }
-
- return null;
- }
-
- public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
- }
-
- public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getValueForField(instance, instance.getClass(), annotation, true);
- }
-
- private Object getValueForField(Object instance, Class<?> resultClass,
- Class<? extends Annotation> annotation, boolean inherited) {
- return getValueForField(instance, null, resultClass, annotation, inherited);
- }
-
- public Map<String, Object> getValueForAnnotatedFields(Object instance,
- Class<? extends Annotation> annotation) {
- return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
- }
-
- private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
- Class<? extends Annotation> annotation, 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 EdmProperty property = field.getAnnotation(EdmProperty.class);
- final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
- 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;
- }
-
- public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, 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(Object instance,
- Class<? extends Annotation> annotation, 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(Object instance, Class<? extends Annotation> annotation) {
- if (instance == null) {
- return null;
- }
- return getAnnotatedFields(instance.getClass(), annotation, true);
- }
-
- public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
- return getAnnotatedFields(fieldClass, annotation, true);
- }
-
- /**
- *
- * @param instance
- * @param resultClass
- * @param annotation
- * @param inherited
- * @return
- */
- private List<Field> getAnnotatedFields(Class<?> resultClass,
- Class<? extends Annotation> annotation, 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(Object instance, String fieldName, Class<?> resultClass,
- Class<? extends Annotation> annotation, 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(Object instance, 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 ODataRuntimeException(ex);
- } catch (IllegalAccessException ex) { // should never happen
- throw new ODataRuntimeException(ex);
- }
- }
-
- private void setFieldValue(Object instance, Field field, 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 ODataRuntimeException(ex);
- } catch (IllegalAccessException ex) { // should never happen
- throw new ODataRuntimeException(ex);
- }
- }
-
- public Object convert(Field field, 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 ODataRuntimeException("Conversion failed for string property with error: "
- + ex.getMessage(), ex);
- }
- }
-
- public boolean isEdmAnnotated(Object object) {
- if (object == null) {
- return false;
- }
- return isEdmAnnotated(object.getClass());
- }
-
- public boolean isEdmTypeAnnotated(Class<?> clazz) {
- boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
- boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
- return isComplexEntity || isEntity;
- }
-
- public boolean isEdmAnnotated(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(Field field) {
- return firstCharToUpperCase(field.getName());
- }
-
- public String getCanonicalName(Class<?> clazz) {
- return firstCharToUpperCase(clazz.getSimpleName());
- }
-
- private String firstCharToUpperCase(String content) {
- if (content == null || content.isEmpty()) {
- return content;
- }
- return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
- }
-
- public EdmSimpleTypeKind mapTypeKind(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 ODataRuntimeException("Unknown type '" + type
- + "' for mapping to EdmSimpleTypeKind.");
- }
- }
-
- public EdmMultiplicity mapMultiplicity(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 ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
- }
- }
-
- /**
- *
- */
- private static class EdmAnnotationException extends RuntimeException {
-
- private static final long serialVersionUID = 42L;
-
- public EdmAnnotationException(String message) {
- super(message);
- }
- }
-
- public String getCanonicalNamespace(Class<?> aClass) {
- return generateNamespace(aClass);
- }
-
- public String extractContainerName(Class<?> aClass) {
- EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
- if(entitySet != null) {
- String containerName = entitySet.container();
- if(!containerName.isEmpty()) {
- return containerName;
- }
- }
- return DEFAULT_CONTAINER_NAME;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
deleted file mode 100644
index 5e9fcdb..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.util;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- */
-public class ClassHelper {
-
- private static final File[] EMPTY_FILE_ARRAY = new File[0];
-
- private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.endsWith(CLASSFILE_ENDING);
- }
- public static final String CLASSFILE_ENDING = ".class";
- };
-
- private static final FileFilter FOLDER_FILTER = new FileFilter() {
- @Override
- public boolean accept(File pathname) {
- return pathname.isDirectory();
- }
- };
-
- public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
- return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
- }
-
-
- public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
- final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- String folderToScan = packageToScan.replace(".", "/");
- URL url = classLoader.getResource(folderToScan);
- if(url == null) {
- throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
- }
- File folder = new File(url.getFile());
- File[] classFiles = folder.listFiles(ff);
- if(classFiles == null) {
- classFiles = EMPTY_FILE_ARRAY;
- }
-
- List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
- for (File file : classFiles) {
- String name = file.getName();
- String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
- try {
- Class<?> c = classLoader.loadClass(fqn);
- if (cv.isClassValid(c)) {
- annotatedClasses.add(c);
- }
- } catch (ClassNotFoundException ex) {
- throw new IllegalArgumentException("Exception during class loading of class '" + fqn +
- "' with message '" + ex.getMessage() + "'.");
- }
- }
-
- // recursive search
- File[] subfolders = listSubFolder(folder);
- for (File file : subfolders) {
- List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
- annotatedClasses.addAll(subFolderClazzes);
- }
- //
-
- return annotatedClasses;
- }
-
- private static File[] listSubFolder(File folder) {
- File[] subfolders = folder.listFiles(FOLDER_FILTER);
- if(subfolders == null) {
- return EMPTY_FILE_ARRAY;
- }
- return subfolders;
- }
-
- public interface ClassValidator {
- boolean isClassValid(Class<?> c);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
deleted file mode 100644
index 04dbefc..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.core.annotation.data;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.edm.provider.EntitySet;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.model.Building;
-import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
-import org.apache.olingo.odata2.core.annotation.model.Photo;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- *
- */
-public class AnnotationsInMemoryDsTest {
-
- private final AnnotationInMemoryDs datasource;
- private AnnotationEdmProvider edmProvider;
- private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
-
- public AnnotationsInMemoryDsTest() {
- datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
- edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
- }
-
- @Test
- public void createSimpleEntity() throws Exception {
- EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
-
- Building building = new Building();
- building.setName("Common Building");
- datasource.createData(edmEntitySet, building);
-
- Map<String, Object> keys = new HashMap<String, Object>();
- keys.put("Id", "1");
-
- Building read = (Building) datasource.readData(edmEntitySet, keys);
- Assert.assertEquals("Common Building", read.getName());
- Assert.assertEquals("1", read.getId());
- }
-
-
- @Test
- public void createSimpleEntityWithOwnKey() throws Exception {
- EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
-
- Building building = new Building();
- building.setName("Common Building");
- AnnotationHelper ah = new AnnotationHelper();
- ah.setValueForProperty(building, "Id", "42");
- datasource.createData(edmEntitySet, building);
-
- Map<String, Object> keys = new HashMap<String, Object>();
- keys.put("Id", "42");
-
- Building read = (Building) datasource.readData(edmEntitySet, keys);
- Assert.assertEquals("Common Building", read.getName());
- Assert.assertEquals("42", read.getId());
- }
-
- @Test
- public void createSimpleEntityWithDuplicateKey() throws Exception {
- EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
- AnnotationHelper ah = new AnnotationHelper();
-
- Building building = new Building();
- building.setName("Common Building");
- ah.setValueForProperty(building, "Id", "42");
- datasource.createData(edmEntitySet, building);
- //
- Building buildingDuplicate = new Building();
- buildingDuplicate.setName("Duplicate Building");
- ah.setValueForProperty(buildingDuplicate, "Id", "42");
- datasource.createData(edmEntitySet, buildingDuplicate);
-
- Map<String, Object> keys42 = new HashMap<String, Object>();
- keys42.put("Id", "42");
- Building read42 = (Building) datasource.readData(edmEntitySet, keys42);
- Assert.assertEquals("Common Building", read42.getName());
- Assert.assertEquals("42", read42.getId());
-
- Map<String, Object> keys = new HashMap<String, Object>();
- keys.put("Id", "1");
- Building read = (Building) datasource.readData(edmEntitySet, keys);
- Assert.assertEquals("Duplicate Building", read.getName());
- Assert.assertEquals("1", read.getId());
-}
-
-
- @Test
- public void createEntityTwoKeys() throws Exception {
- EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
-
- Photo photo = new Photo();
- photo.setName("BigPicture");
- photo.setType("PNG");
- photo.setImageUri("https://localhost/image.png");
- photo.setImageType("image/png");
- datasource.createData(edmEntitySet, photo);
-
- Map<String, Object> keys = new HashMap<String, Object>();
- keys.put("ImageFormat", "PNG");
- keys.put("Name", "BigPicture");
-
- Photo read = (Photo) datasource.readData(edmEntitySet, keys);
- Assert.assertEquals("BigPicture", read.getName());
- Assert.assertEquals("PNG", read.getType());
- Assert.assertEquals("image/png", read.getImageType());
- Assert.assertEquals("https://localhost/image.png", read.getImageUri());
- }
-
- @Test
- // @Ignore("Rethink update method")
- public void createAndUpdateEntityTwoKeys() throws Exception {
- EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
-
- Photo photo = new Photo();
- final String nameKeyValue = "BigPicture";
- final String typeKeyValue = "PNG";
- photo.setName(nameKeyValue);
- photo.setType(typeKeyValue);
- photo.setImageUri("https://localhost/image.png");
- photo.setImageType("image/png");
- datasource.createData(edmEntitySet, photo);
-
- Map<String, Object> keys = new HashMap<String, Object>();
- keys.put("Name", "BigPicture");
- keys.put("ImageFormat", "PNG");
-
- Photo read = (Photo) datasource.readData(edmEntitySet, keys);
- Assert.assertEquals("BigPicture", read.getName());
- Assert.assertEquals("PNG", read.getType());
- Assert.assertEquals("image/png", read.getImageType());
- Assert.assertEquals("https://localhost/image.png", read.getImageUri());
-
- // update
- Photo updatedPhoto = new Photo();
- updatedPhoto.setName(nameKeyValue);
- updatedPhoto.setType(typeKeyValue);
- updatedPhoto.setImageUri("https://localhost/image.jpg");
- updatedPhoto.setImageType("image/jpg");
- datasource.updateData(edmEntitySet, updatedPhoto);
-
- Map<String, Object> updatedKeys = new HashMap<String, Object>();
- updatedKeys.put("Name", nameKeyValue);
- updatedKeys.put("ImageFormat", typeKeyValue);
-
- Photo readUpdated = (Photo) datasource.readData(edmEntitySet, updatedKeys);
- Assert.assertEquals("BigPicture", readUpdated.getName());
- Assert.assertEquals("PNG", readUpdated.getType());
- Assert.assertEquals("image/jpg", readUpdated.getImageType());
- Assert.assertEquals("https://localhost/image.jpg", readUpdated.getImageUri());
- }
-
- private EdmEntitySet createMockedEdmEntitySet(String entitySetName) throws ODataException {
- EntitySet entitySet = edmProvider.getEntitySet(DEFAULT_CONTAINER, entitySetName);
- FullQualifiedName entityType = entitySet.getEntityType();
-
- EdmEntitySet edmEntitySet = Mockito.mock(EdmEntitySet.class);
- Mockito.when(edmEntitySet.getName()).thenReturn(entitySetName);
- EdmEntityType edmEntityType = Mockito.mock(EdmEntityType.class);
- Mockito.when(edmEntitySet.getEntityType()).thenReturn(edmEntityType);
- Mockito.when(edmEntityType.getName()).thenReturn(entityType.getName());
-
- return edmEntitySet;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
deleted file mode 100644
index 494a090..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * 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.core.annotation.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.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.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.apache.olingo.odata2.core.annotation.model.Building;
-import org.apache.olingo.odata2.core.annotation.model.City;
-import org.apache.olingo.odata2.core.annotation.model.Employee;
-import org.apache.olingo.odata2.core.annotation.model.Location;
-import org.apache.olingo.odata2.core.annotation.model.Manager;
-import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
-import org.apache.olingo.odata2.core.annotation.model.Photo;
-import org.apache.olingo.odata2.core.annotation.model.RefBase;
-import org.apache.olingo.odata2.core.annotation.model.Room;
-import org.apache.olingo.odata2.core.annotation.model.Team;
-import org.junit.Test;
-
-/**
- *
- */
-public class AnnotationEdmProviderTest {
-
- @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() {
- 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("org.apache.olingo.odata2.core.annotation.model");
-
- // 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(String name) {
- return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
- }
-
- private void validateAssociation(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(Association association,
- String fromRole, EdmMultiplicity fromMulti, FullQualifiedName fromType,
- String toRole, EdmMultiplicity toMulti, 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(AssociationEnd associationEnd,
- String role, EdmMultiplicity multiplicity, 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());
-
- 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 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(NavigationProperty navigationProperty, String name,
- String relationship, String fromRole, 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(NavigationProperty navigationProperty,
- String relationship, String fromRole, String toRole) {
- validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
- }
-
- private boolean containsProperty(List<Property> properties, String propertyName) {
- return getProperty(properties, propertyName) != null;
- }
-
- private Property getProperty(List<Property> properties, String name) {
- for (Property property : properties) {
- if(name.equals(property.getName())) {
- return property;
- }
- }
- return null;
- }
-
- private PropertyRef getPropertyRef(List<PropertyRef> properties, String name) {
- for (PropertyRef property : properties) {
- if(name.equals(property.getName())) {
- return property;
- }
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
deleted file mode 100644
index 737b5e2..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-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.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Buildings")
-public class Building {
- @EdmKey
- @EdmProperty(type = EdmType.INT32)
- private String id;
- @EdmProperty
- private String name;
- @EdmProperty(name = "Image", type = EdmType.BINARY)
- private byte[] image;
- @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
- association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
- private List<Room> rooms = new ArrayList<Room>();
-
- public Building() {}
-
- public String getId() {
- return id;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setImage(final byte[] byteArray) {
- image = byteArray;
- }
-
- public byte[] getImage() {
- if (image == null) {
- return null;
- } else {
- return image.clone();
- }
- }
-
- public List<Room> getRooms() {
- return rooms;
- }
-
- @Override
- public int hashCode() {
- return id == null ? 0 : id.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
- }
-
- @Override
- public String toString() {
- return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
deleted file mode 100644
index 7b866a3..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-
-/**
- *
- */
-@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
-public class City {
-
- @EdmProperty
- private String postalCode;
- @EdmProperty
- private String cityName;
-
- public City(final String postalCode, final String name) {
- this.postalCode = postalCode;
- cityName = name;
- }
-
- public void setPostalCode(final String postalCode) {
- this.postalCode = postalCode;
- }
-
- public String getPostalCode() {
- return postalCode;
- }
-
- public void setCityName(final String cityName) {
- this.cityName = cityName;
- }
-
- public String getCityName() {
- return cityName;
- }
-
- @Override
- public String toString() {
- return String.format("%s, %s", cityName, postalCode);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
deleted file mode 100644
index 63b8a76..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-
-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.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Employees")
-public class Employee {
- @EdmKey
- @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
- private String employeeId;
- @EdmProperty(name = "EmployeeName")
- private String employeeName;
- @EdmProperty
- private int age;
- @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
- private Manager manager;
- @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
- private Team team;
- @EdmNavigationProperty(name = "ne_Room")
- private Room room;
- @EdmMediaResourceMimeType
- private String imageType;
- @EdmMediaResourceContent
- private byte[] image;
- @EdmProperty(name = "ImageUrl")
- private String imageUrl;
- @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME)
- private Calendar entryDate;
- @EdmProperty(name = "Location")
- private Location location;
-
- public Employee(final String employeeId, final String name) {
- this.employeeId = employeeId;
- setEmployeeName(name);
- }
-
- public String getId() {
- return employeeId;
- }
-
- public void setEmployeeName(final String employeeName) {
- this.employeeName = employeeName;
- }
-
- public String getEmployeeName() {
- return employeeName;
- }
-
- public void setAge(final int age) {
- this.age = age;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setManager(final Manager manager) {
- this.manager = manager;
- }
-
- public Manager getManager() {
- return manager;
- }
-
- public void setTeam(final Team team) {
- this.team = team;
- }
-
- public Team getTeam() {
- return team;
- }
-
- public void setRoom(final Room room) {
- this.room = room;
- }
-
- public Room getRoom() {
- return room;
- }
-
- public void setImageUri(final String imageUri) {
- imageUrl = imageUri;
- }
-
- public String getImageUri() {
- return imageUrl;
- }
-
- public void setLocation(final Location location) {
- this.location = location;
- }
-
- public Location getLocation() {
- return location;
- }
-
- public void setEntryDate(final Calendar date) {
- entryDate = date;
- }
-
- public Calendar getEntryDate() {
- return entryDate;
- }
-
- public void setImageType(final String imageType) {
- this.imageType = imageType;
- }
-
- public String getImageType() {
- return imageType;
- }
-
- public void setImage(final byte[] image) {
- this.image = image;
- }
-
- public byte[] getImage() {
- if (image == null) {
- return null;
- }
- return image.clone();
- }
-
- @Override
- public int hashCode() {
- if (employeeId == null) {
- return 0;
- }
- return employeeId.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj
- || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
- }
-
- @Override
- public String toString() {
- return "{\"EmployeeId\":\"" + employeeId + "\","
- + "\"EmployeeName\":\"" + employeeName + "\","
- + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
- + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
- + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
- + "\"Location\":"
- + (location == null ? "null" :
- "{\"City\":" + (location.getCity() == null ? "null" :
- "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
- + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
- + "\"Country\":\"" + location.getCountry() + "\"}") + ","
- + "\"Age\":" + age + ","
- + "\"EntryDate\":"
- + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
- + "\"ImageUrl\":\"" + imageUrl + "\"}";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
deleted file mode 100644
index 7f3f082..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-
-/**
- *
- */
-@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
-public class Location {
- @EdmProperty
- private String country;
- @EdmProperty
- private City city;
-
- public Location(final String country, final String postalCode, final String cityName) {
- this.country = country;
- city = new City(postalCode, cityName);
- }
-
- public void setCountry(final String country) {
- this.country = country;
- }
-
- public String getCountry() {
- return country;
- }
-
- public void setCity(final City city) {
- this.city = city;
- }
-
- public City getCity() {
- return city;
- }
-
- @Override
- public String toString() {
- return String.format("%s, %s", country, city.toString());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
deleted file mode 100644
index e3edbd0..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-
-/**
- *
- */
-@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Managers")
-public class Manager extends Employee {
-
- @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
- toMultiplicity = Multiplicity.MANY)
- private List<Employee> employees = new ArrayList<Employee>();
-
- public Manager(final String id, final String name) {
- super(id, name);
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
deleted file mode 100644
index 1d44498..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-public interface ModelSharedConstants {
-
- String NAMESPACE_1 = "RefScenario";
- String CONTAINER_1 = "DefaultContainer";
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
deleted file mode 100644
index 520216a..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.model;
-
-import java.util.Arrays;
-
-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.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Photos")
-public class Photo {
- @EdmProperty
- @EdmKey
- private String name;
- @EdmProperty(name = "ImageFormat")
- @EdmKey
- private String type;
- @EdmProperty
- @EdmMediaResourceMimeType
- private String mimeType;
- @EdmProperty
- @EdmMediaResourceSource
- private String imageUrl = "http://localhost/someResource.png";
- @EdmProperty(type = EdmType.BINARY)
- @EdmMediaResourceContent
- private byte[] image = ResourceHelper.generateImage();
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(final String type) {
- this.type = type;
- }
-
- public String getImageUri() {
- return imageUrl;
- }
-
- public void setImageUri(final String uri) {
- imageUrl = uri;
- }
-
- public byte[] getImage() {
- return image.clone();
- }
-
- public void setImage(final byte[] image) {
- this.image = image;
- }
-
- public String getImageType() {
- return mimeType;
- }
-
- public void setImageType(final String imageType) {
- this.mimeType = imageType;
- }
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
- hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final Photo other = (Photo) obj;
- if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
- return false;
- }
- if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "{\"Name\":\"" + name + "\","
- + "\"Type\":\"" + type + "\","
- + "\"ImageUrl\":\"" + imageUrl + "\","
- + "\"Image\":\"" + Arrays.toString(image) + "\","
- + "\"MimeType\":\"" + mimeType + "\"";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
deleted file mode 100644
index 6f3002f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.core.annotation.model;
-
-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.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
-public abstract class RefBase {
- @EdmProperty(name="Name")
- protected String name;
- @EdmProperty(name="Id", type = EdmType.STRING)
- @EdmKey
- protected int id;
-
- public RefBase(int id, String name) {
- this.name = name;
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public String getId() {
- return Integer.toString(id);
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-}
[10/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
new file mode 100644
index 0000000..19218d7
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
@@ -0,0 +1,1630 @@
+/*******************************************************************************
+ * 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.core.annotation.processor;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.batch.BatchHandler;
+import org.apache.olingo.odata2.api.batch.BatchRequestPart;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.InlineCount;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSourceProcessor;
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmTyped;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
+import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.UriParser;
+import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
+import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
+import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
+import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
+import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
+import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
+import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
+import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
+import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
+import org.apache.olingo.odata2.api.uri.expression.SortOrder;
+import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetComplexPropertyUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+
+/**
+ * Implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} for the
+ * actual data handling.
+ *
+ */
+public class ListsProcessor extends DataSourceProcessor {
+
+ // TODO: Paging size should be configurable.
+ private static final int SERVER_PAGING_SIZE = 100;
+
+ public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+ super(dataSource, valueAccess);
+ }
+
+ @Override
+ public ODataResponse readEntitySet(final GetEntitySetUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ ArrayList<Object> data = new ArrayList<Object>();
+ try {
+ data.addAll((List<?>) retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments()));
+ } catch (final ODataNotFoundException e) {
+ data.clear();
+ }
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+ final InlineCount inlineCountType = uriInfo.getInlineCount();
+ final Integer count = applySystemQueryOptions(
+ entitySet,
+ data,
+ uriInfo.getFilter(),
+ inlineCountType,
+ uriInfo.getOrderBy(),
+ uriInfo.getSkipToken(),
+ uriInfo.getSkip(),
+ uriInfo.getTop());
+
+ ODataContext context = getContext();
+ String nextLink = null;
+
+ // Limit the number of returned entities and provide a "next" link
+ // if there are further entities.
+ // Almost all system query options in the current request must be carried
+ // over to the URI for the "next" link, with the exception of $skiptoken
+ // and $skip.
+ if (data.size() > SERVER_PAGING_SIZE) {
+ if (uriInfo.getOrderBy() == null
+ && uriInfo.getSkipToken() == null
+ && uriInfo.getSkip() == null
+ && uriInfo.getTop() == null) {
+ sortInDefaultOrder(entitySet, data);
+ }
+
+ // TODO: Percent-encode "next" link.
+ nextLink = context.getPathInfo().getServiceRoot().relativize(context.getPathInfo().getRequestUri()).toString()
+ .replaceAll("\\$skiptoken=.+?&?", "")
+ .replaceAll("\\$skip=.+?&?", "")
+ .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions
+ // above.
+ nextLink += (nextLink.contains("?") ? "&" : "?")
+ + "$skiptoken=" + getSkipToken(entitySet, data.get(SERVER_PAGING_SIZE));
+
+ while (data.size() > SERVER_PAGING_SIZE) {
+ data.remove(SERVER_PAGING_SIZE);
+ }
+ }
+
+ final EdmEntityType entityType = entitySet.getEntityType();
+ List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+ for (final Object entryData : data) {
+ values.add(getStructuralTypeValueMap(entryData, entityType));
+ }
+
+ final EntityProviderWriteProperties feedProperties = EntityProviderWriteProperties
+ .serviceRoot(context.getPathInfo().getServiceRoot())
+ .inlineCountType(inlineCountType)
+ .inlineCount(count)
+ .expandSelectTree(UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand()))
+ .callbacks(getCallbacks(data, entityType))
+ .nextLink(nextLink)
+ .build();
+
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFeed");
+ final ODataResponse response = EntityProvider.writeFeed(contentType, entitySet, values, feedProperties);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return ODataResponse.fromResponse(response).build();
+ }
+
+ @Override
+ public ODataResponse countEntitySet(final GetEntitySetCountUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ ArrayList<Object> data = new ArrayList<Object>();
+ try {
+ data.addAll((List<?>) retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments()));
+ } catch (final ODataNotFoundException e) {
+ data.clear();
+ }
+
+ applySystemQueryOptions(
+ uriInfo.getTargetEntitySet(),
+ data,
+ uriInfo.getFilter(),
+ null,
+ null,
+ null,
+ uriInfo.getSkip(),
+ uriInfo.getTop());
+
+ return ODataResponse.fromResponse(EntityProvider.writeText(String.valueOf(data.size()))).build();
+ }
+
+ @Override
+ public ODataResponse readEntityLinks(final GetEntitySetLinksUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ ArrayList<Object> data = new ArrayList<Object>();
+ try {
+ data.addAll((List<?>) retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments()));
+ } catch (final ODataNotFoundException e) {
+ data.clear();
+ }
+
+ final Integer count = applySystemQueryOptions(
+ uriInfo.getTargetEntitySet(),
+ data,
+ uriInfo.getFilter(),
+ uriInfo.getInlineCount(),
+ null, // uriInfo.getOrderBy(),
+ uriInfo.getSkipToken(),
+ uriInfo.getSkip(),
+ uriInfo.getTop());
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+
+ List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+ for (final Object entryData : data) {
+ Map<String, Object> entryValues = new HashMap<String, Object>();
+ for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+ entryValues.put(property.getName(), valueAccess.getPropertyValue(entryData, property));
+ }
+ values.add(entryValues);
+ }
+
+ ODataContext context = getContext();
+ final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+ .serviceRoot(context.getPathInfo().getServiceRoot())
+ .inlineCountType(uriInfo.getInlineCount())
+ .inlineCount(count)
+ .build();
+
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLinks");
+
+ final ODataResponse response = EntityProvider.writeLinks(contentType, entitySet, values, entryProperties);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return ODataResponse.fromResponse(response).build();
+ }
+
+ @Override
+ public ODataResponse countEntityLinks(final GetEntitySetLinksCountUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ return countEntitySet((GetEntitySetCountUriInfo) uriInfo, contentType);
+ }
+
+ @Override
+ public ODataResponse readEntity(final GetEntityUriInfo uriInfo, final String contentType) throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final ExpandSelectTreeNode expandSelectTreeNode =
+ UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+ ODataResponse odr =
+ ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTreeNode, data, contentType))
+ .build();
+
+ return odr;
+ }
+
+ @Override
+ public ODataResponse existsEntity(final GetEntityCountUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ return ODataResponse.fromResponse(EntityProvider.writeText(appliesFilter(data, uriInfo.getFilter()) ? "1" : "0"))
+ .build();
+ }
+
+ @Override
+ public ODataResponse deleteEntity(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+ dataSource.deleteData(
+ uriInfo.getStartEntitySet(),
+ mapKey(uriInfo.getKeyPredicates()));
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse createEntity(final PostUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+ final EdmEntityType entityType = entitySet.getEntityType();
+
+ Object data = dataSource.newDataObject(entitySet);
+ ExpandSelectTreeNode expandSelectTree = null;
+
+ if (entityType.hasStream()) {
+ dataSource.createData(entitySet, data);
+ dataSource.writeBinaryData(entitySet, data,
+ new BinaryData(EntityProvider.readBinary(content), requestContentType));
+
+ } else {
+ final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
+ .mergeSemantic(false)
+ .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
+ .build();
+ final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
+
+ setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), false);
+
+ dataSource.createData(entitySet, data);
+
+ createInlinedEntities(entitySet, data, entryValues);
+
+ expandSelectTree = entryValues.getExpandSelectTree();
+ }
+
+ // Link back to the entity the target entity set is related to, if any.
+ final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+ if (!navigationSegments.isEmpty()) {
+ final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+ final Object sourceData = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ previousSegments);
+ final EdmEntitySet previousEntitySet = previousSegments.isEmpty() ?
+ uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+ dataSource.writeRelation(previousEntitySet, sourceData, entitySet, getStructuralTypeValueMap(data, entityType));
+ }
+
+ return ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTree, data, contentType))
+ .eTag(constructETag(entitySet, data)).build();
+ }
+
+ @Override
+ public ODataResponse updateEntity(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final boolean merge, final String contentType) throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+ final EdmEntityType entityType = entitySet.getEntityType();
+ final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
+ .mergeSemantic(merge)
+ .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
+ .build();
+ final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
+
+ setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), merge);
+
+ return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
+ }
+
+ @Override
+ public ODataResponse readEntityLink(final GetEntityLinkUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ // if (!appliesFilter(data, uriInfo.getFilter()))
+ if (data == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+
+ Map<String, Object> values = new HashMap<String, Object>();
+ for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+ values.put(property.getName(), valueAccess.getPropertyValue(data, property));
+ }
+
+ ODataContext context = getContext();
+ final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+ .serviceRoot(context.getPathInfo().getServiceRoot())
+ .build();
+
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLink");
+
+ final ODataResponse response = EntityProvider.writeLink(contentType, entitySet, values, entryProperties);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return ODataResponse.fromResponse(response).build();
+ }
+
+ @Override
+ public ODataResponse existsEntityLink(final GetEntityLinkCountUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ return existsEntity((GetEntityCountUriInfo) uriInfo, contentType);
+ }
+
+ @Override
+ public ODataResponse deleteEntityLink(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+ final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+ final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+ final Object sourceData = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ previousSegments);
+
+ final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+ uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+ final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+ final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
+
+ final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
+
+ // if (!appliesFilter(targetData, uriInfo.getFilter()))
+ if (targetData == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
+
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse createEntityLink(final PostUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+ final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+ final Object sourceData = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ previousSegments);
+
+ final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+ uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+ final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+
+ final Map<String, Object> targetKeys = parseLink(targetEntitySet, content, requestContentType);
+
+ dataSource.writeRelation(entitySet, sourceData, targetEntitySet, targetKeys);
+
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse updateEntityLink(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+ final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+ final Object sourceData = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ previousSegments);
+
+ final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+ uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+ final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+ final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
+
+ final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
+
+ if (!appliesFilter(targetData, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
+
+ final Map<String, Object> newKeys = parseLink(targetEntitySet, content, requestContentType);
+
+ dataSource.writeRelation(entitySet, sourceData, targetEntitySet, newKeys);
+
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse readEntityComplexProperty(final GetComplexPropertyUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ // if (!appliesFilter(data, uriInfo.getFilter()))
+ if (data == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+ final Object value = property.isSimple() ?
+ property.getMapping() == null || property.getMapping().getMimeType() == null ?
+ getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath) :
+ getStructuralTypeValueMap(getPropertyValue(data, propertyPath), (EdmStructuralType) property.getType());
+
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeProperty");
+
+ final ODataResponse response = EntityProvider.writeProperty(contentType, property, value);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return ODataResponse.fromResponse(response).eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+ }
+
+ @Override
+ public ODataResponse readEntitySimpleProperty(final GetSimplePropertyUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ return readEntityComplexProperty((GetComplexPropertyUriInfo) uriInfo, contentType);
+ }
+
+ @Override
+ public ODataResponse readEntitySimplePropertyValue(final GetSimplePropertyUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ // if (!appliesFilter(data, uriInfo.getFilter()))
+ if (data == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+ final Object value = property.getMapping() == null || property.getMapping().getMimeType() == null ?
+ getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath);
+
+ return ODataResponse.fromResponse(EntityProvider.writePropertyValue(property, value)).eTag(
+ constructETag(uriInfo.getTargetEntitySet(), data)).build();
+ }
+
+ @Override
+ public ODataResponse deleteEntitySimplePropertyValue(final DeleteUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (data == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+ data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+ valueAccess.setPropertyValue(data, property, null);
+ valueAccess.setMappingValue(data, property.getMapping(), null);
+
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse updateEntityComplexProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final boolean merge, final String contentType) throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+ data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+
+ ODataContext context = getContext();
+ int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readProperty");
+
+ Map<String, Object> values;
+ try {
+ values =
+ EntityProvider.readProperty(requestContentType, property, content, EntityProviderReadProperties.init()
+ .mergeSemantic(merge).build());
+ } catch (final EntityProviderException e) {
+ throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ final Object value = values.get(property.getName());
+ if (property.isSimple()) {
+ valueAccess.setPropertyValue(data, property, value);
+ } else {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> propertyValue = (Map<String, Object>) value;
+ setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
+ (EdmStructuralType) property.getType(), propertyValue, merge);
+ }
+
+ return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+ }
+
+ @Override
+ public ODataResponse updateEntitySimpleProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ return updateEntityComplexProperty(uriInfo, content, requestContentType, false, contentType);
+ }
+
+ @Override
+ public ODataResponse updateEntitySimplePropertyValue(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+ data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+
+ ODataContext context = getContext();
+ int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readPropertyValue");
+
+ Object value;
+ try {
+ value = EntityProvider.readPropertyValue(property, content);
+ } catch (final EntityProviderException e) {
+ throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ valueAccess.setPropertyValue(data, property, value);
+ valueAccess.setMappingValue(data, property.getMapping(), requestContentType);
+
+ return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+ }
+
+ @Override
+ public ODataResponse readEntityMedia(final GetMediaResourceUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+ final BinaryData binaryData = dataSource.readBinaryData(entitySet, data);
+ if (binaryData == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ final String mimeType = binaryData.getMimeType() == null ?
+ HttpContentType.APPLICATION_OCTET_STREAM : binaryData.getMimeType();
+
+ return ODataResponse.fromResponse(EntityProvider.writeBinary(mimeType, binaryData.getData())).eTag(
+ constructETag(entitySet, data)).build();
+ }
+
+ @Override
+ public ODataResponse deleteEntityMedia(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (data == null) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ dataSource.writeBinaryData(uriInfo.getTargetEntitySet(), data, new BinaryData(null, null));
+
+ return ODataResponse.newBuilder().build();
+ }
+
+ @Override
+ public ODataResponse updateEntityMedia(final PutMergePatchUriInfo uriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataException {
+ final Object data = retrieveData(
+ uriInfo.getStartEntitySet(),
+ uriInfo.getKeyPredicates(),
+ uriInfo.getFunctionImport(),
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ uriInfo.getNavigationSegments());
+
+ if (!appliesFilter(data, uriInfo.getFilter())) {
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readBinary");
+
+ final byte[] value = EntityProvider.readBinary(content);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+ dataSource.writeBinaryData(entitySet, data, new BinaryData(value, requestContentType));
+
+ return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
+ }
+
+ @Override
+ public ODataResponse executeFunctionImport(final GetFunctionImportUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
+ final EdmType type = functionImport.getReturnType().getType();
+
+ final Object data = dataSource.readData(
+ functionImport,
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ null);
+
+ if (data == null) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON);
+ }
+
+ Object value;
+ if (type.getKind() == EdmTypeKind.SIMPLE) {
+ value = type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance() ?
+ ((BinaryData) data).getData() : data;
+ } else if (functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY) {
+ List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+ for (final Object typeData : (List<?>) data) {
+ values.add(getStructuralTypeValueMap(typeData, (EdmStructuralType) type));
+ }
+ value = values;
+ } else {
+ value = getStructuralTypeValueMap(data, (EdmStructuralType) type);
+ }
+
+ ODataContext context = getContext();
+
+ final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+ .serviceRoot(context.getPathInfo().getServiceRoot()).build();
+
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFunctionImport");
+
+ final ODataResponse response =
+ EntityProvider.writeFunctionImport(contentType, functionImport, value, entryProperties);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return ODataResponse.fromResponse(response).build();
+ }
+
+ @Override
+ public ODataResponse executeFunctionImportValue(final GetFunctionImportUriInfo uriInfo, final String contentType)
+ throws ODataException {
+ final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
+ final EdmSimpleType type = (EdmSimpleType) functionImport.getReturnType().getType();
+
+ final Object data = dataSource.readData(
+ functionImport,
+ mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+ null);
+
+ if (data == null) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON);
+ }
+
+ ODataResponse response;
+ if (type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
+ response = EntityProvider.writeBinary(((BinaryData) data).getMimeType(), ((BinaryData) data).getData());
+ } else {
+ final String value = type.valueToString(data, EdmLiteralKind.DEFAULT, null);
+ response = EntityProvider.writeText(value == null ? "" : value);
+ }
+ return ODataResponse.fromResponse(response).build();
+ }
+
+ private static Map<String, Object> mapKey(final List<KeyPredicate> keys) throws EdmException {
+ Map<String, Object> keyMap = new HashMap<String, Object>();
+ for (final KeyPredicate key : keys) {
+ final EdmProperty property = key.getProperty();
+ final EdmSimpleType type = (EdmSimpleType) property.getType();
+ keyMap.put(property.getName(), type.valueOfString(key.getLiteral(), EdmLiteralKind.DEFAULT, property.getFacets(),
+ type.getDefaultType()));
+ }
+ return keyMap;
+ }
+
+ private static Map<String, Object> mapFunctionParameters(final Map<String, EdmLiteral> functionImportParameters)
+ throws EdmSimpleTypeException {
+ if (functionImportParameters == null) {
+ return Collections.emptyMap();
+ } else {
+ Map<String, Object> parameterMap = new HashMap<String, Object>();
+ for (final String parameterName : functionImportParameters.keySet()) {
+ final EdmLiteral literal = functionImportParameters.get(parameterName);
+ final EdmSimpleType type = literal.getType();
+ parameterMap.put(parameterName, type.valueOfString(literal.getLiteral(), EdmLiteralKind.DEFAULT, null, type
+ .getDefaultType()));
+ }
+ return parameterMap;
+ }
+ }
+
+ private Object retrieveData(final EdmEntitySet startEntitySet, final List<KeyPredicate> keyPredicates,
+ final EdmFunctionImport functionImport, final Map<String, Object> functionImportParameters,
+ final List<NavigationSegment> navigationSegments) throws ODataException {
+ Object data;
+ final Map<String, Object> keys = mapKey(keyPredicates);
+
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "retrieveData");
+
+ data = functionImport == null ?
+ keys.isEmpty() ?
+ dataSource.readData(startEntitySet) : dataSource.readData(startEntitySet, keys) :
+ dataSource.readData(functionImport, functionImportParameters, keys);
+
+ EdmEntitySet currentEntitySet =
+ functionImport == null ? startEntitySet : functionImport.getEntitySet();
+ for (NavigationSegment navigationSegment : navigationSegments) {
+ data = dataSource.readRelatedData(
+ currentEntitySet,
+ data,
+ navigationSegment.getEntitySet(),
+ mapKey(navigationSegment.getKeyPredicates()));
+ currentEntitySet = navigationSegment.getEntitySet();
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return data;
+ }
+
+ private <T> String constructETag(final EdmEntitySet entitySet, final T data) throws ODataException {
+ final EdmEntityType entityType = entitySet.getEntityType();
+ String eTag = null;
+ for (final String propertyName : entityType.getPropertyNames()) {
+ final EdmProperty property = (EdmProperty) entityType.getProperty(propertyName);
+ if (property.getFacets() != null && property.getFacets().getConcurrencyMode() == EdmConcurrencyMode.Fixed) {
+ final EdmSimpleType type = (EdmSimpleType) property.getType();
+ final String component = type.valueToString(valueAccess.getPropertyValue(data, property),
+ EdmLiteralKind.DEFAULT, property.getFacets());
+ eTag = eTag == null ? component : eTag + Edm.DELIMITER + component;
+ }
+ }
+ return eTag == null ? null : "W/\"" + eTag + "\"";
+ }
+
+ private <T> Map<String, ODataCallback> getCallbacks(final T data, final EdmEntityType entityType)
+ throws EdmException {
+ final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames();
+ if (navigationPropertyNames.isEmpty()) {
+ return null;
+ } else {
+ final WriteCallback callback = new WriteCallback(data);
+ Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+ for (final String name : navigationPropertyNames) {
+ callbacks.put(name, callback);
+ }
+ return callbacks;
+ }
+ }
+
+ private class WriteCallback implements OnWriteEntryContent, OnWriteFeedContent {
+ private final Object data;
+
+ private <T> WriteCallback(final T data) {
+ this.data = data;
+ }
+
+ @Override
+ public WriteFeedCallbackResult retrieveFeedResult(final WriteFeedCallbackContext context)
+ throws ODataApplicationException {
+ try {
+ final EdmEntityType entityType =
+ context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
+ List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+ Object relatedData = null;
+ try {
+ relatedData = readRelatedData(context);
+ for (final Object entryData : (List<?>) relatedData) {
+ values.add(getStructuralTypeValueMap(entryData, entityType));
+ }
+ } catch (final ODataNotFoundException e) {
+ values.clear();
+ }
+ WriteFeedCallbackResult result = new WriteFeedCallbackResult();
+ result.setFeedData(values);
+ EntityProviderWriteProperties inlineProperties =
+ EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
+ getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
+ .selfLink(context.getSelfLink()).build();
+ result.setInlineProperties(inlineProperties);
+ return result;
+ } catch (final ODataException e) {
+ throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
+ }
+ }
+
+ @Override
+ public WriteEntryCallbackResult retrieveEntryResult(final WriteEntryCallbackContext context)
+ throws ODataApplicationException {
+ try {
+ final EdmEntityType entityType =
+ context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
+ WriteEntryCallbackResult result = new WriteEntryCallbackResult();
+ Object relatedData;
+ try {
+ relatedData = readRelatedData(context);
+ } catch (final ODataNotFoundException e) {
+ relatedData = null;
+ }
+
+ if (relatedData == null) {
+ result.setEntryData(Collections.<String, Object> emptyMap());
+ } else {
+ result.setEntryData(getStructuralTypeValueMap(relatedData, entityType));
+
+ EntityProviderWriteProperties inlineProperties =
+ EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
+ getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
+ .build();
+ result.setInlineProperties(inlineProperties);
+ }
+ return result;
+ } catch (final ODataException e) {
+ throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
+ }
+ }
+
+ private Object readRelatedData(final WriteCallbackContext context) throws ODataException {
+ final EdmEntitySet entitySet = context.getSourceEntitySet();
+ return dataSource.readRelatedData(
+ entitySet,
+ data instanceof List ? readEntryData((List<?>) data, entitySet.getEntityType(), context
+ .extractKeyFromEntryData()) : data,
+ entitySet.getRelatedEntitySet(context.getNavigationProperty()),
+ Collections.<String, Object> emptyMap());
+ }
+
+ private <T> T readEntryData(final List<T> data, final EdmEntityType entityType, final Map<String, Object> key)
+ throws ODataException {
+ for (final T entryData : data) {
+ boolean found = true;
+ for (final EdmProperty keyProperty : entityType.getKeyProperties()) {
+ if (!valueAccess.getPropertyValue(entryData, keyProperty).equals(key.get(keyProperty.getName()))) {
+ found = false;
+ break;
+ }
+ }
+ if (found) {
+ return entryData;
+ }
+ }
+ return null;
+ }
+ }
+
+ private <T> ODataResponse writeEntry(final EdmEntitySet entitySet, final ExpandSelectTreeNode expandSelectTree,
+ final T data, final String contentType) throws ODataException, EntityProviderException {
+ final EdmEntityType entityType = entitySet.getEntityType();
+ final Map<String, Object> values = getStructuralTypeValueMap(data, entityType);
+
+ ODataContext context = getContext();
+ EntityProviderWriteProperties writeProperties = EntityProviderWriteProperties
+ .serviceRoot(context.getPathInfo().getServiceRoot())
+ .expandSelectTree(expandSelectTree)
+ .callbacks(getCallbacks(data, entityType))
+ .build();
+
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeEntry");
+
+ final ODataResponse response = EntityProvider.writeEntry(contentType, entitySet, values, writeProperties);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return response;
+ }
+
+ private ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content,
+ final String requestContentType, final EntityProviderReadProperties properties) throws ODataBadRequestException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readEntry");
+
+ ODataEntry entryValues;
+ try {
+ entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, properties);
+ } catch (final EntityProviderException e) {
+ throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return entryValues;
+ }
+
+ private Map<String, Object> parseLink(final EdmEntitySet entitySet, final InputStream content,
+ final String contentType) throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readLink");
+
+ final String uriString = EntityProvider.readLink(contentType, entitySet, content);
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ final Map<String, Object> targetKeys = parseLinkUri(entitySet, uriString);
+ if (targetKeys == null) {
+ throw new ODataBadRequestException(ODataBadRequestException.BODY);
+ }
+ return targetKeys;
+ }
+
+ private Map<String, Object> parseLinkUri(final EdmEntitySet targetEntitySet, final String uriString)
+ throws EdmException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement("UriParser", "getKeyPredicatesFromEntityLink");
+
+ List<KeyPredicate> key = null;
+ try {
+ key = UriParser.getKeyPredicatesFromEntityLink(targetEntitySet, uriString,
+ context.getPathInfo().getServiceRoot());
+ } catch (ODataException e) {
+ // We don't understand the link target. This could also be seen as an error.
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return key == null ? null : mapKey(key);
+ }
+
+ private <T> void createInlinedEntities(final EdmEntitySet entitySet, final T data, final ODataEntry entryValues)
+ throws ODataException {
+ final EdmEntityType entityType = entitySet.getEntityType();
+ for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
+
+ final EdmNavigationProperty navigationProperty =
+ (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
+ final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
+ final EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
+
+ final Object relatedValue = entryValues.getProperties().get(navigationPropertyName);
+ if (relatedValue == null) {
+ for (final String uriString : entryValues.getMetadata().getAssociationUris(navigationPropertyName)) {
+ final Map<String, Object> key = parseLinkUri(relatedEntitySet, uriString);
+ if (key != null) {
+ dataSource.writeRelation(entitySet, data, relatedEntitySet, key);
+ }
+ }
+
+ } else {
+ if (relatedValue instanceof ODataFeed) {
+ ODataFeed feed = (ODataFeed) relatedValue;
+ final List<ODataEntry> relatedValueList = feed.getEntries();
+ for (final ODataEntry relatedValues : relatedValueList) {
+ Object relatedData = dataSource.newDataObject(relatedEntitySet);
+ setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValues.getProperties(), false);
+ dataSource.createData(relatedEntitySet, relatedData);
+ dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
+ relatedEntityType));
+ createInlinedEntities(relatedEntitySet, relatedData, relatedValues);
+ }
+ } else if (relatedValue instanceof ODataEntry) {
+ final ODataEntry relatedValueEntry = (ODataEntry) relatedValue;
+ Object relatedData = dataSource.newDataObject(relatedEntitySet);
+ setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValueEntry.getProperties(), false);
+ dataSource.createData(relatedEntitySet, relatedData);
+ dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
+ relatedEntityType));
+ createInlinedEntities(relatedEntitySet, relatedData, relatedValueEntry);
+ } else {
+ throw new ODataException("Unexpected class for a related value: " + relatedValue.getClass().getSimpleName());
+ }
+
+ }
+ }
+ }
+
+ private <T> Integer applySystemQueryOptions(final EdmEntitySet entitySet, final List<T> data,
+ final FilterExpression filter, final InlineCount inlineCount, final OrderByExpression orderBy,
+ final String skipToken, final Integer skip, final Integer top) throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "applySystemQueryOptions");
+
+ if (filter != null) {
+ // Remove all elements the filter does not apply for.
+ // A for-each loop would not work with "remove", see Java documentation.
+ for (Iterator<T> iterator = data.iterator(); iterator.hasNext();) {
+ if (!appliesFilter(iterator.next(), filter)) {
+ iterator.remove();
+ }
+ }
+ }
+
+ final Integer count = inlineCount == InlineCount.ALLPAGES ? data.size() : null;
+
+ if (orderBy != null) {
+ sort(data, orderBy);
+ } else if (skipToken != null || skip != null || top != null) {
+ sortInDefaultOrder(entitySet, data);
+ }
+
+ if (skipToken != null) {
+ while (!data.isEmpty() && !getSkipToken(entitySet, data.get(0)).equals(skipToken)) {
+ data.remove(0);
+ }
+ }
+
+ if (skip != null) {
+ if (skip >= data.size()) {
+ data.clear();
+ } else {
+ for (int i = 0; i < skip; i++) {
+ data.remove(0);
+ }
+ }
+ }
+
+ if (top != null) {
+ while (data.size() > top) {
+ data.remove(top.intValue());
+ }
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return count;
+ }
+
+ private <T> void sort(final List<T> data, final OrderByExpression orderBy) {
+ Collections.sort(data, new Comparator<T>() {
+ @Override
+ public int compare(final T entity1, final T entity2) {
+ try {
+ int result = 0;
+ for (final OrderExpression expression : orderBy.getOrders()) {
+ result = evaluateExpression(entity1, expression.getExpression()).compareTo(
+ evaluateExpression(entity2, expression.getExpression()));
+ if (expression.getSortOrder() == SortOrder.desc) {
+ result = -result;
+ }
+ if (result != 0) {
+ break;
+ }
+ }
+ return result;
+ } catch (final ODataException e) {
+ return 0;
+ }
+ }
+ });
+ }
+
+ private <T> void sortInDefaultOrder(final EdmEntitySet entitySet, final List<T> data) {
+ Collections.sort(data, new Comparator<T>() {
+ @Override
+ public int compare(final T entity1, final T entity2) {
+ try {
+ return getSkipToken(entitySet, entity1).compareTo(getSkipToken(entitySet, entity2));
+ } catch (final ODataException e) {
+ return 0;
+ }
+ }
+ });
+ }
+
+ private <T> boolean appliesFilter(final T data, final FilterExpression filter) throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "appliesFilter");
+
+ try {
+ return data != null && (filter == null || evaluateExpression(data, filter.getExpression()).equals("true"));
+ } catch (final RuntimeException e) {
+ return false;
+ } finally {
+ context.stopRuntimeMeasurement(timingHandle);
+ }
+ }
+
+ private <T> String evaluateExpression(final T data, final CommonExpression expression) throws ODataException {
+ switch (expression.getKind()) {
+ case UNARY:
+ final UnaryExpression unaryExpression = (UnaryExpression) expression;
+ final String operand = evaluateExpression(data, unaryExpression.getOperand());
+
+ switch (unaryExpression.getOperator()) {
+ case NOT:
+ return Boolean.toString(!Boolean.parseBoolean(operand));
+ case MINUS:
+ return operand.startsWith("-") ? operand.substring(1) : "-" + operand;
+ default:
+ throw new ODataNotImplementedException();
+ }
+
+ case BINARY:
+ final BinaryExpression binaryExpression = (BinaryExpression) expression;
+ final EdmSimpleType type = (EdmSimpleType) binaryExpression.getLeftOperand().getEdmType();
+ final String left = evaluateExpression(data, binaryExpression.getLeftOperand());
+ final String right = evaluateExpression(data, binaryExpression.getRightOperand());
+
+ switch (binaryExpression.getOperator()) {
+ case ADD:
+ if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+ return Double.toString(Double.valueOf(left) + Double.valueOf(right));
+ } else {
+ return Long.toString(Long.valueOf(left) + Long.valueOf(right));
+ }
+ case SUB:
+ if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+ return Double.toString(Double.valueOf(left) - Double.valueOf(right));
+ } else {
+ return Long.toString(Long.valueOf(left) - Long.valueOf(right));
+ }
+ case MUL:
+ if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+ return Double.toString(Double.valueOf(left) * Double.valueOf(right));
+ } else {
+ return Long.toString(Long.valueOf(left) * Long.valueOf(right));
+ }
+ case DIV:
+ final String number = Double.toString(Double.valueOf(left) / Double.valueOf(right));
+ return number.endsWith(".0") ? number.replace(".0", "") : number;
+ case MODULO:
+ if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+ || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+ return Double.toString(Double.valueOf(left) % Double.valueOf(right));
+ } else {
+ return Long.toString(Long.valueOf(left) % Long.valueOf(right));
+ }
+ case AND:
+ return Boolean.toString(left.equals("true") && right.equals("true"));
+ case OR:
+ return Boolean.toString(left.equals("true") || right.equals("true"));
+ case EQ:
+ return Boolean.toString(left.equals(right));
+ case NE:
+ return Boolean.toString(!left.equals(right));
+ case LT:
+ if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+ return Boolean.toString(left.compareTo(right) < 0);
+ } else {
+ return Boolean.toString(Double.valueOf(left) < Double.valueOf(right));
+ }
+ case LE:
+ if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+ return Boolean.toString(left.compareTo(right) <= 0);
+ } else {
+ return Boolean.toString(Double.valueOf(left) <= Double.valueOf(right));
+ }
+ case GT:
+ if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+ return Boolean.toString(left.compareTo(right) > 0);
+ } else {
+ return Boolean.toString(Double.valueOf(left) > Double.valueOf(right));
+ }
+ case GE:
+ if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+ || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+ return Boolean.toString(left.compareTo(right) >= 0);
+ } else {
+ return Boolean.toString(Double.valueOf(left) >= Double.valueOf(right));
+ }
+ case PROPERTY_ACCESS:
+ throw new ODataNotImplementedException();
+ default:
+ throw new ODataNotImplementedException();
+ }
+
+ case PROPERTY:
+ final EdmProperty property = (EdmProperty) ((PropertyExpression) expression).getEdmProperty();
+ final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
+ return propertyType.valueToString(valueAccess.getPropertyValue(data, property), EdmLiteralKind.DEFAULT,
+ property.getFacets());
+
+ case MEMBER:
+ final MemberExpression memberExpression = (MemberExpression) expression;
+ final PropertyExpression propertyExpression = (PropertyExpression) memberExpression.getProperty();
+ final EdmProperty memberProperty = (EdmProperty) propertyExpression.getEdmProperty();
+ final EdmSimpleType memberType = (EdmSimpleType) memberExpression.getEdmType();
+ List<EdmProperty> propertyPath = new ArrayList<EdmProperty>();
+ CommonExpression currentExpression = memberExpression;
+ while (currentExpression != null) {
+ final PropertyExpression currentPropertyExpression =
+ (PropertyExpression) (currentExpression.getKind() == ExpressionKind.MEMBER ?
+ ((MemberExpression) currentExpression).getProperty() : currentExpression);
+ final EdmTyped currentProperty = currentPropertyExpression.getEdmProperty();
+ final EdmTypeKind kind = currentProperty.getType().getKind();
+ if (kind == EdmTypeKind.SIMPLE || kind == EdmTypeKind.COMPLEX) {
+ propertyPath.add(0, (EdmProperty) currentProperty);
+ } else {
+ throw new ODataNotImplementedException();
+ }
+ currentExpression =
+ currentExpression.getKind() == ExpressionKind.MEMBER ? ((MemberExpression) currentExpression).getPath()
+ : null;
+ }
+ return memberType.valueToString(getPropertyValue(data, propertyPath), EdmLiteralKind.DEFAULT, memberProperty
+ .getFacets());
+
+ case LITERAL:
+ final LiteralExpression literal = (LiteralExpression) expression;
+ final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
+ return literalType.valueToString(literalType.valueOfString(literal.getUriLiteral(), EdmLiteralKind.URI, null,
+ literalType.getDefaultType()),
+ EdmLiteralKind.DEFAULT, null);
+
+ case METHOD:
+ final MethodExpression methodExpression = (MethodExpression) expression;
+ final String first = evaluateExpression(data, methodExpression.getParameters().get(0));
+ final String second = methodExpression.getParameterCount() > 1 ?
+ evaluateExpression(data, methodExpression.getParameters().get(1)) : null;
+ final String third = methodExpression.getParameterCount() > 2 ?
+ evaluateExpression(data, methodExpression.getParameters().get(2)) : null;
+
+ switch (methodExpression.getMethod()) {
+ case ENDSWITH:
+ return Boolean.toString(first.endsWith(second));
+ case INDEXOF:
+ return Integer.toString(first.indexOf(second));
+ case STARTSWITH:
+ return Boolean.toString(first.startsWith(second));
+ case TOLOWER:
+ return first.toLowerCase(Locale.ROOT);
+ case TOUPPER:
+ return first.toUpperCase(Locale.ROOT);
+ case TRIM:
+ return first.trim();
+ case SUBSTRING:
+ final int offset = Integer.parseInt(second);
+ return first.substring(offset, offset + Integer.parseInt(third));
+ case SUBSTRINGOF:
+ return Boolean.toString(second.contains(first));
+ case CONCAT:
+ return first + second;
+ case LENGTH:
+ return Integer.toString(first.length());
+ case YEAR:
+ return String.valueOf(Integer.parseInt(first.substring(0, 4)));
+ case MONTH:
+ return String.valueOf(Integer.parseInt(first.substring(5, 7)));
+ case DAY:
+ return String.valueOf(Integer.parseInt(first.substring(8, 10)));
+ case HOUR:
+ return String.valueOf(Integer.parseInt(first.substring(11, 13)));
+ case MINUTE:
+ return String.valueOf(Integer.parseInt(first.substring(14, 16)));
+ case SECOND:
+ return String.valueOf(Integer.parseInt(first.substring(17, 19)));
+ case ROUND:
+ return Long.toString(Math.round(Double.valueOf(first)));
+ case FLOOR:
+ return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
+ case CEILING:
+ return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
+ default:
+ throw new ODataNotImplementedException();
+ }
+
+ default:
+ throw new ODataNotImplementedException();
+ }
+ }
+
+ private <T> String getSkipToken(final EdmEntitySet entitySet, final T data) throws ODataException {
+ String skipToken = "";
+ for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+ final EdmSimpleType type = (EdmSimpleType) property.getType();
+ skipToken = skipToken.concat(type.valueToString(valueAccess.getPropertyValue(data, property),
+ EdmLiteralKind.DEFAULT, property.getFacets()));
+ }
+ return skipToken;
+ }
+
+ private <T> Object getPropertyValue(final T data, final List<EdmProperty> propertyPath) throws ODataException {
+ Object dataObject = data;
+ for (final EdmProperty property : propertyPath) {
+ if (dataObject != null) {
+ dataObject = valueAccess.getPropertyValue(dataObject, property);
+ }
+ }
+ return dataObject;
+ }
+
+ private void handleMimeType(Object data, EdmMapping mapping, Map<String, Object> valueMap)
+ throws ODataException {
+ final String mimeTypeName = mapping.getMimeType();
+ if (mimeTypeName != null) {
+ Object value = valueAccess.getMappingValue(data, mapping);
+ valueMap.put(mimeTypeName, value);
+ if (mapping.getMediaResourceMimeTypeKey() != null) {
+ valueMap.put(mapping.getMediaResourceMimeTypeKey(), value);
+ }
+ }
+ }
+
+ private <T> Map<String, Object> getSimpleTypeValueMap(final T data, final List<EdmProperty> propertyPath)
+ throws ODataException {
+ final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+ Map<String, Object> valueWithMimeType = new HashMap<String, Object>();
+ valueWithMimeType.put(property.getName(), getPropertyValue(data, propertyPath));
+
+ handleMimeType(data, property.getMapping(), valueWithMimeType);
+
+ return valueWithMimeType;
+ }
+
+ private <T> Map<String, Object> getStructuralTypeValueMap(final T data, final EdmStructuralType type)
+ throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeValueMap");
+
+ Map<String, Object> valueMap = new HashMap<String, Object>();
+
+ EdmMapping mapping = type.getMapping();
+ if (mapping != null) {
+ handleMimeType(data, mapping, valueMap);
+ }
+
+ for (final String propertyName : type.getPropertyNames()) {
+ final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+ final Object value = valueAccess.getPropertyValue(data, property);
+
+ if (property.isSimple()) {
+ if (property.getMapping() == null || property.getMapping().getMimeType() == null) {
+ valueMap.put(propertyName, value);
+ } else {
+ // TODO: enable MIME type mapping outside the current subtree
+ valueMap.put(propertyName, getSimpleTypeValueMap(data, Arrays.asList(property)));
+ }
+ } else {
+ valueMap.put(propertyName, getStructuralTypeValueMap(value, (EdmStructuralType) property.getType()));
+ }
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return valueMap;
+ }
+
+ private <T> Map<String, Object> getStructuralTypeTypeMap(final T data, final EdmStructuralType type)
+ throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeTypeMap");
+
+ Map<String, Object> typeMap = new HashMap<String, Object>();
+ for (final String propertyName : type.getPropertyNames()) {
+ final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+ if (property.isSimple()) {
+ typeMap.put(propertyName, valueAccess.getPropertyType(data, property));
+ } else {
+ typeMap.put(propertyName, getStructuralTypeTypeMap(valueAccess.getPropertyValue(data, property),
+ (EdmStructuralType) property.getType()));
+ }
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+
+ return typeMap;
+ }
+
+ private <T> void setStructuralTypeValuesFromMap(final T data, final EdmStructuralType type,
+ final Map<String, Object> valueMap, final boolean merge) throws ODataException {
+ ODataContext context = getContext();
+ final int timingHandle =
+ context.startRuntimeMeasurement(getClass().getSimpleName(), "setStructuralTypeValuesFromMap");
+
+ for (final String propertyName : type.getPropertyNames()) {
+ final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+ if (type instanceof EdmEntityType && ((EdmEntityType) type).getKeyProperties().contains(property)) {
+ Object v = valueAccess.getPropertyValue(data, property);
+ if(v != null) {
+ continue;
+ }
+ }
+
+ if (!merge || valueMap != null && valueMap.containsKey(propertyName)) {
+ final Object value = valueMap == null ? null : valueMap.get(propertyName);
+ if (property.isSimple()) {
+ valueAccess.setPropertyValue(data, property, value);
+ } else {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> values = (Map<String, Object>) value;
+ setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
+ (EdmStructuralType) property.getType(), values, merge);
+ }
+ }
+ }
+
+ context.stopRuntimeMeasurement(timingHandle);
+ }
+
+ @Override
+ public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content)
+ throws ODataException {
+ ODataResponse batchResponse;
+ List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>();
+ PathInfo pathInfo = getContext().getPathInfo();
+ EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
+ List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties);
+ for (BatchRequestPart batchPart : batchParts) {
+ batchResponseParts.add(handler.handleBatchPart(batchPart));
+ }
+ batchResponse = EntityProvider.writeBatchResponse(batchResponseParts);
+ return batchResponse;
+ }
+
+ @Override
+ public BatchResponsePart executeChangeSet(final BatchHandler handler, final List<ODataRequest> requests)
+ throws ODataException {
+ List<ODataResponse> responses = new ArrayList<ODataResponse>();
+ for (ODataRequest request : requests) {
+ ODataResponse response = handler.handleRequest(request);
+ if (response.getStatus().getStatusCode() >= HttpStatusCodes.BAD_REQUEST.getStatusCode()) {
+ // Rollback
+ List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1);
+ errorResponses.add(response);
+ return BatchResponsePart.responses(errorResponses).changeSet(false).build();
+ }
+ responses.add(response);
+ }
+ return BatchResponsePart.responses(responses).changeSet(true).build();
+ }
+}
[06/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
deleted file mode 100644
index 19218d7..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
+++ /dev/null
@@ -1,1630 +0,0 @@
-/*******************************************************************************
- * 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.core.annotation.processor;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.ODataCallback;
-import org.apache.olingo.odata2.api.batch.BatchHandler;
-import org.apache.olingo.odata2.api.batch.BatchRequestPart;
-import org.apache.olingo.odata2.api.batch.BatchResponsePart;
-import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.commons.InlineCount;
-import org.apache.olingo.odata2.api.data.DataSource;
-import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
-import org.apache.olingo.odata2.api.data.DataSourceProcessor;
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.Edm;
-import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.edm.EdmLiteral;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleType;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.edm.EdmStructuralType;
-import org.apache.olingo.odata2.api.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmTypeKind;
-import org.apache.olingo.odata2.api.edm.EdmTyped;
-import org.apache.olingo.odata2.api.ep.EntityProvider;
-import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
-import org.apache.olingo.odata2.api.ep.EntityProviderException;
-import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
-import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
-import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
-import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
-import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
-import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
-import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
-import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataRequest;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.api.uri.NavigationSegment;
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.apache.olingo.odata2.api.uri.UriParser;
-import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
-import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
-import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
-import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
-import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
-import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
-import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
-import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
-import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
-import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
-import org.apache.olingo.odata2.api.uri.expression.SortOrder;
-import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
-import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetComplexPropertyUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityLinkCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-
-/**
- * Implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link DataSource} for the
- * actual data handling.
- *
- */
-public class ListsProcessor extends DataSourceProcessor {
-
- // TODO: Paging size should be configurable.
- private static final int SERVER_PAGING_SIZE = 100;
-
- public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
- super(dataSource, valueAccess);
- }
-
- @Override
- public ODataResponse readEntitySet(final GetEntitySetUriInfo uriInfo, final String contentType)
- throws ODataException {
- ArrayList<Object> data = new ArrayList<Object>();
- try {
- data.addAll((List<?>) retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments()));
- } catch (final ODataNotFoundException e) {
- data.clear();
- }
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
- final InlineCount inlineCountType = uriInfo.getInlineCount();
- final Integer count = applySystemQueryOptions(
- entitySet,
- data,
- uriInfo.getFilter(),
- inlineCountType,
- uriInfo.getOrderBy(),
- uriInfo.getSkipToken(),
- uriInfo.getSkip(),
- uriInfo.getTop());
-
- ODataContext context = getContext();
- String nextLink = null;
-
- // Limit the number of returned entities and provide a "next" link
- // if there are further entities.
- // Almost all system query options in the current request must be carried
- // over to the URI for the "next" link, with the exception of $skiptoken
- // and $skip.
- if (data.size() > SERVER_PAGING_SIZE) {
- if (uriInfo.getOrderBy() == null
- && uriInfo.getSkipToken() == null
- && uriInfo.getSkip() == null
- && uriInfo.getTop() == null) {
- sortInDefaultOrder(entitySet, data);
- }
-
- // TODO: Percent-encode "next" link.
- nextLink = context.getPathInfo().getServiceRoot().relativize(context.getPathInfo().getRequestUri()).toString()
- .replaceAll("\\$skiptoken=.+?&?", "")
- .replaceAll("\\$skip=.+?&?", "")
- .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions
- // above.
- nextLink += (nextLink.contains("?") ? "&" : "?")
- + "$skiptoken=" + getSkipToken(entitySet, data.get(SERVER_PAGING_SIZE));
-
- while (data.size() > SERVER_PAGING_SIZE) {
- data.remove(SERVER_PAGING_SIZE);
- }
- }
-
- final EdmEntityType entityType = entitySet.getEntityType();
- List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
- for (final Object entryData : data) {
- values.add(getStructuralTypeValueMap(entryData, entityType));
- }
-
- final EntityProviderWriteProperties feedProperties = EntityProviderWriteProperties
- .serviceRoot(context.getPathInfo().getServiceRoot())
- .inlineCountType(inlineCountType)
- .inlineCount(count)
- .expandSelectTree(UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand()))
- .callbacks(getCallbacks(data, entityType))
- .nextLink(nextLink)
- .build();
-
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFeed");
- final ODataResponse response = EntityProvider.writeFeed(contentType, entitySet, values, feedProperties);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return ODataResponse.fromResponse(response).build();
- }
-
- @Override
- public ODataResponse countEntitySet(final GetEntitySetCountUriInfo uriInfo, final String contentType)
- throws ODataException {
- ArrayList<Object> data = new ArrayList<Object>();
- try {
- data.addAll((List<?>) retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments()));
- } catch (final ODataNotFoundException e) {
- data.clear();
- }
-
- applySystemQueryOptions(
- uriInfo.getTargetEntitySet(),
- data,
- uriInfo.getFilter(),
- null,
- null,
- null,
- uriInfo.getSkip(),
- uriInfo.getTop());
-
- return ODataResponse.fromResponse(EntityProvider.writeText(String.valueOf(data.size()))).build();
- }
-
- @Override
- public ODataResponse readEntityLinks(final GetEntitySetLinksUriInfo uriInfo, final String contentType)
- throws ODataException {
- ArrayList<Object> data = new ArrayList<Object>();
- try {
- data.addAll((List<?>) retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments()));
- } catch (final ODataNotFoundException e) {
- data.clear();
- }
-
- final Integer count = applySystemQueryOptions(
- uriInfo.getTargetEntitySet(),
- data,
- uriInfo.getFilter(),
- uriInfo.getInlineCount(),
- null, // uriInfo.getOrderBy(),
- uriInfo.getSkipToken(),
- uriInfo.getSkip(),
- uriInfo.getTop());
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-
- List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
- for (final Object entryData : data) {
- Map<String, Object> entryValues = new HashMap<String, Object>();
- for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
- entryValues.put(property.getName(), valueAccess.getPropertyValue(entryData, property));
- }
- values.add(entryValues);
- }
-
- ODataContext context = getContext();
- final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
- .serviceRoot(context.getPathInfo().getServiceRoot())
- .inlineCountType(uriInfo.getInlineCount())
- .inlineCount(count)
- .build();
-
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLinks");
-
- final ODataResponse response = EntityProvider.writeLinks(contentType, entitySet, values, entryProperties);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return ODataResponse.fromResponse(response).build();
- }
-
- @Override
- public ODataResponse countEntityLinks(final GetEntitySetLinksCountUriInfo uriInfo, final String contentType)
- throws ODataException {
- return countEntitySet((GetEntitySetCountUriInfo) uriInfo, contentType);
- }
-
- @Override
- public ODataResponse readEntity(final GetEntityUriInfo uriInfo, final String contentType) throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final ExpandSelectTreeNode expandSelectTreeNode =
- UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
- ODataResponse odr =
- ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTreeNode, data, contentType))
- .build();
-
- return odr;
- }
-
- @Override
- public ODataResponse existsEntity(final GetEntityCountUriInfo uriInfo, final String contentType)
- throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- return ODataResponse.fromResponse(EntityProvider.writeText(appliesFilter(data, uriInfo.getFilter()) ? "1" : "0"))
- .build();
- }
-
- @Override
- public ODataResponse deleteEntity(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
- dataSource.deleteData(
- uriInfo.getStartEntitySet(),
- mapKey(uriInfo.getKeyPredicates()));
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse createEntity(final PostUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
- final EdmEntityType entityType = entitySet.getEntityType();
-
- Object data = dataSource.newDataObject(entitySet);
- ExpandSelectTreeNode expandSelectTree = null;
-
- if (entityType.hasStream()) {
- dataSource.createData(entitySet, data);
- dataSource.writeBinaryData(entitySet, data,
- new BinaryData(EntityProvider.readBinary(content), requestContentType));
-
- } else {
- final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
- .mergeSemantic(false)
- .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
- .build();
- final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
-
- setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), false);
-
- dataSource.createData(entitySet, data);
-
- createInlinedEntities(entitySet, data, entryValues);
-
- expandSelectTree = entryValues.getExpandSelectTree();
- }
-
- // Link back to the entity the target entity set is related to, if any.
- final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
- if (!navigationSegments.isEmpty()) {
- final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
- final Object sourceData = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- previousSegments);
- final EdmEntitySet previousEntitySet = previousSegments.isEmpty() ?
- uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
- dataSource.writeRelation(previousEntitySet, sourceData, entitySet, getStructuralTypeValueMap(data, entityType));
- }
-
- return ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTree, data, contentType))
- .eTag(constructETag(entitySet, data)).build();
- }
-
- @Override
- public ODataResponse updateEntity(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final boolean merge, final String contentType) throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
- final EdmEntityType entityType = entitySet.getEntityType();
- final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
- .mergeSemantic(merge)
- .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
- .build();
- final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
-
- setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), merge);
-
- return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
- }
-
- @Override
- public ODataResponse readEntityLink(final GetEntityLinkUriInfo uriInfo, final String contentType)
- throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- // if (!appliesFilter(data, uriInfo.getFilter()))
- if (data == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-
- Map<String, Object> values = new HashMap<String, Object>();
- for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
- values.put(property.getName(), valueAccess.getPropertyValue(data, property));
- }
-
- ODataContext context = getContext();
- final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
- .serviceRoot(context.getPathInfo().getServiceRoot())
- .build();
-
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLink");
-
- final ODataResponse response = EntityProvider.writeLink(contentType, entitySet, values, entryProperties);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return ODataResponse.fromResponse(response).build();
- }
-
- @Override
- public ODataResponse existsEntityLink(final GetEntityLinkCountUriInfo uriInfo, final String contentType)
- throws ODataException {
- return existsEntity((GetEntityCountUriInfo) uriInfo, contentType);
- }
-
- @Override
- public ODataResponse deleteEntityLink(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
- final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
- final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
- final Object sourceData = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- previousSegments);
-
- final EdmEntitySet entitySet = previousSegments.isEmpty() ?
- uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
- final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
- final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
-
- final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
-
- // if (!appliesFilter(targetData, uriInfo.getFilter()))
- if (targetData == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
-
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse createEntityLink(final PostUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
- final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
- final Object sourceData = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- previousSegments);
-
- final EdmEntitySet entitySet = previousSegments.isEmpty() ?
- uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
- final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
-
- final Map<String, Object> targetKeys = parseLink(targetEntitySet, content, requestContentType);
-
- dataSource.writeRelation(entitySet, sourceData, targetEntitySet, targetKeys);
-
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse updateEntityLink(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
- final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
- final Object sourceData = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- previousSegments);
-
- final EdmEntitySet entitySet = previousSegments.isEmpty() ?
- uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
- final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
- final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
-
- final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
-
- if (!appliesFilter(targetData, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
-
- final Map<String, Object> newKeys = parseLink(targetEntitySet, content, requestContentType);
-
- dataSource.writeRelation(entitySet, sourceData, targetEntitySet, newKeys);
-
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse readEntityComplexProperty(final GetComplexPropertyUriInfo uriInfo, final String contentType)
- throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- // if (!appliesFilter(data, uriInfo.getFilter()))
- if (data == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
- final Object value = property.isSimple() ?
- property.getMapping() == null || property.getMapping().getMimeType() == null ?
- getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath) :
- getStructuralTypeValueMap(getPropertyValue(data, propertyPath), (EdmStructuralType) property.getType());
-
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeProperty");
-
- final ODataResponse response = EntityProvider.writeProperty(contentType, property, value);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return ODataResponse.fromResponse(response).eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
- }
-
- @Override
- public ODataResponse readEntitySimpleProperty(final GetSimplePropertyUriInfo uriInfo, final String contentType)
- throws ODataException {
- return readEntityComplexProperty((GetComplexPropertyUriInfo) uriInfo, contentType);
- }
-
- @Override
- public ODataResponse readEntitySimplePropertyValue(final GetSimplePropertyUriInfo uriInfo, final String contentType)
- throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- // if (!appliesFilter(data, uriInfo.getFilter()))
- if (data == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
- final Object value = property.getMapping() == null || property.getMapping().getMimeType() == null ?
- getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath);
-
- return ODataResponse.fromResponse(EntityProvider.writePropertyValue(property, value)).eTag(
- constructETag(uriInfo.getTargetEntitySet(), data)).build();
- }
-
- @Override
- public ODataResponse deleteEntitySimplePropertyValue(final DeleteUriInfo uriInfo, final String contentType)
- throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (data == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
- data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
- valueAccess.setPropertyValue(data, property, null);
- valueAccess.setMappingValue(data, property.getMapping(), null);
-
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse updateEntityComplexProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final boolean merge, final String contentType) throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
- data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
-
- ODataContext context = getContext();
- int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readProperty");
-
- Map<String, Object> values;
- try {
- values =
- EntityProvider.readProperty(requestContentType, property, content, EntityProviderReadProperties.init()
- .mergeSemantic(merge).build());
- } catch (final EntityProviderException e) {
- throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- final Object value = values.get(property.getName());
- if (property.isSimple()) {
- valueAccess.setPropertyValue(data, property, value);
- } else {
- @SuppressWarnings("unchecked")
- final Map<String, Object> propertyValue = (Map<String, Object>) value;
- setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
- (EdmStructuralType) property.getType(), propertyValue, merge);
- }
-
- return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
- }
-
- @Override
- public ODataResponse updateEntitySimpleProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- return updateEntityComplexProperty(uriInfo, content, requestContentType, false, contentType);
- }
-
- @Override
- public ODataResponse updateEntitySimplePropertyValue(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
- data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
-
- ODataContext context = getContext();
- int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readPropertyValue");
-
- Object value;
- try {
- value = EntityProvider.readPropertyValue(property, content);
- } catch (final EntityProviderException e) {
- throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- valueAccess.setPropertyValue(data, property, value);
- valueAccess.setMappingValue(data, property.getMapping(), requestContentType);
-
- return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
- }
-
- @Override
- public ODataResponse readEntityMedia(final GetMediaResourceUriInfo uriInfo, final String contentType)
- throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
- final BinaryData binaryData = dataSource.readBinaryData(entitySet, data);
- if (binaryData == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- final String mimeType = binaryData.getMimeType() == null ?
- HttpContentType.APPLICATION_OCTET_STREAM : binaryData.getMimeType();
-
- return ODataResponse.fromResponse(EntityProvider.writeBinary(mimeType, binaryData.getData())).eTag(
- constructETag(entitySet, data)).build();
- }
-
- @Override
- public ODataResponse deleteEntityMedia(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (data == null) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- dataSource.writeBinaryData(uriInfo.getTargetEntitySet(), data, new BinaryData(null, null));
-
- return ODataResponse.newBuilder().build();
- }
-
- @Override
- public ODataResponse updateEntityMedia(final PutMergePatchUriInfo uriInfo, final InputStream content,
- final String requestContentType, final String contentType) throws ODataException {
- final Object data = retrieveData(
- uriInfo.getStartEntitySet(),
- uriInfo.getKeyPredicates(),
- uriInfo.getFunctionImport(),
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- uriInfo.getNavigationSegments());
-
- if (!appliesFilter(data, uriInfo.getFilter())) {
- throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
- }
-
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readBinary");
-
- final byte[] value = EntityProvider.readBinary(content);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
- dataSource.writeBinaryData(entitySet, data, new BinaryData(value, requestContentType));
-
- return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
- }
-
- @Override
- public ODataResponse executeFunctionImport(final GetFunctionImportUriInfo uriInfo, final String contentType)
- throws ODataException {
- final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
- final EdmType type = functionImport.getReturnType().getType();
-
- final Object data = dataSource.readData(
- functionImport,
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- null);
-
- if (data == null) {
- throw new ODataNotFoundException(ODataHttpException.COMMON);
- }
-
- Object value;
- if (type.getKind() == EdmTypeKind.SIMPLE) {
- value = type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance() ?
- ((BinaryData) data).getData() : data;
- } else if (functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY) {
- List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
- for (final Object typeData : (List<?>) data) {
- values.add(getStructuralTypeValueMap(typeData, (EdmStructuralType) type));
- }
- value = values;
- } else {
- value = getStructuralTypeValueMap(data, (EdmStructuralType) type);
- }
-
- ODataContext context = getContext();
-
- final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
- .serviceRoot(context.getPathInfo().getServiceRoot()).build();
-
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFunctionImport");
-
- final ODataResponse response =
- EntityProvider.writeFunctionImport(contentType, functionImport, value, entryProperties);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return ODataResponse.fromResponse(response).build();
- }
-
- @Override
- public ODataResponse executeFunctionImportValue(final GetFunctionImportUriInfo uriInfo, final String contentType)
- throws ODataException {
- final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
- final EdmSimpleType type = (EdmSimpleType) functionImport.getReturnType().getType();
-
- final Object data = dataSource.readData(
- functionImport,
- mapFunctionParameters(uriInfo.getFunctionImportParameters()),
- null);
-
- if (data == null) {
- throw new ODataNotFoundException(ODataHttpException.COMMON);
- }
-
- ODataResponse response;
- if (type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
- response = EntityProvider.writeBinary(((BinaryData) data).getMimeType(), ((BinaryData) data).getData());
- } else {
- final String value = type.valueToString(data, EdmLiteralKind.DEFAULT, null);
- response = EntityProvider.writeText(value == null ? "" : value);
- }
- return ODataResponse.fromResponse(response).build();
- }
-
- private static Map<String, Object> mapKey(final List<KeyPredicate> keys) throws EdmException {
- Map<String, Object> keyMap = new HashMap<String, Object>();
- for (final KeyPredicate key : keys) {
- final EdmProperty property = key.getProperty();
- final EdmSimpleType type = (EdmSimpleType) property.getType();
- keyMap.put(property.getName(), type.valueOfString(key.getLiteral(), EdmLiteralKind.DEFAULT, property.getFacets(),
- type.getDefaultType()));
- }
- return keyMap;
- }
-
- private static Map<String, Object> mapFunctionParameters(final Map<String, EdmLiteral> functionImportParameters)
- throws EdmSimpleTypeException {
- if (functionImportParameters == null) {
- return Collections.emptyMap();
- } else {
- Map<String, Object> parameterMap = new HashMap<String, Object>();
- for (final String parameterName : functionImportParameters.keySet()) {
- final EdmLiteral literal = functionImportParameters.get(parameterName);
- final EdmSimpleType type = literal.getType();
- parameterMap.put(parameterName, type.valueOfString(literal.getLiteral(), EdmLiteralKind.DEFAULT, null, type
- .getDefaultType()));
- }
- return parameterMap;
- }
- }
-
- private Object retrieveData(final EdmEntitySet startEntitySet, final List<KeyPredicate> keyPredicates,
- final EdmFunctionImport functionImport, final Map<String, Object> functionImportParameters,
- final List<NavigationSegment> navigationSegments) throws ODataException {
- Object data;
- final Map<String, Object> keys = mapKey(keyPredicates);
-
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "retrieveData");
-
- data = functionImport == null ?
- keys.isEmpty() ?
- dataSource.readData(startEntitySet) : dataSource.readData(startEntitySet, keys) :
- dataSource.readData(functionImport, functionImportParameters, keys);
-
- EdmEntitySet currentEntitySet =
- functionImport == null ? startEntitySet : functionImport.getEntitySet();
- for (NavigationSegment navigationSegment : navigationSegments) {
- data = dataSource.readRelatedData(
- currentEntitySet,
- data,
- navigationSegment.getEntitySet(),
- mapKey(navigationSegment.getKeyPredicates()));
- currentEntitySet = navigationSegment.getEntitySet();
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return data;
- }
-
- private <T> String constructETag(final EdmEntitySet entitySet, final T data) throws ODataException {
- final EdmEntityType entityType = entitySet.getEntityType();
- String eTag = null;
- for (final String propertyName : entityType.getPropertyNames()) {
- final EdmProperty property = (EdmProperty) entityType.getProperty(propertyName);
- if (property.getFacets() != null && property.getFacets().getConcurrencyMode() == EdmConcurrencyMode.Fixed) {
- final EdmSimpleType type = (EdmSimpleType) property.getType();
- final String component = type.valueToString(valueAccess.getPropertyValue(data, property),
- EdmLiteralKind.DEFAULT, property.getFacets());
- eTag = eTag == null ? component : eTag + Edm.DELIMITER + component;
- }
- }
- return eTag == null ? null : "W/\"" + eTag + "\"";
- }
-
- private <T> Map<String, ODataCallback> getCallbacks(final T data, final EdmEntityType entityType)
- throws EdmException {
- final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames();
- if (navigationPropertyNames.isEmpty()) {
- return null;
- } else {
- final WriteCallback callback = new WriteCallback(data);
- Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
- for (final String name : navigationPropertyNames) {
- callbacks.put(name, callback);
- }
- return callbacks;
- }
- }
-
- private class WriteCallback implements OnWriteEntryContent, OnWriteFeedContent {
- private final Object data;
-
- private <T> WriteCallback(final T data) {
- this.data = data;
- }
-
- @Override
- public WriteFeedCallbackResult retrieveFeedResult(final WriteFeedCallbackContext context)
- throws ODataApplicationException {
- try {
- final EdmEntityType entityType =
- context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
- List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
- Object relatedData = null;
- try {
- relatedData = readRelatedData(context);
- for (final Object entryData : (List<?>) relatedData) {
- values.add(getStructuralTypeValueMap(entryData, entityType));
- }
- } catch (final ODataNotFoundException e) {
- values.clear();
- }
- WriteFeedCallbackResult result = new WriteFeedCallbackResult();
- result.setFeedData(values);
- EntityProviderWriteProperties inlineProperties =
- EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
- getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
- .selfLink(context.getSelfLink()).build();
- result.setInlineProperties(inlineProperties);
- return result;
- } catch (final ODataException e) {
- throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
- }
- }
-
- @Override
- public WriteEntryCallbackResult retrieveEntryResult(final WriteEntryCallbackContext context)
- throws ODataApplicationException {
- try {
- final EdmEntityType entityType =
- context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
- WriteEntryCallbackResult result = new WriteEntryCallbackResult();
- Object relatedData;
- try {
- relatedData = readRelatedData(context);
- } catch (final ODataNotFoundException e) {
- relatedData = null;
- }
-
- if (relatedData == null) {
- result.setEntryData(Collections.<String, Object> emptyMap());
- } else {
- result.setEntryData(getStructuralTypeValueMap(relatedData, entityType));
-
- EntityProviderWriteProperties inlineProperties =
- EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
- getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
- .build();
- result.setInlineProperties(inlineProperties);
- }
- return result;
- } catch (final ODataException e) {
- throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
- }
- }
-
- private Object readRelatedData(final WriteCallbackContext context) throws ODataException {
- final EdmEntitySet entitySet = context.getSourceEntitySet();
- return dataSource.readRelatedData(
- entitySet,
- data instanceof List ? readEntryData((List<?>) data, entitySet.getEntityType(), context
- .extractKeyFromEntryData()) : data,
- entitySet.getRelatedEntitySet(context.getNavigationProperty()),
- Collections.<String, Object> emptyMap());
- }
-
- private <T> T readEntryData(final List<T> data, final EdmEntityType entityType, final Map<String, Object> key)
- throws ODataException {
- for (final T entryData : data) {
- boolean found = true;
- for (final EdmProperty keyProperty : entityType.getKeyProperties()) {
- if (!valueAccess.getPropertyValue(entryData, keyProperty).equals(key.get(keyProperty.getName()))) {
- found = false;
- break;
- }
- }
- if (found) {
- return entryData;
- }
- }
- return null;
- }
- }
-
- private <T> ODataResponse writeEntry(final EdmEntitySet entitySet, final ExpandSelectTreeNode expandSelectTree,
- final T data, final String contentType) throws ODataException, EntityProviderException {
- final EdmEntityType entityType = entitySet.getEntityType();
- final Map<String, Object> values = getStructuralTypeValueMap(data, entityType);
-
- ODataContext context = getContext();
- EntityProviderWriteProperties writeProperties = EntityProviderWriteProperties
- .serviceRoot(context.getPathInfo().getServiceRoot())
- .expandSelectTree(expandSelectTree)
- .callbacks(getCallbacks(data, entityType))
- .build();
-
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeEntry");
-
- final ODataResponse response = EntityProvider.writeEntry(contentType, entitySet, values, writeProperties);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return response;
- }
-
- private ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content,
- final String requestContentType, final EntityProviderReadProperties properties) throws ODataBadRequestException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readEntry");
-
- ODataEntry entryValues;
- try {
- entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, properties);
- } catch (final EntityProviderException e) {
- throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return entryValues;
- }
-
- private Map<String, Object> parseLink(final EdmEntitySet entitySet, final InputStream content,
- final String contentType) throws ODataException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readLink");
-
- final String uriString = EntityProvider.readLink(contentType, entitySet, content);
-
- context.stopRuntimeMeasurement(timingHandle);
-
- final Map<String, Object> targetKeys = parseLinkUri(entitySet, uriString);
- if (targetKeys == null) {
- throw new ODataBadRequestException(ODataBadRequestException.BODY);
- }
- return targetKeys;
- }
-
- private Map<String, Object> parseLinkUri(final EdmEntitySet targetEntitySet, final String uriString)
- throws EdmException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement("UriParser", "getKeyPredicatesFromEntityLink");
-
- List<KeyPredicate> key = null;
- try {
- key = UriParser.getKeyPredicatesFromEntityLink(targetEntitySet, uriString,
- context.getPathInfo().getServiceRoot());
- } catch (ODataException e) {
- // We don't understand the link target. This could also be seen as an error.
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return key == null ? null : mapKey(key);
- }
-
- private <T> void createInlinedEntities(final EdmEntitySet entitySet, final T data, final ODataEntry entryValues)
- throws ODataException {
- final EdmEntityType entityType = entitySet.getEntityType();
- for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
-
- final EdmNavigationProperty navigationProperty =
- (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
- final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
- final EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
-
- final Object relatedValue = entryValues.getProperties().get(navigationPropertyName);
- if (relatedValue == null) {
- for (final String uriString : entryValues.getMetadata().getAssociationUris(navigationPropertyName)) {
- final Map<String, Object> key = parseLinkUri(relatedEntitySet, uriString);
- if (key != null) {
- dataSource.writeRelation(entitySet, data, relatedEntitySet, key);
- }
- }
-
- } else {
- if (relatedValue instanceof ODataFeed) {
- ODataFeed feed = (ODataFeed) relatedValue;
- final List<ODataEntry> relatedValueList = feed.getEntries();
- for (final ODataEntry relatedValues : relatedValueList) {
- Object relatedData = dataSource.newDataObject(relatedEntitySet);
- setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValues.getProperties(), false);
- dataSource.createData(relatedEntitySet, relatedData);
- dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
- relatedEntityType));
- createInlinedEntities(relatedEntitySet, relatedData, relatedValues);
- }
- } else if (relatedValue instanceof ODataEntry) {
- final ODataEntry relatedValueEntry = (ODataEntry) relatedValue;
- Object relatedData = dataSource.newDataObject(relatedEntitySet);
- setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValueEntry.getProperties(), false);
- dataSource.createData(relatedEntitySet, relatedData);
- dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
- relatedEntityType));
- createInlinedEntities(relatedEntitySet, relatedData, relatedValueEntry);
- } else {
- throw new ODataException("Unexpected class for a related value: " + relatedValue.getClass().getSimpleName());
- }
-
- }
- }
- }
-
- private <T> Integer applySystemQueryOptions(final EdmEntitySet entitySet, final List<T> data,
- final FilterExpression filter, final InlineCount inlineCount, final OrderByExpression orderBy,
- final String skipToken, final Integer skip, final Integer top) throws ODataException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "applySystemQueryOptions");
-
- if (filter != null) {
- // Remove all elements the filter does not apply for.
- // A for-each loop would not work with "remove", see Java documentation.
- for (Iterator<T> iterator = data.iterator(); iterator.hasNext();) {
- if (!appliesFilter(iterator.next(), filter)) {
- iterator.remove();
- }
- }
- }
-
- final Integer count = inlineCount == InlineCount.ALLPAGES ? data.size() : null;
-
- if (orderBy != null) {
- sort(data, orderBy);
- } else if (skipToken != null || skip != null || top != null) {
- sortInDefaultOrder(entitySet, data);
- }
-
- if (skipToken != null) {
- while (!data.isEmpty() && !getSkipToken(entitySet, data.get(0)).equals(skipToken)) {
- data.remove(0);
- }
- }
-
- if (skip != null) {
- if (skip >= data.size()) {
- data.clear();
- } else {
- for (int i = 0; i < skip; i++) {
- data.remove(0);
- }
- }
- }
-
- if (top != null) {
- while (data.size() > top) {
- data.remove(top.intValue());
- }
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return count;
- }
-
- private <T> void sort(final List<T> data, final OrderByExpression orderBy) {
- Collections.sort(data, new Comparator<T>() {
- @Override
- public int compare(final T entity1, final T entity2) {
- try {
- int result = 0;
- for (final OrderExpression expression : orderBy.getOrders()) {
- result = evaluateExpression(entity1, expression.getExpression()).compareTo(
- evaluateExpression(entity2, expression.getExpression()));
- if (expression.getSortOrder() == SortOrder.desc) {
- result = -result;
- }
- if (result != 0) {
- break;
- }
- }
- return result;
- } catch (final ODataException e) {
- return 0;
- }
- }
- });
- }
-
- private <T> void sortInDefaultOrder(final EdmEntitySet entitySet, final List<T> data) {
- Collections.sort(data, new Comparator<T>() {
- @Override
- public int compare(final T entity1, final T entity2) {
- try {
- return getSkipToken(entitySet, entity1).compareTo(getSkipToken(entitySet, entity2));
- } catch (final ODataException e) {
- return 0;
- }
- }
- });
- }
-
- private <T> boolean appliesFilter(final T data, final FilterExpression filter) throws ODataException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "appliesFilter");
-
- try {
- return data != null && (filter == null || evaluateExpression(data, filter.getExpression()).equals("true"));
- } catch (final RuntimeException e) {
- return false;
- } finally {
- context.stopRuntimeMeasurement(timingHandle);
- }
- }
-
- private <T> String evaluateExpression(final T data, final CommonExpression expression) throws ODataException {
- switch (expression.getKind()) {
- case UNARY:
- final UnaryExpression unaryExpression = (UnaryExpression) expression;
- final String operand = evaluateExpression(data, unaryExpression.getOperand());
-
- switch (unaryExpression.getOperator()) {
- case NOT:
- return Boolean.toString(!Boolean.parseBoolean(operand));
- case MINUS:
- return operand.startsWith("-") ? operand.substring(1) : "-" + operand;
- default:
- throw new ODataNotImplementedException();
- }
-
- case BINARY:
- final BinaryExpression binaryExpression = (BinaryExpression) expression;
- final EdmSimpleType type = (EdmSimpleType) binaryExpression.getLeftOperand().getEdmType();
- final String left = evaluateExpression(data, binaryExpression.getLeftOperand());
- final String right = evaluateExpression(data, binaryExpression.getRightOperand());
-
- switch (binaryExpression.getOperator()) {
- case ADD:
- if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
- return Double.toString(Double.valueOf(left) + Double.valueOf(right));
- } else {
- return Long.toString(Long.valueOf(left) + Long.valueOf(right));
- }
- case SUB:
- if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
- return Double.toString(Double.valueOf(left) - Double.valueOf(right));
- } else {
- return Long.toString(Long.valueOf(left) - Long.valueOf(right));
- }
- case MUL:
- if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
- return Double.toString(Double.valueOf(left) * Double.valueOf(right));
- } else {
- return Long.toString(Long.valueOf(left) * Long.valueOf(right));
- }
- case DIV:
- final String number = Double.toString(Double.valueOf(left) / Double.valueOf(right));
- return number.endsWith(".0") ? number.replace(".0", "") : number;
- case MODULO:
- if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
- || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
- return Double.toString(Double.valueOf(left) % Double.valueOf(right));
- } else {
- return Long.toString(Long.valueOf(left) % Long.valueOf(right));
- }
- case AND:
- return Boolean.toString(left.equals("true") && right.equals("true"));
- case OR:
- return Boolean.toString(left.equals("true") || right.equals("true"));
- case EQ:
- return Boolean.toString(left.equals(right));
- case NE:
- return Boolean.toString(!left.equals(right));
- case LT:
- if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
- return Boolean.toString(left.compareTo(right) < 0);
- } else {
- return Boolean.toString(Double.valueOf(left) < Double.valueOf(right));
- }
- case LE:
- if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
- return Boolean.toString(left.compareTo(right) <= 0);
- } else {
- return Boolean.toString(Double.valueOf(left) <= Double.valueOf(right));
- }
- case GT:
- if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
- return Boolean.toString(left.compareTo(right) > 0);
- } else {
- return Boolean.toString(Double.valueOf(left) > Double.valueOf(right));
- }
- case GE:
- if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
- || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
- return Boolean.toString(left.compareTo(right) >= 0);
- } else {
- return Boolean.toString(Double.valueOf(left) >= Double.valueOf(right));
- }
- case PROPERTY_ACCESS:
- throw new ODataNotImplementedException();
- default:
- throw new ODataNotImplementedException();
- }
-
- case PROPERTY:
- final EdmProperty property = (EdmProperty) ((PropertyExpression) expression).getEdmProperty();
- final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
- return propertyType.valueToString(valueAccess.getPropertyValue(data, property), EdmLiteralKind.DEFAULT,
- property.getFacets());
-
- case MEMBER:
- final MemberExpression memberExpression = (MemberExpression) expression;
- final PropertyExpression propertyExpression = (PropertyExpression) memberExpression.getProperty();
- final EdmProperty memberProperty = (EdmProperty) propertyExpression.getEdmProperty();
- final EdmSimpleType memberType = (EdmSimpleType) memberExpression.getEdmType();
- List<EdmProperty> propertyPath = new ArrayList<EdmProperty>();
- CommonExpression currentExpression = memberExpression;
- while (currentExpression != null) {
- final PropertyExpression currentPropertyExpression =
- (PropertyExpression) (currentExpression.getKind() == ExpressionKind.MEMBER ?
- ((MemberExpression) currentExpression).getProperty() : currentExpression);
- final EdmTyped currentProperty = currentPropertyExpression.getEdmProperty();
- final EdmTypeKind kind = currentProperty.getType().getKind();
- if (kind == EdmTypeKind.SIMPLE || kind == EdmTypeKind.COMPLEX) {
- propertyPath.add(0, (EdmProperty) currentProperty);
- } else {
- throw new ODataNotImplementedException();
- }
- currentExpression =
- currentExpression.getKind() == ExpressionKind.MEMBER ? ((MemberExpression) currentExpression).getPath()
- : null;
- }
- return memberType.valueToString(getPropertyValue(data, propertyPath), EdmLiteralKind.DEFAULT, memberProperty
- .getFacets());
-
- case LITERAL:
- final LiteralExpression literal = (LiteralExpression) expression;
- final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
- return literalType.valueToString(literalType.valueOfString(literal.getUriLiteral(), EdmLiteralKind.URI, null,
- literalType.getDefaultType()),
- EdmLiteralKind.DEFAULT, null);
-
- case METHOD:
- final MethodExpression methodExpression = (MethodExpression) expression;
- final String first = evaluateExpression(data, methodExpression.getParameters().get(0));
- final String second = methodExpression.getParameterCount() > 1 ?
- evaluateExpression(data, methodExpression.getParameters().get(1)) : null;
- final String third = methodExpression.getParameterCount() > 2 ?
- evaluateExpression(data, methodExpression.getParameters().get(2)) : null;
-
- switch (methodExpression.getMethod()) {
- case ENDSWITH:
- return Boolean.toString(first.endsWith(second));
- case INDEXOF:
- return Integer.toString(first.indexOf(second));
- case STARTSWITH:
- return Boolean.toString(first.startsWith(second));
- case TOLOWER:
- return first.toLowerCase(Locale.ROOT);
- case TOUPPER:
- return first.toUpperCase(Locale.ROOT);
- case TRIM:
- return first.trim();
- case SUBSTRING:
- final int offset = Integer.parseInt(second);
- return first.substring(offset, offset + Integer.parseInt(third));
- case SUBSTRINGOF:
- return Boolean.toString(second.contains(first));
- case CONCAT:
- return first + second;
- case LENGTH:
- return Integer.toString(first.length());
- case YEAR:
- return String.valueOf(Integer.parseInt(first.substring(0, 4)));
- case MONTH:
- return String.valueOf(Integer.parseInt(first.substring(5, 7)));
- case DAY:
- return String.valueOf(Integer.parseInt(first.substring(8, 10)));
- case HOUR:
- return String.valueOf(Integer.parseInt(first.substring(11, 13)));
- case MINUTE:
- return String.valueOf(Integer.parseInt(first.substring(14, 16)));
- case SECOND:
- return String.valueOf(Integer.parseInt(first.substring(17, 19)));
- case ROUND:
- return Long.toString(Math.round(Double.valueOf(first)));
- case FLOOR:
- return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
- case CEILING:
- return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
- default:
- throw new ODataNotImplementedException();
- }
-
- default:
- throw new ODataNotImplementedException();
- }
- }
-
- private <T> String getSkipToken(final EdmEntitySet entitySet, final T data) throws ODataException {
- String skipToken = "";
- for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
- final EdmSimpleType type = (EdmSimpleType) property.getType();
- skipToken = skipToken.concat(type.valueToString(valueAccess.getPropertyValue(data, property),
- EdmLiteralKind.DEFAULT, property.getFacets()));
- }
- return skipToken;
- }
-
- private <T> Object getPropertyValue(final T data, final List<EdmProperty> propertyPath) throws ODataException {
- Object dataObject = data;
- for (final EdmProperty property : propertyPath) {
- if (dataObject != null) {
- dataObject = valueAccess.getPropertyValue(dataObject, property);
- }
- }
- return dataObject;
- }
-
- private void handleMimeType(Object data, EdmMapping mapping, Map<String, Object> valueMap)
- throws ODataException {
- final String mimeTypeName = mapping.getMimeType();
- if (mimeTypeName != null) {
- Object value = valueAccess.getMappingValue(data, mapping);
- valueMap.put(mimeTypeName, value);
- if (mapping.getMediaResourceMimeTypeKey() != null) {
- valueMap.put(mapping.getMediaResourceMimeTypeKey(), value);
- }
- }
- }
-
- private <T> Map<String, Object> getSimpleTypeValueMap(final T data, final List<EdmProperty> propertyPath)
- throws ODataException {
- final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
- Map<String, Object> valueWithMimeType = new HashMap<String, Object>();
- valueWithMimeType.put(property.getName(), getPropertyValue(data, propertyPath));
-
- handleMimeType(data, property.getMapping(), valueWithMimeType);
-
- return valueWithMimeType;
- }
-
- private <T> Map<String, Object> getStructuralTypeValueMap(final T data, final EdmStructuralType type)
- throws ODataException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeValueMap");
-
- Map<String, Object> valueMap = new HashMap<String, Object>();
-
- EdmMapping mapping = type.getMapping();
- if (mapping != null) {
- handleMimeType(data, mapping, valueMap);
- }
-
- for (final String propertyName : type.getPropertyNames()) {
- final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
- final Object value = valueAccess.getPropertyValue(data, property);
-
- if (property.isSimple()) {
- if (property.getMapping() == null || property.getMapping().getMimeType() == null) {
- valueMap.put(propertyName, value);
- } else {
- // TODO: enable MIME type mapping outside the current subtree
- valueMap.put(propertyName, getSimpleTypeValueMap(data, Arrays.asList(property)));
- }
- } else {
- valueMap.put(propertyName, getStructuralTypeValueMap(value, (EdmStructuralType) property.getType()));
- }
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return valueMap;
- }
-
- private <T> Map<String, Object> getStructuralTypeTypeMap(final T data, final EdmStructuralType type)
- throws ODataException {
- ODataContext context = getContext();
- final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeTypeMap");
-
- Map<String, Object> typeMap = new HashMap<String, Object>();
- for (final String propertyName : type.getPropertyNames()) {
- final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
- if (property.isSimple()) {
- typeMap.put(propertyName, valueAccess.getPropertyType(data, property));
- } else {
- typeMap.put(propertyName, getStructuralTypeTypeMap(valueAccess.getPropertyValue(data, property),
- (EdmStructuralType) property.getType()));
- }
- }
-
- context.stopRuntimeMeasurement(timingHandle);
-
- return typeMap;
- }
-
- private <T> void setStructuralTypeValuesFromMap(final T data, final EdmStructuralType type,
- final Map<String, Object> valueMap, final boolean merge) throws ODataException {
- ODataContext context = getContext();
- final int timingHandle =
- context.startRuntimeMeasurement(getClass().getSimpleName(), "setStructuralTypeValuesFromMap");
-
- for (final String propertyName : type.getPropertyNames()) {
- final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
- if (type instanceof EdmEntityType && ((EdmEntityType) type).getKeyProperties().contains(property)) {
- Object v = valueAccess.getPropertyValue(data, property);
- if(v != null) {
- continue;
- }
- }
-
- if (!merge || valueMap != null && valueMap.containsKey(propertyName)) {
- final Object value = valueMap == null ? null : valueMap.get(propertyName);
- if (property.isSimple()) {
- valueAccess.setPropertyValue(data, property, value);
- } else {
- @SuppressWarnings("unchecked")
- final Map<String, Object> values = (Map<String, Object>) value;
- setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
- (EdmStructuralType) property.getType(), values, merge);
- }
- }
- }
-
- context.stopRuntimeMeasurement(timingHandle);
- }
-
- @Override
- public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content)
- throws ODataException {
- ODataResponse batchResponse;
- List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>();
- PathInfo pathInfo = getContext().getPathInfo();
- EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
- List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties);
- for (BatchRequestPart batchPart : batchParts) {
- batchResponseParts.add(handler.handleBatchPart(batchPart));
- }
- batchResponse = EntityProvider.writeBatchResponse(batchResponseParts);
- return batchResponse;
- }
-
- @Override
- public BatchResponsePart executeChangeSet(final BatchHandler handler, final List<ODataRequest> requests)
- throws ODataException {
- List<ODataResponse> responses = new ArrayList<ODataResponse>();
- for (ODataRequest request : requests) {
- ODataResponse response = handler.handleRequest(request);
- if (response.getStatus().getStatusCode() >= HttpStatusCodes.BAD_REQUEST.getStatusCode()) {
- // Rollback
- List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1);
- errorResponses.add(response);
- return BatchResponsePart.responses(errorResponses).changeSet(false).build();
- }
- responses.add(response);
- }
- return BatchResponsePart.responses(responses).changeSet(true).build();
- }
-}
[11/12] Renamed project
Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
new file mode 100644
index 0000000..97f5b53
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -0,0 +1,773 @@
+/*******************************************************************************
+ * 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.core.annotation.edm;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+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.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+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.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+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.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ * Provider for the entity data model used in the reference scenario
+ *
+ */
+public class AnnotationEdmProvider extends EdmProvider {
+
+ private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+ private final List<Class<?>> annotatedClasses;
+ private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
+ private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
+ private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
+ private EntityContainer defaultContainer;
+
+ public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
+
+ this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
+ for (Class<?> aClass : annotatedClasses) {
+ if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
+ this.annotatedClasses.add(aClass);
+ }
+ }
+
+ init();
+ }
+
+ public AnnotationEdmProvider(String packageToScan) {
+ this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+ @Override
+ public boolean isClassValid(Class<?> c) {
+ return ANNOTATION_HELPER.isEdmAnnotated(c);
+ }
+ });
+
+ init();
+ }
+
+ private void init() {
+ for (Class<?> aClass : annotatedClasses) {
+ updateSchema(aClass);
+ handleEntityContainer(aClass);
+ }
+
+ finish();
+ }
+
+ @Override
+ public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
+ Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+ if (schema != null) {
+ List<Association> associations = schema.getAssociations();
+ for (Association association : associations) {
+ if (association.getName().equals(edmFQName.getName())) {
+ return association;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
+ String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
+ EntityContainer container = name2Container.get(entityContainer);
+ if (container != null) {
+ List<AssociationSet> associations = container.getAssociationSets();
+ for (AssociationSet associationSet : associations) {
+ if (associationSet.getAssociation().equals(association)) {
+ final AssociationSetEnd endOne = associationSet.getEnd1();
+ if (endOne.getRole().equals(sourceEntitySetRole)
+ && endOne.getEntitySet().equals(sourceEntitySetName)) {
+ return associationSet;
+ }
+ final AssociationSetEnd endTwo = associationSet.getEnd2();
+ if (endTwo.getRole().equals(sourceEntitySetRole)
+ && endTwo.getEntitySet().equals(sourceEntitySetName)) {
+ return associationSet;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
+ Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+ if (schema != null) {
+ List<ComplexType> complexTypes = schema.getComplexTypes();
+ for (ComplexType complexType : complexTypes) {
+ if (complexType.getName().equals(edmFQName.getName())) {
+ return complexType;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
+ EntityContainer container = name2Container.get(name);
+ if (container == null) {
+ // use default container (if set)
+ container = defaultContainer;
+ }
+ if (container != null) {
+ EntityContainerInfo info = new EntityContainerInfo();
+ info.setName(container.getName());
+ info.setDefaultEntityContainer(container.isDefaultEntityContainer());
+ info.setExtendz(container.getExtendz());
+ info.setAnnotationAttributes(container.getAnnotationAttributes());
+ info.setAnnotationElements(container.getAnnotationElements());
+
+ return info;
+ }
+
+ return null;
+ }
+
+ @Override
+ public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
+ EntityContainer container = name2Container.get(entityContainer);
+ if (container != null) {
+ List<EntitySet> entitySets = container.getEntitySets();
+ for (EntitySet entitySet : entitySets) {
+ if (entitySet.getName().equals(name)) {
+ return entitySet;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
+ Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+ if (schema != null) {
+ List<EntityType> complexTypes = schema.getEntityTypes();
+ for (EntityType complexType : complexTypes) {
+ if (complexType.getName().equals(edmFQName.getName())) {
+ return complexType;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
+ EntityContainer container = name2Container.get(entityContainer);
+ if (container != null) {
+ List<FunctionImport> functionImports = container.getFunctionImports();
+ for (FunctionImport functionImport : functionImports) {
+ if (functionImport.getName().equals(name)) {
+ return functionImport;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<Schema> getSchemas() throws ODataException {
+ return new ArrayList<Schema>(namespace2Schema.values());
+ }
+
+ //
+ //
+ //
+ private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
+
+ private void updateSchema(Class<?> aClass) {
+ EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
+ if (et != null) {
+ updateSchema(aClass, et);
+ }
+ EdmComplexType ect = aClass.getAnnotation(EdmComplexType.class);
+ if (ect != null) {
+ updateSchema(aClass, ect);
+ }
+ }
+
+ private void updateSchema(Class<?> aClass, EdmEntityType et) {
+ SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
+ TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+ b.addEntityType(typeBuilder.buildEntityType());
+ b.addAssociations(typeBuilder.buildAssociations());
+ }
+
+ private SchemaBuilder getSchemaBuilder(String namespace, Class<?> aClass) {
+ String usedNamespace = namespace;
+ if(usedNamespace.isEmpty()) {
+ usedNamespace = ANNOTATION_HELPER.getCanonicalNamespace(aClass);
+ }
+ SchemaBuilder builder = namespace2SchemaBuilder.get(usedNamespace);
+ if (builder == null) {
+ builder = SchemaBuilder.init(usedNamespace);
+ namespace2SchemaBuilder.put(usedNamespace, builder);
+ }
+ return builder;
+ }
+
+ private void updateSchema(Class<?> aClass, EdmComplexType et) {
+ SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
+ TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+ b.addComplexType(typeBuilder.buildComplexType());
+ }
+
+ private void handleEntityContainer(Class<?> aClass) {
+ EdmEntityType entityType = aClass.getAnnotation(EdmEntityType.class);
+ if (entityType != null) {
+ FullQualifiedName typeName = createFqnForEntityType(aClass, entityType);
+ String containerName = ANNOTATION_HELPER.extractContainerName(aClass);
+ ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
+ if (builder == null) {
+ builder = ContainerBuilder.init(typeName.getNamespace(), containerName);
+ containerName2ContainerBuilder.put(containerName, builder);
+ }
+ EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+ if (entitySet != null) {
+ builder.addEntitySet(createEntitySet(typeName, entitySet));
+ }
+ }
+ }
+
+ private EntitySet createEntitySet(FullQualifiedName typeName, EdmEntitySet entitySet) {
+ return new EntitySet().setName(entitySet.name()).setEntityType(typeName);
+ }
+
+ private FullQualifiedName createFqnForEntityType(Class<?> annotatedClass, EdmEntityType entityType) {
+ return ANNOTATION_HELPER.extractEntityTypeFqn(annotatedClass);
+ }
+
+ private void finish() {
+ //
+ Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
+ for (ContainerBuilder containerBuilder : containers) {
+ SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
+ containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
+ final EntityContainer container = containerBuilder.build();
+ schemaBuilder.addEntityContainer(container);
+ name2Container.put(container.getName(), container);
+ if (container.isDefaultEntityContainer()) {
+ defaultContainer = container;
+ }
+ }
+ //
+ Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
+ for (SchemaBuilder schemaBuilder : schemaBuilders) {
+ final Schema schema = schemaBuilder.build();
+ namespace2Schema.put(schema.getNamespace(), schema);
+ }
+ }
+
+ //
+ //
+ //
+ static class TypeBuilder {
+
+ final private String namespace;
+ final private String name;
+ private boolean isAbstract = false;
+ private boolean isMediaResource = false;
+ private FullQualifiedName baseEntityType = null;
+ private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
+ private final List<Property> properties = new ArrayList<Property>();
+ private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+ private final List<Association> associations = new ArrayList<Association>();
+
+ public TypeBuilder(FullQualifiedName fqn) {
+ this.namespace = fqn.getNamespace();
+ this.name = fqn.getName();
+ }
+
+ public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
+ return new TypeBuilder(ANNOTATION_HELPER.extractEntityTypeFqn(entity, aClass)).withClass(aClass);
+ }
+
+ public static TypeBuilder init(EdmComplexType entity, Class<?> aClass) {
+ return new TypeBuilder(ANNOTATION_HELPER.extractComplexTypeFqn(entity, aClass)).withClass(aClass);
+ }
+
+ private TypeBuilder withClass(Class<?> aClass) {
+ baseEntityType = createBaseEntityFqn(aClass);
+
+ if (Modifier.isAbstract(aClass.getModifiers())) {
+ this.isAbstract = true;
+ }
+
+ Field[] fields = aClass.getDeclaredFields();
+ for (Field field : fields) {
+ EdmProperty ep = field.getAnnotation(EdmProperty.class);
+ if (ep != null) {
+ properties.add(createProperty(ep, field, namespace));
+ EdmKey eti = field.getAnnotation(EdmKey.class);
+ if (eti != null) {
+ keyProperties.add(createKeyProperty(ep, field));
+ }
+ }
+ EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
+ if (enp != null) {
+ final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
+ navProperties.add(navProperty);
+ Association association = createAssociation(field, navProperty);
+ associations.add(association);
+ }
+ EdmMediaResourceContent emrc = field.getAnnotation(EdmMediaResourceContent.class);
+ if (emrc != null) {
+ isMediaResource = true;
+ }
+ }
+
+ return this;
+ }
+
+ public TypeBuilder addProperty(PropertyRef property) {
+ keyProperties.add(property);
+ return this;
+ }
+
+ public TypeBuilder addProperty(Property property) {
+ properties.add(property);
+ return this;
+ }
+
+ public TypeBuilder addNavigationProperty(NavigationProperty property) {
+ navProperties.add(property);
+ return this;
+ }
+
+ public TypeBuilder setAbstract(boolean isAbstract) {
+ this.isAbstract = isAbstract;
+ return this;
+ }
+
+ public ComplexType buildComplexType() {
+ ComplexType complexType = new ComplexType();
+ if (baseEntityType != null) {
+ complexType.setBaseType(baseEntityType);
+ }
+ return complexType.setName(name).setProperties(properties);
+ }
+
+ public EntityType buildEntityType() {
+ EntityType entityType = new EntityType();
+ if (baseEntityType != null) {
+ entityType.setBaseType(baseEntityType);
+ }
+ if (!keyProperties.isEmpty()) {
+ entityType.setKey(new Key().setKeys(keyProperties));
+ }
+ if (!navProperties.isEmpty()) {
+ entityType.setNavigationProperties(navProperties);
+ }
+ return entityType.setName(name)
+ .setAbstract(isAbstract)
+ .setHasStream(isMediaResource)
+ .setProperties(properties);
+ }
+
+ public Collection<Association> buildAssociations() {
+ return Collections.unmodifiableCollection(associations);
+ }
+
+ private PropertyRef createKeyProperty(EdmProperty et, Field field) {
+ PropertyRef keyProperty = new PropertyRef();
+ String entityName = et.name();
+ if (entityName.isEmpty()) {
+ entityName = getCanonicalName(field);
+ }
+ return keyProperty.setName(entityName);
+ }
+
+ private Property createProperty(EdmProperty ep, Field field, String defaultNamespace) {
+ if (isAnnotatedEntity(field.getType())) {
+ return createComplexProperty(field, defaultNamespace);
+ } else {
+ return createSimpleProperty(ep, field);
+ }
+ }
+
+ private Property createSimpleProperty(EdmProperty ep, Field field) {
+ SimpleProperty sp = new SimpleProperty();
+ String entityName = ANNOTATION_HELPER.getPropertyName(field);
+ sp.setName(entityName);
+ //
+ EdmType type = ep.type();
+ if (type == EdmType.NULL) {
+ type = getEdmType(field.getType());
+ }
+ sp.setType(ANNOTATION_HELPER.mapTypeKind(type));
+
+ return sp;
+ }
+
+ private Property createComplexProperty(Field field, String defaultNamespace) {
+ ComplexProperty cp = new ComplexProperty();
+ // settings from property
+ String entityName = ANNOTATION_HELPER.getPropertyName(field);
+ cp.setName(entityName);
+
+ // settings from related complex entity
+ EdmComplexType ece = field.getType().getAnnotation(EdmComplexType.class);
+ String complexEntityNamespace = ece.namespace();
+ if (complexEntityNamespace.isEmpty()) {
+ complexEntityNamespace = defaultNamespace;
+ }
+ cp.setType(new FullQualifiedName(complexEntityNamespace, ece.name()));
+
+ return cp;
+ }
+
+ private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
+ NavigationProperty navProp = new NavigationProperty();
+ navProp.setName(ANNOTATION_HELPER.getPropertyName(field));
+ String fromRole = ANNOTATION_HELPER.extractFromRoleName(enp, field);
+ navProp.setFromRole(fromRole);
+
+ String toRole = ANNOTATION_HELPER.extractToRoleName(enp, field);
+ navProp.setToRole(toRole);
+
+ String relationshipName = ANNOTATION_HELPER.extractRelationshipName(enp, field);
+ navProp.setRelationship(new FullQualifiedName(namespace, relationshipName));
+
+ return navProp;
+ }
+
+// private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
+// if (type == String.class) {
+// return EdmType.String;
+// } else if (type == boolean.class || type == Boolean.class) {
+// return EdmType.Boolean;
+// } else if (type == byte.class || type == Byte.class) {
+// return EdmType.SByte;
+// } else if (type == short.class || type == Short.class) {
+// return EdmType.Int16;
+// } else if (type == int.class || type == Integer.class) {
+// return EdmType.Int32;
+// } else if (type == long.class || type == Long.class) {
+// return EdmType.Int64;
+// } else if (type == double.class || type == Double.class) {
+// return EdmType.Double;
+// } else if (type == float.class || type == Float.class) {
+// return EdmType.Single;
+// } else if (type == BigInteger.class || type == BigDecimal.class) {
+// return EdmType.Decimal;
+// } else if (type == Byte[].class || type == byte[].class) {
+// return EdmType.Binary;
+// } else if (type == Date.class) {
+// return EdmType.DateTime;
+// } else if (type == Calendar.class) {
+// return EdmType.DateTimeOffset;
+// } else if (type == UUID.class) {
+// return EdmType.Guid;
+// } else {
+// throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
+// }
+// }
+
+ private EdmType getEdmType(Class<?> type) {
+ if (type == String.class) {
+ return EdmType.STRING;
+ } else if (type == boolean.class || type == Boolean.class) {
+ return EdmType.BOOLEAN;
+ } else if (type == byte.class || type == Byte.class) {
+ return EdmType.SBYTE;
+ } else if (type == short.class || type == Short.class) {
+ return EdmType.INT16;
+ } else if (type == int.class || type == Integer.class) {
+ return EdmType.INT32;
+ } else if (type == long.class || type == Long.class) {
+ return EdmType.INT64;
+ } else if (type == double.class || type == Double.class) {
+ return EdmType.DOUBLE;
+ } else if (type == float.class || type == Float.class) {
+ return EdmType.SINGLE;
+ } else if (type == BigInteger.class || type == BigDecimal.class) {
+ return EdmType.DECIMAL;
+ } else if (type == Byte[].class || type == byte[].class) {
+ return EdmType.BINARY;
+ } else if (type == Date.class) {
+ return EdmType.DATE_TIME;
+ } else if (type == Calendar.class) {
+ return EdmType.DATE_TIME_OFFSET;
+ } else if (type == UUID.class) {
+ return EdmType.GUID;
+ } else {
+ throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
+ }
+ }
+
+
+ private Class<?> checkForBaseEntityClass(Class<?> aClass) {
+ Class<?> superClass = aClass.getSuperclass();
+ if (superClass == Object.class) {
+ return null;
+ } else {
+ EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
+ if (edmEntity == null) {
+ return checkForBaseEntityClass(superClass);
+ } else {
+ return superClass;
+ }
+ }
+ }
+
+ private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
+ Class<?> baseEntityClass = checkForBaseEntityClass(aClass);
+ if (baseEntityClass == null) {
+ return null;
+ }
+ return ANNOTATION_HELPER.extractEntityTypeFqn(baseEntityClass);
+ }
+
+ private Association createAssociation(Field field, NavigationProperty navProperty) {
+ Association association = new Association();
+ EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
+
+ AssociationEnd fromEnd = new AssociationEnd();
+ fromEnd.setRole(navProperty.getFromRole());
+ String typeName = ANNOTATION_HELPER.extractEntityTypeName(field.getDeclaringClass());
+ fromEnd.setType(new FullQualifiedName(namespace, typeName));
+ fromEnd.setMultiplicity(EdmMultiplicity.ONE);
+ association.setEnd1(fromEnd);
+
+ AssociationEnd toEnd = new AssociationEnd();
+ toEnd.setRole(navProperty.getToRole());
+ String toTypeName = ANNOTATION_HELPER.extractEntitTypeName(navigation, field);
+ toEnd.setType(new FullQualifiedName(namespace, toTypeName));
+ toEnd.setMultiplicity(ANNOTATION_HELPER.getMultiplicity(navigation, field));
+ association.setEnd2(toEnd);
+
+ String associationName = navProperty.getRelationship().getName();
+ association.setName(associationName);
+ return association;
+ }
+
+ private String getCanonicalName(Field field) {
+ return ANNOTATION_HELPER.getCanonicalName(field);
+ }
+
+ private boolean isAnnotatedEntity(Class<?> clazz) {
+ return ANNOTATION_HELPER.isEdmTypeAnnotated(clazz);
+ }
+ }
+
+ static class SchemaBuilder {
+
+ final private String namespace;
+ // private String alias;
+ private final List<Using> usings = new ArrayList<Using>();
+ private final List<EntityType> entityTypes = new ArrayList<EntityType>();
+ private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
+ private final Map<String, Association> name2Associations = new HashMap<String, Association>();
+ private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
+ private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+ private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ private SchemaBuilder(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public static SchemaBuilder init(String namespace) {
+ return new SchemaBuilder(namespace);
+ }
+
+ public SchemaBuilder addEntityType(EntityType type) {
+ entityTypes.add(type);
+ return this;
+ }
+
+ public SchemaBuilder addEntityContainer(EntityContainer container) {
+ entityContainers.add(container);
+ return this;
+ }
+
+ public SchemaBuilder addComplexType(ComplexType createEntityType) {
+ complexTypes.add(createEntityType);
+ return this;
+ }
+
+ public void addAssociations(Collection<Association> associations) {
+ for (Association association : associations) {
+ final String relationshipName = association.getName();
+ if (name2Associations.containsKey(relationshipName)) {
+ association = mergeAssociations(name2Associations.get(relationshipName), association);
+ }
+ name2Associations.put(relationshipName, association);
+ }
+ }
+
+ private Association mergeAssociations(Association associationOne, Association associationTwo) {
+ AssociationEnd oneEnd1 = associationOne.getEnd1();
+ AssociationEnd oneEnd2 = associationOne.getEnd2();
+ AssociationEnd twoEnd1 = associationTwo.getEnd1();
+ AssociationEnd twoEnd2 = associationTwo.getEnd2();
+ AssociationEnd[] oneEnds = new AssociationEnd[] { oneEnd1, oneEnd2 };
+
+ for (AssociationEnd associationEnd : oneEnds) {
+ if (associationEnd.getRole().equals(twoEnd1.getRole())) {
+ if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
+ associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+ }
+ } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
+ if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
+ associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+ }
+ }
+ }
+
+ return associationOne;
+ }
+
+ public Schema build() {
+ Schema s = new Schema();
+ s.setUsings(usings);
+ s.setEntityTypes(entityTypes);
+ s.setComplexTypes(complexTypes);
+ s.setAssociations(new ArrayList<Association>(name2Associations.values()));
+ s.setEntityContainers(entityContainers);
+ s.setAnnotationAttributes(annotationAttributes);
+ s.setAnnotationElements(annotationElements);
+ s.setNamespace(namespace);
+ return s;
+ }
+ }
+
+ private static class ContainerBuilder {
+
+ final private String name;
+ final private String namespace;
+ private boolean defaultContainer = true;
+ private final List<EntitySet> entitySets = new ArrayList<EntitySet>();
+ private final List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
+ private final List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
+
+ // private Documentation documentation;
+
+ private ContainerBuilder(String namespace, String containerName) {
+ this.namespace = namespace;
+ name = containerName;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public static ContainerBuilder init(String namespace, String containerName) {
+ return new ContainerBuilder(namespace, containerName);
+ }
+
+ public ContainerBuilder setDefaultContainer(boolean isDefault) {
+ defaultContainer = isDefault;
+ return this;
+ }
+
+ public ContainerBuilder addEntitySet(EntitySet entitySet) {
+ entitySets.add(entitySet);
+ return this;
+ }
+
+ public void addAssociationSets(Collection<Association> associations) {
+ for (Association association : associations) {
+ AssociationSet as = new AssociationSet();
+ as.setName(association.getName());
+ FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
+ as.setAssociation(asAssociationFqn);
+
+ AssociationSetEnd asEnd1 = new AssociationSetEnd();
+ asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
+ asEnd1.setRole(association.getEnd1().getRole());
+ as.setEnd1(asEnd1);
+
+ AssociationSetEnd asEnd2 = new AssociationSetEnd();
+ asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
+ asEnd2.setRole(association.getEnd2().getRole());
+ as.setEnd2(asEnd2);
+
+ associationSets.add(as);
+ }
+ }
+
+ public EntityContainer build() {
+ EntityContainer ec = new EntityContainer();
+ ec.setName(name);
+ ec.setDefaultEntityContainer(defaultContainer);
+ ec.setEntitySets(entitySets);
+ ec.setAssociationSets(associationSets);
+ ec.setFunctionImports(functionImports);
+ return ec;
+ }
+
+ private String getEntitySetName(AssociationEnd end) {
+ for (EntitySet entitySet : entitySets) {
+ if (entitySet.getEntityType().equals(end.getType())) {
+ return entitySet.getName();
+ }
+ }
+ throw new ODataRuntimeException("No entity set found for " + end.getType());
+ }
+ }
+}
[03/12] git commit: Extract abstract,
rename and refactore processor parts
Posted by mi...@apache.org.
Extract abstract, rename and refactore processor parts
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/28b35fff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/28b35fff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/28b35fff
Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 28b35fff8c68aec2fbdac3f2f4f127cba62641b6
Parents: 8764e11
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 09:44:11 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 09:44:11 2013 +0100
----------------------------------------------------------------------
.../olingo/odata2/api/data/DataSource.java | 200 +++++++++++++++++++
.../odata2/api/data/DataSourceProcessor.java | 47 +++++
.../olingo/odata2/api/data/ListsDataSource.java | 200 -------------------
.../annotation/data/AnnotationInMemoryDs.java | 4 +-
.../annotation/processor/ListsProcessor.java | 18 +-
.../odata2/fit/ref/EntryXmlReadOnlyTest.java | 15 +-
.../ref/processor/ScenarioDataSource.java | 4 +-
7 files changed, 271 insertions(+), 217 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
new file mode 100644
index 0000000..694f199
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.api.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+
+/**
+ * <p>This interface is intended to make it easier to implement an OData
+ * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
+ * properties described in the
+ * Entity Data Model can be retrieved and set.</p>
+ * <p>By obeying these restrictions, data-source implementations get the
+ * following advantages:
+ * <ul>
+ * <li>All system query options can be handled centrally.</li>
+ * <li>Following navigation paths must only be done step by step.</li>
+ * </ul>
+ * </p>
+ *
+ */
+public interface DataSource {
+
+ /**
+ * Retrieves the whole data list for the specified entity set.
+ * @param entitySet the requested {@link EdmEntitySet}
+ * @return the requested data list
+ */
+ List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Retrieves a single data object for the specified entity set and key.
+ * @param entitySet the requested {@link EdmEntitySet}
+ * @param keys the entity key as map of key names to key values
+ * @return the requested data object
+ */
+ Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Retrieves data for the specified function import and key.</p>
+ * <p>This method is called also for function imports that have defined in
+ * their metadata an other HTTP method than <code>GET</code>.</p>
+ * @param function the requested {@link EdmFunctionImport}
+ * @param parameters the parameters of the function import
+ * as map of parameter names to parameter values
+ * @param keys the key of the returned entity set, as map of key names to key values,
+ * if the return type of the function import is a collection of entities
+ * (optional)
+ * @return the requested data object, either a list or a single object;
+ * if the function import's return type is of type <code>Binary</code>,
+ * the returned object(s) must be of type {@link BinaryData}
+ */
+ Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Retrieves related data for the specified source data, entity set, and key.</p>
+ * <p>If the underlying association of the EDM is specified to have target
+ * multiplicity '*' and no target key is given, this method returns a list of
+ * related data, otherwise it returns a single data object.</p>
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the requested target {@link EdmEntitySet}
+ * @param targetKeys the key of the target entity as map of key names to key values
+ * (optional)
+ * @return the requested releated data object, either a list or a single object
+ */
+ Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Retrieves the binary data and the MIME type for the media resource
+ * associated to the specified media-link entry.
+ * @param entitySet the {@link EdmEntitySet} of the media-link entry
+ * @param mediaLinkEntryData the data object of the media-link entry
+ * @return the binary data and the MIME type of the media resource
+ */
+ BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Creates and returns a new instance of the requested data-object type.</p>
+ * <p>This instance must not be part of the corresponding list and should
+ * have empty content, apart from the key and other mandatory properties.
+ * However, intermediate objects to access complex properties must not be
+ * <code>null</code>.</p>
+ * @param entitySet the {@link EdmEntitySet} the object must correspond to
+ * @return the new data object
+ */
+ Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Writes the binary data for the media resource associated to the
+ * specified media-link entry.
+ * @param entitySet the {@link EdmEntitySet} of the media-link entry
+ * @param mediaLinkEntryData the data object of the media-link entry
+ * @param binaryData the binary data of the media resource along with
+ * the MIME type of the binary data
+ */
+ void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * Deletes a single data object identified by the specified entity set and key.
+ * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
+ * @param keys the entity key as map of key names to key values
+ */
+ void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Inserts an instance into the entity list of the specified entity set.</p>
+ * <p>If {@link #newDataObject} has not set the key and other mandatory
+ * properties already, this method must set them before inserting the
+ * instance into the list.</p>
+ * @param entitySet the {@link EdmEntitySet} the object must correspond to
+ * @param data the data object of the new entity
+ */
+ void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Deletes the relation from the specified source data to a target entity
+ * specified by entity set and key.
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the {@link EdmEntitySet} of the target entity
+ * @param targetKeys the key of the target entity as map of key names to key values
+ * (optional)
+ */
+ void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Writes a relation from the specified source data to a target entity
+ * specified by entity set and key.
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the {@link EdmEntitySet} of the relation target
+ * @param targetKeys the key of the target entity as map of key names to key values
+ */
+ void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Container to store binary data (as byte array) and the associated MIME type.
+ */
+ public class BinaryData {
+ private final byte[] data;
+ private final String mimeType;
+
+ public BinaryData(final byte[] data, final String mimeType) {
+ this.data = data;
+ this.mimeType = mimeType;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ @Override
+ public String toString() {
+ return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
new file mode 100644
index 0000000..2be5663
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.api.data;
+
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+
+/**
+ * Abstract class for implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
+ * actual data handling.
+ * <br/>
+ * Extend this class and implement a DataSourceProcessor if the default implementation
+ * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
+ */
+public abstract class DataSourceProcessor extends ODataSingleProcessor {
+
+ protected final DataSource dataSource;
+ protected final ValueAccess valueAccess;
+
+ /**
+ * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
+ * and {@link ValueAccess} (accessing values of data objects).
+ *
+ * @param dataSource used for accessing the data objects
+ * @param valueAccess for accessing the values provided by the data objects
+ */
+ public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+ this.dataSource = dataSource;
+ this.valueAccess = valueAccess;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
deleted file mode 100644
index e9229e3..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * 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.api.data;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-
-/**
- * <p>This interface is intended to make it easier to implement an OData
- * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
- * properties described in the
- * Entity Data Model can be retrieved and set.</p>
- * <p>By obeying these restrictions, data-source implementations get the
- * following advantages:
- * <ul>
- * <li>All system query options can be handled centrally.</li>
- * <li>Following navigation paths must only be done step by step.</li>
- * </ul>
- * </p>
- *
- */
-public interface ListsDataSource {
-
- /**
- * Retrieves the whole data list for the specified entity set.
- * @param entitySet the requested {@link EdmEntitySet}
- * @return the requested data list
- */
- List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Retrieves a single data object for the specified entity set and key.
- * @param entitySet the requested {@link EdmEntitySet}
- * @param keys the entity key as map of key names to key values
- * @return the requested data object
- */
- Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Retrieves data for the specified function import and key.</p>
- * <p>This method is called also for function imports that have defined in
- * their metadata an other HTTP method than <code>GET</code>.</p>
- * @param function the requested {@link EdmFunctionImport}
- * @param parameters the parameters of the function import
- * as map of parameter names to parameter values
- * @param keys the key of the returned entity set, as map of key names to key values,
- * if the return type of the function import is a collection of entities
- * (optional)
- * @return the requested data object, either a list or a single object;
- * if the function import's return type is of type <code>Binary</code>,
- * the returned object(s) must be of type {@link BinaryData}
- */
- Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Retrieves related data for the specified source data, entity set, and key.</p>
- * <p>If the underlying association of the EDM is specified to have target
- * multiplicity '*' and no target key is given, this method returns a list of
- * related data, otherwise it returns a single data object.</p>
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the requested target {@link EdmEntitySet}
- * @param targetKeys the key of the target entity as map of key names to key values
- * (optional)
- * @return the requested releated data object, either a list or a single object
- */
- Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Retrieves the binary data and the MIME type for the media resource
- * associated to the specified media-link entry.
- * @param entitySet the {@link EdmEntitySet} of the media-link entry
- * @param mediaLinkEntryData the data object of the media-link entry
- * @return the binary data and the MIME type of the media resource
- */
- BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Creates and returns a new instance of the requested data-object type.</p>
- * <p>This instance must not be part of the corresponding list and should
- * have empty content, apart from the key and other mandatory properties.
- * However, intermediate objects to access complex properties must not be
- * <code>null</code>.</p>
- * @param entitySet the {@link EdmEntitySet} the object must correspond to
- * @return the new data object
- */
- Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
- ODataApplicationException;
-
- /**
- * Writes the binary data for the media resource associated to the
- * specified media-link entry.
- * @param entitySet the {@link EdmEntitySet} of the media-link entry
- * @param mediaLinkEntryData the data object of the media-link entry
- * @param binaryData the binary data of the media resource along with
- * the MIME type of the binary data
- */
- void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
- throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * Deletes a single data object identified by the specified entity set and key.
- * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
- * @param keys the entity key as map of key names to key values
- */
- void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
- ODataNotFoundException, EdmException, ODataApplicationException;
-
- /**
- * <p>Inserts an instance into the entity list of the specified entity set.</p>
- * <p>If {@link #newDataObject} has not set the key and other mandatory
- * properties already, this method must set them before inserting the
- * instance into the list.</p>
- * @param entitySet the {@link EdmEntitySet} the object must correspond to
- * @param data the data object of the new entity
- */
- void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
- ODataApplicationException;
-
- /**
- * Deletes the relation from the specified source data to a target entity
- * specified by entity set and key.
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the {@link EdmEntitySet} of the target entity
- * @param targetKeys the key of the target entity as map of key names to key values
- * (optional)
- */
- void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Writes a relation from the specified source data to a target entity
- * specified by entity set and key.
- * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
- * @param sourceData the data object of the source entity
- * @param targetEntitySet the {@link EdmEntitySet} of the relation target
- * @param targetKeys the key of the target entity as map of key names to key values
- */
- void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
- ODataApplicationException;
-
- /**
- * Container to store binary data (as byte array) and the associated MIME type.
- */
- public class BinaryData {
- private final byte[] data;
- private final String mimeType;
-
- public BinaryData(final byte[] data, final String mimeType) {
- this.data = data;
- this.mimeType = mimeType;
- }
-
- public byte[] getData() {
- return data;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- @Override
- public String toString() {
- return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
index 030cc93..db03a4c 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -24,7 +24,7 @@ import java.util.Map;
import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
+import org.apache.olingo.odata2.api.data.DataSource;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
@@ -38,7 +38,7 @@ import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedN
import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-public class AnnotationInMemoryDs implements ListsDataSource {
+public class AnnotationInMemoryDs implements DataSource {
private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
index 16e1eab..19218d7 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
@@ -36,8 +36,9 @@ import org.apache.olingo.odata2.api.batch.BatchResponsePart;
import org.apache.olingo.odata2.api.commons.HttpContentType;
import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
import org.apache.olingo.odata2.api.commons.InlineCount;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
-import org.apache.olingo.odata2.api.data.ListsDataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSourceProcessor;
import org.apache.olingo.odata2.api.data.ValueAccess;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
@@ -81,7 +82,6 @@ import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
import org.apache.olingo.odata2.api.processor.ODataContext;
import org.apache.olingo.odata2.api.processor.ODataRequest;
import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.api.uri.KeyPredicate;
import org.apache.olingo.odata2.api.uri.NavigationSegment;
@@ -117,21 +117,17 @@ import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
/**
* Implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link ListsDataSource} for the
+ * allowing to use the simplified {@link DataSource} for the
* actual data handling.
*
*/
-public class ListsProcessor extends ODataSingleProcessor {
+public class ListsProcessor extends DataSourceProcessor {
// TODO: Paging size should be configurable.
private static final int SERVER_PAGING_SIZE = 100;
- private final ListsDataSource dataSource;
- private final ValueAccess valueAccess;
-
- public ListsProcessor(final ListsDataSource dataSource, final ValueAccess valueAccess) {
- this.dataSource = dataSource;
- this.valueAccess = valueAccess;
+ public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+ super(dataSource, valueAccess);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
index eec1f42..6e319c6 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
@@ -96,10 +96,10 @@ public class EntryXmlReadOnlyTest extends AbstractRefXmlTest {
public void entryWithSpecialKey() throws Exception {
// Ugly hack to create an entity with a key containing special characters just for this test.
ListsProcessor processor = (ListsProcessor) getService().getEntityProcessor();
- Field field = processor.getClass().getDeclaredField("dataSource");
+ Field field = getField(processor.getClass(), "dataSource");
field.setAccessible(true);
ScenarioDataSource dataSource = (ScenarioDataSource) field.get(processor);
- field = dataSource.getClass().getDeclaredField("dataContainer");
+ field = getField(dataSource.getClass(), "dataContainer");
field.setAccessible(true);
DataContainer dataContainer = (DataContainer) field.get(dataSource);
// Add a new Photo where the "Type" property is set to, space-separated,
@@ -118,6 +118,17 @@ public class EntryXmlReadOnlyTest extends AbstractRefXmlTest {
assertXpathEvaluatesTo(expected + "/$value", "/atom:entry/atom:link[@rel=\"edit-media\"]/@href", body);
}
+ private Field getField(Class<?> clazz, String string) throws Exception {
+ try {
+ return clazz.getDeclaredField(string);
+ } catch (NoSuchFieldException e) {
+ if(clazz == Object.class) {
+ throw e;
+ }
+ return getField(clazz.getSuperclass(), string);
+ }
+ }
+
@Test
public void expand() throws Exception {
HttpResponse response = callUri("Employees('5')?$expand=ne_Manager");
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
index 0047226..cc70639 100644
--- a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
+++ b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
@@ -28,7 +28,7 @@ import java.util.Map;
import java.util.Map.Entry;
import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
+import org.apache.olingo.odata2.api.data.DataSource;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
@@ -48,7 +48,7 @@ import org.apache.olingo.odata2.ref.model.Team;
* Data for the reference scenario
*
*/
-public class ScenarioDataSource implements ListsDataSource {
+public class ScenarioDataSource implements DataSource {
private static final String ENTITYSET_1_1 = "Employees";
private static final String ENTITYSET_1_2 = "Teams";
[12/12] git commit: Renamed project
Posted by mi...@apache.org.
Renamed project
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/12ea18ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/12ea18ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/12ea18ae
Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 12ea18aed44f33fb58b577887533bf841771bfea
Parents: 28b35ff
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 10:03:26 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 10:03:26 2013 +0100
----------------------------------------------------------------------
.../annotation-processor-api/pom.xml | 42 +
.../olingo/odata2/api/data/DataSource.java | 200 +++
.../odata2/api/data/DataSourceProcessor.java | 47 +
.../olingo/odata2/api/data/ValueAccess.java | 69 +
.../annotation-processor-core/pom.xml | 48 +
.../annotation/data/AnnotationInMemoryDs.java | 351 ++++
.../annotation/data/AnnotationValueAccess.java | 106 ++
.../annotation/data/BeanPropertyAccess.java | 186 ++
.../odata2/core/annotation/data/DataStore.java | 192 +++
.../annotation/edm/AnnotationEdmProvider.java | 773 +++++++++
.../annotation/processor/ListsProcessor.java | 1630 ++++++++++++++++++
.../core/annotation/util/AnnotationHelper.java | 726 ++++++++
.../core/annotation/util/ClassHelper.java | 105 ++
.../data/AnnotationsInMemoryDsTest.java | 190 ++
.../edm/AnnotationEdmProviderTest.java | 463 +++++
.../odata2/core/annotation/model/Building.java | 95 +
.../odata2/core/annotation/model/City.java | 62 +
.../odata2/core/annotation/model/Employee.java | 187 ++
.../odata2/core/annotation/model/Location.java | 61 +
.../odata2/core/annotation/model/Manager.java | 47 +
.../annotation/model/ModelSharedConstants.java | 25 +
.../odata2/core/annotation/model/Photo.java | 128 ++
.../odata2/core/annotation/model/RefBase.java | 55 +
.../core/annotation/model/ResourceHelper.java | 64 +
.../odata2/core/annotation/model/Room.java | 89 +
.../odata2/core/annotation/model/Team.java | 81 +
.../annotation-processor-webref/pom.xml | 120 ++
.../odata2/ref/annotation/model/Building.java | 97 ++
.../odata2/ref/annotation/model/City.java | 61 +
.../odata2/ref/annotation/model/Employee.java | 192 +++
.../odata2/ref/annotation/model/Location.java | 60 +
.../odata2/ref/annotation/model/Manager.java | 43 +
.../annotation/model/ModelSharedConstants.java | 25 +
.../odata2/ref/annotation/model/Photo.java | 128 ++
.../odata2/ref/annotation/model/RefBase.java | 78 +
.../ref/annotation/model/ResourceHelper.java | 93 +
.../odata2/ref/annotation/model/Room.java | 88 +
.../odata2/ref/annotation/model/Team.java | 73 +
.../processor/AnnotationPocServiceFactory.java | 202 +++
.../src/main/resources/log4j.xml | 39 +
.../src/main/version/version.html | 27 +
.../src/main/webapp/WEB-INF/web.xml | 48 +
.../src/main/webapp/index.jsp | 116 ++
odata2-annotation-processor/pom.xml | 30 +
.../edm-annotation-api/pom.xml | 42 -
.../olingo/odata2/api/data/DataSource.java | 200 ---
.../odata2/api/data/DataSourceProcessor.java | 47 -
.../olingo/odata2/api/data/ValueAccess.java | 69 -
.../edm-annotation-core/pom.xml | 48 -
.../annotation/data/AnnotationInMemoryDs.java | 351 ----
.../annotation/data/AnnotationValueAccess.java | 106 --
.../annotation/data/BeanPropertyAccess.java | 186 --
.../odata2/core/annotation/data/DataStore.java | 192 ---
.../annotation/edm/AnnotationEdmProvider.java | 773 ---------
.../annotation/processor/ListsProcessor.java | 1630 ------------------
.../core/annotation/util/AnnotationHelper.java | 726 --------
.../core/annotation/util/ClassHelper.java | 105 --
.../data/AnnotationsInMemoryDsTest.java | 190 --
.../edm/AnnotationEdmProviderTest.java | 463 -----
.../odata2/core/annotation/model/Building.java | 95 -
.../odata2/core/annotation/model/City.java | 62 -
.../odata2/core/annotation/model/Employee.java | 187 --
.../odata2/core/annotation/model/Location.java | 61 -
.../odata2/core/annotation/model/Manager.java | 47 -
.../annotation/model/ModelSharedConstants.java | 25 -
.../odata2/core/annotation/model/Photo.java | 128 --
.../odata2/core/annotation/model/RefBase.java | 55 -
.../core/annotation/model/ResourceHelper.java | 64 -
.../odata2/core/annotation/model/Room.java | 89 -
.../odata2/core/annotation/model/Team.java | 81 -
.../edm-annotation-webref/pom.xml | 120 --
.../odata2/ref/annotation/model/Building.java | 97 --
.../odata2/ref/annotation/model/City.java | 61 -
.../odata2/ref/annotation/model/Employee.java | 192 ---
.../odata2/ref/annotation/model/Location.java | 60 -
.../odata2/ref/annotation/model/Manager.java | 43 -
.../annotation/model/ModelSharedConstants.java | 25 -
.../odata2/ref/annotation/model/Photo.java | 128 --
.../odata2/ref/annotation/model/RefBase.java | 78 -
.../ref/annotation/model/ResourceHelper.java | 93 -
.../odata2/ref/annotation/model/Room.java | 88 -
.../odata2/ref/annotation/model/Team.java | 73 -
.../processor/AnnotationPocServiceFactory.java | 202 ---
.../src/main/resources/log4j.xml | 39 -
.../src/main/version/version.html | 27 -
.../src/main/webapp/WEB-INF/web.xml | 48 -
.../src/main/webapp/index.jsp | 116 --
odata2-edm-annotation/pom.xml | 30 -
odata2-lib/odata-ref/pom.xml | 2 +-
pom.xml | 2 +-
90 files changed, 7544 insertions(+), 7544 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/pom.xml b/odata2-annotation-processor/annotation-processor-api/pom.xml
new file mode 100644
index 0000000..e42ec20
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+ <name>${project.artifactId}</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-api-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
new file mode 100644
index 0000000..694f199
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.api.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+
+/**
+ * <p>This interface is intended to make it easier to implement an OData
+ * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
+ * properties described in the
+ * Entity Data Model can be retrieved and set.</p>
+ * <p>By obeying these restrictions, data-source implementations get the
+ * following advantages:
+ * <ul>
+ * <li>All system query options can be handled centrally.</li>
+ * <li>Following navigation paths must only be done step by step.</li>
+ * </ul>
+ * </p>
+ *
+ */
+public interface DataSource {
+
+ /**
+ * Retrieves the whole data list for the specified entity set.
+ * @param entitySet the requested {@link EdmEntitySet}
+ * @return the requested data list
+ */
+ List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Retrieves a single data object for the specified entity set and key.
+ * @param entitySet the requested {@link EdmEntitySet}
+ * @param keys the entity key as map of key names to key values
+ * @return the requested data object
+ */
+ Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Retrieves data for the specified function import and key.</p>
+ * <p>This method is called also for function imports that have defined in
+ * their metadata an other HTTP method than <code>GET</code>.</p>
+ * @param function the requested {@link EdmFunctionImport}
+ * @param parameters the parameters of the function import
+ * as map of parameter names to parameter values
+ * @param keys the key of the returned entity set, as map of key names to key values,
+ * if the return type of the function import is a collection of entities
+ * (optional)
+ * @return the requested data object, either a list or a single object;
+ * if the function import's return type is of type <code>Binary</code>,
+ * the returned object(s) must be of type {@link BinaryData}
+ */
+ Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Retrieves related data for the specified source data, entity set, and key.</p>
+ * <p>If the underlying association of the EDM is specified to have target
+ * multiplicity '*' and no target key is given, this method returns a list of
+ * related data, otherwise it returns a single data object.</p>
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the requested target {@link EdmEntitySet}
+ * @param targetKeys the key of the target entity as map of key names to key values
+ * (optional)
+ * @return the requested releated data object, either a list or a single object
+ */
+ Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Retrieves the binary data and the MIME type for the media resource
+ * associated to the specified media-link entry.
+ * @param entitySet the {@link EdmEntitySet} of the media-link entry
+ * @param mediaLinkEntryData the data object of the media-link entry
+ * @return the binary data and the MIME type of the media resource
+ */
+ BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Creates and returns a new instance of the requested data-object type.</p>
+ * <p>This instance must not be part of the corresponding list and should
+ * have empty content, apart from the key and other mandatory properties.
+ * However, intermediate objects to access complex properties must not be
+ * <code>null</code>.</p>
+ * @param entitySet the {@link EdmEntitySet} the object must correspond to
+ * @return the new data object
+ */
+ Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Writes the binary data for the media resource associated to the
+ * specified media-link entry.
+ * @param entitySet the {@link EdmEntitySet} of the media-link entry
+ * @param mediaLinkEntryData the data object of the media-link entry
+ * @param binaryData the binary data of the media resource along with
+ * the MIME type of the binary data
+ */
+ void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * Deletes a single data object identified by the specified entity set and key.
+ * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
+ * @param keys the entity key as map of key names to key values
+ */
+ void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException;
+
+ /**
+ * <p>Inserts an instance into the entity list of the specified entity set.</p>
+ * <p>If {@link #newDataObject} has not set the key and other mandatory
+ * properties already, this method must set them before inserting the
+ * instance into the list.</p>
+ * @param entitySet the {@link EdmEntitySet} the object must correspond to
+ * @param data the data object of the new entity
+ */
+ void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Deletes the relation from the specified source data to a target entity
+ * specified by entity set and key.
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the {@link EdmEntitySet} of the target entity
+ * @param targetKeys the key of the target entity as map of key names to key values
+ * (optional)
+ */
+ void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Writes a relation from the specified source data to a target entity
+ * specified by entity set and key.
+ * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+ * @param sourceData the data object of the source entity
+ * @param targetEntitySet the {@link EdmEntitySet} of the relation target
+ * @param targetKeys the key of the target entity as map of key names to key values
+ */
+ void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+ ODataApplicationException;
+
+ /**
+ * Container to store binary data (as byte array) and the associated MIME type.
+ */
+ public class BinaryData {
+ private final byte[] data;
+ private final String mimeType;
+
+ public BinaryData(final byte[] data, final String mimeType) {
+ this.data = data;
+ this.mimeType = mimeType;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ @Override
+ public String toString() {
+ return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
new file mode 100644
index 0000000..2be5663
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.api.data;
+
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+
+/**
+ * Abstract class for implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
+ * actual data handling.
+ * <br/>
+ * Extend this class and implement a DataSourceProcessor if the default implementation
+ * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
+ */
+public abstract class DataSourceProcessor extends ODataSingleProcessor {
+
+ protected final DataSource dataSource;
+ protected final ValueAccess valueAccess;
+
+ /**
+ * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
+ * and {@link ValueAccess} (accessing values of data objects).
+ *
+ * @param dataSource used for accessing the data objects
+ * @param valueAccess for accessing the values provided by the data objects
+ */
+ public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+ this.dataSource = dataSource;
+ this.valueAccess = valueAccess;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
new file mode 100644
index 0000000..685e1b6
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.api.data;
+
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.exception.ODataException;
+
+/**
+ * This interface is intended to access values in a Java object.
+ */
+public interface ValueAccess {
+
+ /**
+ * Retrieves the value of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the requested {@link EdmProperty}
+ * @return the requested property value
+ */
+ public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException;
+
+ /**
+ * Sets the value of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the {@link EdmProperty}
+ * @param value the new value of the property
+ */
+ public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException;
+
+ /**
+ * Retrieves the Java type of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the requested {@link EdmProperty}
+ * @return the requested Java type
+ */
+ public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException;
+
+ /**
+ * Retrieves the value defined by a mapping object for the given data object.
+ * @param data the Java data object
+ * @param mapping the requested {@link EdmMapping}
+ * @return the requested value
+ */
+ public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException;
+
+ /**
+ * Sets the value defined by a mapping object for the given data object.
+ * @param data the Java data object
+ * @param mapping the {@link EdmMapping}
+ * @param value the new value
+ */
+ public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/pom.xml b/odata2-annotation-processor/annotation-processor-core/pom.xml
new file mode 100644
index 0000000..4732522
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+
+ <parent>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-api-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-api-annotation-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>olingo-odata2-core-incubating</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
new file mode 100644
index 0000000..db03a4c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -0,0 +1,351 @@
+/**
+ * *****************************************************************************
+ * 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.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class AnnotationInMemoryDs implements DataSource {
+
+ private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+ private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
+ private final boolean persistInMemory;
+
+ public AnnotationInMemoryDs(String packageToScan) {
+ this(packageToScan, true);
+ }
+
+ public AnnotationInMemoryDs(String packageToScan, boolean persistInMemory) {
+ this.persistInMemory = persistInMemory;
+ List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+ @Override
+ public boolean isClassValid(Class<?> c) {
+ return null != c.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
+ }
+ });
+
+ init(foundClasses);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void init(List<Class<?>> foundClasses) {
+ for (Class<?> clz : foundClasses) {
+
+ DataStore<Object> dhs = (DataStore<Object>) getDataStore(clz);
+ org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet entitySet =
+ clz.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
+ dataStores.put(entitySet.name(), dhs);
+ }
+ }
+
+ public <T> DataStore<T> getDataStore(Class<T> clazz) {
+ return DataStore.createInMemory(clazz, persistInMemory);
+ }
+
+ @Override
+ public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
+ ODataNotFoundException, EdmException, ODataApplicationException {
+
+ DataStore<Object> holder = getDataStore(entitySet);
+ if (holder != null) {
+ return new ArrayList<Object>(holder.read());
+ }
+
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ @Override
+ public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
+ throws ODataNotFoundException, EdmException, ODataApplicationException {
+
+ DataStore<Object> store = getDataStore(entitySet);
+ if (store != null) {
+ Object keyInstance = store.createInstance();
+ ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+
+ Object result = store.read(keyInstance);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+ }
+
+ @Override
+ public Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+ throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ }
+
+ @Override
+ public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+ DataStore<?> sourceStore = dataStores.get(sourceEntitySet.getName());
+ DataStore<?> targetStore = dataStores.get(targetEntitySet.getName());
+
+ AnnotatedNavInfo navInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
+ sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
+ Field sourceField = navInfo.getFromField();
+ if (sourceField == null) {
+ throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
+ + "', targetStore='" + targetStore + "').");
+ }
+
+ Object navigationInstance = getValue(sourceField, sourceData);
+ List<Object> resultData = new ArrayList<Object>();
+ for (Object targetInstance : targetStore.read()) {
+ if (navigationInstance instanceof Collection) {
+ for (Object object : (Collection<?>) navigationInstance) {
+ if (ANNOTATION_HELPER.keyMatch(targetInstance, object)) {
+ resultData.add(targetInstance);
+ }
+ }
+ } else if (ANNOTATION_HELPER.keyMatch(targetInstance, navigationInstance)) {
+ resultData.add(targetInstance);
+ }
+ }
+
+ if (navInfo.getToMultiplicity() == EdmMultiplicity.MANY) {
+ if (targetKeys.isEmpty()) {
+ return resultData;
+ } else {
+ for (Object result : resultData) {
+ if (ANNOTATION_HELPER.keyMatch(result, targetKeys)) {
+ return result;
+ }
+ }
+ return null;
+ }
+ } else {
+ if (resultData.isEmpty()) {
+ return null;
+ }
+ return resultData.get(0);
+ }
+ }
+
+ @Override
+ public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+ Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
+ Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
+
+ BinaryData db = new BinaryData((byte[]) data, String.valueOf(mimeType));
+ return db;
+ }
+
+ @Override
+ public Object newDataObject(EdmEntitySet entitySet)
+ throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+ DataStore<Object> dataStore = getDataStore(entitySet);
+ if (dataStore != null) {
+ return dataStore.createInstance();
+ }
+
+ throw new ODataRuntimeException("No DataStore found for entitySet with name: " + entitySet.getName());
+ }
+
+ @Override
+ public void writeBinaryData(EdmEntitySet entitySet, Object mediaEntityInstance, BinaryData binaryData)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+ try {
+ ANNOTATION_HELPER.setValueForAnnotatedField(
+ mediaEntityInstance, EdmMediaResourceContent.class, binaryData.getData());
+ ANNOTATION_HELPER.setValueForAnnotatedField(
+ mediaEntityInstance, EdmMediaResourceMimeType.class, binaryData.getMimeType());
+ } catch (ODataAnnotationException e) {
+ throw new ODataRuntimeException("Invalid media resource annotation at entity set '" + entitySet.getName()
+ + "' with message '" + e.getMessage() + "'.", e);
+ }
+ }
+
+ /**
+ * <p>Updates a single data object identified by the specified entity set and key fields of
+ * the data object.</p>
+ * @param entitySet the {@link EdmEntitySet} the object must correspond to
+ * @param data the data object of the new entity
+ * @return updated data object instance
+ * @throws org.apache.olingo.odata2.api.exception.ODataNotImplementedException
+ * @throws org.apache.olingo.odata2.api.edm.EdmException
+ * @throws org.apache.olingo.odata2.api.exception.ODataApplicationException
+ */
+ public Object updateData(EdmEntitySet entitySet, Object data)
+ throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+ DataStore<Object> dataStore = getDataStore(entitySet);
+ return dataStore.update(data);
+ }
+
+ @Override
+ public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+ DataStore<Object> dataStore = getDataStore(entitySet);
+ Object keyInstance = dataStore.createInstance();
+ ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+ dataStore.delete(keyInstance);
+ }
+
+ @Override
+ public void createData(EdmEntitySet entitySet, Object data)
+ throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+ DataStore<Object> dataStore = getDataStore(entitySet);
+ dataStore.create(data);
+ }
+
+ @Override
+ public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetKeys)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+ throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ }
+
+ @Override
+ public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceEntity, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetEntityValues)
+ throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+ // get common data
+ DataStore<Object> sourceStore = dataStores.get(sourceEntitySet.getName());
+ DataStore<Object> targetStore = dataStores.get(targetEntitySet.getName());
+
+ AnnotatedNavInfo commonNavInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
+ sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
+
+ // get and validate source fields
+ Field sourceField = commonNavInfo.getFromField();
+ if (sourceField == null) {
+ throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
+ + "', targetStore='" + targetStore + "').");
+ }
+
+ // get related target entity
+ Object targetEntity = targetStore.createInstance();
+ ANNOTATION_HELPER.setKeyFields(targetEntity, targetEntityValues);
+ targetEntity = targetStore.read(targetEntity);
+
+ // set at source
+ setValueAtNavigationField(sourceEntity, sourceField, targetEntity);
+ // set at target
+ Field targetField = commonNavInfo.getToField();
+ if(targetField != null) {
+ setValueAtNavigationField(targetEntity, targetField, sourceEntity);
+ }
+ }
+
+ /**
+ * Set (Multiplicity != *) or add (Multiplicity == *) <code>value</code> at <code>field</code>
+ * of <code>instance</code>.
+ *
+ * @param instance
+ * @param field
+ * @param value
+ * @throws EdmException
+ */
+ private void setValueAtNavigationField(Object instance, Field field, Object value)
+ throws EdmException {
+ Class<?> fieldTypeClass = field.getType();
+ if (Collection.class.isAssignableFrom(fieldTypeClass)) {
+ @SuppressWarnings("unchecked")
+ Collection<Object> collection = (Collection<Object>) ANNOTATION_HELPER.getValueForField(
+ instance, field.getName(), EdmNavigationProperty.class);
+ if(collection == null) {
+ collection = new ArrayList<Object>();
+ setValue(instance, field, collection);
+ }
+ collection.add(value);
+ } else if(fieldTypeClass.isArray()) {
+ throw new ODataRuntimeException("Write relations for internal used arrays is not supported.");
+ } else {
+ setValue(instance, field, value);
+ }
+ }
+
+ /**
+ * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
+ * ODataRuntimeException is thrown.
+ * Never returns NULL.
+ *
+ * @param entitySet for which the corresponding DataStore is returned
+ * @return a DataStore object
+ * @throws EdmException
+ * @throws ODataRuntimeException if no DataStore is found
+ */
+ private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
+ final String name = entitySet.getName();
+ DataStore<Object> dataStore = dataStores.get(name);
+ if (dataStore == null) {
+ throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
+ }
+ return dataStore;
+ }
+
+ private Object getValue(Field field, Object instance) {
+ try {
+ boolean access = field.isAccessible();
+ field.setAccessible(true);
+ Object value = field.get(instance);
+ field.setAccessible(access);
+ return value;
+ } catch (IllegalArgumentException e) {
+ throw new ODataRuntimeException("Error for getting value of field '"
+ + field + "' at instance '" + instance + "'.", e);
+ } catch (IllegalAccessException e) {
+ throw new ODataRuntimeException("Error for getting value of field '"
+ + field + "' at instance '" + instance + "'.", e);
+ }
+ }
+
+ private void setValue(Object instance, Field field, Object value) {
+ try {
+ boolean access = field.isAccessible();
+ field.setAccessible(true);
+ field.set(instance, value);
+ field.setAccessible(access);
+ } catch (IllegalArgumentException e) {
+ throw new ODataRuntimeException("Error for setting value of field: '"
+ + field + "' at instance: '" + instance + "'.", e);
+ } catch (IllegalAccessException e) {
+ throw new ODataRuntimeException("Error for setting value of field: '"
+ + field + "' at instance: '" + instance + "'.", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
new file mode 100644
index 0000000..14183bf
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.core.annotation.data;
+
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+
+/**
+ *
+ */
+public class AnnotationValueAccess implements ValueAccess {
+ private final AnnotationHelper annotationHelper = new AnnotationHelper();
+
+ /**
+ * Retrieves the value of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the requested {@link EdmProperty}
+ * @return the requested property value
+ */
+ @Override
+ public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+ if(data == null) {
+ return null;
+ } else if (annotationHelper.isEdmAnnotated(data)) {
+ return annotationHelper.getValueForProperty(data, property.getName());
+ }
+ throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ }
+
+ /**
+ * Sets the value of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the {@link EdmProperty}
+ * @param value the new value of the property
+ */
+ @Override
+ public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+ if (annotationHelper.isEdmAnnotated(data)) {
+ annotationHelper.setValueForProperty(data, property.getName(), value);
+ } else {
+ throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ }
+ }
+
+ /**
+ * Retrieves the Java type of an EDM property for the given data object.
+ * @param data the Java data object
+ * @param property the requested {@link EdmProperty}
+ * @return the requested Java type
+ */
+ public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+ if (annotationHelper.isEdmAnnotated(data)) {
+ Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
+ if (fieldType == null) {
+ throw new ODataException("No field type found for property " + property);
+ }
+ return fieldType;
+ }
+ throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ }
+
+ /**
+ * Retrieves the value defined by a mapping object for the given data object.
+ * @param data the Java data object
+ * @param mapping the requested {@link EdmMapping}
+ * @return the requested value
+ */
+ public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+ if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
+ return annotationHelper.getValueForProperty(data, mapping.getMediaResourceMimeTypeKey());
+ }
+ return null;
+ }
+
+ /**
+ * Sets the value defined by a mapping object for the given data object.
+ * @param data the Java data object
+ * @param mapping the {@link EdmMapping}
+ * @param value the new value
+ */
+ public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+ if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
+ annotationHelper.setValueForProperty(data, mapping.getMediaResourceMimeTypeKey(), value);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
new file mode 100644
index 0000000..be3baac
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.core.annotation.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+
+/**
+ * Data access.
+ */
+public class BeanPropertyAccess implements ValueAccess {
+
+ @Override
+ public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+ return getValue(data, getGetterMethodName(property));
+ }
+
+ @Override
+ public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+ final String methodName = getSetterMethodName(getGetterMethodName(property));
+ if (methodName != null) {
+ setValue(data, methodName, value);
+ }
+ }
+
+ @Override
+ public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+ return getType(data, getGetterMethodName(property));
+ }
+
+ @Override
+ public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+ if (mapping != null && mapping.getMimeType() != null) {
+ return getValue(data, mapping.getMimeType());
+ }
+ return null;
+ }
+
+ @Override
+ public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+ if (mapping != null && mapping.getMimeType() != null) {
+ setValue(data, getSetterMethodName(mapping.getMimeType()), value);
+ }
+ }
+
+ private String getGetterMethodName(final EdmProperty property) throws EdmException {
+ final String prefix = isBooleanProperty(property) ? "is" : "get";
+ final String defaultMethodName = prefix + property.getName();
+ return property.getMapping() == null || property.getMapping().getInternalName() == null ?
+ defaultMethodName : property.getMapping().getInternalName();
+ }
+
+ private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
+ return property.isSimple()
+ && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
+ }
+
+ private String getSetterMethodName(final String getterMethodName) {
+ return getterMethodName.contains(".") ?
+ null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
+ }
+
+ private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
+ Object dataObject = data;
+
+ for (final String method : methodName.split("\\.", -1)) {
+ if (dataObject != null) {
+ try {
+ dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
+ } catch (SecurityException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ } catch (NoSuchMethodException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ } catch (IllegalArgumentException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ } catch (IllegalAccessException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ } catch (InvocationTargetException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ }
+ }
+ }
+
+ return dataObject;
+ }
+
+ private <T, V> void setValue(final T data, final String methodName, final V value)
+ throws ODataNotFoundException {
+ try {
+ boolean found = false;
+ for (final Method method : Arrays.asList(data.getClass().getMethods())) {
+ if (method.getName().equals(methodName)) {
+ found = true;
+ final Class<?> type = method.getParameterTypes()[0];
+ if (value == null) {
+ if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
+ || type.equals(long.class) || type.equals(char.class)) {
+ method.invoke(data, 0);
+ } else if (type.equals(float.class) || type.equals(double.class)) {
+ method.invoke(data, 0.0);
+ } else if (type.equals(boolean.class)) {
+ method.invoke(data, false);
+ } else {
+ method.invoke(data, value);
+ }
+ } else {
+ method.invoke(data, value);
+ }
+ break;
+ }
+ }
+ if (!found) {
+ throw new ODataNotFoundException(null);
+ }
+ } catch (SecurityException e) {
+ throw new ODataNotFoundException(null, e);
+ } catch (IllegalArgumentException e) {
+ throw new ODataNotFoundException(null, e);
+ } catch (IllegalAccessException e) {
+ throw new ODataNotFoundException(null, e);
+ } catch (InvocationTargetException e) {
+ throw new ODataNotFoundException(null, e);
+ }
+ }
+
+ private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
+ if (data == null) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON);
+ }
+
+ Class<?> type = data.getClass();
+ for (final String method : methodName.split("\\.", -1)) {
+ try {
+ type = type.getMethod(method).getReturnType();
+ if (type.isPrimitive()) {
+ if (type == boolean.class) {
+ type = Boolean.class;
+ } else if (type == byte.class) {
+ type = Byte.class;
+ } else if (type == short.class) {
+ type = Short.class;
+ } else if (type == int.class) {
+ type = Integer.class;
+ } else if (type == long.class) {
+ type = Long.class;
+ } else if (type == float.class) {
+ type = Float.class;
+ } else if (type == double.class) {
+ type = Double.class;
+ }
+ }
+ } catch (final SecurityException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ } catch (final NoSuchMethodException e) {
+ throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+ }
+ }
+ return type;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
new file mode 100644
index 0000000..696ab9a
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class DataStore<T> {
+
+ private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+ private final List<T> dataStore;
+ private final Class<T> dataTypeClass;
+
+ private int idCounter = 1;
+
+ private static class InMemoryDataStore {
+ private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
+
+ @SuppressWarnings("unchecked")
+ static DataStore<?> getInstance(Class<?> clz, boolean createNewInstance) {
+ DataStore<?> ds = c2ds.get(clz);
+ if (createNewInstance || ds == null) {
+ ds = new DataStore<Object>((Class<Object>) clz);
+ c2ds.put(clz, ds);
+ }
+ return ds;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> DataStore<T> createInMemory(Class<T> clazz) {
+ return (DataStore<T>) InMemoryDataStore.getInstance(clazz, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> DataStore<T> createInMemory(Class<T> clazz, boolean keepExisting) {
+ return (DataStore<T>) InMemoryDataStore.getInstance(clazz, !keepExisting);
+ }
+
+ private DataStore(List<T> wrapStore, Class<T> clz) {
+ dataStore = Collections.synchronizedList(wrapStore);
+ dataTypeClass = clz;
+ }
+
+ private DataStore(Class<T> clz) {
+ this(new ArrayList<T>(), clz);
+ }
+
+ public Class<T> getDataTypeClass() {
+ return dataTypeClass;
+ }
+
+ public String getEntityTypeName() {
+ return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
+ }
+
+ public T createInstance() {
+ try {
+ return dataTypeClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ } catch (IllegalAccessException e) {
+ throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ }
+ }
+
+ public T read(T obj) {
+ List<Object> objKeys = getKeys(obj);
+ for (T stored : dataStore) {
+ if (objKeys.equals(getKeys(stored))) {
+ return stored;
+ }
+ }
+ return null;
+ }
+
+ public Collection<T> read() {
+ return Collections.unmodifiableCollection(dataStore);
+ }
+
+ public T create(T object) throws DataStoreException {
+ synchronized (dataStore) {
+ if (read(object) != null || getKeys(object).contains(null)) {
+ createKeys(object);
+ return this.create(object);
+ }
+ dataStore.add(object);
+ }
+ return object;
+ }
+
+ public T update(T object) {
+ synchronized (dataStore) {
+ T stored = read(object);
+ dataStore.remove(stored);
+ dataStore.add(object);
+ }
+ return object;
+ }
+
+ public T delete(T object) {
+ synchronized (dataStore) {
+ T stored = read(object);
+ if (stored != null) {
+ dataStore.remove(stored);
+ }
+ return stored;
+ }
+ }
+
+ private List<Object> getKeys(T object) {
+ Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
+
+ // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable
+ List<Object> keyList = new ArrayList<Object>(keys.values());
+ return keyList;
+ }
+
+ private T createKeys(T object) throws DataStoreException {
+ List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
+ if (fields.isEmpty()) {
+ throw new DataStoreException("No EdmKey annotated fields found for class " + object.getClass());
+ }
+ Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
+
+ for (Field field : fields) {
+ Object key = createKey(field);
+ fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
+ }
+
+ ANNOTATION_HELPER.setValuesToAnnotatedFields(object, EdmKey.class, fieldName2KeyValue);
+
+ return object;
+ }
+
+ private Object createKey(Field field) {
+ Class<?> type = field.getType();
+
+ if (type == String.class) {
+ return String.valueOf(idCounter++);
+ } else if (type == Integer.class || type == int.class) {
+ return Integer.valueOf(idCounter++);
+ } else if (type == Long.class || type == long.class) {
+ return Long.valueOf(idCounter++);
+ }
+
+ throw new UnsupportedOperationException("Automated key generation for type '" + type
+ + "' is not supported (caused on field '" + field + "').");
+ }
+
+ public static class DataStoreException extends ODataApplicationException {
+ private static final long serialVersionUID = 42L;
+
+ public DataStoreException(String message) {
+ this(message, null);
+ }
+
+ public DataStoreException(String message, Throwable cause) {
+ super(message, Locale.ENGLISH, cause);
+ }
+ }
+}