Package org.apache.olingo.odata2.core.batch

Source Code of org.apache.olingo.odata2.core.batch.BatchHandlerImpl

/*******************************************************************************
* 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.odata2.core.batch;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.api.batch.BatchHandler;
import org.apache.olingo.odata2.api.batch.BatchRequestPart;
import org.apache.olingo.odata2.api.batch.BatchResponsePart;
import org.apache.olingo.odata2.api.commons.HttpHeaders;
import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.processor.ODataContext;
import org.apache.olingo.odata2.api.processor.ODataRequest;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.uri.PathSegment;
import org.apache.olingo.odata2.core.ODataContextImpl;
import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
import org.apache.olingo.odata2.core.ODataRequestHandler;
import org.apache.olingo.odata2.core.PathInfoImpl;

public class BatchHandlerImpl implements BatchHandler {
  private static final int BAD_REQUEST = 400;
  private ODataServiceFactory factory;
  private ODataService service;
  private Map<String, String> contentIdMap;

  public BatchHandlerImpl(final ODataServiceFactory factory, final ODataService service) {
    this.factory = factory;
    this.service = service;
  }

  @Override
  public BatchResponsePart handleBatchPart(final BatchRequestPart batchPart) throws ODataException {
    if (batchPart.isChangeSet()) {
      List<ODataRequest> changeSetRequests = batchPart.getRequests();
      contentIdMap = new HashMap<String, String>();
      return service.getBatchProcessor().executeChangeSet(this, changeSetRequests);
    } else {
      if (batchPart.getRequests().size() != 1) {
        throw new ODataException("Query Operation should contain one request");
      }
      ODataRequest request = batchPart.getRequests().get(0);
      ODataRequestHandler handler = createHandler(request);
      String mimeHeaderContentId =
          request.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));
      String requestHeaderContentId =
          request.getRequestHeaderValue(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));
      ODataResponse response = setContentIdHeader(handler.handle(request), mimeHeaderContentId, requestHeaderContentId);
      List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
      responses.add(response);
      return BatchResponsePart.responses(responses).changeSet(false).build();
    }
  }

  @Override
  public ODataResponse handleRequest(final ODataRequest suppliedRequest) throws ODataException {
    ODataRequest request;
    String mimeHeaderContentId =
        suppliedRequest.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));
    String requestHeaderContentId =
        suppliedRequest.getRequestHeaderValue(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));

    List<PathSegment> odataSegments = suppliedRequest.getPathInfo().getODataSegments();
    if (!odataSegments.isEmpty() && odataSegments.get(0).getPath().matches("\\$.*")) {
      request = modifyRequest(suppliedRequest, odataSegments);
    } else {
      request = suppliedRequest;
    }
    ODataRequestHandler handler = createHandler(request);
    ODataResponse response = handler.handle(request);
    if (response.getStatus().getStatusCode() < BAD_REQUEST) {
      response = setContentIdHeader(response, mimeHeaderContentId, requestHeaderContentId);
    }
    if (request.getMethod().equals(ODataHttpMethod.POST)) {
      String baseUri = getBaseUri(request);
      if (mimeHeaderContentId != null) {
        fillContentIdMap(response, mimeHeaderContentId, baseUri);
      } else if (requestHeaderContentId != null) {
        fillContentIdMap(response, requestHeaderContentId, baseUri);
      }
    }
    return response;
  }

  private void fillContentIdMap(final ODataResponse response, final String contentId, final String baseUri) {
    String location = response.getHeader(HttpHeaders.LOCATION);
    String relLocation = location.replace(baseUri + "/", "");
    contentIdMap.put("$" + contentId, relLocation);
  }

  private ODataRequest modifyRequest(final ODataRequest request, final List<PathSegment> odataSegments)
      throws ODataException {
    String contentId = contentIdMap.get(odataSegments.get(0).getPath());
    PathInfoImpl pathInfo = new PathInfoImpl();
    try {
      List<PathSegment> modifiedODataSegments = new ArrayList<PathSegment>();
      String[] segments = contentId.split("/");
      for (String segment : segments) {
        modifiedODataSegments.add(new ODataPathSegmentImpl(segment, null));
      }
      String newRequestUri = getBaseUri(request);
      newRequestUri += "/" + contentId;
      for (int i = 1; i < odataSegments.size(); i++) {
        newRequestUri += "/" + odataSegments.get(i).getPath();
        modifiedODataSegments.add(odataSegments.get(i));
      }
      for (Map.Entry<String, String> entry : request.getQueryParameters().entrySet()) {
        newRequestUri += "/" + entry;
      }

      pathInfo.setServiceRoot(request.getPathInfo().getServiceRoot());
      pathInfo.setPrecedingPathSegment(request.getPathInfo().getPrecedingSegments());
      pathInfo.setRequestUri(new URI(newRequestUri));
      pathInfo.setODataPathSegment(modifiedODataSegments);
    } catch (URISyntaxException e) {
      throw new ODataException(e);
    }
    ODataRequest modifiedRequest = ODataRequest.fromRequest(request).pathInfo(pathInfo).build();
    return modifiedRequest;
  }

  private ODataResponse setContentIdHeader(final ODataResponse response, final String mimeHeaderContentId,
      final String requestHeaderContentId) {
    ODataResponse modifiedResponse;
    if (requestHeaderContentId != null && mimeHeaderContentId != null) {
      modifiedResponse =
          ODataResponse.fromResponse(response).header(BatchHelper.REQUEST_HEADER_CONTENT_ID, requestHeaderContentId)
              .header(BatchHelper.MIME_HEADER_CONTENT_ID, mimeHeaderContentId).build();
    } else if (requestHeaderContentId != null) {
      modifiedResponse =
          ODataResponse.fromResponse(response).header(BatchHelper.REQUEST_HEADER_CONTENT_ID, requestHeaderContentId)
              .build();
    } else if (mimeHeaderContentId != null) {
      modifiedResponse =
          ODataResponse.fromResponse(response).header(BatchHelper.MIME_HEADER_CONTENT_ID, mimeHeaderContentId).build();
    } else {
      return response;
    }
    return modifiedResponse;
  }

  private String getBaseUri(final ODataRequest request) {
    String baseUri = request.getPathInfo().getServiceRoot().toASCIIString();
    if (baseUri.endsWith("/")) {
      baseUri = baseUri.substring(0, baseUri.length() - 1);
    }
    for (PathSegment segment : request.getPathInfo().getPrecedingSegments()) {
      baseUri += "/" + segment.getPath();
    }
    return baseUri;
  }

  private ODataRequestHandler createHandler(final ODataRequest request) throws ODataException {
    ODataContextImpl context = new ODataContextImpl(request, factory);
    ODataContext parentContext = service.getProcessor().getContext();
    context.setBatchParentContext(parentContext);
    context.setService(service);
    service.getProcessor().setContext(context);
    return new ODataRequestHandler(factory, service, context);
  }

}
TOP

Related Classes of org.apache.olingo.odata2.core.batch.BatchHandlerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.