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 13:31:27 UTC
[34/52] git commit: Added support for write relations
Added support for write relations
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/e39b0b95
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/e39b0b95
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/e39b0b95
Branch: refs/heads/master
Commit: e39b0b9586aa1c64034fc23d245bbce55d84a63b
Parents: 49786b4
Author: Michael Bolz <mi...@apache.org>
Authored: Tue Dec 3 05:28:05 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Tue Dec 3 08:14:21 2013 +0100
----------------------------------------------------------------------
.../annotation/data/AnnotationInMemoryDs.java | 85 +++++++++++++++++---
.../core/annotation/edm/AnnotationHelper.java | 31 ++++++-
.../data/AnnotationsInMemoryDsTest.java | 8 --
3 files changed, 101 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/e39b0b95/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 d7c7f59..938a0d2 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
@@ -33,6 +33,7 @@ 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.ClassHelper;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
@@ -111,7 +112,9 @@ public class AnnotationInMemoryDs implements ListsDataSource {
DataStore<?> sourceStore = dataStores.get(sourceEntitySet.getName());
DataStore<?> targetStore = dataStores.get(targetEntitySet.getName());
- Field sourceField = extractSourceField(sourceStore, targetStore);
+ 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 + "').");
@@ -131,8 +134,7 @@ public class AnnotationInMemoryDs implements ListsDataSource {
}
}
- EdmNavigationProperty navProperty = sourceField.getAnnotation(EdmNavigationProperty.class);
- if (navProperty.toMultiplicity() == EdmMultiplicity.MANY) {
+ if (navInfo.getToMultiplicity() == EdmMultiplicity.MANY) {
if (targetKeys.isEmpty()) {
return resultData;
} else {
@@ -223,10 +225,63 @@ public class AnnotationInMemoryDs implements ListsDataSource {
}
@Override
- public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
- Map<String, Object> targetKeys)
+ public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceEntity, EdmEntitySet targetEntitySet,
+ Map<String, Object> targetEntityValues)
throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
- throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+ // 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);
+ }
}
/**
@@ -264,10 +319,18 @@ public class AnnotationInMemoryDs implements ListsDataSource {
}
}
- private Field extractSourceField(DataStore<?> sourceStore, DataStore<?> targetStore) {
- Class<?> sourceDataTypeClass = sourceStore.getDataTypeClass();
- Class<?> targetDataTypeClass = targetStore.getDataTypeClass();
-
- return ANNOTATION_HELPER.getCommonNavigationInfo(sourceDataTypeClass, targetDataTypeClass).getFromField();
+ 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/e39b0b95/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
index 462a0bc..08699fa 100644
--- 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
@@ -275,12 +275,18 @@ public class AnnotationHelper {
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);
- if (fields.size() != keys.size()) {
- throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
- + fields + " given key predicates = " + keys);
- }
for (Field field : fields) {
String propertyName = getPropertyName(field);
@@ -327,12 +333,17 @@ public class AnnotationHelper {
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);
@@ -344,6 +355,18 @@ public class AnnotationHelper {
}
}
}
+
+ // 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;
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/e39b0b95/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 3063004..02881f0 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
@@ -39,20 +39,12 @@ public class AnnotationsInMemoryDsTest {
private final AnnotationInMemoryDs datasource;
private AnnotationEdmProvider edmProvider;
private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
- private static final String DEFAULT_NAMESPACE = ModelSharedConstants.NAMESPACE_1;
public AnnotationsInMemoryDsTest() {
datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName());
edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
}
- // @Test(expected = ODataApplicationException.class)
- // public void invalidEntity() throws Exception {
- // EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
- //
- // datasource.createData(edmEntitySet, this);
- // }
-
@Test
public void createSimpleEntity() throws Exception {
EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");