private BatchChangeSetPart createBatchChangeSetPart( Edm edm, Map<String, String> contentIdMap, Olingo2BatchChangeRequest batchRequest) throws EdmException, URISyntaxException, EntityProviderException, IOException, ODataApplicationException { // build body string String resourcePath = batchRequest.getResourcePath(); // is it a referenced entity? if (resourcePath.startsWith("$")) { resourcePath = replaceContentId(edm, resourcePath, contentIdMap); } final UriInfoWithType uriInfo = parseUri(edm, resourcePath, null); // serialize data into ODataResponse object, if set in request and this is not a DELETE request final Map<String, String> headers = new HashMap<String, String>(); byte[] body = null; if (batchRequest.getBody() != null && !Operation.DELETE.equals(batchRequest.getOperation())) { final ODataResponse response = writeContent(edm, uriInfo, batchRequest.getBody()); // copy response headers for (String header : response.getHeaderNames()) { headers.put(header, response.getHeader(header)); } // get (http) entity which is for default Olingo2 implementation an InputStream body = response.getEntity() instanceof InputStream ? EntityProvider.readBinary((InputStream) response.getEntity()) : null; if (body != null) { headers.put(HttpHeaders.CONTENT_LENGTH, String.valueOf(body.length)); } } // Olingo is sensitive to batch part charset case!! headers.put(HttpHeaders.ACCEPT, getResourceContentType(uriInfo).toString().toLowerCase()); if (!headers.containsKey(HttpHeaders.CONTENT_TYPE)) { headers.put(HttpHeaders.CONTENT_TYPE, getContentType()); } // add request headers headers.putAll(batchRequest.getHeaders()); final String contentId = batchRequest.getContentId(); if (contentId != null) { contentIdMap.put("$" + contentId, resourcePath); } return BatchChangeSetPart.uri(createBatchUri(batchRequest)) .method(batchRequest.getOperation().getHttpMethod()) .contentId(contentId) .headers(headers) .body(body == null ? null : new String(body, Consts.UTF_8)) .build(); }
private <T> void writeContent( final Edm edm, HttpEntityEnclosingRequestBase httpEntityRequest, final UriInfoWithType uriInfo, final Object content, final Olingo2ResponseHandler<T> responseHandler) { try { // process resource by UriType final ODataResponse response = writeContent(edm, uriInfo, content); // copy all response headers for (String header : response.getHeaderNames()) { httpEntityRequest.setHeader(header, response.getHeader(header)); } // get (http) entity which is for default Olingo2 implementation an InputStream if (response.getEntity() instanceof InputStream) { httpEntityRequest.setEntity(new InputStreamEntity((InputStream) response.getEntity())); /* // avoid sending it without a header field set if (!httpEntityRequest.containsHeader(HttpHeaders.CONTENT_TYPE)) { httpEntityRequest.addHeader(HttpHeaders.CONTENT_TYPE, getContentType()); } */ } // execute HTTP request final Header requestContentTypeHeader = httpEntityRequest.getFirstHeader(HttpHeaders.CONTENT_TYPE); final ContentType requestContentType = requestContentTypeHeader != null ? ContentType.parse(requestContentTypeHeader.getValue()) : contentType; execute( httpEntityRequest, requestContentType, new AbstractFutureCallback<T>(responseHandler) { @SuppressWarnings("unchecked") @Override public void onCompleted(HttpResponse result) throws IOException, EntityProviderException, BatchException, ODataApplicationException { // if a entity is created (via POST request) the response body contains the new // created entity HttpStatusCodes statusCode = HttpStatusCodes.fromStatusCode(result.getStatusLine().getStatusCode()); // look for no content, or no response body!!! final boolean noEntity = result.getEntity() == null || result.getEntity().getContentLength() == 0; if (statusCode == HttpStatusCodes.NO_CONTENT || noEntity) { responseHandler.onResponse( (T) HttpStatusCodes.fromStatusCode(result.getStatusLine().getStatusCode())); } else { switch (uriInfo.getUriType()) { case URI9: // $batch final List<BatchSingleResponse> singleResponses = EntityProvider.parseBatchResponse( result.getEntity().getContent(), result.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()); // parse batch response bodies final List<Olingo2BatchResponse> responses = new ArrayList<Olingo2BatchResponse>(); Map<String, String> contentIdLocationMap = new HashMap<String, String>(); final List<Olingo2BatchRequest> batchRequests = (List<Olingo2BatchRequest>) content; final Iterator<Olingo2BatchRequest> iterator = batchRequests.iterator(); for (BatchSingleResponse response : singleResponses) { final Olingo2BatchRequest request = iterator.next(); if (request instanceof Olingo2BatchChangeRequest && ((Olingo2BatchChangeRequest) request).getContentId() != null) { contentIdLocationMap.put( "$" + ((Olingo2BatchChangeRequest) request).getContentId(), response.getHeader(HttpHeaders.LOCATION)); } try { responses.add(parseResponse(edm, contentIdLocationMap, request, response)); } catch (Exception e) { // report any parsing errors as error response responses.add( new Olingo2BatchResponse( Integer.parseInt(response.getStatusCode()), response.getStatusInfo(), response.getContentId(), response.getHeaders(), new ODataApplicationException( "Error parsing response for " + request + ": " + e.getMessage(), Locale.ENGLISH, e))); } } responseHandler.onResponse((T) responses); break; case URI4: case URI5: // simple property // get the response content as Object for $value or Map<String, Object> // otherwise final List<EdmProperty> simplePropertyPath = uriInfo.getPropertyPath(); final EdmProperty simpleProperty = simplePropertyPath.get(simplePropertyPath.size() - 1); if (uriInfo.isValue()) { responseHandler.onResponse( (T) EntityProvider.readPropertyValue( simpleProperty, result.getEntity().getContent())); } else { responseHandler.onResponse( (T) EntityProvider.readProperty( getContentType(), simpleProperty, result.getEntity().getContent(), EntityProviderReadProperties.init().build())); } break; case URI3: // complex property // get the response content as Map<String, Object> final List<EdmProperty> complexPropertyPath = uriInfo.getPropertyPath(); final EdmProperty complexProperty = complexPropertyPath.get(complexPropertyPath.size() - 1); responseHandler.onResponse( (T) EntityProvider.readProperty( getContentType(), complexProperty, result.getEntity().getContent(), EntityProviderReadProperties.init().build())); break; case URI7A: // $links with 0..1 cardinality property // get the response content as String final EdmEntitySet targetLinkEntitySet = uriInfo.getTargetEntitySet(); responseHandler.onResponse( (T) EntityProvider.readLink( getContentType(), targetLinkEntitySet, result.getEntity().getContent())); break; case URI7B: // $links with * cardinality property // get the response content as java.util.List<String> final EdmEntitySet targetLinksEntitySet = uriInfo.getTargetEntitySet(); responseHandler.onResponse( (T) EntityProvider.readLinks( getContentType(), targetLinksEntitySet, result.getEntity().getContent())); break; case URI1: case URI2: case URI6A: case URI6B: // Entity // get the response content as an ODataEntry object responseHandler.onResponse( (T) EntityProvider.readEntry( response.getContentHeader(), uriInfo.getTargetEntitySet(), result.getEntity().getContent(), EntityProviderReadProperties.init().build())); break; default: throw new ODataApplicationException( "Unsupported resource type " + uriInfo.getTargetType(), Locale.ENGLISH); } } } }); } catch (ODataException e) { responseHandler.onException(e); } catch (URISyntaxException e) { responseHandler.onException(e); } catch (UnsupportedEncodingException e) { responseHandler.onException(e); } catch (IOException e) { responseHandler.onException(e); } }