diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index fb31f09c4..49b2e4c7a 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -345,6 +345,17 @@ public class V4Services extends AbstractServices {
return new ByteArrayInputStream(bos.toByteArray());
}
+ @GET
+ @Path("/Boss")
+ public Response getSingletonBoss(
+ @Context UriInfo uriInfo,
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
+
+ return getEntityInternal(
+ uriInfo.getRequestUri().toASCIIString(), accept, "Boss", StringUtils.EMPTY, format, null, null, false);
+ }
+
@GET
@Path("/Company")
public Response getSingletonCompany(
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
index bddb01729..58e5772fc 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
@@ -125,6 +125,8 @@ public class DataBinder {
properties.add(toJSONProperty((AtomPropertyImpl) property));
}
+ jsonEntity.getAnnotations().addAll(atomEntity.getAnnotations());
+
return jsonEntity;
}
diff --git a/fit/src/main/resources/V40/Boss/entity.full.json b/fit/src/main/resources/V40/Boss/entity.full.json
new file mode 100644
index 000000000..d89b4a58c
--- /dev/null
+++ b/fit/src/main/resources/V40/Boss/entity.full.json
@@ -0,0 +1,46 @@
+{
+ "@odata.context": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/$metadata#Boss",
+ "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "@odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss",
+ "@odata.editLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+ "@Microsoft.Test.OData.Services.ODataWCFService.IsBoss": true,
+ "PersonID": 2,
+ "FirstName": "Jill",
+ "LastName": "Jones",
+ "MiddleName": null,
+ "HomeAddress": null,
+ "Home@odata.type": "#GeographyPoint",
+ "Home": {
+ "type": "Point",
+ "coordinates": [161.8, 15.0],
+ "crs": {
+ "type": "name",
+ "properties": {
+ "name": "EPSG:4326"
+ }
+ }
+ },
+ "Numbers@odata.type": "#Collection(String)",
+ "Numbers": [],
+ "Emails@odata.type": "#Collection(String)",
+ "Emails": [],
+ "City": "Sydney",
+ "Birthday@odata.type": "#DateTimeOffset",
+ "Birthday": "1983-01-15T00:00:00Z",
+ "TimeBetweenLastTwoOrders@odata.type": "#Duration",
+ "TimeBetweenLastTwoOrders": "PT0.0000002S",
+ "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
+ "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
+ "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
+ "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
+ "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
+ "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
+ "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress": {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+ "target": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+ },
+ "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress": {
+ "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+ "target": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Boss/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+ }
+}
diff --git a/fit/src/main/resources/V40/Boss/entity.xml b/fit/src/main/resources/V40/Boss/entity.xml
new file mode 100644
index 000000000..72ccb4c62
--- /dev/null
+++ b/fit/src/main/resources/V40/Boss/entity.xml
@@ -0,0 +1,51 @@
+
+
+
+ http://localhost:9080/stub/StaticService/V40/Static.svc/Boss
+
+
+
+
+
+
+
+
+
+ 2
+ Jill
+ Jones
+
+
+
+
+ 161.8 15.0
+
+
+
+
+ Sydney
+ 1983-01-15T01:00:00+01:00
+ PT0.0000002S
+
+
+ true
+
diff --git a/fit/src/main/resources/V40/badRequest.json b/fit/src/main/resources/V40/badRequest.json
index fbc0c63e1..a7150b1c2 100644
--- a/fit/src/main/resources/V40/badRequest.json
+++ b/fit/src/main/resources/V40/badRequest.json
@@ -1,35 +1,24 @@
{
-
"error": {
-
"code": "400",
-
"message": "Bad request.",
-
"target": "query",
-
"details": [
-
{
-
- "code": "400",
-
- "target": "$search" ,
-
- "message": "Microsoft.Data.OData.BadRequest"
+ "code": "400",
+ "target": "$search",
+ "message": "Microsoft.Data.OData.BadRequest"
}
],
-
"innererror": {
-
- "trace": ["at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings....","callmethod2 etc"],
-
- "context": {"key1":"for debug deployment only"}
+ "trace": ["at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings....", "callmethod2 etc"],
+ "context": {
+ "key1": "for debug deployment only"
+ }
}
}
-
}
diff --git a/fit/src/main/resources/V40/metadata.xml b/fit/src/main/resources/V40/metadata.xml
index 5e7c9c62b..4bb360cb1 100644
--- a/fit/src/main/resources/V40/metadata.xml
+++ b/fit/src/main/resources/V40/metadata.xml
@@ -22,418 +22,441 @@
+
-
-
-
+
+
+
-
+
-
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
+
+
+
-
+
+
-
-
+
+
+
-
+
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+ OrderID
+
+
+
+
+ OrderDetails
+
+
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
\ No newline at end of file
diff --git a/fit/src/main/resources/V40/notFound.json b/fit/src/main/resources/V40/notFound.json
index 2af461881..3f2d311e4 100644
--- a/fit/src/main/resources/V40/notFound.json
+++ b/fit/src/main/resources/V40/notFound.json
@@ -1,35 +1,23 @@
{
-
"error": {
-
"code": "501",
-
"message": "Unsupported functionality",
-
"target": "query",
-
"details": [
-
{
-
- "code": "301",
-
- "target": "$search",
-
- "message": "$search query option not supported"
+ "code": "301",
+ "target": "$search",
+ "message": "$search query option not supported"
}
],
-
"innererror": {
-
- "trace": ["callmethod1 etc","callmethod2 etc"],
-
- "context": {"key1":"for debug deployment only"}
+ "trace": ["callmethod1 etc", "callmethod2 etc"],
+ "context": {
+ "key1": "for debug deployment only"
+ }
}
-
}
-
}
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/ErrorResponseTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/ErrorResponseTestITCase.java
index 7e576f0c0..a9530cc32 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/ErrorResponseTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/ErrorResponseTestITCase.java
@@ -19,11 +19,10 @@
package org.apache.olingo.fit.v4;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
import java.net.URI;
-import java.util.Dictionary;
-
+import java.util.Map;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.commons.api.domain.ODataError;
@@ -34,43 +33,33 @@ import org.junit.Test;
public class ErrorResponseTestITCase extends AbstractTestITCase {
- @Test
- public void jsonError() {
+ @Test
+ public void jsonError() {
+ final URI readURI = getClient().getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("Customers").appendKeySegment(32).
+ build();
- ODataPubFormat format = ODataPubFormat.JSON;
- final URI readURI = getClient().getURIBuilder(testStaticServiceRootURL)
- .appendEntitySetSegment("Customers").appendKeySegment(32)
- .build();
+ final ODataEntityRequest req = getClient().getRetrieveRequestFactory().getEntityRequest(readURI);
+ try {
+ final ODataEntity read = read(ODataPubFormat.JSON, readURI);
- final ODataEntityRequest req = getClient()
- .getRetrieveRequestFactory().getEntityRequest(readURI);
- try {
- final ODataEntity read = read(format, readURI);
- } catch (Exception ex) {
- ODataError err = ((ODataClientErrorException) ex).getODataError();
+ fail("should have got exception");
+ } catch (Exception ex) {
+ final ODataError err = ((ODataClientErrorException) ex).getODataError();
- // verify details
- ODataErrorDetail detail = (ODataErrorDetail) err.getDetails()
- .get(0);
- assertEquals("Code should be correct", "301", detail.getCode());
- assertEquals("Target should be correct", "$search",
- detail.getTarget());
- assertEquals("Message should be correct",
- "$search query option not supported", detail.getMessage());
+ // verify details
+ final ODataErrorDetail detail = (ODataErrorDetail) err.getDetails().get(0);
+ assertEquals("Code should be correct", "301", detail.getCode());
+ assertEquals("Target should be correct", "$search", detail.getTarget());
+ assertEquals("Message should be correct", "$search query option not supported", detail.getMessage());
- // verify inner error dictionary
- Dictionary innerErr = err.getInnerError();
- assertEquals("innerError dictionary size should be correct", 2,
- innerErr.size());
- assertEquals("innerError['context'] should be correct",
- "{\"key1\":\"for debug deployment only\"}",
- innerErr.get("context"));
- assertEquals("innerError['trace'] should be correct",
- "[\"callmethod1 etc\",\"callmethod2 etc\"]",
- innerErr.get("trace"));
- return;
- }
-
- assertNotNull("should have got exception", null);
- }
+ // verify inner error dictionary
+ final Map innerErr = err.getInnerError();
+ assertEquals("innerError dictionary size should be correct", 2, innerErr.size());
+ assertEquals("innerError['context'] should be correct",
+ "{\"key1\":\"for debug deployment only\"}", innerErr.get("context"));
+ assertEquals("innerError['trace'] should be correct",
+ "[\"callmethod1 etc\",\"callmethod2 etc\"]", innerErr.get("trace"));
+ }
+ }
}
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/MetadataTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/MetadataTestITCase.java
index 4a2143701..6db180465 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/MetadataTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/MetadataTestITCase.java
@@ -20,6 +20,7 @@ package org.apache.olingo.fit.v4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.apache.olingo.commons.api.edm.Edm;
@@ -28,35 +29,56 @@ import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmSchema;
import org.apache.olingo.commons.api.edm.EdmTerm;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.annotation.EdmRecord;
import org.apache.olingo.commons.core.edm.primitivetype.EdmBoolean;
import org.junit.Test;
public class MetadataTestITCase extends AbstractTestITCase {
@Test
- public void retrieve() {
- final Edm metadata = client.getRetrieveRequestFactory().
- getMetadataRequest(testStaticServiceRootURL).execute().getBody();
- assertNotNull(metadata);
+ public void retrieve() throws EdmPrimitiveTypeException {
+ final Edm edm = client.getRetrieveRequestFactory().getMetadataRequest(testStaticServiceRootURL).execute().getBody();
+ assertNotNull(edm);
- final EdmEntityType order = metadata.getEntityType(
+ final EdmEntityType order = edm.getEntityType(
new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService", "Order"));
assertNotNull(order);
final EdmProperty orderDate = order.getStructuralProperty("OrderDate");
assertNotNull(orderDate);
assertEquals("Edm.DateTimeOffset", orderDate.getType().getFullQualifiedName().toString());
+
+ final EdmTerm isBoss = edm.getTerm(new FullQualifiedName(edm.getSchemas().get(0).getNamespace(), "IsBoss"));
+ assertNotNull(isBoss);
+ assertEquals(EdmBoolean.getInstance(), isBoss.getType());
+
+ final EdmEntitySet orders = edm.getSchemas().get(0).getEntityContainer().getEntitySet("Orders");
+ assertNotNull(orders);
+ assertFalse(orders.getAnnotations().isEmpty());
+ assertTrue(orders.getAnnotations().get(0).getExpression().isDynamic());
+ assertTrue(orders.getAnnotations().get(0).getExpression().asDynamic().isRecord());
+ final EdmRecord record = orders.getAnnotations().get(0).getExpression().asDynamic().asRecord();
+ assertNotNull(record);
+ assertEquals(3, record.getPropertyValues().size());
+ assertTrue(record.getPropertyValues().get(0).getValue().isConstant());
+ assertTrue(record.getPropertyValues().get(0).getValue().asConstant().getValue().asPrimitive().
+ toCastValue(Boolean.class));
+ assertTrue(record.getPropertyValues().get(1).getValue().asDynamic().isCollection());
+ assertEquals(1, record.getPropertyValues().get(1).getValue().asDynamic().asCollection().getItems().size());
+ assertTrue(record.getPropertyValues().get(1).getValue().asDynamic().asCollection().getItems().get(0).isDynamic());
+ assertEquals("OrderID", record.getPropertyValues().get(1).getValue().asDynamic().asCollection().
+ getItems().get(0).asDynamic().asPropertyPath().getValue());
}
@Test
public void include() {
- final Edm edm = client.getRetrieveRequestFactory().
- getMetadataRequest(testNorthwindRootURL).execute().getBody();
+ final Edm edm = client.getRetrieveRequestFactory().getMetadataRequest(testNorthwindRootURL).execute().getBody();
assertNotNull(edm);
final EdmEntityContainer container = edm.getEntityContainer(
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/SingletonTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/SingletonTestITCase.java
index 4d2df429a..64e7f7103 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/SingletonTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/SingletonTestITCase.java
@@ -20,6 +20,7 @@ package org.apache.olingo.fit.v4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.net.URI;
@@ -29,6 +30,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRe
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
import org.apache.olingo.client.api.uri.v4.URIBuilder;
import org.apache.olingo.client.api.v4.ODataClient;
+import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import org.apache.olingo.commons.api.domain.v4.ODataValuable;
import org.apache.olingo.commons.api.domain.v4.Singleton;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
@@ -55,12 +57,12 @@ public class SingletonTestITCase extends AbstractTestITCase {
}
@Test
- public void readfromAtom() throws EdmPrimitiveTypeException {
+ public void readFromAtom() throws EdmPrimitiveTypeException {
read(client, ODataPubFormat.ATOM);
}
@Test
- public void readfromJSON() throws EdmPrimitiveTypeException {
+ public void readFromJSON() throws EdmPrimitiveTypeException {
read(edmClient, ODataPubFormat.JSON);
}
@@ -69,6 +71,37 @@ public class SingletonTestITCase extends AbstractTestITCase {
read(client, ODataPubFormat.JSON_FULL_METADATA);
}
+ private void readWithAnnotations(final ODataClient client, final ODataPubFormat format)
+ throws EdmPrimitiveTypeException {
+
+ final URIBuilder builder = client.getURIBuilder(testStaticServiceRootURL).appendSingletonSegment("Boss");
+ final ODataEntityRequest singleton =
+ client.getRetrieveRequestFactory().getSingletonRequest(builder.build());
+ singleton.setFormat(format);
+ singleton.setPrefer(client.newPreferences().includeAnnotations("*"));
+ final Singleton boss = singleton.execute().getBody();
+ assertNotNull(boss);
+
+ assertFalse(boss.getAnnotations().isEmpty());
+ final ODataAnnotation isBoss = boss.getAnnotations().get(0);
+ assertTrue(isBoss.getPrimitiveValue().toCastValue(Boolean.class));
+ }
+
+ @Test
+ public void readWithAnnotationsFromAtom() throws EdmPrimitiveTypeException {
+ readWithAnnotations(client, ODataPubFormat.ATOM);
+ }
+
+ @Test
+ public void readWithAnnotationsFromJSON() throws EdmPrimitiveTypeException {
+ readWithAnnotations(edmClient, ODataPubFormat.JSON);
+ }
+
+ @Test
+ public void readWithAnnotationsFromJSONFull() throws EdmPrimitiveTypeException {
+ readWithAnnotations(client, ODataPubFormat.JSON_FULL_METADATA);
+ }
+
private void update(final ODataPubFormat format) throws EdmPrimitiveTypeException {
final Singleton changes = getClient().getObjectFactory().newSingleton(
new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Company"));
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/v4/annotation/EdmRecordImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/v4/annotation/EdmRecordImpl.java
index 270cf87e5..e01f7b039 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/v4/annotation/EdmRecordImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/v4/annotation/EdmRecordImpl.java
@@ -32,14 +32,16 @@ public class EdmRecordImpl extends AbstractEdmAnnotatableDynamicAnnotationExpres
private final List propertyValues;
- private final EdmStructuredType type;
+ private EdmStructuredType type;
public EdmRecordImpl(final Edm edm, final String type, final List propertyValues) {
this.edm = edm;
this.propertyValues = propertyValues;
- final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(type).build();
- this.type = typeInfo.getEntityType() == null ? typeInfo.getComplexType() : typeInfo.getEntityType();
+ if (type != null) {
+ final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(type).build();
+ this.type = typeInfo.getEntityType() == null ? typeInfo.getComplexType() : typeInfo.getEntityType();
+ }
}
@Override
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
index a4a38ea4e..05279517f 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
@@ -145,6 +145,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
final Annotation annotation = new AnnotationImpl();
annotation.setTerm(odataAnnotation.getTerm());
+ annotation.setType(odataAnnotation.getValue().getTypeName());
updateValuable(annotation, odataAnnotation, reference);
annotatable.getAnnotations().add(annotation);
@@ -230,8 +231,16 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
}
}
+ if (fqn == null && annotation.getType() != null) {
+ final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build();
+ if (typeInfo.isPrimitiveType()) {
+ fqn = typeInfo.getPrimitiveTypeKind().getFullQualifiedName();
+ }
+ }
+
final ODataAnnotation odataAnnotation = new ODataAnnotationImpl(annotation.getTerm(),
(org.apache.olingo.commons.api.domain.v4.ODataValue) getODataValue(fqn, annotation, null, null));
+ odataAnnotatable.getAnnotations().add(odataAnnotation);
}
}
@@ -278,7 +287,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
final ODataProperty property = new ODataPropertyImpl(resource.getPayload().getName(),
getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(),
- resource.getPayload(), resource.getContextURL(), resource.getMetadataETag()));
+ resource.getPayload(), resource.getContextURL(), resource.getMetadataETag()));
odataAnnotations(resource.getPayload(), property);
return property;
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
index a9e0b06a6..2edab5ec9 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
@@ -246,8 +246,8 @@ public interface Constants {
public static final String ERROR_TARGET = "target";
public static final String ERROR_DETAILS = "details";
-
- public static final String ERROR_INNERERROR= "innererror";
+
+ public static final String ERROR_INNERERROR = "innererror";
// canonical functions to be applied via dynamic annotation Apply
public static final String CANONICAL_FUNCTION_CONCAT = "odata.concat";
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java
index f899d9aea..1d2b83eb8 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java
@@ -18,8 +18,8 @@
*/
package org.apache.olingo.commons.api.domain;
-import java.util.Dictionary;
import java.util.List;
+import java.util.Map;
/**
* OData error.
@@ -46,7 +46,6 @@ public interface ODataError {
* @return error message.
*/
String getTarget();
-
/**
* Gets error details.
@@ -58,7 +57,7 @@ public interface ODataError {
/**
* Gets server defined key-value pairs for debug environment only.
*
- * @return a Dictionary representing server defined object.
+ * @return a pair representing server defined object.
*/
- Dictionary getInnerError();
+ Map getInnerError();
}
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java
index 462e91e84..48985e53e 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataErrorDetail.java
@@ -19,9 +19,9 @@
package org.apache.olingo.commons.api.domain;
/**
- * OData details, for example - { "error": {..., "details":[
+ * OData details, for example { "error": {..., "details":[
* {"code": "301","target": "$search" ,"message": "$search query option not supported"}
- * ],...}}
+ * ],...}}.
*/
public interface ODataErrorDetail {
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
index 2401a0944..bb115cfca 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
@@ -209,7 +209,7 @@ abstract class AbstractJsonSerializer extends ODataJacksonSerializer {
}
protected void valuable(final JsonGenerator jgen, final Valuable valuable, final String name) throws IOException {
- if (serverMode && !Constants.VALUE.equals(name)) {
+ if (serverMode && !Constants.VALUE.equals(name) && !(valuable instanceof Annotation)) {
String type = valuable.getType();
if (StringUtils.isBlank(type) && valuable.getValue().isPrimitive() || valuable.getValue().isNull()) {
type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java
index 62cbebf27..1e9cf519d 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java
@@ -18,30 +18,22 @@
*/
package org.apache.olingo.commons.core.data;
-import java.util.Dictionary;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
-// {
-// "error": {
-// "code": "501",
-// "message": "Unsupported functionality",
-// "target": "query",
-// "details": [
-// {
-// "code": "301",
-// "target": "$search",
-// "message": "$search query option not supported"
-// }
-// ],
-// "innererror": {
-// "trace": [...],
-// "context": {...}
-// }
-// }
-// }
+/**
+ * Example:
+ *
+ * {
+ * "error": { "code": "501", "message": "Unsupported functionality", "target": "query", "details": [ { "code": "301",
+ * "target": "$search", "message": "$search query option not supported" } ], "innererror": { "trace": [...], "context":
+ * {...} } } }
+ * .
+ */
public abstract class AbstractODataError implements ODataError {
private String code;
@@ -51,9 +43,9 @@ public abstract class AbstractODataError implements ODataError {
private String target;
private List details;
-
- private Dictionary innerError;
-
+
+ private Map innerError = new LinkedHashMap();
+
@Override
public String getCode() {
return code;
@@ -91,11 +83,7 @@ public abstract class AbstractODataError implements ODataError {
}
@Override
- public Dictionary getInnerError() {
+ public Map getInnerError() {
return innerError;
}
-
- public void setInnerError(final Dictionary innerError) {
- this.innerError = innerError;
- }
}
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java
index 50fa1f9b2..36818a9e5 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java
@@ -24,17 +24,12 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
-
import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
@@ -65,29 +60,25 @@ public class JSONODataErrorDeserializer extends AbstractJsonDeserializer details = new ArrayList();
- for (final Iterator itor = errorNode.get(Constants.ERROR_DETAILS).iterator(); itor.hasNext();) {
- details.add(
- itor.next().traverse(parser.getCodec()).>readValueAs(
- new TypeReference() {
- }).getPayload());
- }
-
- error.setDetails(details);
+ final List details = new ArrayList();
+ for (final Iterator itor = errorNode.get(Constants.ERROR_DETAILS).iterator(); itor.hasNext();) {
+ details.add(itor.next().traverse(parser.getCodec()).>readValueAs(
+ new TypeReference() {
+ }).getPayload());
+ }
+
+ error.setDetails(details);
}
if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) {
- JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR);
- Dictionary innerErr = new Hashtable();
- for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) {
- String keyTmp = itor.next();
- String val = innerError.get(keyTmp).toString();
- innerErr.put(keyTmp,val);
- }
-
- error.setInnerError(innerErr);
+ final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR);
+ for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) {
+ final String keyTmp = itor.next();
+ final String val = innerError.get(keyTmp).toString();
+ error.getInnerError().put(keyTmp, val);
+ }
}
}
-
+
return new ResWrap((URI) null, null, error);
}
}
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailDeserializer.java
index 9c2ce7bb5..38ea04342 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailDeserializer.java
@@ -20,47 +20,37 @@ package org.apache.olingo.commons.core.data;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
import java.io.IOException;
import java.net.URI;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.ResWrap;
-import org.apache.olingo.commons.api.domain.ODataErrorDetail;
-public class JSONODataErrorDetailDeserializer extends
- AbstractJsonDeserializer {
+public class JSONODataErrorDetailDeserializer extends AbstractJsonDeserializer {
- @Override
- protected ResWrap doDeserialize(
- final JsonParser parser, final DeserializationContext ctxt)
- throws IOException, JsonProcessingException {
+ @Override
+ protected ResWrap doDeserialize(
+ final JsonParser parser, final DeserializationContext ctxt)
+ throws IOException, JsonProcessingException {
- final JSONODataErrorDetailImpl error = new JSONODataErrorDetailImpl();
- final JsonNode errorNode = parser.getCodec().readTree(parser);
- if (errorNode.has(Constants.ERROR_CODE)) {
- error.setCode(errorNode.get(Constants.ERROR_CODE).textValue());
- }
- if (errorNode.has(Constants.ERROR_MESSAGE)) {
- final JsonNode message = errorNode.get(Constants.ERROR_MESSAGE);
- if (message.isValueNode()) {
- error.setMessage(message.textValue());
- } else if (message.isObject()) {
- error.setMessage(message.get(Constants.VALUE).asText());
- }
- }
- if (errorNode.has(Constants.ERROR_TARGET)) {
- error.setTarget(errorNode.get(Constants.ERROR_TARGET).textValue());
- }
+ final JSONODataErrorDetailImpl error = new JSONODataErrorDetailImpl();
+ final JsonNode errorNode = parser.getCodec().readTree(parser);
+ if (errorNode.has(Constants.ERROR_CODE)) {
+ error.setCode(errorNode.get(Constants.ERROR_CODE).textValue());
+ }
+ if (errorNode.has(Constants.ERROR_MESSAGE)) {
+ final JsonNode message = errorNode.get(Constants.ERROR_MESSAGE);
+ if (message.isValueNode()) {
+ error.setMessage(message.textValue());
+ } else if (message.isObject()) {
+ error.setMessage(message.get(Constants.VALUE).asText());
+ }
+ }
+ if (errorNode.has(Constants.ERROR_TARGET)) {
+ error.setTarget(errorNode.get(Constants.ERROR_TARGET).textValue());
+ }
- return new ResWrap((URI) null, null, error);
- }
+ return new ResWrap((URI) null, null, error);
+ }
}
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailImpl.java
index 2f4585aaf..49f31593a 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDetailImpl.java
@@ -27,36 +27,36 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(using = JSONODataErrorDetailDeserializer.class)
public class JSONODataErrorDetailImpl implements ODataErrorDetail {
- private String code;
+ private String code;
- private String message;
+ private String message;
- private String target;
+ private String target;
- @Override
- public String getCode() {
- return code;
- }
+ @Override
+ public String getCode() {
+ return code;
+ }
- public void setCode(final String code) {
- this.code = code;
- }
+ public void setCode(final String code) {
+ this.code = code;
+ }
- @Override
- public String getMessage() {
- return message;
- }
+ @Override
+ public String getMessage() {
+ return message;
+ }
- public void setMessage(final String message) {
- this.message = message;
- }
+ public void setMessage(final String message) {
+ this.message = message;
+ }
- @Override
- public String getTarget() {
- return target;
- }
+ @Override
+ public String getTarget() {
+ return target;
+ }
- public void setTarget(final String target) {
- this.target = target;
- }
-}
\ No newline at end of file
+ public void setTarget(final String target) {
+ this.target = target;
+ }
+}