All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.odata4j.cxf.consumer.CxFConsumerQueryEntitiesRequest Maven / Gradle / Ivy

package org.odata4j.cxf.consumer;

import java.net.URLDecoder;
import java.util.Iterator;

import org.apache.http.HttpResponse;
import org.core4j.Enumerable;
import org.core4j.Func;
import org.core4j.Func1;
import org.core4j.ReadOnlyIterator;
import org.odata4j.consumer.ODataClientRequest;
import org.odata4j.core.ODataConstants;
import org.odata4j.core.ODataVersion;
import org.odata4j.edm.EdmDataServices;
import org.odata4j.format.Entry;
import org.odata4j.format.Feed;
import org.odata4j.format.FormatParser;
import org.odata4j.format.FormatParserFactory;
import org.odata4j.format.FormatType;
import org.odata4j.format.Settings;
import org.odata4j.internal.FeedCustomizationMapping;
import org.odata4j.internal.InternalUtil;

class CxFConsumerQueryEntitiesRequest extends CxfConsumerQueryRequestBase {

  private final Class entityType;
  private final FeedCustomizationMapping fcMapping;

  CxFConsumerQueryEntitiesRequest(FormatType formatType, Class entityType, String serviceRootUri, EdmDataServices metadata, String entitySetName, FeedCustomizationMapping fcMapping) {
    super(formatType, serviceRootUri, metadata, entitySetName);
    this.entityType = entityType;
    this.fcMapping = fcMapping;
  }

  @Override
  public Enumerable execute() {
    ODataClientRequest request = buildRequest(null);
    Enumerable entries = getEntries(request);

    return entries.select(new Func1() {
      public T apply(Entry input) {
        return InternalUtil.toEntity(entityType, input.getEntity());
      }
    }).cast(entityType);
  }

  private Enumerable getEntries(final ODataClientRequest request) {
    return Enumerable.createFromIterator(new Func>() {
      public Iterator apply() {
        return new EntryIterator(request, CxFConsumerQueryEntitiesRequest.this.getFormatType());
      }
    });
  }

  private class EntryIterator extends ReadOnlyIterator {

    private FormatType formatType;
    private ODataClientRequest request;
    private FormatParser parser;
    private Feed feed;
    private Iterator feedEntries;
    private int feedEntryCount;

    public EntryIterator(ODataClientRequest request, FormatType formatType) {
      this.request = request;
      this.formatType = formatType;
    }

    @Override
    protected IterationResult advance() throws Exception {

      ODataCxfClient client = new ODataCxfClient(this.formatType);

      try {

        if (feed == null) {
          HttpResponse response = client.getEntities(request);

          ODataVersion version = InternalUtil.getDataServiceVersion(response.getFirstHeader(ODataConstants.Headers.DATA_SERVICE_VERSION).getValue());

          parser = FormatParserFactory.getParser(Feed.class, client.getFormatType(),
              new Settings(version, getMetadata(), getLastSegment(), null, fcMapping));

          feed = parser.parse(client.getFeedReader(response));
          feedEntries = feed.getEntries().iterator();
          feedEntryCount = 0;
        }

        if (feedEntries.hasNext()) {
          feedEntryCount++;
          return IterationResult.next(feedEntries.next());
        }

        // old-style paging: $page and $itemsPerPage
        if (request.getQueryParams().containsKey("$page") && request.getQueryParams().containsKey("$itemsPerPage")) {
          if (feedEntryCount == 0)
            return IterationResult.done();

          int page = Integer.parseInt(request.getQueryParams().get("$page"));
          // int itemsPerPage = Integer.parseInt(request.getQueryParams().get("$itemsPerPage"));

          request = request.queryParam("$page", Integer.toString(page + 1));
        }

        // new-style paging: $skiptoken
        else {
          if (feed.getNext() == null)
            return IterationResult.done();

          int skipTokenIndex = feed.getNext().indexOf("$skiptoken=");
          if (skipTokenIndex > -1) {
            String skiptoken = feed.getNext().substring(skipTokenIndex + "$skiptoken=".length());
            // decode the skiptoken first since it gets encoded as a query param
            skiptoken = URLDecoder.decode(skiptoken, "UTF-8");
            request = request.queryParam("$skiptoken", skiptoken);
          } else if (feed.getNext().toLowerCase().startsWith("http")) {
            request = ODataClientRequest.get(feed.getNext());
          } else {
            throw new UnsupportedOperationException();
          }

        }

        feed = null;

        return advance(); // TODO stackoverflow possible here
      } finally {
        client.shuttdown();
      }
    }

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy