Fix for proxy inline entity and entity set retrieving

This commit is contained in:
fmartelli 2014-07-14 16:07:47 +02:00
parent baf2cd1098
commit bda51643b1
5 changed files with 62 additions and 59 deletions

View File

@ -109,7 +109,7 @@ public class FilterTestITCase extends AbstractTestITCase {
public void loadWithSelectAndExpand() { public void loadWithSelectAndExpand() {
final Customer customer = container.getCustomers().getByKey(1); final Customer customer = container.getCustomers().getByKey(1);
// customer.expand("Orders"); customer.expand("Orders");
customer.select("Orders", "PersonID"); customer.select("Orders", "PersonID");
customer.load(); customer.load();

View File

@ -94,7 +94,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (ServiceDocumentItem entitySet : resource.getEntitySets()) { for (ServiceDocumentItem entitySet : resource.getEntitySets()) {
serviceDocument.getEntitySets(). serviceDocument.getEntitySets().
put(entitySet.getName(), URIUtils.getURI(resource.getBaseURI(), entitySet.getUrl())); put(entitySet.getName(), URIUtils.getURI(resource.getBaseURI(), entitySet.getUrl()));
} }
return serviceDocument; return serviceDocument;
@ -250,19 +250,20 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
final StringWriter writer = new StringWriter(); final StringWriter writer = new StringWriter();
try { try {
client.getSerializer(ODataFormat.JSON).write(writer, resource.getPayload()); client.getSerializer(ODataFormat.JSON).write(writer, resource.getPayload());
} catch (final ODataSerializerException e) {} } catch (final ODataSerializerException e) {
}
writer.flush(); writer.flush();
LOG.debug("EntitySet -> ODataEntitySet:\n{}", writer.toString()); LOG.debug("EntitySet -> ODataEntitySet:\n{}", writer.toString());
} }
final URI base = resource.getContextURL() == null final URI base = resource.getContextURL() == null
? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot(); ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
final URI next = resource.getPayload().getNext(); final URI next = resource.getPayload().getNext();
final CommonODataEntitySet entitySet = next == null final CommonODataEntitySet entitySet = next == null
? client.getObjectFactory().newEntitySet() ? client.getObjectFactory().newEntitySet()
: client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString())); : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
if (resource.getPayload().getCount() != null) { if (resource.getPayload().getCount() != null) {
entitySet.setCount(resource.getPayload().getCount()); entitySet.setCount(resource.getPayload().getCount());
@ -270,14 +271,14 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (Entity entityResource : resource.getPayload().getEntities()) { for (Entity entityResource : resource.getPayload().getEntities()) {
add(entitySet, getODataEntity( add(entitySet, getODataEntity(
new ResWrap<Entity>(resource.getContextURL(), resource.getMetadataETag(), entityResource))); new ResWrap<Entity>(resource.getContextURL(), resource.getMetadataETag(), entityResource)));
} }
return entitySet; return entitySet;
} }
protected void odataNavigationLinks(final EdmType edmType, protected void odataNavigationLinks(final EdmType edmType,
final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) { final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) {
for (Link link : linked.getNavigationLinks()) { for (Link link : linked.getNavigationLinks()) {
final Entity inlineEntity = link.getInlineEntity(); final Entity inlineEntity = link.getInlineEntity();
@ -289,33 +290,33 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
final EdmNavigationProperty navProp = ((EdmStructuredType) edmType).getNavigationProperty(link.getTitle()); final EdmNavigationProperty navProp = ((EdmStructuredType) edmType).getNavigationProperty(link.getTitle());
if (navProp != null) { if (navProp != null) {
linkType = navProp.isCollection() linkType = navProp.isCollection()
? ODataLinkType.ENTITY_SET_NAVIGATION ? ODataLinkType.ENTITY_SET_NAVIGATION
: ODataLinkType.ENTITY_NAVIGATION; : ODataLinkType.ENTITY_NAVIGATION;
} }
} }
if (linkType == null) { if (linkType == null) {
linkType = link.getType() == null linkType = link.getType() == null
? ODataLinkType.ENTITY_NAVIGATION ? ODataLinkType.ENTITY_NAVIGATION
: ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType()); : ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType());
} }
odataLinked.addLink(linkType == ODataLinkType.ENTITY_NAVIGATION odataLinked.addLink(linkType == ODataLinkType.ENTITY_NAVIGATION
? client.getObjectFactory(). ? client.getObjectFactory().
newEntityNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref())) newEntityNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref()))
: client.getObjectFactory(). : client.getObjectFactory().
newEntitySetNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref()))); newEntitySetNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref())));
} else if (inlineEntity != null) { } else if (inlineEntity != null) {
odataLinked.addLink(new ODataInlineEntity(client.getServiceVersion(), odataLinked.addLink(new ODataInlineEntity(client.getServiceVersion(),
URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_NAVIGATION, link.getTitle(), URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_NAVIGATION, link.getTitle(),
getODataEntity(new ResWrap<Entity>( getODataEntity(new ResWrap<Entity>(
inlineEntity.getBaseURI() == null ? base : inlineEntity.getBaseURI(), inlineEntity.getBaseURI() == null ? null : inlineEntity.getBaseURI(),
metadataETag, metadataETag,
inlineEntity)))); inlineEntity))));
} else { } else {
odataLinked.addLink(new ODataInlineEntitySet(client.getServiceVersion(), odataLinked.addLink(new ODataInlineEntitySet(client.getServiceVersion(),
URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_SET_NAVIGATION, link.getTitle(), URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_SET_NAVIGATION, link.getTitle(),
getODataEntitySet(new ResWrap<EntitySet>( getODataEntitySet(new ResWrap<EntitySet>(
inlineEntitySet.getBaseURI() == null ? base : inlineEntitySet.getBaseURI(), inlineEntitySet.getBaseURI() == null ? null : inlineEntitySet.getBaseURI(),
metadataETag, metadataETag,
inlineEntitySet)))); inlineEntitySet))));
} }
@ -348,18 +349,18 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
type = bindingTarget.getEntityType(); type = bindingTarget.getEntityType();
} else { } else {
final EdmNavigationProperty navProp = bindingTarget.getEntityType(). final EdmNavigationProperty navProp = bindingTarget.getEntityType().
getNavigationProperty(contextURL.getNavOrPropertyPath()); getNavigationProperty(contextURL.getNavOrPropertyPath());
type = navProp == null type = navProp == null
? bindingTarget.getEntityType() ? bindingTarget.getEntityType()
: navProp.getType(); : navProp.getType();
} }
} }
} }
} }
if (type == null) { if (type == null) {
type = new EdmTypeInfo.Builder().setEdm(edm). type = new EdmTypeInfo.Builder().setEdm(edm).
setTypeExpression(contextURL.getEntitySetOrSingletonOrType()).build().getType(); setTypeExpression(contextURL.getEntitySetOrSingletonOrType()).build().getType();
} }
} else { } else {
type = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); type = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity()));
@ -375,14 +376,14 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
final StringWriter writer = new StringWriter(); final StringWriter writer = new StringWriter();
try { try {
client.getSerializer(ODataFormat.JSON).write(writer, resource.getPayload()); client.getSerializer(ODataFormat.JSON).write(writer, resource.getPayload());
} catch (final ODataSerializerException e) {} } catch (final ODataSerializerException e) {
}
writer.flush(); writer.flush();
LOG.debug("EntityResource -> ODataEntity:\n{}", writer.toString()); LOG.debug("EntityResource -> ODataEntity:\n{}", writer.toString());
} }
final URI base = resource.getContextURL() == null final URI base = resource.getContextURL() == null
? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot(); ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
final EdmType edmType = findType(resource.getContextURL(), resource.getMetadataETag()); final EdmType edmType = findType(resource.getContextURL(), resource.getMetadataETag());
FullQualifiedName typeName = null; FullQualifiedName typeName = null;
if (resource.getPayload().getType() == null) { if (resource.getPayload().getType() == null) {
@ -394,8 +395,8 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
} }
final CommonODataEntity entity = resource.getPayload().getSelfLink() == null final CommonODataEntity entity = resource.getPayload().getSelfLink() == null
? client.getObjectFactory().newEntity(typeName) ? client.getObjectFactory().newEntity(typeName)
: client.getObjectFactory().newEntity(typeName, : client.getObjectFactory().newEntity(typeName,
URIUtils.getURI(base, resource.getPayload().getSelfLink().getHref())); URIUtils.getURI(base, resource.getPayload().getSelfLink().getHref()));
if (StringUtils.isNotBlank(resource.getPayload().getETag())) { if (StringUtils.isNotBlank(resource.getPayload().getETag())) {
@ -408,14 +409,14 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (Link link : resource.getPayload().getAssociationLinks()) { for (Link link : resource.getPayload().getAssociationLinks()) {
entity.addLink(client.getObjectFactory(). entity.addLink(client.getObjectFactory().
newAssociationLink(link.getTitle(), URIUtils.getURI(base, link.getHref()))); newAssociationLink(link.getTitle(), URIUtils.getURI(base, link.getHref())));
} }
odataNavigationLinks(edmType, resource.getPayload(), entity, resource.getMetadataETag(), base); odataNavigationLinks(edmType, resource.getPayload(), entity, resource.getMetadataETag(), base);
for (Link link : resource.getPayload().getMediaEditLinks()) { for (Link link : resource.getPayload().getMediaEditLinks()) {
entity.addLink(client.getObjectFactory(). entity.addLink(client.getObjectFactory().
newMediaEditLink(link.getTitle(), URIUtils.getURI(base, link.getHref()))); newMediaEditLink(link.getTitle(), URIUtils.getURI(base, link.getHref())));
} }
for (ODataOperation operation : resource.getPayload().getOperations()) { for (ODataOperation operation : resource.getPayload().getOperations()) {
@ -445,7 +446,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
} }
protected EdmTypeInfo buildTypeInfo(final ContextURL contextURL, final String metadataETag, protected EdmTypeInfo buildTypeInfo(final ContextURL contextURL, final String metadataETag,
final String propertyName, final String propertyType) { final String propertyName, final String propertyType) {
FullQualifiedName typeName = null; FullQualifiedName typeName = null;
final EdmType type = findType(contextURL, metadataETag); final EdmType type = findType(contextURL, metadataETag);
@ -481,27 +482,27 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
protected abstract CommonODataProperty getODataProperty(EdmType type, Property resource); protected abstract CommonODataProperty getODataProperty(EdmType type, Property resource);
protected ODataValue getODataValue(final FullQualifiedName type, protected ODataValue getODataValue(final FullQualifiedName type,
final Valuable valuable, final ContextURL contextURL, final String metadataETag) { final Valuable valuable, final ContextURL contextURL, final String metadataETag) {
ODataValue value = null; ODataValue value = null;
if (valuable.isGeospatial()) { if (valuable.isGeospatial()) {
value = client.getObjectFactory().newPrimitiveValueBuilder() value = client.getObjectFactory().newPrimitiveValueBuilder()
.setValue(valuable.asGeospatial()) .setValue(valuable.asGeospatial())
.setType(type == null .setType(type == null
|| EdmPrimitiveTypeKind.Geography.getFullQualifiedName().equals(type) || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().equals(type)
|| EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().equals(type) ? || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().equals(type)
valuable.asGeospatial().getEdmPrimitiveTypeKind() : ? valuable.asGeospatial().getEdmPrimitiveTypeKind()
EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), type.toString())).build(); : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), type.toString())).build();
} else if (valuable.isPrimitive() || valuable.getValueType() == null) { } else if (valuable.isPrimitive() || valuable.getValueType() == null) {
value = client.getObjectFactory().newPrimitiveValueBuilder() value = client.getObjectFactory().newPrimitiveValueBuilder()
.setValue(valuable.asPrimitive()) .setValue(valuable.asPrimitive())
.setType(type == null || !EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace()) ? null : .setType(type == null || !EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace()) ? null
EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), type.toString())).build(); : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), type.toString())).build();
} else if (valuable.isComplex() || valuable.isLinkedComplex()) { } else if (valuable.isComplex() || valuable.isLinkedComplex()) {
value = client.getObjectFactory().newComplexValue(type == null ? null : type.toString()); value = client.getObjectFactory().newComplexValue(type == null ? null : type.toString());
if (!valuable.isNull()) { if (!valuable.isNull()) {
final List<Property> properties = valuable.isLinkedComplex() ? final List<Property> properties = valuable.isLinkedComplex()
valuable.asLinkedComplex().getValue() : valuable.asComplex(); ? valuable.asLinkedComplex().getValue() : valuable.asComplex();
for (Property property : properties) { for (Property property : properties) {
value.asComplex().add(getODataProperty(new ResWrap<Property>(contextURL, metadataETag, property))); value.asComplex().add(getODataProperty(new ResWrap<Property>(contextURL, metadataETag, property)));
} }

View File

@ -129,28 +129,28 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
if (odataValuable.hasPrimitiveValue()) { if (odataValuable.hasPrimitiveValue()) {
propertyResource.setType(odataValuable.getPrimitiveValue().getTypeName()); propertyResource.setType(odataValuable.getPrimitiveValue().getTypeName());
propertyResource.setValue( propertyResource.setValue(
propertyValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE, propertyValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
propertyValue); propertyValue);
} else if (odataValuable.hasEnumValue()) { } else if (odataValuable.hasEnumValue()) {
propertyResource.setType(odataValuable.getEnumValue().getTypeName()); propertyResource.setType(odataValuable.getEnumValue().getTypeName());
propertyResource.setValue(ValueType.ENUM, propertyValue); propertyResource.setValue(ValueType.ENUM, propertyValue);
} else if (odataValuable.hasComplexValue()) { } else if (odataValuable.hasComplexValue()) {
propertyResource.setType(odataValuable.getComplexValue().getTypeName()); propertyResource.setType(odataValuable.getComplexValue().getTypeName());
propertyResource.setValue( propertyResource.setValue(
propertyValue instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, propertyValue instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX,
propertyValue); propertyValue);
} else if (odataValuable.hasCollectionValue()) { } else if (odataValuable.hasCollectionValue()) {
final ODataCollectionValue<org.apache.olingo.commons.api.domain.v4.ODataValue> collectionValue = final ODataCollectionValue<org.apache.olingo.commons.api.domain.v4.ODataValue> collectionValue =
odataValuable.getCollectionValue(); odataValuable.getCollectionValue();
propertyResource.setType(collectionValue.getTypeName()); propertyResource.setType(collectionValue.getTypeName());
final org.apache.olingo.commons.api.domain.v4.ODataValue value = final org.apache.olingo.commons.api.domain.v4.ODataValue value =
collectionValue.iterator().hasNext() ? collectionValue.iterator().next() : null; collectionValue.iterator().hasNext() ? collectionValue.iterator().next() : null;
ValueType valueType = ValueType.COLLECTION_PRIMITIVE; ValueType valueType = ValueType.COLLECTION_PRIMITIVE;
if (value == null) { if (value == null) {
valueType = ValueType.COLLECTION_PRIMITIVE; valueType = ValueType.COLLECTION_PRIMITIVE;
} else if (value.isPrimitive()) { } else if (value.isPrimitive()) {
valueType = value.asPrimitive().toValue() instanceof Geospatial ? valueType = value.asPrimitive().toValue() instanceof Geospatial
ValueType.COLLECTION_GEOSPATIAL : ValueType.COLLECTION_PRIMITIVE; ? ValueType.COLLECTION_GEOSPATIAL : ValueType.COLLECTION_PRIMITIVE;
} else if (value.isEnum()) { } else if (value.isEnum()) {
valueType = ValueType.COLLECTION_ENUM; valueType = ValueType.COLLECTION_ENUM;
} else if (value.isLinkedComplex()) { } else if (value.isLinkedComplex()) {
@ -308,10 +308,10 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
public ODataProperty getODataProperty(final ResWrap<Property> resource) { public ODataProperty getODataProperty(final ResWrap<Property> resource) {
final Property payload = resource.getPayload(); final Property payload = resource.getPayload();
final EdmTypeInfo typeInfo = buildTypeInfo(resource.getContextURL(), resource.getMetadataETag(), final EdmTypeInfo typeInfo = buildTypeInfo(resource.getContextURL(), resource.getMetadataETag(),
payload.getName(), payload.getType()); payload.getName(), payload.getType());
final ODataProperty property = new ODataPropertyImpl(payload.getName(), final ODataProperty property = new ODataPropertyImpl(payload.getName(),
getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(), getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(),
payload, resource.getContextURL(), resource.getMetadataETag())); payload, resource.getContextURL(), resource.getMetadataETag()));
odataAnnotations(payload, property); odataAnnotations(payload, property);
@ -323,7 +323,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
final EdmTypeInfo typeInfo = buildTypeInfo(type == null ? null : type.getFullQualifiedName(), resource.getType()); final EdmTypeInfo typeInfo = buildTypeInfo(type == null ? null : type.getFullQualifiedName(), resource.getType());
final ODataProperty property = new ODataPropertyImpl(resource.getName(), final ODataProperty property = new ODataPropertyImpl(resource.getName(),
getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(), getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(),
resource, null, null)); resource, null, null));
odataAnnotations(resource, property); odataAnnotations(resource, property);

View File

@ -25,7 +25,7 @@ import org.apache.olingo.commons.api.Constants;
/** /**
* High-level representation of a context URL, built from the string value returned by a service; provides access to the * High-level representation of a context URL, built from the string value returned by a service; provides access to the
* various components of the context URL, defined in the <a * various components of the context URL, defined in the <a
* href="http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793655"> * href="http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793655">
* protocol specification</a>. * protocol specification</a>.
*/ */
@ -53,6 +53,9 @@ public class ContextURL {
private boolean deltaDeletedLink; private boolean deltaDeletedLink;
private ContextURL() {
}
public static ContextURL getInstance(final URI contextURL) { public static ContextURL getInstance(final URI contextURL) {
final ContextURL instance = new ContextURL(); final ContextURL instance = new ContextURL();
instance.uri = contextURL; instance.uri = contextURL;
@ -61,7 +64,7 @@ public class ContextURL {
instance.entity = contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element"); instance.entity = contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element");
contextURLasString = contextURLasString. contextURLasString = contextURLasString.
replace("/$entity", StringUtils.EMPTY).replace("/@Element", StringUtils.EMPTY); replace("/$entity", StringUtils.EMPTY).replace("/@Element", StringUtils.EMPTY);
instance.delta = contextURLasString.endsWith("/$delta"); instance.delta = contextURLasString.endsWith("/$delta");
contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY); contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY);
@ -193,5 +196,4 @@ public class ContextURL {
public String toString() { public String toString() {
return uri.toString(); return uri.toString();
} }
} }