[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("Advertisements_f89dee73-af9f-4cd4-b330-db93c25ff3c7", getODataPubFormat());
|
||||||
entity("entityReference", getODataPubFormat());
|
entity("entityReference", getODataPubFormat());
|
||||||
entity("entity.withcomplexnavigation", getODataPubFormat());
|
entity("entity.withcomplexnavigation", getODataPubFormat());
|
||||||
|
entity("annotated", getODataPubFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void property(final String filename, final ODataFormat format) throws Exception {
|
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 ATTR_RELATIONSHIP = "relationship";
|
||||||
|
|
||||||
|
public static final String ANNOTATION = "annotation";
|
||||||
|
|
||||||
// JSON stuff
|
// JSON stuff
|
||||||
public final static String JSON_METADATA = "odata.metadata";
|
public final static String JSON_METADATA = "odata.metadata";
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,9 @@ package org.apache.olingo.commons.api.data;
|
||||||
/**
|
/**
|
||||||
* Represents an instance annotation.
|
* Represents an instance annotation.
|
||||||
*/
|
*/
|
||||||
public interface Annotation {
|
public interface Annotation extends Valuable {
|
||||||
|
|
||||||
String getTerm();
|
String getTerm();
|
||||||
|
|
||||||
void setTerm(String term);
|
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;
|
package org.apache.olingo.commons.api.data;
|
||||||
|
|
||||||
public interface Property extends Annotatable {
|
public interface Property extends Valuable, Annotatable {
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
void setName(String name);
|
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 nextQName;
|
||||||
|
|
||||||
|
protected final QName annotationQName;
|
||||||
|
|
||||||
protected final QName contextQName;
|
protected final QName contextQName;
|
||||||
|
|
||||||
protected final QName entryRefQName;
|
protected final QName entryRefQName;
|
||||||
|
@ -98,6 +100,8 @@ abstract class AbstractAtomDealer {
|
||||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_URI);
|
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_URI);
|
||||||
this.nextQName =
|
this.nextQName =
|
||||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.NEXT_LINK_REL);
|
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 =
|
this.contextQName =
|
||||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.CONTEXT);
|
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.CONTEXT);
|
||||||
this.entryRefQName =
|
this.entryRefQName =
|
||||||
|
|
|
@ -27,14 +27,21 @@ import java.io.IOException;
|
||||||
import java.util.AbstractMap.SimpleEntry;
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.CollectionValue;
|
||||||
import org.apache.olingo.commons.api.data.ComplexValue;
|
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.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.data.Value;
|
||||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||||
import org.apache.olingo.commons.api.domain.ODataPropertyType;
|
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>> {
|
abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResWrap<T>> {
|
||||||
|
|
||||||
|
protected final Pattern CUSTOM_ANNOTATION = Pattern.compile("(.+)@(.+)\\.(.+)");
|
||||||
|
|
||||||
private JSONGeoValueDeserializer geoDeserializer;
|
private JSONGeoValueDeserializer geoDeserializer;
|
||||||
|
|
||||||
private JSONGeoValueDeserializer getGeoDeserializer() {
|
private JSONGeoValueDeserializer getGeoDeserializer() {
|
||||||
|
@ -203,6 +212,48 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
||||||
return new SimpleEntry<ODataPropertyType, EdmTypeInfo>(type, typeInfo);
|
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) {
|
private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
|
||||||
final Value value;
|
final Value value;
|
||||||
|
|
||||||
|
@ -234,22 +285,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
||||||
node.remove(toRemove);
|
node.remove(toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
String type = null;
|
populate(value.asLinkedComplex(), value.get(), node, codec);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -283,12 +319,12 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
||||||
return value;
|
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 {
|
throws IOException {
|
||||||
|
|
||||||
EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
|
EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType())
|
||||||
? null
|
? null
|
||||||
: new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
|
: new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
|
||||||
|
|
||||||
final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
|
final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
|
||||||
if (typeInfo == null) {
|
if (typeInfo == null) {
|
||||||
|
@ -307,31 +343,31 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
|
||||||
|
|
||||||
switch (propType) {
|
switch (propType) {
|
||||||
case COLLECTION:
|
case COLLECTION:
|
||||||
property.setValue(fromCollection(node.elements(), typeInfo, codec));
|
valuable.setValue(fromCollection(node.elements(), typeInfo, codec));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMPLEX:
|
case COMPLEX:
|
||||||
if (node.has(jsonType)) {
|
if (node.has(jsonType)) {
|
||||||
property.setType(node.get(jsonType).asText());
|
valuable.setType(node.get(jsonType).asText());
|
||||||
((ObjectNode) node).remove(jsonType);
|
((ObjectNode) node).remove(jsonType);
|
||||||
}
|
}
|
||||||
property.setValue(fromComplex((ObjectNode) node, codec));
|
valuable.setValue(fromComplex((ObjectNode) node, codec));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENUM:
|
case ENUM:
|
||||||
property.setValue(new EnumValueImpl(node.asText()));
|
valuable.setValue(new EnumValueImpl(node.asText()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRIMITIVE:
|
case PRIMITIVE:
|
||||||
if (property.getType() == null && typeInfo != null) {
|
if (valuable.getType() == null && typeInfo != null) {
|
||||||
property.setType(typeInfo.getFullQualifiedName().toString());
|
valuable.setType(typeInfo.getFullQualifiedName().toString());
|
||||||
}
|
}
|
||||||
property.setValue(fromPrimitive(node, typeInfo));
|
valuable.setValue(fromPrimitive(node, typeInfo));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMPTY:
|
case EMPTY:
|
||||||
default:
|
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.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.CollectionValue;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.Link;
|
import org.apache.olingo.commons.api.data.Link;
|
||||||
import org.apache.olingo.commons.api.data.Linked;
|
import org.apache.olingo.commons.api.data.Linked;
|
||||||
import org.apache.olingo.commons.api.data.PrimitiveValue;
|
import org.apache.olingo.commons.api.data.PrimitiveValue;
|
||||||
import org.apache.olingo.commons.api.data.Property;
|
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.data.Value;
|
||||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
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 {
|
protected void clientLinks(final Linked linked, final JsonGenerator jgen) throws IOException {
|
||||||
final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>();
|
final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>();
|
||||||
for (Link link : linked.getNavigationLinks()) {
|
for (Link link : linked.getNavigationLinks()) {
|
||||||
|
for (Annotation annotation : link.getAnnotations()) {
|
||||||
|
valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm());
|
||||||
|
}
|
||||||
|
|
||||||
ODataLinkType type = null;
|
ODataLinkType type = null;
|
||||||
try {
|
try {
|
||||||
type = ODataLinkType.fromString(version, link.getRel(), link.getType());
|
type = ODataLinkType.fromString(version, link.getRel(), link.getType());
|
||||||
|
@ -185,7 +192,7 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
|
||||||
} else if (value.isComplex()) {
|
} else if (value.isComplex()) {
|
||||||
jgen.writeStartObject();
|
jgen.writeStartObject();
|
||||||
for (Property property : value.asComplex().get()) {
|
for (Property property : value.asComplex().get()) {
|
||||||
property(jgen, property, property.getName());
|
valuable(jgen, property, property.getName());
|
||||||
}
|
}
|
||||||
if (value.isLinkedComplex()) {
|
if (value.isLinkedComplex()) {
|
||||||
links(value.asLinkedComplex(), jgen);
|
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)) {
|
if (serverMode && !Constants.VALUE.equals(name)) {
|
||||||
String type = property.getType();
|
String type = valuable.getType();
|
||||||
if (StringUtils.isBlank(type)
|
if (StringUtils.isBlank(type) && valuable.getValue().isPrimitive() || valuable.getValue().isNull()) {
|
||||||
&& property.getValue().isPrimitive() || property.getValue().isNull()) {
|
|
||||||
|
|
||||||
type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
|
type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(type)) {
|
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);
|
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 {
|
public abstract class AbstractProperty extends AbstractAnnotatedObject implements Property {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -7175704800169997060L;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private String type;
|
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.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.text.ParseException;
|
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.namespace.QName;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
@ -32,10 +36,13 @@ import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.CollectionValue;
|
||||||
import org.apache.olingo.commons.api.data.DeletedEntity.Reason;
|
import org.apache.olingo.commons.api.data.DeletedEntity.Reason;
|
||||||
import org.apache.olingo.commons.api.data.EntitySet;
|
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.ResWrap;
|
||||||
|
import org.apache.olingo.commons.api.data.Valuable;
|
||||||
import org.apache.olingo.commons.api.data.Value;
|
import org.apache.olingo.commons.api.data.Value;
|
||||||
import org.apache.olingo.commons.api.domain.ODataOperation;
|
import org.apache.olingo.commons.api.domain.ODataOperation;
|
||||||
import org.apache.olingo.commons.api.domain.ODataPropertyType;
|
import org.apache.olingo.commons.api.domain.ODataPropertyType;
|
||||||
|
@ -242,6 +249,14 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
property.setName(start.getName().getLocalPart());
|
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);
|
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
|
||||||
|
|
||||||
Value value;
|
Value value;
|
||||||
|
@ -254,7 +269,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
: new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
|
: new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
|
||||||
|
|
||||||
if (typeInfo != null) {
|
if (typeInfo != null) {
|
||||||
property.setType(typeInfo.internal());
|
valuable.setType(typeInfo.internal());
|
||||||
}
|
}
|
||||||
|
|
||||||
final ODataPropertyType propType = typeInfo == null
|
final ODataPropertyType propType = typeInfo == null
|
||||||
|
@ -277,7 +292,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
case PRIMITIVE:
|
case PRIMITIVE:
|
||||||
// No type specified? Defaults to Edm.String
|
// No type specified? Defaults to Edm.String
|
||||||
if (typeInfo == null) {
|
if (typeInfo == null) {
|
||||||
property.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString());
|
valuable.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString());
|
||||||
}
|
}
|
||||||
value = fromPrimitive(reader, start, typeInfo);
|
value = fromPrimitive(reader, start, typeInfo);
|
||||||
break;
|
break;
|
||||||
|
@ -290,9 +305,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
value = new NullValueImpl();
|
value = new NullValueImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
property.setValue(value);
|
valuable.setValue(value);
|
||||||
|
|
||||||
return property;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResWrap<AtomPropertyImpl> property(final InputStream input) throws XMLStreamException {
|
private ResWrap<AtomPropertyImpl> property(final InputStream input) throws XMLStreamException {
|
||||||
|
@ -344,23 +357,27 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
while (reader.hasNext() && !foundEndElement) {
|
while (reader.hasNext() && !foundEndElement) {
|
||||||
final XMLEvent event = reader.nextEvent();
|
final XMLEvent event = reader.nextEvent();
|
||||||
|
|
||||||
if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
|
if (event.isStartElement()) {
|
||||||
StartElement inline = null;
|
if (inlineQName.equals(event.asStartElement().getName())) {
|
||||||
while (reader.hasNext() && inline == null) {
|
StartElement inline = null;
|
||||||
final XMLEvent innerEvent = reader.peek();
|
while (reader.hasNext() && inline == null) {
|
||||||
if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
|
final XMLEvent innerEvent = reader.peek();
|
||||||
reader.nextEvent();
|
if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
|
||||||
} else if (innerEvent.isStartElement()) {
|
reader.nextEvent();
|
||||||
inline = innerEvent.asStartElement();
|
} else if (innerEvent.isStartElement()) {
|
||||||
|
inline = innerEvent.asStartElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (inline != null) {
|
||||||
if (inline != null) {
|
if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
|
||||||
if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
|
link.setInlineEntity(entity(reader, inline));
|
||||||
link.setInlineEntity(entity(reader, inline));
|
}
|
||||||
}
|
if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
|
||||||
if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
|
link.setInlineEntitySet(entitySet(reader, inline));
|
||||||
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)
|
private void properties(final XMLEventReader reader, final StartElement start, final AtomEntityImpl entity)
|
||||||
throws XMLStreamException {
|
throws XMLStreamException {
|
||||||
|
|
||||||
|
final Map<String, List<Annotation>> annotations = new HashMap<String, List<Annotation>>();
|
||||||
|
|
||||||
boolean foundEndProperties = false;
|
boolean foundEndProperties = false;
|
||||||
while (reader.hasNext() && !foundEndProperties) {
|
while (reader.hasNext() && !foundEndProperties) {
|
||||||
final XMLEvent event = reader.nextEvent();
|
final XMLEvent event = reader.nextEvent();
|
||||||
|
|
||||||
if (event.isStartElement()) {
|
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())) {
|
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
|
||||||
foundEndProperties = true;
|
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 {
|
private AtomEntityImpl entityRef(final StartElement start) throws XMLStreamException {
|
||||||
|
@ -636,6 +682,8 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
}
|
}
|
||||||
} else if (propertiesQName.equals(event.asStartElement().getName())) {
|
} else if (propertiesQName.equals(event.asStartElement().getName())) {
|
||||||
properties(reader, event.asStartElement(), entity);
|
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;
|
foundEndEntry = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
|
||||||
} else {
|
} else {
|
||||||
entity = null;
|
entity = null;
|
||||||
}
|
}
|
||||||
|
@ -719,6 +765,8 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
||||||
entitySet.getEntities().add(entity(reader, event.asStartElement()));
|
entitySet.getEntities().add(entity(reader, event.asStartElement()));
|
||||||
} else if (entryRefQName.equals(event.asStartElement().getName())) {
|
} else if (entryRefQName.equals(event.asStartElement().getName())) {
|
||||||
entitySet.getEntities().add(entityRef(event.asStartElement()));
|
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 javax.xml.stream.XMLStreamWriter;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.CollectionValue;
|
||||||
import org.apache.olingo.commons.api.data.ResWrap;
|
import org.apache.olingo.commons.api.data.ResWrap;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
|
@ -124,6 +125,10 @@ public class AtomSerializer extends AbstractAtomDealer {
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeEndElement();
|
writer.writeEndElement();
|
||||||
|
|
||||||
|
for (Annotation annotation : property.getAnnotations()) {
|
||||||
|
annotation(writer, annotation, property.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void property(final XMLStreamWriter writer, final Property property) throws XMLStreamException {
|
private void property(final XMLStreamWriter writer, final Property property) throws XMLStreamException {
|
||||||
|
@ -185,6 +190,10 @@ public class AtomSerializer extends AbstractAtomDealer {
|
||||||
writer.writeEndElement();
|
writer.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Annotation annotation : link.getAnnotations()) {
|
||||||
|
annotation(writer, annotation, null);
|
||||||
|
}
|
||||||
|
|
||||||
writer.writeEndElement();
|
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 {
|
private void entity(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
|
||||||
if (entity.getBaseURI() != null) {
|
if (entity.getBaseURI() != null) {
|
||||||
writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entity.getBaseURI().toASCIIString());
|
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();
|
||||||
}
|
}
|
||||||
writer.writeEndElement();
|
writer.writeEndElement();
|
||||||
|
|
||||||
|
for (Annotation annotation : entity.getAnnotations()) {
|
||||||
|
annotation(writer, annotation, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
|
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 com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
import org.apache.olingo.commons.api.data.Link;
|
import org.apache.olingo.commons.api.data.Link;
|
||||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||||
|
@ -106,7 +111,6 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
||||||
|
|
||||||
if (tree.hasNonNull(jsonEditLink)) {
|
if (tree.hasNonNull(jsonEditLink)) {
|
||||||
final LinkImpl link = new LinkImpl();
|
final LinkImpl link = new LinkImpl();
|
||||||
// Server mode
|
|
||||||
if (serverMode) {
|
if (serverMode) {
|
||||||
link.setRel(Constants.EDIT_LINK_REL);
|
link.setRel(Constants.EDIT_LINK_REL);
|
||||||
}
|
}
|
||||||
|
@ -134,8 +138,11 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<String> toRemove = new HashSet<String>();
|
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();) {
|
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.fields(); itor.hasNext();) {
|
||||||
final Map.Entry<String, JsonNode> field = itor.next();
|
final Map.Entry<String, JsonNode> field = itor.next();
|
||||||
|
final Matcher customAnnotation = CUSTOM_ANNOTATION.matcher(field.getKey());
|
||||||
|
|
||||||
links(field, entity, toRemove, tree, parser.getCodec());
|
links(field, entity, toRemove, tree, parser.getCodec());
|
||||||
if (field.getKey().endsWith(getJSONAnnotation(jsonMediaEditLink))) {
|
if (field.getKey().endsWith(getJSONAnnotation(jsonMediaEditLink))) {
|
||||||
|
@ -172,29 +179,39 @@ public class JSONEntityDeserializer extends AbstractJsonDeserializer<JSONEntityI
|
||||||
entity.getOperations().add(operation);
|
entity.getOperations().add(operation);
|
||||||
|
|
||||||
toRemove.add(field.getKey());
|
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);
|
tree.remove(toRemove);
|
||||||
|
|
||||||
String type = null;
|
populate(entity, entity.getProperties(), tree, parser.getCodec());
|
||||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = tree.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 == 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);
|
return new ResWrap<JSONEntityImpl>(contextURL, metadataETag, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.Link;
|
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());
|
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()) {
|
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())) {
|
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.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,12 +76,15 @@ public class JSONEntitySetDeserializer extends AbstractJsonDeserializer<JSONEnti
|
||||||
|
|
||||||
if (tree.hasNonNull(jsonCount)) {
|
if (tree.hasNonNull(jsonCount)) {
|
||||||
entitySet.setCount(tree.get(jsonCount).asInt());
|
entitySet.setCount(tree.get(jsonCount).asInt());
|
||||||
|
tree.remove(jsonCount);
|
||||||
}
|
}
|
||||||
if (tree.hasNonNull(jsonNextLink)) {
|
if (tree.hasNonNull(jsonNextLink)) {
|
||||||
entitySet.setNext(URI.create(tree.get(jsonNextLink).textValue()));
|
entitySet.setNext(URI.create(tree.get(jsonNextLink).textValue()));
|
||||||
|
tree.remove(jsonNextLink);
|
||||||
}
|
}
|
||||||
if (tree.hasNonNull(jsonDeltaLink)) {
|
if (tree.hasNonNull(jsonDeltaLink)) {
|
||||||
entitySet.setDeltaLink(URI.create(tree.get(jsonDeltaLink).textValue()));
|
entitySet.setDeltaLink(URI.create(tree.get(jsonDeltaLink).textValue()));
|
||||||
|
tree.remove(jsonDeltaLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree.hasNonNull(Constants.VALUE)) {
|
if (tree.hasNonNull(Constants.VALUE)) {
|
||||||
|
@ -89,6 +94,19 @@ public class JSONEntitySetDeserializer extends AbstractJsonDeserializer<JSONEnti
|
||||||
new TypeReference<JSONEntityImpl>() {
|
new TypeReference<JSONEntityImpl>() {
|
||||||
}).getPayload());
|
}).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);
|
return new ResWrap<JSONEntitySetImpl>(contextURL, metadataETag, entitySet);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
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);
|
jgen.writeArrayFieldStart(Constants.VALUE);
|
||||||
for (Entity entity : entitySet.getEntities()) {
|
for (Entity entity : entitySet.getEntities()) {
|
||||||
jgen.writeObject(entity);
|
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.JsonParser;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
|
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
|
||||||
|
|
||||||
|
@ -68,14 +72,29 @@ public class JSONPropertyDeserializer extends AbstractJsonDeserializer<JSONPrope
|
||||||
|
|
||||||
if (tree.has(jsonType)) {
|
if (tree.has(jsonType)) {
|
||||||
property.setType(new EdmTypeInfo.Builder().setTypeExpression(tree.get(jsonType).textValue()).build().internal());
|
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()) {
|
if (tree.has(Constants.JSON_NULL) && tree.get(Constants.JSON_NULL).asBoolean()) {
|
||||||
property.setValue(new NullValueImpl());
|
property.setValue(new NullValueImpl());
|
||||||
|
tree.remove(Constants.JSON_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.getValue() == null) {
|
if (property.getValue() == null) {
|
||||||
value(property, tree.has(Constants.VALUE) ? tree.get(Constants.VALUE) : tree, parser.getCodec());
|
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);
|
return new ResWrap<JSONPropertyImpl>(contextURL, metadataETag, property);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.olingo.commons.api.Constants;
|
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.ResWrap;
|
||||||
import org.apache.olingo.commons.api.data.Property;
|
import org.apache.olingo.commons.api.data.Property;
|
||||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||||
|
@ -40,7 +41,7 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
||||||
@Override
|
@Override
|
||||||
protected void doSerialize(final JSONPropertyImpl property, final JsonGenerator jgen,
|
protected void doSerialize(final JSONPropertyImpl property, final JsonGenerator jgen,
|
||||||
final SerializerProvider provider) throws IOException, JsonProcessingException {
|
final SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||||
|
|
||||||
doContainerSerialize(new ResWrap<JSONPropertyImpl>((URI) null, null, property), jgen, provider);
|
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));
|
new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build().external(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Annotation annotation : property.getAnnotations()) {
|
||||||
|
valuable(jgen, annotation, "@" + annotation.getTerm());
|
||||||
|
}
|
||||||
|
|
||||||
if (property.getValue().isNull()) {
|
if (property.getValue().isNull()) {
|
||||||
jgen.writeBooleanField(Constants.JSON_NULL, true);
|
jgen.writeBooleanField(Constants.JSON_NULL, true);
|
||||||
} else if (property.getValue().isPrimitive()) {
|
} else if (property.getValue().isPrimitive()) {
|
||||||
|
@ -76,10 +81,10 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
||||||
} else if (property.getValue().isEnum()) {
|
} else if (property.getValue().isEnum()) {
|
||||||
jgen.writeStringField(Constants.VALUE, property.getValue().asEnum().get());
|
jgen.writeStringField(Constants.VALUE, property.getValue().asEnum().get());
|
||||||
} else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
|
} else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
|
||||||
property(jgen, property, Constants.VALUE);
|
valuable(jgen, property, Constants.VALUE);
|
||||||
} else if (property.getValue().isComplex()) {
|
} else if (property.getValue().isComplex()) {
|
||||||
for (Property cproperty : property.getValue().asComplex().get()) {
|
for (Property cproperty : property.getValue().asComplex().get()) {
|
||||||
property(jgen, cproperty, cproperty.getName());
|
valuable(jgen, cproperty, cproperty.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue