[OLINGO-264] Atom and JSON (de)serializers now dealing with instance annotations
This commit is contained in:
parent
936e19ca49
commit
ec9e8cabf1
|
@ -166,6 +166,7 @@ public class JSONTest extends AbstractTest {
|
|||
entity("Advertisements_f89dee73-af9f-4cd4-b330-db93c25ff3c7", getODataPubFormat());
|
||||
entity("entityReference", getODataPubFormat());
|
||||
entity("entity.withcomplexnavigation", getODataPubFormat());
|
||||
entity("annotated", getODataPubFormat());
|
||||
}
|
||||
|
||||
protected void property(final String filename, final ODataFormat format) throws Exception {
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"odata.metadata":"http://services.odata.org/V3/OData/OData.svc/$metadata#PersonDetails/@Element","odata.type":"ODataDemo.PersonDetail","odata.id":"http://services.odata.org/V3/OData/OData.svc/PersonDetails(0)","odata.editLink":"PersonDetails(0)","Person@odata.navigationLinkUrl":"PersonDetails(0)/Person","Person@odata.associationLinkUrl":"PersonDetails(0)/$links/Person","Person":{"odata.type":"ODataDemo.Person","odata.id":"http://services.odata.org/V3/OData/OData.svc/Persons(0)","odata.editLink":"Persons(0)","PersonDetail@odata.navigationLinkUrl":"Persons(0)/PersonDetail","PersonDetail@odata.associationLinkUrl":"Persons(0)/$links/PersonDetail","ID":0,"Name":"Paula Wilson"},"PersonID":0,"Age@odata.type":"Edm.Byte","Age":21,"Gender":false,"Phone":"(505) 555-5939","Address":{"odata.type":"ODataDemo.Address","Street":"2817 Milton Dr.","City":"Albuquerque","State":"NM","ZipCode":"87110","Country":"USA"},"Photo@odata.mediaEditLink":"PersonDetails(0)/Photo","Photo@odata.mediaETag":"\"nCP1Tf4Uax96eYIWjvoC/6ZflG8=\""}
|
||||
{"odata.metadata":"http://services.odata.org/V3/OData/OData.svc/$metadata#PersonDetails/@Element","odata.type":"ODataDemo.PersonDetail","odata.id":"http://services.odata.org/V3/OData/OData.svc/PersonDetails(0)","odata.editLink":"PersonDetails(0)","Person@odata.navigationLinkUrl":"PersonDetails(0)/Person","Person@odata.associationLinkUrl":"PersonDetails(0)/$links/Person","Person":{"odata.type":"ODataDemo.Person","odata.id":"http://services.odata.org/V3/OData/OData.svc/Persons(0)","odata.editLink":"Persons(0)","PersonDetail@odata.navigationLinkUrl":"Persons(0)/PersonDetail","PersonDetail@odata.associationLinkUrl":"Persons(0)/$links/PersonDetail","ID":0,"Name":"Paula Wilson"},"PersonID":0,"Age@odata.type":"Edm.Byte","Age":21,"Gender":false,"Phone":"(505) 555-5939","Address":{"odata.type":"ODataDemo.Address","Street":"2817 Milton Dr.","City":"Albuquerque","State":"NM","ZipCode":"87110","Country":"USA"},"Photo@odata.mediaEditLink":"PersonDetails(0)/Photo","Photo@odata.mediaEtag":"\"nCP1Tf4Uax96eYIWjvoC/6ZflG8=\""}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers/$entity",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
|
||||
"@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
|
||||
"@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
|
||||
"@com.contoso.display.highlight": true,
|
||||
"@com.contoso.PersonalInfo.PhoneNumbers": ["(203)555-1718", "(203)555-1719"],
|
||||
"PersonID": 1,
|
||||
"FirstName": "Bob",
|
||||
"LastName@com.contoso.display.style": {
|
||||
"@odata.type": "#com.contoso.display.styleType",
|
||||
"title": true,
|
||||
"order": 1
|
||||
},
|
||||
"LastName": "Cat",
|
||||
"MiddleName": null,
|
||||
"HomeAddress": {
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
|
||||
"Street": "1 Microsoft Way",
|
||||
"City": "London",
|
||||
"PostalCode": "98052",
|
||||
"FamilyName": "Cats"
|
||||
},
|
||||
"Home@odata.type": "#GeographyPoint",
|
||||
"Home": {
|
||||
"type": "Point",
|
||||
"coordinates": [23.1, 32.1],
|
||||
"crs": {
|
||||
"type": "name",
|
||||
"properties": {
|
||||
"name": "EPSG:4326"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Numbers@odata.type": "#Collection(String)",
|
||||
"Numbers": ["111-111-1111", "0-12", "3-10", "bca", "ayz"],
|
||||
"Emails@odata.type": "#Collection(String)",
|
||||
"Emails": ["abc@abc.com"],
|
||||
"City": "London",
|
||||
"Birthday@odata.type": "#DateTimeOffset",
|
||||
"Birthday": "1957-04-03T00:00:00Z",
|
||||
"TimeBetweenLastTwoOrders@odata.type": "#Duration",
|
||||
"TimeBetweenLastTwoOrders": "PT0.0000001S",
|
||||
"Parent@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent/$ref",
|
||||
"Parent@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent",
|
||||
"Orders@com.contoso.display.style": {
|
||||
"@odata.type": "#com.contoso.display.styleType",
|
||||
"order": 2
|
||||
},
|
||||
"Orders@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders/$ref",
|
||||
"Orders@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders",
|
||||
"Company@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company/$ref",
|
||||
"Company@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company",
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress": {
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
|
||||
"target": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
|
||||
},
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress": {
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
|
||||
"target": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Products/$entity">
|
||||
<id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
|
||||
<link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)"/>
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent"/>
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders">
|
||||
<m:annotation term="com.contoso.display.style" m:type="#com.contoso.display.styleType">
|
||||
<d:order m:type="Int32">2</d:order>
|
||||
</m:annotation>
|
||||
</link>
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company"/>
|
||||
<title/>
|
||||
<updated>2014-03-31T09:35:14Z</updated>
|
||||
<author>
|
||||
<name/>
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:PersonID m:type="Int32">1</d:PersonID>
|
||||
<d:FirstName>Bob</d:FirstName>
|
||||
<d:LastName>Cat</d:LastName>
|
||||
<m:annotation term="com.contoso.display.style" target="LastName" m:type="#com.contoso.display.styleType">
|
||||
<d:title m:type="Boolean">true</d:title>
|
||||
<d:order m:type="Int32">1</d:order>
|
||||
</m:annotation>
|
||||
<d:MiddleName m:null="true"/>
|
||||
<d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
|
||||
<d:Street>1 Microsoft Way</d:Street>
|
||||
<d:City>London</d:City>
|
||||
<d:PostalCode>98052</d:PostalCode>
|
||||
<d:FamilyName>Cats</d:FamilyName>
|
||||
</d:HomeAddress>
|
||||
<d:Home m:type="GeographyPoint">
|
||||
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
|
||||
<gml:pos>32.1 23.1</gml:pos>
|
||||
</gml:Point>
|
||||
</d:Home>
|
||||
<d:Numbers m:type="#Collection(String)">
|
||||
<m:element>111-111-1111</m:element>
|
||||
</d:Numbers>
|
||||
<d:Emails m:type="#Collection(String)">
|
||||
<m:element>abc@abc.com</m:element>
|
||||
</d:Emails>
|
||||
<d:City>London</d:City>
|
||||
<d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
|
||||
<d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
|
||||
</m:properties>
|
||||
</content>
|
||||
<m:annotation term="com.contoso.display.highlight" m:type="Boolean">true</m:annotation>
|
||||
<m:annotation term="com.contoso.PersonalInfo.PhoneNumbers" m:type="#Collection(String)">
|
||||
<m:element>(203)555-1718</m:element>
|
||||
<m:element>(203)555-1719</m:element>
|
||||
</m:annotation>
|
||||
</entry>
|
||||
|
|
@ -152,6 +152,8 @@ public interface Constants {
|
|||
|
||||
public static final String ATTR_RELATIONSHIP = "relationship";
|
||||
|
||||
public static final String ANNOTATION = "annotation";
|
||||
|
||||
// JSON stuff
|
||||
public final static String JSON_METADATA = "odata.metadata";
|
||||
|
||||
|
|
|
@ -21,17 +21,9 @@ package org.apache.olingo.commons.api.data;
|
|||
/**
|
||||
* Represents an instance annotation.
|
||||
*/
|
||||
public interface Annotation {
|
||||
public interface Annotation extends Valuable {
|
||||
|
||||
String getTerm();
|
||||
|
||||
void setTerm(String term);
|
||||
|
||||
String getType();
|
||||
|
||||
void setType(String type);
|
||||
|
||||
Value getValue();
|
||||
|
||||
void setValue(Value value);
|
||||
}
|
||||
|
|
|
@ -18,17 +18,9 @@
|
|||
*/
|
||||
package org.apache.olingo.commons.api.data;
|
||||
|
||||
public interface Property extends Annotatable {
|
||||
public interface Property extends Valuable, Annotatable {
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
String getType();
|
||||
|
||||
void setType(String type);
|
||||
|
||||
Value getValue();
|
||||
|
||||
void setValue(Value value);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.commons.api.data;
|
||||
|
||||
public interface Valuable {
|
||||
|
||||
String getType();
|
||||
|
||||
void setType(String type);
|
||||
|
||||
Value getValue();
|
||||
|
||||
void setValue(Value value);
|
||||
}
|
|
@ -54,6 +54,8 @@ abstract class AbstractAtomDealer {
|
|||
|
||||
protected final QName nextQName;
|
||||
|
||||
protected final QName annotationQName;
|
||||
|
||||
protected final QName contextQName;
|
||||
|
||||
protected final QName entryRefQName;
|
||||
|
@ -98,6 +100,8 @@ abstract class AbstractAtomDealer {
|
|||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_URI);
|
||||
this.nextQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.NEXT_LINK_REL);
|
||||
this.annotationQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ANNOTATION);
|
||||
this.contextQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.CONTEXT);
|
||||
this.entryRefQName =
|
||||
|
|
|
@ -27,14 +27,21 @@ import java.io.IOException;
|
|||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotatable;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.CollectionValue;
|
||||
import org.apache.olingo.commons.api.data.ComplexValue;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Linked;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Valuable;
|
||||
import org.apache.olingo.commons.api.data.Value;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
import org.apache.olingo.commons.api.domain.ODataPropertyType;
|
||||
|
@ -44,6 +51,8 @@ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
|
|||
|
||||
abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResWrap<T>> {
|
||||
|
||||
protected final Pattern CUSTOM_ANNOTATION = Pattern.compile("(.+)@(.+)\\.(.+)");
|
||||
|
||||
private JSONGeoValueDeserializer geoDeserializer;
|
||||
|
||||
private JSONGeoValueDeserializer getGeoDeserializer() {
|
||||
|
@ -203,6 +212,48 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
|||
return new SimpleEntry<ODataPropertyType, EdmTypeInfo>(type, typeInfo);
|
||||
}
|
||||
|
||||
protected void populate(final Annotatable annotatable, final List<Property> properties,
|
||||
final ObjectNode tree, final ObjectCodec codec) throws IOException {
|
||||
|
||||
String type = null;
|
||||
Annotation annotation = null;
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
final Matcher customAnnotation = CUSTOM_ANNOTATION.matcher(field.getKey());
|
||||
|
||||
if (field.getKey().charAt(0) == '@') {
|
||||
final Annotation entityAnnot = new AnnotationImpl();
|
||||
entityAnnot.setTerm(field.getKey().substring(1));
|
||||
|
||||
value(entityAnnot, field.getValue(), codec);
|
||||
if (annotatable != null) {
|
||||
annotatable.getAnnotations().add(entityAnnot);
|
||||
}
|
||||
} else if (type == null && field.getKey().endsWith(getJSONAnnotation(jsonType))) {
|
||||
type = field.getValue().asText();
|
||||
} else if (annotation == null && customAnnotation.matches() && !"odata".equals(customAnnotation.group(2))) {
|
||||
annotation = new AnnotationImpl();
|
||||
annotation.setTerm(customAnnotation.group(2) + "." + customAnnotation.group(3));
|
||||
value(annotation, field.getValue(), codec);
|
||||
} else {
|
||||
final JSONPropertyImpl property = new JSONPropertyImpl();
|
||||
property.setName(field.getKey());
|
||||
property.setType(type == null
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
|
||||
type = null;
|
||||
|
||||
value(property, field.getValue(), codec);
|
||||
properties.add(property);
|
||||
|
||||
if (annotation != null) {
|
||||
property.getAnnotations().add(annotation);
|
||||
annotation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
|
||||
final Value value;
|
||||
|
||||
|
@ -234,22 +285,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
|||
node.remove(toRemove);
|
||||
}
|
||||
|
||||
String type = null;
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
|
||||
if (type == null && field.getKey().endsWith(getJSONAnnotation(jsonType))) {
|
||||
type = field.getValue().asText();
|
||||
} else {
|
||||
final JSONPropertyImpl property = new JSONPropertyImpl();
|
||||
property.setName(field.getKey());
|
||||
property.setType(type);
|
||||
type = null;
|
||||
|
||||
value(property, field.getValue(), codec);
|
||||
value.get().add(property);
|
||||
}
|
||||
}
|
||||
populate(value.asLinkedComplex(), value.get(), node, codec);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -283,12 +319,12 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
|||
return value;
|
||||
}
|
||||
|
||||
protected void value(final JSONPropertyImpl property, final JsonNode node, final ObjectCodec codec)
|
||||
protected void value(final Valuable valuable, final JsonNode node, final ObjectCodec codec)
|
||||
throws IOException {
|
||||
|
||||
EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
|
||||
EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType())
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
|
||||
|
||||
final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
|
||||
if (typeInfo == null) {
|
||||
|
@ -307,31 +343,31 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
|||
|
||||
switch (propType) {
|
||||
case COLLECTION:
|
||||
property.setValue(fromCollection(node.elements(), typeInfo, codec));
|
||||
valuable.setValue(fromCollection(node.elements(), typeInfo, codec));
|
||||
break;
|
||||
|
||||
case COMPLEX:
|
||||
if (node.has(jsonType)) {
|
||||
property.setType(node.get(jsonType).asText());
|
||||
valuable.setType(node.get(jsonType).asText());
|
||||
((ObjectNode) node).remove(jsonType);
|
||||
}
|
||||
property.setValue(fromComplex((ObjectNode) node, codec));
|
||||
valuable.setValue(fromComplex((ObjectNode) node, codec));
|
||||
break;
|
||||
|
||||
case ENUM:
|
||||
property.setValue(new EnumValueImpl(node.asText()));
|
||||
valuable.setValue(new EnumValueImpl(node.asText()));
|
||||
break;
|
||||
|
||||
case PRIMITIVE:
|
||||
if (property.getType() == null && typeInfo != null) {
|
||||
property.setType(typeInfo.getFullQualifiedName().toString());
|
||||
if (valuable.getType() == null && typeInfo != null) {
|
||||
valuable.setType(typeInfo.getFullQualifiedName().toString());
|
||||
}
|
||||
property.setValue(fromPrimitive(node, typeInfo));
|
||||
valuable.setValue(fromPrimitive(node, typeInfo));
|
||||
break;
|
||||
|
||||
case EMPTY:
|
||||
default:
|
||||
property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
|
||||
valuable.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,15 @@ import org.apache.commons.lang3.BooleanUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotatable;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.CollectionValue;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.data.Linked;
|
||||
import org.apache.olingo.commons.api.data.PrimitiveValue;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.Valuable;
|
||||
import org.apache.olingo.commons.api.data.Value;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
|
@ -62,6 +65,10 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
|
|||
protected void clientLinks(final Linked linked, final JsonGenerator jgen) throws IOException {
|
||||
final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>();
|
||||
for (Link link : linked.getNavigationLinks()) {
|
||||
for (Annotation annotation : link.getAnnotations()) {
|
||||
valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm());
|
||||
}
|
||||
|
||||
ODataLinkType type = null;
|
||||
try {
|
||||
type = ODataLinkType.fromString(version, link.getRel(), link.getType());
|
||||
|
@ -185,7 +192,7 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
|
|||
} else if (value.isComplex()) {
|
||||
jgen.writeStartObject();
|
||||
for (Property property : value.asComplex().get()) {
|
||||
property(jgen, property, property.getName());
|
||||
valuable(jgen, property, property.getName());
|
||||
}
|
||||
if (value.isLinkedComplex()) {
|
||||
links(value.asLinkedComplex(), jgen);
|
||||
|
@ -194,12 +201,10 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
|
|||
}
|
||||
}
|
||||
|
||||
protected void property(final JsonGenerator jgen, final Property property, final String name) throws IOException {
|
||||
protected void valuable(final JsonGenerator jgen, final Valuable valuable, final String name) throws IOException {
|
||||
if (serverMode && !Constants.VALUE.equals(name)) {
|
||||
String type = property.getType();
|
||||
if (StringUtils.isBlank(type)
|
||||
&& property.getValue().isPrimitive() || property.getValue().isNull()) {
|
||||
|
||||
String type = valuable.getType();
|
||||
if (StringUtils.isBlank(type) && valuable.getValue().isPrimitive() || valuable.getValue().isNull()) {
|
||||
type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
|
||||
}
|
||||
if (StringUtils.isNotBlank(type)) {
|
||||
|
@ -209,7 +214,13 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
|
|||
}
|
||||
}
|
||||
|
||||
if (valuable instanceof Annotatable) {
|
||||
for (Annotation annotation : ((Annotatable) valuable).getAnnotations()) {
|
||||
valuable(jgen, annotation, name + "@" + annotation.getTerm());
|
||||
}
|
||||
}
|
||||
|
||||
jgen.writeFieldName(name);
|
||||
value(jgen, property.getType(), property.getValue());
|
||||
value(jgen, valuable.getType(), valuable.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.apache.olingo.commons.api.data.Value;
|
|||
|
||||
public abstract class AbstractProperty extends AbstractAnnotatedObject implements Property {
|
||||
|
||||
private static final long serialVersionUID = -7175704800169997060L;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.commons.core.data;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.Value;
|
||||
|
||||
public class AnnotationImpl extends AbstractAnnotatedObject implements Annotation {
|
||||
|
||||
private static final long serialVersionUID = -2532246000091187020L;
|
||||
|
||||
private String term;
|
||||
|
||||
private String type;
|
||||
|
||||
private Value value;
|
||||
|
||||
@Override
|
||||
public String getTerm() {
|
||||
return term;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTerm(final String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(final Value value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -23,6 +23,10 @@ import org.apache.olingo.commons.core.data.v4.AtomDeltaImpl;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
|
@ -32,10 +36,13 @@ import javax.xml.stream.events.StartElement;
|
|||
import javax.xml.stream.events.XMLEvent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.CollectionValue;
|
||||
import org.apache.olingo.commons.api.data.DeletedEntity.Reason;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Valuable;
|
||||
import org.apache.olingo.commons.api.data.Value;
|
||||
import org.apache.olingo.commons.api.domain.ODataOperation;
|
||||
import org.apache.olingo.commons.api.domain.ODataPropertyType;
|
||||
|
@ -242,6 +249,14 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
property.setName(start.getName().getLocalPart());
|
||||
}
|
||||
|
||||
valuable(property, reader, start);
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
private void valuable(final Valuable valuable, final XMLEventReader reader, final StartElement start)
|
||||
throws XMLStreamException {
|
||||
|
||||
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
|
||||
|
||||
Value value;
|
||||
|
@ -254,7 +269,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
: new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
|
||||
|
||||
if (typeInfo != null) {
|
||||
property.setType(typeInfo.internal());
|
||||
valuable.setType(typeInfo.internal());
|
||||
}
|
||||
|
||||
final ODataPropertyType propType = typeInfo == null
|
||||
|
@ -277,7 +292,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
case PRIMITIVE:
|
||||
// No type specified? Defaults to Edm.String
|
||||
if (typeInfo == null) {
|
||||
property.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString());
|
||||
valuable.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString());
|
||||
}
|
||||
value = fromPrimitive(reader, start, typeInfo);
|
||||
break;
|
||||
|
@ -290,9 +305,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
value = new NullValueImpl();
|
||||
}
|
||||
|
||||
property.setValue(value);
|
||||
|
||||
return property;
|
||||
valuable.setValue(value);
|
||||
}
|
||||
|
||||
private ResWrap<AtomPropertyImpl> property(final InputStream input) throws XMLStreamException {
|
||||
|
@ -344,23 +357,27 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
while (reader.hasNext() && !foundEndElement) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
|
||||
if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
|
||||
StartElement inline = null;
|
||||
while (reader.hasNext() && inline == null) {
|
||||
final XMLEvent innerEvent = reader.peek();
|
||||
if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
|
||||
reader.nextEvent();
|
||||
} else if (innerEvent.isStartElement()) {
|
||||
inline = innerEvent.asStartElement();
|
||||
if (event.isStartElement()) {
|
||||
if (inlineQName.equals(event.asStartElement().getName())) {
|
||||
StartElement inline = null;
|
||||
while (reader.hasNext() && inline == null) {
|
||||
final XMLEvent innerEvent = reader.peek();
|
||||
if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
|
||||
reader.nextEvent();
|
||||
} else if (innerEvent.isStartElement()) {
|
||||
inline = innerEvent.asStartElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inline != null) {
|
||||
if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
|
||||
link.setInlineEntity(entity(reader, inline));
|
||||
}
|
||||
if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
|
||||
link.setInlineEntitySet(entitySet(reader, inline));
|
||||
if (inline != null) {
|
||||
if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
|
||||
link.setInlineEntity(entity(reader, inline));
|
||||
}
|
||||
if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
|
||||
link.setInlineEntitySet(entitySet(reader, inline));
|
||||
}
|
||||
}
|
||||
} else if (annotationQName.equals(event.asStartElement().getName())) {
|
||||
link.getAnnotations().add(annotation(reader, event.asStartElement()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,18 +519,47 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
|
||||
private void properties(final XMLEventReader reader, final StartElement start, final AtomEntityImpl entity)
|
||||
throws XMLStreamException {
|
||||
|
||||
final Map<String, List<Annotation>> annotations = new HashMap<String, List<Annotation>>();
|
||||
|
||||
boolean foundEndProperties = false;
|
||||
while (reader.hasNext() && !foundEndProperties) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
|
||||
if (event.isStartElement()) {
|
||||
entity.getProperties().add(property(reader, event.asStartElement()));
|
||||
if (annotationQName.equals(event.asStartElement().getName())) {
|
||||
final String target = event.asStartElement().
|
||||
getAttributeByName(QName.valueOf(Constants.ATTR_TARGET)).getValue();
|
||||
if (!annotations.containsKey(target)) {
|
||||
annotations.put(target, new ArrayList<Annotation>());
|
||||
}
|
||||
annotations.get(target).add(annotation(reader, event.asStartElement()));
|
||||
} else {
|
||||
entity.getProperties().add(property(reader, event.asStartElement()));
|
||||
}
|
||||
}
|
||||
|
||||
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
|
||||
foundEndProperties = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (Property property : entity.getProperties()) {
|
||||
if (annotations.containsKey(property.getName())) {
|
||||
property.getAnnotations().addAll(annotations.get(property.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Annotation annotation(final XMLEventReader reader, final StartElement start)
|
||||
throws XMLStreamException {
|
||||
|
||||
final Annotation annotation = new AnnotationImpl();
|
||||
|
||||
annotation.setTerm(start.getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM)).getValue());
|
||||
valuable(annotation, reader, start);
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
private AtomEntityImpl entityRef(final StartElement start) throws XMLStreamException {
|
||||
|
@ -636,6 +682,8 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
}
|
||||
} else if (propertiesQName.equals(event.asStartElement().getName())) {
|
||||
properties(reader, event.asStartElement(), entity);
|
||||
} else if (annotationQName.equals(event.asStartElement().getName())) {
|
||||
entity.getAnnotations().add(annotation(reader, event.asStartElement()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,8 +691,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
foundEndEntry = true;
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
} else {
|
||||
entity = null;
|
||||
}
|
||||
|
@ -719,6 +765,8 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
entitySet.getEntities().add(entity(reader, event.asStartElement()));
|
||||
} else if (entryRefQName.equals(event.asStartElement().getName())) {
|
||||
entitySet.getEntities().add(entityRef(event.asStartElement()));
|
||||
} else if (annotationQName.equals(event.asStartElement().getName())) {
|
||||
entitySet.getAnnotations().add(annotation(reader, event.asStartElement()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import javax.xml.stream.XMLStreamException;
|
|||
import javax.xml.stream.XMLStreamWriter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.CollectionValue;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
|
@ -124,6 +125,10 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
|
||||
for (Annotation annotation : property.getAnnotations()) {
|
||||
annotation(writer, annotation, property.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void property(final XMLStreamWriter writer, final Property property) throws XMLStreamException {
|
||||
|
@ -185,6 +190,10 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
for (Annotation annotation : link.getAnnotations()) {
|
||||
annotation(writer, annotation, null);
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +220,36 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
}
|
||||
}
|
||||
|
||||
private void annotation(final XMLStreamWriter writer, final Annotation annotation, final String target)
|
||||
throws XMLStreamException {
|
||||
|
||||
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ANNOTATION,
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
|
||||
|
||||
writer.writeAttribute(Constants.ATOM_ATTR_TERM, annotation.getTerm());
|
||||
|
||||
if (target != null) {
|
||||
writer.writeAttribute(Constants.ATTR_TARGET, target);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(annotation.getType())) {
|
||||
final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build();
|
||||
if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
|
||||
writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
|
||||
Constants.ATTR_TYPE, typeInfo.external(version));
|
||||
}
|
||||
}
|
||||
|
||||
if (annotation.getValue().isNull()) {
|
||||
writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
|
||||
Constants.ATTR_NULL, Boolean.TRUE.toString());
|
||||
} else {
|
||||
value(writer, annotation.getValue());
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
private void entity(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
|
||||
if (entity.getBaseURI() != null) {
|
||||
writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entity.getBaseURI().toASCIIString());
|
||||
|
@ -284,6 +323,10 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
writer.writeEndElement();
|
||||
}
|
||||
writer.writeEndElement();
|
||||
|
||||
for (Annotation annotation : entity.getAnnotations()) {
|
||||
annotation(writer, annotation, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void entityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
|
||||
|
|
|
@ -26,12 +26,17 @@ 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.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
|
@ -106,7 +111,6 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
|||
|
||||
if (tree.hasNonNull(jsonEditLink)) {
|
||||
final LinkImpl link = new LinkImpl();
|
||||
// Server mode
|
||||
if (serverMode) {
|
||||
link.setRel(Constants.EDIT_LINK_REL);
|
||||
}
|
||||
|
@ -134,8 +138,11 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
|||
}
|
||||
|
||||
final Set<String> toRemove = new HashSet<String>();
|
||||
|
||||
final Map<String, List<Annotation>> annotations = new HashMap<String, List<Annotation>>();
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
final Matcher customAnnotation = CUSTOM_ANNOTATION.matcher(field.getKey());
|
||||
|
||||
links(field, entity, toRemove, tree, parser.getCodec());
|
||||
if (field.getKey().endsWith(getJSONAnnotation(jsonMediaEditLink))) {
|
||||
|
@ -172,29 +179,39 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
|||
entity.getOperations().add(operation);
|
||||
|
||||
toRemove.add(field.getKey());
|
||||
} else if (customAnnotation.matches() && !"odata".equals(customAnnotation.group(2))) {
|
||||
final Annotation annotation = new AnnotationImpl();
|
||||
annotation.setTerm(customAnnotation.group(2) + "." + customAnnotation.group(3));
|
||||
value(annotation, field.getValue(), parser.getCodec());
|
||||
|
||||
if (!annotations.containsKey(customAnnotation.group(1))) {
|
||||
annotations.put(customAnnotation.group(1), new ArrayList<Annotation>());
|
||||
}
|
||||
annotations.get(customAnnotation.group(1)).add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
for (Link link : entity.getNavigationLinks()) {
|
||||
if (annotations.containsKey(link.getTitle())) {
|
||||
link.getAnnotations().addAll(annotations.get(link.getTitle()));
|
||||
for (Annotation annotation : annotations.get(link.getTitle())) {
|
||||
toRemove.add(link.getTitle() + "@" + annotation.getTerm());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Link link : entity.getMediaEditLinks()) {
|
||||
if (annotations.containsKey(link.getTitle())) {
|
||||
link.getAnnotations().addAll(annotations.get(link.getTitle()));
|
||||
for (Annotation annotation : annotations.get(link.getTitle())) {
|
||||
toRemove.add(link.getTitle() + "@" + annotation.getTerm());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tree.remove(toRemove);
|
||||
|
||||
String type = null;
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
populate(entity, entity.getProperties(), tree, parser.getCodec());
|
||||
|
||||
if (type == null && field.getKey().endsWith(getJSONAnnotation(jsonType))) {
|
||||
type = field.getValue().asText();
|
||||
} else {
|
||||
final JSONPropertyImpl property = new JSONPropertyImpl();
|
||||
property.setName(field.getKey());
|
||||
property.setType(type == null
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
|
||||
type = null;
|
||||
|
||||
value(property, field.getValue(), parser.getCodec());
|
||||
entity.getProperties().add(property);
|
||||
}
|
||||
}
|
||||
|
||||
return new ResWrap<JSONEntityImpl>(contextURL, metadataETag, entity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
|
@ -78,8 +79,12 @@ public class JSONEntitySerializer extends AbstractJsonSerializer<JSONEntityImpl>
|
|||
jgen.writeStringField(version.getJSONMap().get(ODataServiceVersion.JSON_ID), entity.getId());
|
||||
}
|
||||
|
||||
for (Annotation annotation : entity.getAnnotations()) {
|
||||
valuable(jgen, annotation, "@" + annotation.getTerm());
|
||||
}
|
||||
|
||||
for (Property property : entity.getProperties()) {
|
||||
property(jgen, property, property.getName());
|
||||
valuable(jgen, property, property.getName());
|
||||
}
|
||||
|
||||
if (serverMode && entity.getEditLink() != null && StringUtils.isNotBlank(entity.getEditLink().getHref())) {
|
||||
|
|
|
@ -27,8 +27,10 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
|
||||
/**
|
||||
|
@ -74,12 +76,15 @@ public class JSONEntitySetDeserializer extends AbstractJsonDeserializer<JSONEnti
|
|||
|
||||
if (tree.hasNonNull(jsonCount)) {
|
||||
entitySet.setCount(tree.get(jsonCount).asInt());
|
||||
tree.remove(jsonCount);
|
||||
}
|
||||
if (tree.hasNonNull(jsonNextLink)) {
|
||||
entitySet.setNext(URI.create(tree.get(jsonNextLink).textValue()));
|
||||
tree.remove(jsonNextLink);
|
||||
}
|
||||
if (tree.hasNonNull(jsonDeltaLink)) {
|
||||
entitySet.setDeltaLink(URI.create(tree.get(jsonDeltaLink).textValue()));
|
||||
tree.remove(jsonDeltaLink);
|
||||
}
|
||||
|
||||
if (tree.hasNonNull(Constants.VALUE)) {
|
||||
|
@ -89,6 +94,19 @@ public class JSONEntitySetDeserializer extends AbstractJsonDeserializer<JSONEnti
|
|||
new TypeReference<JSONEntityImpl>() {
|
||||
}).getPayload());
|
||||
}
|
||||
tree.remove(Constants.VALUE);
|
||||
}
|
||||
|
||||
// any remaining entry is supposed to be an annotation or is ignored
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
if (field.getKey().charAt(0) == '@') {
|
||||
final Annotation annotation = new AnnotationImpl();
|
||||
annotation.setTerm(field.getKey().substring(1));
|
||||
|
||||
value(annotation, field.getValue(), parser.getCodec());
|
||||
entitySet.getAnnotations().add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
return new ResWrap<JSONEntitySetImpl>(contextURL, metadataETag, entitySet);
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
@ -78,6 +79,10 @@ public class JSONEntitySetSerializer extends AbstractJsonSerializer<JSONEntitySe
|
|||
}
|
||||
}
|
||||
|
||||
for (Annotation annotation : entitySet.getAnnotations()) {
|
||||
valuable(jgen, annotation, "@" + annotation.getTerm());
|
||||
}
|
||||
|
||||
jgen.writeArrayFieldStart(Constants.VALUE);
|
||||
for (Entity entity : entitySet.getEntities()) {
|
||||
jgen.writeObject(entity);
|
||||
|
|
|
@ -21,11 +21,15 @@ package org.apache.olingo.commons.core.data;
|
|||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
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.Iterator;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
|
||||
|
||||
|
@ -68,14 +72,29 @@ public class JSONPropertyDeserializer extends AbstractJsonDeserializer<JSONPrope
|
|||
|
||||
if (tree.has(jsonType)) {
|
||||
property.setType(new EdmTypeInfo.Builder().setTypeExpression(tree.get(jsonType).textValue()).build().internal());
|
||||
tree.remove(jsonType);
|
||||
}
|
||||
|
||||
if (tree.has(Constants.JSON_NULL) && tree.get(Constants.JSON_NULL).asBoolean()) {
|
||||
property.setValue(new NullValueImpl());
|
||||
tree.remove(Constants.JSON_NULL);
|
||||
}
|
||||
|
||||
if (property.getValue() == null) {
|
||||
value(property, tree.has(Constants.VALUE) ? tree.get(Constants.VALUE) : tree, parser.getCodec());
|
||||
tree.remove(Constants.VALUE);
|
||||
}
|
||||
|
||||
// any remaining entry is supposed to be an annotation or is ignored
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
if (field.getKey().charAt(0) == '@') {
|
||||
final Annotation annotation = new AnnotationImpl();
|
||||
annotation.setTerm(field.getKey().substring(1));
|
||||
|
||||
value(annotation, field.getValue(), parser.getCodec());
|
||||
property.getAnnotations().add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
return new ResWrap<JSONPropertyImpl>(contextURL, metadataETag, property);
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ResWrap;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
@ -40,7 +41,7 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
|||
@Override
|
||||
protected void doSerialize(final JSONPropertyImpl property, final JsonGenerator jgen,
|
||||
final SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
|
||||
|
||||
doContainerSerialize(new ResWrap<JSONPropertyImpl>((URI) null, null, property), jgen, provider);
|
||||
}
|
||||
|
||||
|
@ -64,6 +65,10 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
|||
new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build().external(version));
|
||||
}
|
||||
|
||||
for (Annotation annotation : property.getAnnotations()) {
|
||||
valuable(jgen, annotation, "@" + annotation.getTerm());
|
||||
}
|
||||
|
||||
if (property.getValue().isNull()) {
|
||||
jgen.writeBooleanField(Constants.JSON_NULL, true);
|
||||
} else if (property.getValue().isPrimitive()) {
|
||||
|
@ -76,10 +81,10 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
|||
} else if (property.getValue().isEnum()) {
|
||||
jgen.writeStringField(Constants.VALUE, property.getValue().asEnum().get());
|
||||
} else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
|
||||
property(jgen, property, Constants.VALUE);
|
||||
valuable(jgen, property, Constants.VALUE);
|
||||
} else if (property.getValue().isComplex()) {
|
||||
for (Property cproperty : property.getValue().asComplex().get()) {
|
||||
property(jgen, cproperty, cproperty.getName());
|
||||
valuable(jgen, cproperty, cproperty.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue