[OLINGO-246] improve hasNext() and next() item iterator methods

This commit is contained in:
fmartelli 2014-04-26 15:51:11 +02:00
parent 96b8cd96ae
commit 6a5fc35483
13 changed files with 89 additions and 41 deletions

View File

@ -49,6 +49,13 @@ public interface ODataBatchResponseItem extends Iterator<ODataResponse> {
*/ */
boolean isChangeset(); boolean isChangeset();
/**
* Checks if the current item is a braking item like as error item or asynchronous response part.
*
* @return 'TRUE' if breaking; 'FALSE' otherwise.
*/
boolean isBreakingitem();
/** /**
* Closes the current batch responses item including all wrapped OData responses. * Closes the current batch responses item including all wrapped OData responses.
*/ */

View File

@ -27,4 +27,6 @@ import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
*/ */
public interface ODataBatchRequest public interface ODataBatchRequest
extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> { extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
ODataBatchRequest continueOnError();
} }

View File

@ -22,9 +22,9 @@ public abstract class AbstractBatchRequestFactory implements CommonBatchRequestF
private static final long serialVersionUID = -3875283254713404483L; private static final long serialVersionUID = -3875283254713404483L;
protected final CommonODataClient client; protected final CommonODataClient<?> client;
protected AbstractBatchRequestFactory(final CommonODataClient client) { protected AbstractBatchRequestFactory(final CommonODataClient<?> client) {
this.client = client; this.client = client;
} }
} }

View File

@ -67,6 +67,13 @@ public abstract class AbstractODataBatchResponseItem implements ODataBatchRespon
*/ */
protected boolean closed = false; protected boolean closed = false;
/**
* Last cached OData response.
*/
protected ODataResponse current;
protected boolean breakingitem = false;
/** /**
* Constructor. * Constructor.
* *
@ -74,6 +81,7 @@ public abstract class AbstractODataBatchResponseItem implements ODataBatchRespon
*/ */
public AbstractODataBatchResponseItem(boolean isChangeset) { public AbstractODataBatchResponseItem(boolean isChangeset) {
this.changeset = isChangeset; this.changeset = isChangeset;
this.current = null;
} }
/** /**
@ -135,7 +143,15 @@ public abstract class AbstractODataBatchResponseItem implements ODataBatchRespon
expectedItemsIterator = responses.values().iterator(); expectedItemsIterator = responses.values().iterator();
} }
return expectedItemsIterator.hasNext(); return !breakingitem && expectedItemsIterator.hasNext();
}
/**
* {@inheritDoc }
*/
@Override
public boolean isBreakingitem() {
return breakingitem;
} }
/** /**

View File

@ -31,11 +31,6 @@ import org.apache.olingo.client.core.communication.response.batch.ODataBatchErro
*/ */
public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem { public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
/**
* Last cached OData response.
*/
private ODataResponse current = null;
private boolean unexpected = false; private boolean unexpected = false;
/** /**
@ -62,7 +57,12 @@ public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
throw new IllegalStateException("Invalid request - the item has been closed"); throw new IllegalStateException("Invalid request - the item has been closed");
} }
if (!hasNext()) {
throw new NoSuchElementException("No item found");
}
if (unexpected) { if (unexpected) {
breakingitem = true;
return nextUnexpected(); return nextUnexpected();
} else { } else {
return nextExpected(); return nextExpected();
@ -70,12 +70,8 @@ public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
} }
private ODataResponse nextExpected() { private ODataResponse nextExpected() {
if (hasNext()) { // consume item for condition above (used like a counter ...)
// consume item for condition above (like a counter ...)
expectedItemsIterator.next(); expectedItemsIterator.next();
} else {
throw new NoSuchElementException("No item found");
}
final Map<String, Collection<String>> nextItemHeaders = final Map<String, Collection<String>> nextItemHeaders =
ODataBatchUtilities.nextItemHeaders(batchLineIterator, boundary); ODataBatchUtilities.nextItemHeaders(batchLineIterator, boundary);
@ -109,10 +105,8 @@ public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
current.initFromBatch(responseLine, headers, batchLineIterator, boundary); current.initFromBatch(responseLine, headers, batchLineIterator, boundary);
if (current.getStatusCode() >= 400) { if (current.getStatusCode() >= 400) {
// found error .... consume expeted items // found error ....
while (expectedItemsIterator.hasNext()) { breakingitem = true;
expectedItemsIterator.next();
}
} }
return current; return current;
@ -127,7 +121,8 @@ public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator); final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator);
LOG.debug("Retrieved item headers {}", headers); LOG.debug("Retrieved item headers {}", headers);
return new ODataBatchErrorResponse(responseLine, headers, batchLineIterator, boundary); current = new ODataBatchErrorResponse(responseLine, headers, batchLineIterator, boundary);
return current;
} }
throw new IllegalStateException("Expected item not found"); throw new IllegalStateException("Expected item not found");

View File

@ -48,25 +48,28 @@ public class ODataRetrieveResponseItem extends AbstractODataBatchResponseItem {
throw new IllegalStateException("Invalid request - the item has been closed"); throw new IllegalStateException("Invalid request - the item has been closed");
} }
if (!hasNext()) {
throw new NoSuchElementException("No item found");
}
final Map.Entry<Integer, String> responseLine = ODataBatchUtilities.readResponseLine(batchLineIterator); final Map.Entry<Integer, String> responseLine = ODataBatchUtilities.readResponseLine(batchLineIterator);
LOG.debug("Retrieved item response {}", responseLine); LOG.debug("Retrieved item response {}", responseLine);
final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator); final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator);
LOG.debug("Retrieved item headers {}", headers); LOG.debug("Retrieved item headers {}", headers);
final ODataResponse res;
if (responseLine.getKey() >= 400) { if (responseLine.getKey() >= 400) {
// generate error response // generate error response
res = new ODataBatchErrorResponse(responseLine, headers, batchLineIterator, boundary); current = new ODataBatchErrorResponse(responseLine, headers, batchLineIterator, boundary);
breakingitem = true;
} else { } else {
if (!hasNext()) { if (!hasNext()) {
throw new NoSuchElementException("No item found"); throw new NoSuchElementException("No item found");
} }
res = expectedItemsIterator.next().initFromBatch(responseLine, headers, batchLineIterator, boundary); current = expectedItemsIterator.next().initFromBatch(responseLine, headers, batchLineIterator, boundary);
} }
return res; return current;
} }
/** /**

View File

@ -34,6 +34,7 @@ public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
@Override @Override
public ODataBatchRequest getBatchRequest(final String serviceRoot) { public ODataBatchRequest getBatchRequest(final String serviceRoot) {
return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build()); return new ODataBatchRequestImpl(
(ODataClient) client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
} }
} }

View File

@ -24,12 +24,12 @@ import java.util.Iterator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest; import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem; import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
import org.apache.olingo.client.api.communication.request.batch.v3.BatchStreamManager; import org.apache.olingo.client.api.communication.request.batch.v3.BatchStreamManager;
import org.apache.olingo.client.api.communication.request.batch.v3.ODataBatchRequest; import org.apache.olingo.client.api.communication.request.batch.v3.ODataBatchRequest;
import org.apache.olingo.client.api.communication.response.ODataBatchResponse; import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
import org.apache.olingo.client.api.v3.ODataClient;
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager; import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager;
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest; import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest;
import org.apache.olingo.client.core.communication.request.batch.v3.ODataBatchRequestImpl.BatchStreamManagerImpl; import org.apache.olingo.client.core.communication.request.batch.v3.ODataBatchRequestImpl.BatchStreamManagerImpl;
@ -44,7 +44,7 @@ public class ODataBatchRequestImpl
extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager> extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> { implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
public ODataBatchRequestImpl(final CommonODataClient<?> odataClient, final URI uri) { public ODataBatchRequestImpl(final ODataClient odataClient, final URI uri) {
super(odataClient, uri); super(odataClient, uri);
} }

View File

@ -34,6 +34,7 @@ public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
@Override @Override
public ODataBatchRequest getBatchRequest(final String serviceRoot) { public ODataBatchRequest getBatchRequest(final String serviceRoot) {
return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build()); return new ODataBatchRequestImpl(
(ODataClient) client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
} }
} }

View File

@ -24,12 +24,14 @@ import java.util.Iterator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.header.HeaderName;
import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem; import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
import org.apache.olingo.client.api.communication.request.batch.v4.BatchStreamManager; import org.apache.olingo.client.api.communication.request.batch.v4.BatchStreamManager;
import org.apache.olingo.client.api.communication.request.batch.v4.ODataBatchRequest; import org.apache.olingo.client.api.communication.request.batch.v4.ODataBatchRequest;
import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate; import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
import org.apache.olingo.client.api.communication.response.ODataBatchResponse; import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
import org.apache.olingo.client.api.v4.ODataClient;
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager; import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager;
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest; import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse; import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
@ -43,7 +45,9 @@ public class ODataBatchRequestImpl
extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager> extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
implements ODataBatchRequest { implements ODataBatchRequest {
public ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) { private boolean continueOnError = false;
public ODataBatchRequestImpl(final ODataClient odataClient, final URI uri) {
super(odataClient, uri); super(odataClient, uri);
setAccept(ContentType.MULTIPART_MIXED); setAccept(ContentType.MULTIPART_MIXED);
} }
@ -74,6 +78,13 @@ public class ODataBatchRequestImpl
return this; return this;
} }
@Override
public ODataBatchRequest continueOnError() {
addCustomHeader(HeaderName.prefer, new ODataPreferences(odataClient.getServiceVersion()).continueOnError());
continueOnError = true;
return this;
}
/** /**
* Batch request payload management. * Batch request payload management.
*/ */
@ -126,7 +137,7 @@ public class ODataBatchRequestImpl
*/ */
@Override @Override
public Iterator<ODataBatchResponseItem> getBody() { public Iterator<ODataBatchResponseItem> getBody() {
return new ODataBatchResponseManager(this, expectedResItems); return new ODataBatchResponseManager(this, expectedResItems, continueOnError);
} }
} }
} }

View File

@ -68,7 +68,7 @@ public abstract class AbstractODataStreamedRequest<V extends ODataResponse, T ex
* @param method OData request HTTP method. * @param method OData request HTTP method.
* @param uri OData request URI. * @param uri OData request URI.
*/ */
public AbstractODataStreamedRequest(final CommonODataClient odataClient, public AbstractODataStreamedRequest(final CommonODataClient<?> odataClient,
final HttpMethod method, final URI uri) { final HttpMethod method, final URI uri) {
super(odataClient, ODataMediaFormat.class, method, uri); super(odataClient, ODataMediaFormat.class, method, uri);

View File

@ -66,13 +66,26 @@ public class ODataBatchResponseManager implements Iterator<ODataBatchResponseIte
*/ */
private ODataBatchResponseItem current = null; private ODataBatchResponseItem current = null;
private final boolean continueOnError;
/** /**
* Constructor. * Constructor.
* *
* @param res OData batch response. * @param res OData batch response.
* @param expectedItems expected batch response items. * @param expectedItems expected batch response items.
*/ */
public ODataBatchResponseManager(final ODataBatchResponse res, final List<ODataBatchResponseItem> expectedItems) { public ODataBatchResponseManager(
final ODataBatchResponse res,
final List<ODataBatchResponseItem> expectedItems) {
this(res, expectedItems, false);
}
public ODataBatchResponseManager(
final ODataBatchResponse res,
final List<ODataBatchResponseItem> expectedItems,
final boolean continueOnError) {
this.continueOnError = continueOnError;
try { try {
this.expectedItemsIterator = expectedItems.iterator(); this.expectedItemsIterator = expectedItems.iterator();
this.batchLineIterator = new ODataBatchLineIteratorImpl( this.batchLineIterator = new ODataBatchLineIteratorImpl(
@ -93,7 +106,7 @@ public class ODataBatchResponseManager implements Iterator<ODataBatchResponseIte
*/ */
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return expectedItemsIterator.hasNext(); return (current == null || continueOnError || !current.isBreakingitem()) && expectedItemsIterator.hasNext();
} }
/** /**

View File

@ -32,8 +32,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.olingo.client.api.ODataBatchConstants; import org.apache.olingo.client.api.ODataBatchConstants;
import org.apache.olingo.client.api.communication.header.HeaderName;
import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.ODataStreamManager; import org.apache.olingo.client.api.communication.request.ODataStreamManager;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem; import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
import org.apache.olingo.client.api.communication.request.batch.ODataChangeset; import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
@ -154,8 +152,9 @@ public class BatchTestITCase extends AbstractTestITCase {
assertEquals(200, response.getStatusCode()); assertEquals(200, response.getStatusCode());
assertEquals("OK", response.getStatusMessage()); assertEquals("OK", response.getStatusMessage());
final Iterator<ODataBatchResponseItem> iter = response.getBody();
// retrieve the first item (ODataRetrieve) // retrieve the first item (ODataRetrieve)
ODataBatchResponseItem item = response.getBody().next(); ODataBatchResponseItem item = iter.next();
ODataChangesetResponseItem retitem = (ODataChangesetResponseItem) item; ODataChangesetResponseItem retitem = (ODataChangesetResponseItem) item;
ODataResponse res = retitem.next(); ODataResponse res = retitem.next();
@ -163,6 +162,9 @@ public class BatchTestITCase extends AbstractTestITCase {
assertEquals("Not Found", res.getStatusMessage()); assertEquals("Not Found", res.getStatusMessage());
assertEquals(Integer.valueOf(3), Integer.valueOf( assertEquals(Integer.valueOf(3), Integer.valueOf(
res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next())); res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next()));
assertFalse(retitem.hasNext());
assertFalse(iter.hasNext());
} }
@Test @Test
@ -179,10 +181,7 @@ public class BatchTestITCase extends AbstractTestITCase {
// create your request // create your request
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL); final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
request.setAccept(ACCEPT); request.setAccept(ACCEPT);
request.continueOnError();
if (continueOnError) {
request.addCustomHeader(HeaderName.prefer, new ODataPreferences(client.getServiceVersion()).continueOnError());
}
final BatchStreamManager streamManager = request.execute(); final BatchStreamManager streamManager = request.execute();