diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractEntityCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractEntityCollectionInvocationHandler.java index 2435e088d..d63ab734a 100644 --- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractEntityCollectionInvocationHandler.java +++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractEntityCollectionInvocationHandler.java @@ -56,6 +56,8 @@ public abstract class AbstractEntityCollectionInvocationHandler< protected final URI baseURI; + protected URI targetEntitySetURI; + protected CommonURIBuilder uri; private boolean isSingleton = false; @@ -69,6 +71,7 @@ public abstract class AbstractEntityCollectionInvocationHandler< this.uri = uri; this.baseURI = uri.build(); + this.targetEntitySetURI = uri.build(); this.isSingleton = AbstractSingleton.class.isAssignableFrom(ref); final Type[] entitySetParams = @@ -83,6 +86,7 @@ public abstract class AbstractEntityCollectionInvocationHandler< final Class itemRef, final Class collItemRef, final Service service, + final URI targetEntitySetURI, final CommonURIBuilder uri) { super(service); @@ -90,6 +94,7 @@ public abstract class AbstractEntityCollectionInvocationHandler< this.baseURI = uri == null ? null : uri.build(); this.itemRef = (Class) itemRef; this.collItemRef = collItemRef; + this.targetEntitySetURI = targetEntitySetURI; } protected Class getTypeRef() { @@ -116,7 +121,7 @@ public abstract class AbstractEntityCollectionInvocationHandler< } final EntityCollectionInvocationHandler entityCollectionHandler = - new EntityCollectionInvocationHandler(service, items, typeRef, uriBuilder); + new EntityCollectionInvocationHandler(service, items, typeRef, targetEntitySetURI, uriBuilder); entityCollectionHandler.setAnnotations(annotations); return (SEC) Proxy.newProxyInstance( @@ -167,7 +172,7 @@ public abstract class AbstractEntityCollectionInvocationHandler< typeRef) : EntityInvocationHandler.getInstance( entity, - null, + targetEntitySetURI, typeRef, service); 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 b7c7b9472..67b3d586e 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 @@ -97,21 +97,23 @@ abstract class AbstractInvocationHandler implements InvocationHandler { protected Object getEntityCollectionProxy( final Class typeRef, final Class typeCollectionRef, - final String entityContainerName, + final URI targetEntitySetURI, final CommonODataEntitySet entitySet, final URI uri, final boolean checkInTheContext) { final List items = new ArrayList(); - for (CommonODataEntity entityFromSet : entitySet.getEntities()) { - items.add(getEntityProxy(entityFromSet, entityContainerName, uri, typeRef, null, checkInTheContext)); + if (entitySet != null) { + for (CommonODataEntity entityFromSet : entitySet.getEntities()) { + items.add(getEntityProxy(entityFromSet, uri, typeRef, null, checkInTheContext)); + } } return Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), new Class[] {typeCollectionRef}, - new EntityCollectionInvocationHandler(service, items, typeRef, + new EntityCollectionInvocationHandler(service, items, typeRef, targetEntitySetURI, uri == null ? null : getClient().newURIBuilder(uri.toASCIIString()))); } @@ -127,7 +129,6 @@ abstract class AbstractInvocationHandler implements InvocationHandler { protected Object getEntityProxy( final CommonODataEntity entity, - final String entityContainerName, final URI entitySetURI, final Class type, final String eTag, @@ -238,7 +239,6 @@ abstract class AbstractInvocationHandler implements InvocationHandler { return getEntityProxy( (CommonODataEntity) result, null, - null, method.getReturnType(), null, false); 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 ffc166b59..1e88bfe70 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 @@ -135,7 +135,6 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca return invokeSelfMethod(method, args); } else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) { load(); - attach(); // attach the current handler return proxy; } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) { final Class returnType = method.getReturnType(); @@ -232,13 +231,14 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca final Object navPropValue; + URI targetEntitySetURI = CoreUtils.getTargetEntitySetURI(getClient(), property); final ODataLink link = ((ODataLinked) internal).getNavigationLink(property.name()); + if (link instanceof ODataInlineEntity) { // return entity navPropValue = getEntityProxy( ((ODataInlineEntity) link).getEntity(), - property.targetContainer(), - getClient().newURIBuilder().appendEntitySetSegment(property.targetEntitySet()).build(), + targetEntitySetURI, type, null, false); @@ -247,28 +247,26 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca navPropValue = getEntityCollectionProxy( collItemType, type, - property.targetContainer(), + targetEntitySetURI, ((ODataInlineEntitySet) link).getEntitySet(), - link.getLink(), + targetEntitySetURI, false); } else { // navigate - final URI uri = URIUtils.getURI(getEntityHandler().getEntityURI(), property.name()); + final URI targetURI = URIUtils.getURI(getEntityHandler().getEntityURI(), property.name()); if (EntityCollection.class.isAssignableFrom(type)) { navPropValue = getEntityCollectionProxy( collItemType, type, - property.targetContainer(), - getClient().getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody(), - uri, + targetEntitySetURI, + null, + targetURI, true); } else if (AbstractEntitySet.class.isAssignableFrom(type)) { - navPropValue = getEntitySetProxy(type, uri); + navPropValue = getEntitySetProxy(type, targetURI); // cannot be used standard target entity set URI } else { - URI entitySetURI = CoreUtils.getTargetEntitySetURI(getClient(), property); - - final EntityUUID uuid = new EntityUUID(entitySetURI, collItemType, null); + final EntityUUID uuid = new EntityUUID(targetEntitySetURI, collItemType, null); LOG.debug("Ask for '{}({})'", collItemType.getSimpleName(), null); EntityInvocationHandler handler = getContext().entityContext().getEntity(uuid); @@ -278,7 +276,11 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca collItemType.getAnnotation(Namespace.class).value(), ClassUtils.getEntityTypeName(collItemType))); handler = EntityInvocationHandler.getInstance( - entity, URIUtils.getURI(this.uri.build(), property.name()), entitySetURI, collItemType, service); + entity, + URIUtils.getURI(this.uri.build(), property.name()), + targetEntitySetURI, + collItemType, + service); } else if (getContext().entityContext().getStatus(handler) == AttachedEntityStatus.DELETED) { // object deleted diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java index 6182dd3af..fe8cfa808 100644 --- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java +++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java @@ -56,14 +56,20 @@ public class EntityCollectionInvocationHandler new HashMap, Object>(); public EntityCollectionInvocationHandler( - final Service service, final Collection items, final Class itemRef) { - this(service, items, itemRef, null); + final Service service, + final Collection items, + final Class itemRef) { + this(service, items, itemRef, null, null); } public EntityCollectionInvocationHandler( - final Service service, final Collection items, final Class itemRef, final CommonURIBuilder uri) { + final Service service, + final Collection items, + final Class itemRef, + final URI targetEntitySetURI, + final CommonURIBuilder uri) { - super(itemRef, null, service, uri); + super(itemRef, null, service, targetEntitySetURI, uri); this.items = items; } @@ -120,19 +126,21 @@ public class EntityCollectionInvocationHandler @SuppressWarnings("unchecked") public EntityCollection execute() { - final Triple, URI, List> entitySet = fetchPartialEntitySet(this.uri.build(), itemRef); - this.nextPageURI = entitySet.getMiddle(); + if (this.uri != null) { + final Triple, URI, List> entitySet = fetchPartialEntitySet(this.uri.build(), itemRef); + this.nextPageURI = entitySet.getMiddle(); - if (items == null) { - items = entitySet.getLeft(); - } else { - items.clear(); - items.addAll(entitySet.getLeft()); + if (items == null) { + items = entitySet.getLeft(); + } else { + items.clear(); + items.addAll(entitySet.getLeft()); + } + + annotations.clear(); + annotations.addAll(entitySet.getRight()); } - annotations.clear(); - annotations.addAll(entitySet.getRight()); - return this; } 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 c29e6ea09..11b8b61dd 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 @@ -74,6 +74,8 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler protected final Map linkChanges = new HashMap(); + protected final Map linkChache = new HashMap(); + protected int propertiesTag = 0; protected int linksTag = 0; @@ -233,6 +235,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler this.streamedPropertyChanges.clear(); this.propertyChanges.clear(); this.linkChanges.clear(); + this.linkChache.clear(); this.propertiesTag = 0; this.linksTag = 0; this.annotations.clear(); @@ -465,6 +468,8 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler if (linkChanges.containsKey(property)) { navPropValue = linkChanges.get(property); + } else if (linkChache.containsKey(property)) { + navPropValue = linkChache.get(property); } else { navPropValue = retrieveNavigationProperty(property, getter); } @@ -490,13 +495,17 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler @Override protected void addLinkChanges(final NavigationProperty navProp, final Object value) { - linkChanges.put(navProp, value); - } - - protected void cacheLink(final NavigationProperty navProp, final Object value) { final int checkpoint = linkChanges.hashCode(); linkChanges.put(navProp, value); updateLinksTag(checkpoint); + + if (linkChache.containsKey(navProp)) { + linkChache.remove(navProp); + } + } + + protected void cacheLink(final NavigationProperty navProp, final Object value) { + linkChache.put(navProp, value); } @Override 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 cb87c1ed7..9e55ec76e 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 @@ -79,7 +79,7 @@ class EntitySetInvocationHandler< @SuppressWarnings({"rawtypes", "unchecked"}) static EntitySetInvocationHandler getInstance( - final Class ref, final Service service, final URI uri) {; + final Class ref, final Service service, final URI uri) { return new EntitySetInvocationHandler( ref, @@ -139,7 +139,7 @@ class EntitySetInvocationHandler< final String entitySetName, final CommonURIBuilder uri) { - super(itemRef, collItemRef, service, uri); + super(itemRef, collItemRef, service, uri.build(), uri); } @Override @@ -246,7 +246,7 @@ class EntitySetInvocationHandler< annotations.addAll(entitySet.getRight()); final EntityCollectionInvocationHandler entityCollectionHandler = - new EntityCollectionInvocationHandler(service, entitySet.getLeft(), ref, uriBuilder); + new EntityCollectionInvocationHandler(service, entitySet.getLeft(), ref, this.baseURI, uriBuilder); entityCollectionHandler.setAnnotations(annotations); entityCollectionHandler.setNextPage(entitySet.getMiddle()); diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java index a424a3d0a..7f2852d0c 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java @@ -163,7 +163,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase { Customer actual = readCustomer(container, id); checkSampleCustomerProfile(actual, id, sampleName); - assertEquals(1, actual.getOrders().size()); + assertEquals(1, actual.getOrders().execute().size()); assertEquals(id, actual.getOrders().iterator().next().getOrderId()); assertEquals(id, actual.getOrders().iterator().next().getCustomerId()); diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java index fbe08902f..d2b5d0461 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java @@ -160,7 +160,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { @Test public void withInlineFeed() { final Customer customer = readCustomer(getContainer(), -10); - final OrderCollection orders = customer.getOrders(); + final OrderCollection orders = customer.getOrders().execute(); assertFalse(orders.isEmpty()); } diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java index 03167d053..58c3f1986 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java @@ -92,7 +92,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase { customer = container.getCustomer().getByKey(-9); - assertEquals(2, customer.getOrders().size()); + assertEquals(2, customer.getOrders().execute().size()); int count = 0; for (Order inside : customer.getOrders()) { 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 117e12e1e..69bcfc245 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 @@ -32,6 +32,7 @@ import java.sql.Timestamp; import java.util.Arrays; import java.util.Calendar; import java.util.TimeZone; +import static org.apache.olingo.fit.proxy.v4.AbstractTestITCase.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -60,6 +61,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase { assertNull(customer.getPersonID()); assertEquals(1, customer.load().getPersonID(), 0); + service.getContext().detachAll(); } @Test @@ -74,6 +76,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase { } assertEquals(2, pageCount); + service.getContext().detachAll(); // avoid influences } @Test @@ -93,6 +96,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase { order.load(); assertNotNull(order.getOrderDate()); assertNotNull(order.getOrderID()); + service.getContext().detachAll(); // avoid influences } @Test @@ -104,6 +108,19 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase { customer.load(); assertEquals(1, customer.getOrders().size()); + service.getContext().detachAll(); // avoid influences + } + + @Test + public void navigateLinks() { + final Customer customer = getContainer().getCustomers().getByKey(1); // no query + assertNotNull(customer.getCompany().load().getCompanyID()); // singleton: single query + assertEquals(1, customer.getOrders().execute().size()); // collection: single query + + final Order order = getContainer().getOrders().getByKey(8); // no querys + assertNotNull(order.getCustomerForOrder().load().getPersonID()); // entity type: single query + + service.getContext().detachAll(); // avoid influences } @Test @@ -147,5 +164,6 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase { fail(); } catch (IllegalArgumentException e) { } + service.getContext().detachAll(); // avoid influences } } diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java index 66a015bdf..73874d26f 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java @@ -150,7 +150,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase { Customer actual = readCustomer(getContainer(), id); assertEquals(homeAddress.getCity(), actual.getHomeAddress().getCity()); - assertEquals(1, actual.getOrders().size()); + assertEquals(1, actual.getOrders().execute().size()); assertEquals(8, actual.getOrders().iterator().next().getOrderID(), 0); getContainer().getCustomers().delete(actual.getPersonID()); @@ -218,7 +218,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase { Customer actual = readCustomer(getContainer(), id); assertEquals(homeAddress.getCity(), actual.getHomeAddress().getCity()); - assertEquals(1, actual.getOrders().size()); + assertEquals(1, actual.getOrders().execute().size()); assertEquals(id, actual.getOrders().iterator().next().getOrderID()); order = getContainer().getOrders().getByKey(id); @@ -308,7 +308,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase { product = getContainer().getProducts().getByKey(12).load(); assertEquals("Latte", product.getName()); - assertEquals(12, product.getDetails().iterator().next().getProductDetailID(), 0); + assertEquals(12, product.getDetails().execute().iterator().next().getProductDetailID(), 0); } @Test diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityRetrieveTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityRetrieveTestITCase.java index db8e73a05..b1d016304 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityRetrieveTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityRetrieveTestITCase.java @@ -135,7 +135,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase { public void withInlineFeed() { final Customer customer = readCustomer(getContainer(), 1); final OrderCollection orders = customer.getOrders(); - assertEquals(1, orders.size()); + assertEquals(1, orders.execute().size()); assertEquals(8, orders.iterator().next().getOrderID(), 0); } diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityUpdateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityUpdateTestITCase.java index 9bbc58faf..fca1159a3 100644 --- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityUpdateTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityUpdateTestITCase.java @@ -148,7 +148,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase { // assertEquals(1, customer.getOrders().size()); int count = 0; - for (Order inside : customer.getOrders()) { + for (Order inside : customer.getOrders().execute()) { if (inside.getOrderID() == orderId) { count++; }