[OLINGO-365] provided more tests
This commit is contained in:
parent
05e41557f5
commit
72dc69dc8e
|
@ -23,4 +23,19 @@ import java.util.Collection;
|
|||
public interface EntityCollection<
|
||||
T extends StructuredType<?>, EC extends Collection<T>, CT extends StructuredCollection<T, EC, ?>>
|
||||
extends StructuredCollection<T, EC, CT> {
|
||||
|
||||
/**
|
||||
* Appends ref segment to the URI.
|
||||
*
|
||||
* @return the same query instance.
|
||||
*/
|
||||
CT refs();
|
||||
|
||||
/**
|
||||
* Add entity by its reference ID.
|
||||
*
|
||||
* @param element entity to be linked.
|
||||
* @return <tt>TRUE</tt> if correctly added; <tt>FALSE</tt> otherwise.
|
||||
*/
|
||||
<ET extends EntityType<?>> boolean addRef(ET element);
|
||||
}
|
||||
|
|
|
@ -19,4 +19,18 @@
|
|||
package org.apache.olingo.ext.proxy.api;
|
||||
|
||||
public interface EntityType<T extends StructuredType<?>> extends StructuredType<T> {
|
||||
|
||||
/**
|
||||
* Appends ref segment to the URI.
|
||||
*
|
||||
* @return the same query instance.
|
||||
*/
|
||||
T refs();
|
||||
|
||||
/**
|
||||
* Gets entity reference ID.
|
||||
*
|
||||
* @return entity reference ID.
|
||||
*/
|
||||
String getEntityReferenceID();
|
||||
}
|
||||
|
|
|
@ -26,4 +26,6 @@ public interface PrimitiveCollection<T extends Serializable>
|
|||
CollectionQuery<PrimitiveCollection<T>>,
|
||||
Collection<T>,
|
||||
Serializable {
|
||||
|
||||
void delete();
|
||||
}
|
||||
|
|
|
@ -33,9 +33,13 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.Future;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.apache.olingo.client.api.uri.URIFilter;
|
||||
import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.ext.proxy.AbstractService;
|
||||
import org.apache.olingo.ext.proxy.api.AbstractTerm;
|
||||
import org.apache.olingo.ext.proxy.api.EntityType;
|
||||
import org.apache.olingo.ext.proxy.api.Sort;
|
||||
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
|
||||
import org.apache.olingo.ext.proxy.api.annotations.Term;
|
||||
|
@ -50,6 +54,8 @@ public abstract class AbstractCollectionInvocationHandler<T extends Serializable
|
|||
|
||||
protected Collection<T> items;
|
||||
|
||||
protected Collection<String> referenceItems;
|
||||
|
||||
protected final URI baseURI;
|
||||
|
||||
protected CommonURIBuilder<?> uri;
|
||||
|
@ -71,13 +77,13 @@ public abstract class AbstractCollectionInvocationHandler<T extends Serializable
|
|||
|
||||
this.itemRef = itemRef;
|
||||
this.items = items;
|
||||
this.referenceItems = new ArrayList<String>();
|
||||
this.uri = uri;
|
||||
this.baseURI = this.uri == null ? null : this.uri.build();
|
||||
}
|
||||
|
||||
public Future<Collection<T>> executeAsync() {
|
||||
return service.getClient().getConfiguration().getExecutor().submit(new Callable<Collection<T>>() {
|
||||
|
||||
@Override
|
||||
public Collection<T> call() throws Exception {
|
||||
return execute();
|
||||
|
@ -173,6 +179,30 @@ public abstract class AbstractCollectionInvocationHandler<T extends Serializable
|
|||
return items.add(element);
|
||||
}
|
||||
|
||||
public <ET extends EntityType<?>> boolean addRef(final ET element) {
|
||||
if (getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element instanceof Proxy && Proxy.getInvocationHandler(element) instanceof EntityInvocationHandler) {
|
||||
final EntityInvocationHandler handler = EntityInvocationHandler.class.cast(Proxy.getInvocationHandler(element));
|
||||
final URI id = ((ODataEntity) handler.getEntity()).getId();
|
||||
if (id == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return referenceItems.add(id.toASCIIString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void refs() {
|
||||
if (getClient().getServiceVersion().compareTo(ODataServiceVersion.V40) >= 0) {
|
||||
((URIBuilder) this.uri).appendRefSegment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return items.size();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.ext.proxy.commons;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
|
@ -33,6 +34,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.apache.olingo.client.api.communication.header.ODataPreferences;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceAddingRequest;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
|
@ -71,7 +73,6 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
@Override
|
||||
public Future<List<ODataRuntimeException>> flushAsync() {
|
||||
return service.getClient().getConfiguration().getExecutor().submit(new Callable<List<ODataRuntimeException>>() {
|
||||
|
||||
@Override
|
||||
public List<ODataRuntimeException> call() throws Exception {
|
||||
return flush();
|
||||
|
@ -93,7 +94,6 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
if (((status != AttachedEntityStatus.ATTACHED
|
||||
&& status != AttachedEntityStatus.LINKED) || attachedEntity.getEntity().isChanged())
|
||||
&& !items.contains(attachedEntity.getEntity())) {
|
||||
|
||||
pos++;
|
||||
pos = processEntityContext(attachedEntity.getEntity(), pos, items, delayedUpdates, changes);
|
||||
}
|
||||
|
@ -224,6 +224,16 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
if (!toBeLinked.isEmpty()) {
|
||||
delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, toBeLinked, type));
|
||||
}
|
||||
|
||||
if (property.getValue() instanceof Proxy) {
|
||||
final InvocationHandler target = Proxy.getInvocationHandler(property.getValue());
|
||||
|
||||
if (target instanceof EntityCollectionInvocationHandler) {
|
||||
for (String ref : ((EntityCollectionInvocationHandler<?>) target).referenceItems) {
|
||||
delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof ODataEntity) {
|
||||
|
@ -253,7 +263,7 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
final URI targetURI = currentStatus == AttachedEntityStatus.NEW
|
||||
? URI.create("$" + startingPos)
|
||||
: URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(), handler.getEntity().getEditLink().toASCIIString());
|
||||
service.getClient().getServiceRoot(), handler.getEntity().getEditLink().toASCIIString());
|
||||
queueUpdate(handler, targetURI, entity, changeset);
|
||||
pos++;
|
||||
items.put(handler, pos);
|
||||
|
@ -265,8 +275,8 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
final URI targetURI = currentStatus == AttachedEntityStatus.NEW
|
||||
? URI.create("$" + startingPos + "/$value")
|
||||
: URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(),
|
||||
handler.getEntity().getEditLink().toASCIIString() + "/$value");
|
||||
service.getClient().getServiceRoot(),
|
||||
handler.getEntity().getEditLink().toASCIIString() + "/$value");
|
||||
|
||||
queueUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);
|
||||
|
||||
|
@ -280,8 +290,8 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
for (Map.Entry<String, EdmStreamValue> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
|
||||
final URI targetURI = currentStatus == AttachedEntityStatus.NEW
|
||||
? URI.create("$" + startingPos) : URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(),
|
||||
CoreUtils.getMediaEditLink(streamedChanges.getKey(), entity).toASCIIString());
|
||||
service.getClient().getServiceRoot(),
|
||||
CoreUtils.getMediaEditLink(streamedChanges.getKey(), entity).toASCIIString());
|
||||
|
||||
queueUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);
|
||||
|
||||
|
@ -302,46 +312,60 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
final PersistenceChanges changeset) {
|
||||
|
||||
for (EntityLinkDesc delayedUpdate : delayedUpdates) {
|
||||
pos++;
|
||||
items.put(delayedUpdate.getSource(), pos);
|
||||
if (StringUtils.isBlank(delayedUpdate.getReference())) {
|
||||
|
||||
final CommonODataEntity changes =
|
||||
service.getClient().getObjectFactory().newEntity(delayedUpdate.getSource().getEntity().getTypeName());
|
||||
pos++;
|
||||
items.put(delayedUpdate.getSource(), pos);
|
||||
|
||||
AttachedEntityStatus status = service.getContext().entityContext().getStatus(delayedUpdate.getSource());
|
||||
final CommonODataEntity changes =
|
||||
service.getClient().getObjectFactory().newEntity(delayedUpdate.getSource().getEntity().getTypeName());
|
||||
|
||||
final URI sourceURI;
|
||||
if (status == AttachedEntityStatus.CHANGED) {
|
||||
sourceURI = URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(),
|
||||
delayedUpdate.getSource().getEntity().getEditLink().toASCIIString());
|
||||
} else {
|
||||
int sourcePos = items.get(delayedUpdate.getSource());
|
||||
sourceURI = URI.create("$" + sourcePos);
|
||||
}
|
||||
AttachedEntityStatus status = service.getContext().entityContext().getStatus(delayedUpdate.getSource());
|
||||
|
||||
for (EntityInvocationHandler target : delayedUpdate.getTargets()) {
|
||||
status = service.getContext().entityContext().getStatus(target);
|
||||
|
||||
final URI targetURI;
|
||||
final URI sourceURI;
|
||||
if (status == AttachedEntityStatus.CHANGED) {
|
||||
targetURI = URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(), target.getEntity().getEditLink().toASCIIString());
|
||||
sourceURI = URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(),
|
||||
delayedUpdate.getSource().getEntity().getEditLink().toASCIIString());
|
||||
} else {
|
||||
int targetPos = items.get(target);
|
||||
targetURI = URI.create("$" + targetPos);
|
||||
int sourcePos = items.get(delayedUpdate.getSource());
|
||||
sourceURI = URI.create("$" + sourcePos);
|
||||
}
|
||||
|
||||
changes.addLink(delayedUpdate.getType() == ODataLinkType.ENTITY_NAVIGATION
|
||||
? service.getClient().getObjectFactory().
|
||||
newEntityNavigationLink(delayedUpdate.getSourceName(), targetURI)
|
||||
: service.getClient().getObjectFactory().
|
||||
newEntitySetNavigationLink(delayedUpdate.getSourceName(), targetURI));
|
||||
for (EntityInvocationHandler target : delayedUpdate.getTargets()) {
|
||||
status = service.getContext().entityContext().getStatus(target);
|
||||
|
||||
LOG.debug("'{}' from {} to {}", delayedUpdate.getType().name(), sourceURI, targetURI);
|
||||
final URI targetURI;
|
||||
if (status == AttachedEntityStatus.CHANGED) {
|
||||
targetURI = URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(), target.getEntity().getEditLink().toASCIIString());
|
||||
} else {
|
||||
int targetPos = items.get(target);
|
||||
targetURI = URI.create("$" + targetPos);
|
||||
}
|
||||
|
||||
changes.addLink(delayedUpdate.getType() == ODataLinkType.ENTITY_NAVIGATION
|
||||
? service.getClient().getObjectFactory().
|
||||
newEntityNavigationLink(delayedUpdate.getSourceName(), targetURI)
|
||||
: service.getClient().getObjectFactory().
|
||||
newEntitySetNavigationLink(delayedUpdate.getSourceName(), targetURI));
|
||||
|
||||
LOG.debug("'{}' from {} to {}", delayedUpdate.getType().name(), sourceURI, targetURI);
|
||||
}
|
||||
|
||||
queueUpdate(delayedUpdate.getSource(), sourceURI, changes, changeset);
|
||||
} else {
|
||||
URI sourceURI = URIUtils.getURI(
|
||||
service.getClient().getServiceRoot(),
|
||||
delayedUpdate.getSource().getEntity().getEditLink().toASCIIString()
|
||||
+ "/" + delayedUpdate.getSourceName() + "/$ref");
|
||||
|
||||
if (queueUpdateLinkViaRef(
|
||||
delayedUpdate.getSource(), sourceURI, URI.create(delayedUpdate.getReference()), changeset)) {
|
||||
pos++;
|
||||
items.put(delayedUpdate.getSource(), pos);
|
||||
}
|
||||
}
|
||||
|
||||
queueUpdate(delayedUpdate.getSource(), sourceURI, changes, changeset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,10 +459,10 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
service.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
|
||||
? ((org.apache.olingo.client.api.v3.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
|
||||
getEntityUpdateRequest(handler.getEntityURI(),
|
||||
org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
|
||||
org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
|
||||
: ((org.apache.olingo.client.api.v4.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
|
||||
getEntityUpdateRequest(handler.getEntityURI(),
|
||||
org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
|
||||
org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
|
||||
|
||||
req.setPrefer(new ODataPreferences(service.getClient().getServiceVersion()).returnContent());
|
||||
|
||||
|
@ -449,6 +473,30 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
changeset.addChange(req, handler);
|
||||
}
|
||||
|
||||
private boolean queueUpdateLinkViaRef(
|
||||
final EntityInvocationHandler handler,
|
||||
final URI source,
|
||||
final URI targetRef,
|
||||
final PersistenceChanges changeset) {
|
||||
|
||||
LOG.debug("Update '{}'", targetRef);
|
||||
if (service.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) >= 1) {
|
||||
final ODataReferenceAddingRequest req =
|
||||
((org.apache.olingo.client.api.v4.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
|
||||
getReferenceAddingRequest(source, targetRef);
|
||||
|
||||
req.setPrefer(new ODataPreferences(service.getClient().getServiceVersion()).returnContent());
|
||||
|
||||
if (StringUtils.isNotBlank(handler.getETag())) {
|
||||
req.setIfMatch(handler.getETag());
|
||||
}
|
||||
|
||||
changeset.addChange(req, handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void queueUpdate(
|
||||
final EntityInvocationHandler handler,
|
||||
final URI uri,
|
||||
|
@ -461,10 +509,10 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
|||
service.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
|
||||
? ((org.apache.olingo.client.api.v3.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
|
||||
getEntityUpdateRequest(uri,
|
||||
org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
|
||||
org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
|
||||
: ((org.apache.olingo.client.api.v4.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
|
||||
getEntityUpdateRequest(uri,
|
||||
org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
|
||||
org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
|
||||
|
||||
req.setPrefer(new ODataPreferences(service.getClient().getServiceVersion()).returnContent());
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.concurrent.Callable;
|
|||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.olingo.client.api.uri.CommonURIBuilder;
|
||||
import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataProperty;
|
||||
|
@ -47,6 +48,7 @@ import org.apache.olingo.commons.api.domain.ODataLinked;
|
|||
import org.apache.olingo.commons.api.domain.ODataValue;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.ext.proxy.AbstractService;
|
||||
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
|
||||
import org.apache.olingo.ext.proxy.api.ComplexCollection;
|
||||
|
@ -156,7 +158,9 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
|
|||
|
||||
@Override
|
||||
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
|
||||
if ("expand".equals(method.getName()) || "select".equals(method.getName())) {
|
||||
if ("expand".equals(method.getName())
|
||||
|| "select".equals(method.getName())
|
||||
|| "refs".equals(method.getName())) {
|
||||
invokeSelfMethod(method, args);
|
||||
return proxy;
|
||||
} else if (isSelfMethod(method, args)) {
|
||||
|
@ -238,7 +242,8 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
|
|||
public void delete(final String name) {
|
||||
if (baseURI != null) {
|
||||
getContext().entityContext().addFurtherDeletes(
|
||||
getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).build());
|
||||
getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).appendValueSegment().
|
||||
build());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +259,8 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
|
|||
entityContext.attach(handler, AttachedEntityStatus.DELETED);
|
||||
}
|
||||
} else if (baseURI != null) {
|
||||
entityContext.addFurtherDeletes(baseURI);
|
||||
entityContext.addFurtherDeletes(
|
||||
getClient().newURIBuilder(baseURI.toASCIIString()).appendValueSegment().build());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,6 +638,12 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
|
|||
this.uri.select(select);
|
||||
}
|
||||
|
||||
public void refs() {
|
||||
if (getClient().getServiceVersion().compareTo(ODataServiceVersion.V40) >= 0) {
|
||||
((URIBuilder) this.uri).appendRefSegment();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearQueryOptions() {
|
||||
this.uri = baseURI == null ? null : getClient().newURIBuilder(baseURI.toASCIIString());
|
||||
}
|
||||
|
|
|
@ -59,8 +59,8 @@ public class EntityCollectionInvocationHandler<T extends EntityType<?>>
|
|||
|| "expand".equals(method.getName())
|
||||
|| "select".equals(method.getName())
|
||||
|| "nextPage".equals(method.getName())
|
||||
|| "refs".equals(method.getName())
|
||||
|| "execute".equals(method.getName())) {
|
||||
|
||||
invokeSelfMethod(method, args);
|
||||
return proxy;
|
||||
} else if (isSelfMethod(method, args)) {
|
||||
|
|
|
@ -508,6 +508,15 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
|
|||
return getEntity() == null ? null : getEntity().getProperty(name);
|
||||
}
|
||||
|
||||
public String getEntityReferenceID() {
|
||||
URI id = getEntity() == null ? null
|
||||
: getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
|
||||
? ((org.apache.olingo.commons.api.domain.v3.ODataEntity) getEntity()).getLink()
|
||||
: ((org.apache.olingo.commons.api.domain.v4.ODataEntity) getEntity()).getId();
|
||||
|
||||
return id == null ? null : id.toASCIIString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return uuid.toString();
|
||||
|
|
|
@ -114,6 +114,13 @@ public class PrimitiveCollectionInvocationHandler<T extends Serializable>
|
|||
resItems, null, Collections.<ODataAnnotation>emptyList());
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (baseURI != null) {
|
||||
getContext().entityContext().addFurtherDeletes(
|
||||
getClient().newURIBuilder(baseURI.toASCIIString()).appendValueSegment().build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof Proxy) {
|
||||
|
|
|
@ -41,6 +41,8 @@ public class EntityLinkDesc implements Serializable {
|
|||
|
||||
private final ODataLinkType type;
|
||||
|
||||
private final String reference;
|
||||
|
||||
public EntityLinkDesc(
|
||||
final String sourceName,
|
||||
final EntityInvocationHandler source,
|
||||
|
@ -50,6 +52,7 @@ public class EntityLinkDesc implements Serializable {
|
|||
this.source = source;
|
||||
this.targets = target;
|
||||
this.type = type;
|
||||
this.reference = null;
|
||||
}
|
||||
|
||||
public EntityLinkDesc(
|
||||
|
@ -61,6 +64,18 @@ public class EntityLinkDesc implements Serializable {
|
|||
this.source = source;
|
||||
this.targets = Collections.<EntityInvocationHandler>singleton(target);
|
||||
this.type = type;
|
||||
this.reference = null;
|
||||
}
|
||||
|
||||
public EntityLinkDesc(
|
||||
final String sourceName,
|
||||
final EntityInvocationHandler source,
|
||||
final String targetRef) {
|
||||
this.sourceName = sourceName;
|
||||
this.source = source;
|
||||
this.targets = null;
|
||||
this.type = null;
|
||||
this.reference = targetRef;
|
||||
}
|
||||
|
||||
public String getSourceName() {
|
||||
|
@ -79,6 +94,10 @@ public class EntityLinkDesc implements Serializable {
|
|||
return type;
|
||||
}
|
||||
|
||||
public String getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
|
|
|
@ -1365,6 +1365,17 @@ public class V4Services extends AbstractServices {
|
|||
return xml.createResponse(null, null, null, Status.NO_CONTENT);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/Customers(1)/Orders/$ref")
|
||||
public Response linkOrderViaRef(
|
||||
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
|
||||
@HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
|
||||
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
|
||||
final String entity) {
|
||||
|
||||
return xml.createResponse(null, null, null, Status.NO_CONTENT);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/Products({productId})/Categories({categoryId})/$ref")
|
||||
public Response deleteLinked(
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/$metadata#$ref",
|
||||
"value":
|
||||
[
|
||||
{"@odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Orders(7)"},
|
||||
{"@odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Orders(8)"}
|
||||
]
|
||||
}
|
|
@ -54,8 +54,10 @@ import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.service
|
|||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.AddressCollection;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Color;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Customer;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.CustomerCollection;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.HomeAddress;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Order;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.OrderCollection;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Person;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.PersonCollection;
|
||||
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Product;
|
||||
|
@ -74,6 +76,46 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
|
|||
return container;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readEntitySet() {
|
||||
final OrderCollection orders = container.getOrders().execute();
|
||||
assertFalse(orders.isEmpty());
|
||||
|
||||
final CustomerCollection customers = container.getCustomers().
|
||||
orderBy("PersonID").
|
||||
select("FirstName", "LastName", "Orders").
|
||||
expand("Orders").
|
||||
execute();
|
||||
|
||||
assertEquals(2, customers.size());
|
||||
for (Customer customer : customers) {
|
||||
assertNotNull(customer.getFirstName());
|
||||
assertNotNull(customer.getLastName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readWithReferences() {
|
||||
final Person person = container.getOrders().getByKey(8).getCustomerForOrder().refs().load();
|
||||
assertEquals("http://localhost:9080/stub/StaticService/V40/Static.svc/Customers(PersonID=1)",
|
||||
person.getEntityReferenceID());
|
||||
|
||||
final OrderCollection orders = container.getCustomers().getByKey(1).getOrders().refs().execute();
|
||||
assertEquals("http://localhost:9080/stub/StaticService/V40/Static.svc/Orders(7)",
|
||||
orders.iterator().next().getEntityReferenceID());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addViaReference() {
|
||||
final Order order = container.getOrders().getByKey(8).load();
|
||||
|
||||
final OrderCollection orders = container.newEntityCollection(OrderCollection.class);
|
||||
orders.addRef(order);
|
||||
|
||||
container.getCustomers().getByKey(1).setOrders(orders);
|
||||
container.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readAndCheckForPrimitive() {
|
||||
final Customer customer = getContainer().getCustomers().getByKey(1);
|
||||
|
@ -243,6 +285,42 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
|
|||
service.getContext().detachAll(); // avoid influences
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteSingleProperty() {
|
||||
container.getCustomers().getByKey(1).delete("City");
|
||||
container.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteComplex() {
|
||||
container.getCustomers().getByKey(1).getHomeAddress().delete();
|
||||
container.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteCollection() {
|
||||
container.getCustomers().getByKey(1).getEmails().delete();
|
||||
container.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteEdmStreamProperty() throws IOException {
|
||||
// ---------------------------------------
|
||||
// Instantiate Demo Service
|
||||
// ---------------------------------------
|
||||
final org.apache.olingo.fit.proxy.v4.demo.Service<EdmEnabledODataClient> dservice =
|
||||
org.apache.olingo.fit.proxy.v4.demo.Service.getV4(testDemoServiceRootURL);
|
||||
dservice.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
|
||||
final DemoService dcontainer = dservice.getEntityContainer(DemoService.class);
|
||||
assertNotNull(dcontainer);
|
||||
dservice.getContext().detachAll();
|
||||
// ---------------------------------------
|
||||
dcontainer.getPersonDetails().getByKey(1).delete("Photo");
|
||||
dcontainer.flush();
|
||||
|
||||
dservice.getContext().detachAll(); // avoid influences
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateComplexProperty() {
|
||||
Address homeAddress = container.getCustomers().getByKey(1).getHomeAddress();
|
||||
|
@ -327,7 +405,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
|
|||
// ---------------------------------------
|
||||
org.apache.olingo.fit.proxy.v3.staticservice.Service<org.apache.olingo.client.api.v3.EdmEnabledODataClient> v3serv =
|
||||
org.apache.olingo.fit.proxy.v3.staticservice.Service.getV3(
|
||||
"http://localhost:9080/stub/StaticService/V30/Static.svc");
|
||||
"http://localhost:9080/stub/StaticService/V30/Static.svc");
|
||||
v3serv.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
|
||||
final DefaultContainer v3cont = v3serv.getEntityContainer(DefaultContainer.class);
|
||||
assertNotNull(v3cont);
|
||||
|
@ -378,11 +456,32 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
|
|||
// container.getOrders().getByKey(1).getCustomerForOrder().getEmails().execute().isEmpty());
|
||||
// Not supported by the test service BTW generates a single request as expected:
|
||||
// <service root>/Orders(1)/CustomerForOrder/Emails
|
||||
|
||||
emails.add("fabio.martelli@tirasa.net");
|
||||
container.getPeople().getByKey(1).setEmails(emails);
|
||||
|
||||
container.flush();
|
||||
|
||||
boolean found = false;
|
||||
for (String email : container.getPeople().getByKey(1).getEmails().execute()) {
|
||||
if (email.equals("fabio.martelli@tirasa.net")) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(found);
|
||||
|
||||
getService().getContext().detachAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workingWithSingletons() {
|
||||
assertNotNull(container.getCompany().getVipCustomer().load().getPersonID());
|
||||
|
||||
container.getCompany().setName("new name");
|
||||
container.flush();
|
||||
|
||||
assertEquals("new name", container.getCompany().load().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -424,7 +523,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
|
|||
final AddressCollection ac = container.newComplexCollection(AddressCollection.class);
|
||||
final Person updated = container.getCustomers().getByKey(2).operations().
|
||||
resetAddress(ac, 0).select("Name").expand("Orders").execute();
|
||||
assertNotNull(person);
|
||||
assertNotNull(updated);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -62,7 +62,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
|
|||
|
||||
@Test
|
||||
public void update() {
|
||||
Person person = getContainer().getPeople().getByKey(1).load();
|
||||
Person person = getContainer().getPeople().getByKey(1);
|
||||
|
||||
final Address address = person.getHomeAddress();
|
||||
address.setCity("XXX");
|
||||
|
|
|
@ -32,4 +32,16 @@ public interface CUDRequestFactory extends CommonCUDRequestFactory<UpdateType> {
|
|||
ODataEntityUpdateRequest<ODataSingleton> getSingletonUpdateRequest(
|
||||
UpdateType type, ODataSingleton entity);
|
||||
|
||||
/**
|
||||
* A successful POST request to a navigation property's references collection adds a relationship to an existing
|
||||
* entity. The request body MUST contain a single entity reference that identifies the entity to be added. See the
|
||||
* appropriate format document for details. On successful completion, the response MUST be 204 No Content and contain
|
||||
* an empty body.
|
||||
*
|
||||
* @param <E> concrete ODataEntity implementation
|
||||
* @param targetURI entity set URI.
|
||||
* @param entity entity to be created.
|
||||
* @return new ODataEntityCreateRequest instance.
|
||||
*/
|
||||
ODataReferenceAddingRequest getReferenceAddingRequest(URI targetURI, URI reference);
|
||||
}
|
||||
|
|
|
@ -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.client.api.communication.request.cud.v4;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.response.v4.ODataReferenceAddingResponse;
|
||||
|
||||
/**
|
||||
* This class implements an OData delete request.
|
||||
*/
|
||||
public interface ODataReferenceAddingRequest
|
||||
extends ODataBasicRequest<ODataReferenceAddingResponse>, ODataBatchableRequest {
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.client.api.communication.response.v4;
|
||||
|
||||
import org.apache.olingo.client.api.communication.response.*;
|
||||
|
||||
/**
|
||||
* This class implements the response to an OData delete request.
|
||||
*
|
||||
* @see org.apache.olingo.client.core.communication.request.cud.ODataDeleteRequest
|
||||
*/
|
||||
public interface ODataReferenceAddingResponse extends ODataResponse {
|
||||
}
|
|
@ -22,7 +22,9 @@ import java.net.URI;
|
|||
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceAddingRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.api.v4.ODataClient;
|
||||
import org.apache.olingo.client.core.communication.request.cud.AbstractCUDRequestFactory;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataSingleton;
|
||||
|
@ -47,4 +49,8 @@ public class CUDRequestFactoryImpl extends AbstractCUDRequestFactory<UpdateType>
|
|||
return super.getEntityUpdateRequest(targetURI, type, changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataReferenceAddingRequest getReferenceAddingRequest(final URI targetURI, final URI reference) {
|
||||
return new ODataReferenceAddingRequestImpl(client, HttpMethod.POST, targetURI, reference);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.client.core.communication.request.cud.v4;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
|
||||
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceAddingRequest;
|
||||
import org.apache.olingo.client.api.communication.response.v4.ODataReferenceAddingResponse;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
|
||||
/**
|
||||
* This class implements an OData delete request.
|
||||
*/
|
||||
public class ODataReferenceAddingRequestImpl extends AbstractODataBasicRequest<ODataReferenceAddingResponse>
|
||||
implements ODataReferenceAddingRequest {
|
||||
|
||||
final URI reference;
|
||||
|
||||
ODataReferenceAddingRequestImpl(
|
||||
final CommonODataClient<?> odataClient, final HttpMethod method, final URI uri, final URI reference) {
|
||||
super(odataClient, method, uri);
|
||||
this.reference = reference;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataFormat getDefaultFormat() {
|
||||
return odataClient.getConfiguration().getDefaultPubFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* No payload: null will be returned.
|
||||
*/
|
||||
@Override
|
||||
protected InputStream getPayload() {
|
||||
if (reference == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return IOUtils.toInputStream(reference.toASCIIString(), Constants.UTF8);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Error serializing reference {}", reference);
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataReferenceAddingResponse execute() {
|
||||
return new ODataReferenceAddingResponseImpl(odataClient, httpClient, doExecute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Response class about an ODataDeleteRequest.
|
||||
*/
|
||||
private class ODataReferenceAddingResponseImpl extends AbstractODataResponse implements ODataReferenceAddingResponse {
|
||||
|
||||
private ODataReferenceAddingResponseImpl(
|
||||
final CommonODataClient<?> odataClient, final HttpClient httpClient, final HttpResponse res) {
|
||||
|
||||
super(odataClient, httpClient, res);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue