You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/08/09 08:46:09 UTC
git commit: [OLINGO-395] fixed
Repository: olingo-odata4
Updated Branches:
refs/heads/master 5cdf64db2 -> e3d3bde6e
[OLINGO-395] fixed
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/e3d3bde6
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/e3d3bde6
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/e3d3bde6
Branch: refs/heads/master
Commit: e3d3bde6e297a7074951c901e7e33290088b5a82
Parents: 5cdf64d
Author: fmartelli <fa...@gmail.com>
Authored: Sat Aug 9 08:45:52 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Sat Aug 9 08:45:52 2014 +0200
----------------------------------------------------------------------
.../olingo/ext/proxy/api/AbstractEntitySet.java | 4 +-
.../commons/AbstractInvocationHandler.java | 51 +++++++++++++-
.../commons/AbstractPersistenceManager.java | 9 +--
.../AbstractStructuredInvocationHandler.java | 16 ++---
.../commons/CompoundKeyElementWrapper.java | 57 ---------------
.../proxy/commons/EntityInvocationHandler.java | 74 ++++++++------------
.../commons/EntitySetInvocationHandler.java | 25 +++----
.../olingo/ext/proxy/context/EntityContext.java | 15 +++-
.../proxy/utils/CompoundKeyElementWrapper.java | 51 ++++++++++++++
.../olingo/ext/proxy/utils/CoreUtils.java | 53 ++++++++++++++
.../fit/proxy/v4/APIBasicDesignTestITCase.java | 58 ++++++++++++++-
11 files changed, 273 insertions(+), 140 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/api/AbstractEntitySet.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/api/AbstractEntitySet.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/api/AbstractEntitySet.java
index 57ad175..3e98f12 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/api/AbstractEntitySet.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/api/AbstractEntitySet.java
@@ -78,9 +78,9 @@ public interface AbstractEntitySet<
* Deletes the given entity in a batch.
*
* @param <S>
- * @param entities to be deleted
+ * @param entity to be deleted
*/
- <S extends T> void delete(S entities);
+ <S extends T> void delete(S entity);
/**
* Deletes the given entities in a batch.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
index 3dcec81..ae30342 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
@@ -32,16 +32,20 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.ComplexType;
+import org.apache.olingo.ext.proxy.api.EntityType;
import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
+import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.api.annotations.Singleton;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
import org.apache.olingo.ext.proxy.context.Context;
+import org.apache.olingo.ext.proxy.context.EntityContext;
import org.apache.olingo.ext.proxy.utils.CoreUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -130,7 +134,52 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
}
protected boolean isDeleted(final EntityInvocationHandler handler) {
- return getContext().entityContext().getStatus(handler) == AttachedEntityStatus.DELETED;
+ return (getContext().entityContext().isAttached(handler)
+ && getContext().entityContext().getStatus(handler) == AttachedEntityStatus.DELETED)
+ || getContext().entityContext().getFurtherDeletes().contains(handler.getEntityURI());
+ }
+
+ protected <S extends EntityType<?>> void deleteEntity(final EntityInvocationHandler handler, final URI entitySetURI) {
+ final EntityContext entityContext = getContext().entityContext();
+
+ final URI baseURI = entitySetURI == null ? handler.getEntitySetURI() : entitySetURI;
+
+ if (baseURI == null) {
+ throw new IllegalStateException("Entity base URI not available");
+ }
+
+ final String name = handler.getUUID().getType().
+ getAnnotation(org.apache.olingo.ext.proxy.api.annotations.EntityType.class).name();
+
+ final String namespace = handler.getUUID().getType().getAnnotation(Namespace.class).value();
+
+ final CommonODataEntity template;
+
+ final URI entityURI;
+ if (handler.getEntityURI() == null || handler.getUUID().getKey() == null) {
+ template = service.getClient().getObjectFactory().newEntity(new FullQualifiedName(namespace, name));
+ CoreUtils.addProperties(getClient(), handler.getPropertyChanges(), template);
+ final Object key = CoreUtils.getKey(getClient(), handler, handler.getUUID().getType(), template);
+
+ entityURI = CoreUtils.buildEditLink(getClient(), baseURI.toASCIIString(), template, key).build();
+ template.setEditLink(entityURI);
+ } else {
+ entityURI = handler.getEntityURI();
+ template = handler.getEntity();
+ }
+
+ // https://issues.apache.org/jira/browse/OLINGO-395
+ if (entityContext.isAttached(handler)) {
+ entityContext.addFurtherDeletes(entityURI);
+ } else {
+ if (handler.getUUID().getKey() == null) {
+ // objects created ad-hoc to generate deletion requests
+ handler.updateEntityUUID(baseURI, handler.getUUID().getType(), template);
+ } else {
+ handler.updateUUID(baseURI, handler.getUUID().getType(), handler.getUUID().getKey());
+ }
+ entityContext.attach(handler, AttachedEntityStatus.DELETED, true);
+ }
}
protected static CommonURIBuilder<?> buildEntitySetURI(
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
index 62b701a..0d5e850 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
@@ -528,20 +528,17 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
final CommonODataEntity entity,
final PersistenceChanges changeset) {
final URI deleteURI = entity.getEditLink() == null ? handler.getEntityURI() : entity.getEditLink();
- changeset.addChange(buildDeleteRequest(deleteURI, handler.getETag(), changeset), handler);
+ changeset.addChange(buildDeleteRequest(deleteURI, handler.getETag()), handler);
}
private void queueDelete(
final URI deleteURI,
final String etag,
final PersistenceChanges changeset) {
- changeset.addChange(buildDeleteRequest(deleteURI, etag, changeset), null);
+ changeset.addChange(buildDeleteRequest(deleteURI, etag), null);
}
- private ODataDeleteRequest buildDeleteRequest(
- final URI deleteURI,
- final String etag,
- final PersistenceChanges changeset) {
+ private ODataDeleteRequest buildDeleteRequest(final URI deleteURI, final String etag) {
LOG.debug("Delete '{}'", deleteURI);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
index 3189842..c6cfe77 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
@@ -251,13 +251,7 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
final EntityContext entityContext = getContext().entityContext();
if (this instanceof EntityInvocationHandler) {
- final EntityInvocationHandler handler = EntityInvocationHandler.class.cast(this);
-
- if (entityContext.isAttached(handler)) {
- entityContext.setStatus(handler, AttachedEntityStatus.DELETED);
- } else {
- entityContext.attach(handler, AttachedEntityStatus.DELETED);
- }
+ deleteEntity(EntityInvocationHandler.class.cast(this), null);
} else if (baseURI != null) {
entityContext.addFurtherDeletes(
getClient().newURIBuilder(baseURI.toASCIIString()).appendValueSegment().build());
@@ -297,10 +291,10 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
res = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {EdmStreamValue.class}, new EdmStreamValueHandler(
- baseURI == null
- ? null
- : getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).build(),
- service));
+ baseURI == null
+ ? null
+ : getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).build(),
+ service));
streamedPropertyCache.put(name, EdmStreamValue.class.cast(res));
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/CompoundKeyElementWrapper.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/CompoundKeyElementWrapper.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/CompoundKeyElementWrapper.java
deleted file mode 100644
index 0b78fe1..0000000
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/CompoundKeyElementWrapper.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.ext.proxy.commons;
-
-import java.lang.reflect.Method;
-
-class CompoundKeyElementWrapper implements Comparable<CompoundKeyElementWrapper> {
-
- private final String name;
-
- private final Method method;
-
- private final int position;
-
- protected CompoundKeyElementWrapper(final String name, final Method method, final int position) {
- this.name = name;
- this.method = method;
- this.position = position;
- }
-
- public String getName() {
- return name;
- }
-
- public Method getMethod() {
- return method;
- }
-
- public int getPosition() {
- return position;
- }
-
- @Override
- public int compareTo(final CompoundKeyElementWrapper other) {
- if (other == null) {
- return 1;
- } else {
- return getPosition() > other.getPosition() ? 1 : getPosition() == other.getPosition() ? 0 : -1;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
index e7e11b6..32d3b26 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
@@ -19,7 +19,6 @@
package org.apache.olingo.ext.proxy.commons;
import java.io.InputStream;
-import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -27,11 +26,8 @@ import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
@@ -48,8 +44,6 @@ import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.AbstractTerm;
import org.apache.olingo.ext.proxy.api.Annotatable;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
-import org.apache.olingo.ext.proxy.api.annotations.CompoundKey;
-import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
import org.apache.olingo.ext.proxy.api.annotations.EntityType;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
@@ -197,15 +191,8 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
this.baseURI = entity.getEditLink();
this.uri = getClient().newURIBuilder(baseURI.toASCIIString());
} else if (key != null) {
- final CommonURIBuilder<?> uriBuilder = getClient().newURIBuilder(entitySetURI.toASCIIString());
-
- if (key.getClass().getAnnotation(CompoundKey.class) == null) {
- LOG.debug("Append key segment '{}'", key);
- uriBuilder.appendKeySegment(key);
- } else {
- LOG.debug("Append compound key segment '{}'", key);
- uriBuilder.appendKeySegment(getCompoundKey(key));
- }
+ final CommonURIBuilder<?> uriBuilder =
+ CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), entity, key);
this.uri = uriBuilder;
this.baseURI = this.uri.build();
@@ -225,15 +212,19 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
this.internal = entity;
getEntity().setMediaEntity(typeRef.getAnnotation(EntityType.class).hasStream());
- this.uuid = new EntityUUID(
- getUUID().getEntitySetURI(),
- getUUID().getType(),
- CoreUtils.getKey(getClient(), this, typeRef, entity));
+ final Object key = CoreUtils.getKey(getClient(), this, typeRef, entity);
+
+ this.uuid = new EntityUUID(getUUID().getEntitySetURI(), getUUID().getType(), key);
// fix for OLINGO-353
if (this.uri == null) {
- this.baseURI = entity.getEditLink();
- this.uri = this.baseURI == null ? null : getClient().newURIBuilder(this.baseURI.toASCIIString());
+ final CommonURIBuilder<?> uriBuilder =
+ entity.getEditLink() == null
+ ? CoreUtils.buildEditLink(getClient(), getUUID().getEntitySetURI().toASCIIString(), entity, key)
+ : getClient().newURIBuilder(entity.getEditLink().toASCIIString());
+
+ this.uri = uriBuilder;
+ this.baseURI = this.uri == null ? null : this.uri.build();
}
this.streamedPropertyChanges.clear();
@@ -250,8 +241,25 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
return uuid;
}
+ public EntityUUID updateEntityUUID(final URI entitySetURI, final Class<?> type, final CommonODataEntity entity) {
+ CoreUtils.addProperties(service.getClient(), this.getPropertyChanges(), entity);
+ final Object key = CoreUtils.getKey(getClient(), this, this.getUUID().getType(), entity);
+ return updateUUID(entitySetURI, type, key);
+ }
+
public EntityUUID updateUUID(final URI entitySetURI, final Class<?> type, final Object key) {
this.uuid = new EntityUUID(entitySetURI, type, key);
+
+ if (this.uri == null) {
+ final CommonURIBuilder<?> uriBuilder =
+ getEntity().getEditLink() == null
+ ? CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), getEntity(), key)
+ : getClient().newURIBuilder(getEntity().getEditLink().toASCIIString());
+
+ this.uri = uriBuilder;
+ this.baseURI = this.uri == null ? null : this.uri.build();
+ }
+
return this.uuid;
}
@@ -474,30 +482,6 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
}
}
- private Map<String, Object> getCompoundKey(final Object key) {
- final Set<CompoundKeyElementWrapper> elements = new TreeSet<CompoundKeyElementWrapper>();
-
- for (Method method : key.getClass().getMethods()) {
- final Annotation annotation = method.getAnnotation(CompoundKeyElement.class);
- if (annotation instanceof CompoundKeyElement) {
- elements.add(new CompoundKeyElementWrapper(
- ((CompoundKeyElement) annotation).name(), method, ((CompoundKeyElement) annotation).position()));
- }
- }
-
- final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
-
- for (CompoundKeyElementWrapper element : elements) {
- try {
- map.put(element.getName(), element.getMethod().invoke(key));
- } catch (Exception e) {
- LOG.warn("Error retrieving compound key element '{}' value", element.getName(), e);
- }
- }
-
- return map;
- }
-
@Override
@SuppressWarnings("unchecked")
protected <T extends CommonODataProperty> List<T> getInternalProperties() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
index 72355c3..bf52a85 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
@@ -135,16 +135,18 @@ public class EntitySetInvocationHandler<
typeRef.getAnnotation(Namespace.class).value(), ClassUtils.getEntityTypeName(typeRef)));
handler = EntityInvocationHandler.getInstance(key, entity, this.baseURI, typeRef, service);
- } else if (isDeleted(handler)) {
+ }
+
+ if (isDeleted(handler)) {
// object deleted
LOG.debug("Object '{}({})' has been deleted", typeRef.getSimpleName(), uuid);
- handler = null;
+ return null;
+ } else {
+ return (S) Proxy.newProxyInstance(
+ Thread.currentThread().getContextClassLoader(),
+ new Class<?>[] {typeRef},
+ handler);
}
-
- return handler == null ? null : (S) Proxy.newProxyInstance(
- Thread.currentThread().getContextClassLoader(),
- new Class<?>[] {typeRef},
- handler);
}
@Override
@@ -257,14 +259,7 @@ public class EntitySetInvocationHandler<
@Override
public <S extends T> void delete(final S entity) {
- final EntityContext entityContext = getContext().entityContext();
-
- final EntityInvocationHandler handler = (EntityInvocationHandler) Proxy.getInvocationHandler(entity);
- if (entityContext.isAttached(handler)) {
- entityContext.setStatus(handler, AttachedEntityStatus.DELETED);
- } else {
- entityContext.attach(handler, AttachedEntityStatus.DELETED);
- }
+ deleteEntity((EntityInvocationHandler) Proxy.getInvocationHandler(entity), this.baseURI);
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
index 945273e..be63762 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
@@ -93,11 +93,24 @@ public class EntityContext implements Iterable<AttachedEntity> {
* @param status status.
*/
public void attach(final EntityInvocationHandler entity, final AttachedEntityStatus status) {
+ attach(entity, status, false);
+ }
+
+ /**
+ * Attaches an entity with specified status.
+ * <br/>
+ * Use this method to attach an existing entity.
+ *
+ * @param entity entity to be attached.
+ * @param status status.
+ * @param force force attach.
+ */
+ public void attach(final EntityInvocationHandler entity, final AttachedEntityStatus status, final boolean force) {
if (isAttached(entity)) {
throw new IllegalStateException("An entity with the same profile has already been attached");
}
- if (entity.getUUID().getEntitySetURI() != null) {
+ if (force || entity.getUUID().getEntitySetURI() != null) {
allAttachedEntities.put(entity, status);
if (entity.getUUID().getKey() != null) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CompoundKeyElementWrapper.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CompoundKeyElementWrapper.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CompoundKeyElementWrapper.java
new file mode 100644
index 0000000..7880174
--- /dev/null
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CompoundKeyElementWrapper.java
@@ -0,0 +1,51 @@
+/**
+ * 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.ext.proxy.utils;
+
+import java.lang.reflect.Method;
+
+public class CompoundKeyElementWrapper implements Comparable<CompoundKeyElementWrapper> {
+
+ private final String name;
+
+ private final Method method;
+
+ private final int position;
+
+ public CompoundKeyElementWrapper(final String name, final Method method, final int position) {
+ this.name = name;
+ this.method = method;
+ this.position = position;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ @Override
+ public int compareTo(final CompoundKeyElementWrapper other) {
+ if (other == null) {
+ return 1;
+ } else {
+ return getPosition() > other.getPosition() ? 1 : getPosition() == other.getPosition() ? 0 : -1;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index 1fdea3f..64a77a5 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -30,8 +30,11 @@ import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
@@ -62,6 +65,7 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.AbstractTerm;
import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
+import org.apache.olingo.ext.proxy.api.annotations.CompoundKey;
import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
import org.apache.olingo.ext.proxy.api.annotations.EnumType;
import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -397,6 +401,55 @@ public final class CoreUtils {
return propertyClass;
}
+ public static CommonURIBuilder<?> buildEditLink(
+ final CommonEdmEnabledODataClient<?> client,
+ final String entitySetURI,
+ final CommonODataEntity entity,
+ final Object key) {
+
+ if (key == null) {
+ return null;
+ }
+
+ final CommonURIBuilder<?> uriBuilder = StringUtils.isNotBlank(entitySetURI)
+ ? client.newURIBuilder(entitySetURI)
+ : client.newURIBuilder();
+
+ if (key.getClass().getAnnotation(CompoundKey.class) == null) {
+ LOG.debug("Append key segment '{}'", key);
+ uriBuilder.appendKeySegment(key);
+ } else {
+ LOG.debug("Append compound key segment '{}'", key);
+ uriBuilder.appendKeySegment(CoreUtils.getCompoundKey(key));
+ }
+
+ return uriBuilder;
+ }
+
+ public static Map<String, Object> getCompoundKey(final Object key) {
+ final Set<CompoundKeyElementWrapper> elements = new TreeSet<CompoundKeyElementWrapper>();
+
+ for (Method method : key.getClass().getMethods()) {
+ final Annotation annotation = method.getAnnotation(CompoundKeyElement.class);
+ if (annotation instanceof CompoundKeyElement) {
+ elements.add(new CompoundKeyElementWrapper(
+ ((CompoundKeyElement) annotation).name(), method, ((CompoundKeyElement) annotation).position()));
+ }
+ }
+
+ final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
+
+ for (CompoundKeyElementWrapper element : elements) {
+ try {
+ map.put(element.getName(), element.getMethod().invoke(key));
+ } catch (Exception e) {
+ LOG.warn("Error retrieving compound key element '{}' value", element.getName(), e);
+ }
+ }
+
+ return map;
+ }
+
public static Object getKey(
final CommonEdmEnabledODataClient<?> client,
final EntityInvocationHandler typeHandler,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e3d3bde6/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
index 7d592c6..4804191 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
@@ -29,10 +29,12 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;
+import java.util.List;
import java.util.TimeZone;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
+import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
@@ -278,7 +280,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
service.getContext().detachAll();
try {
- getContainer().getOrders().getByKey(105).load();
+ getContainer().getOrders().getByKey(1105).load();
fail();
} catch (IllegalArgumentException e) {
}
@@ -410,7 +412,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);
@@ -572,4 +574,56 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
assertNotNull(parent);
assertEquals(2, parent.getPersonID(), 0);
}
+
+ /**
+ * Java client should support the deletion based on locally created entity.
+ *
+ * @see https://issues.apache.org/jira/browse/OLINGO-395
+ */
+ @Test
+ public void issueOLINGO395() {
+ Order order = getContainer().newEntityInstance(Order.class);
+ order.setOrderID(1105);
+
+ final Calendar orderDate = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ orderDate.clear();
+ orderDate.set(2011, 3, 4, 16, 3, 57);
+ order.setOrderDate(new Timestamp(orderDate.getTimeInMillis()));
+
+ order.setShelfLife(BigDecimal.ZERO);
+
+ final PrimitiveCollection<BigDecimal> osl = getContainer().newPrimitiveCollection(BigDecimal.class);
+ osl.add(BigDecimal.TEN.negate());
+ osl.add(BigDecimal.TEN);
+
+ order.setOrderShelfLifes(osl);
+
+ getContainer().getOrders().add(order);
+ getContainer().getOrders().delete(order);
+
+ List<ODataRuntimeException> res = getContainer().flush();
+ assertTrue(res.isEmpty() || res.iterator().next() == null);
+
+ service.getContext().detachAll();
+ try {
+ getContainer().getOrders().getByKey(1105).load();
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ service.getContext().detachAll(); // avoid influences
+
+ order = getContainer().newEntityInstance(Order.class);
+ order.setOrderID(1105);
+
+ getContainer().getOrders().delete(order);
+ getContainer().flush(); // test service doesn't fail for delete requests about unexisting objects
+
+ service.getContext().detachAll();
+ try {
+ getContainer().getOrders().getByKey(1105).load();
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ service.getContext().detachAll(); // avoid influences
+ }
}