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

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

package org.odata4j.cxf.consumer;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.core4j.Enumerable;
import org.core4j.Func;
import org.core4j.ReadOnlyIterator;
import org.joda.time.LocalDateTime;
import org.odata4j.consumer.ODataClientRequest;
import org.odata4j.core.Guid;
import org.odata4j.core.OCollection;
import org.odata4j.core.ODataConstants;
import org.odata4j.core.ODataVersion;
import org.odata4j.core.OFunctionParameter;
import org.odata4j.core.OFunctionParameters;
import org.odata4j.core.OFunctionRequest;
import org.odata4j.core.OObject;
import org.odata4j.core.OSimpleObject;
import org.odata4j.core.OSimpleObjects;
import org.odata4j.core.UnsignedByte;
import org.odata4j.edm.EdmCollectionType;
import org.odata4j.edm.EdmDataServices;
import org.odata4j.edm.EdmFunctionImport;
import org.odata4j.edm.EdmSimpleType;
import org.odata4j.edm.EdmType;
import org.odata4j.expression.Expression;
import org.odata4j.expression.LiteralExpression;
import org.odata4j.format.FormatParser;
import org.odata4j.format.FormatParserFactory;
import org.odata4j.format.FormatType;
import org.odata4j.format.Settings;
import org.odata4j.internal.InternalUtil;

class CxfConsumerFunctionCallRequest
    extends CxfConsumerQueryRequestBase
    implements OFunctionRequest {

  private final List params = new LinkedList();
  private final EdmFunctionImport function;

  CxfConsumerFunctionCallRequest(FormatType formatType, String serviceRootUri,
      EdmDataServices metadata, String lastSegment) {
    super(formatType, serviceRootUri, metadata, lastSegment);
    // lastSegment is the function call name.
    function = metadata.findEdmFunctionImport(lastSegment);
  }

  @SuppressWarnings("unchecked")
  @Override
  public Enumerable execute() {
    final ODataCxfClient client = new ODataCxfClient(this.getFormatType());
    try {
      // turn each param into a custom query option
      for (OFunctionParameter p : params) {
        custom(p.getName(), toUriString(p));
      }
      final ODataClientRequest request = buildRequest(null);
      Enumerable results = Enumerable.createFromIterator(
          new Func>() {
            @Override
            public Iterator apply() {
              return new FunctionResultsIterator(client, request);
            }
          });
      return (Enumerable) results;
    } finally {
      client.shuttdown();
    }
  }

  private static String toUriString(OFunctionParameter p) {
    OObject obj = p.getValue();
    if (obj instanceof OSimpleObject) {
      OSimpleObject simple = (OSimpleObject) obj;
      LiteralExpression le = Expression.literal(simple.getType(), simple.getValue());
      return Expression.asFilterString(le);

    }
    throw new UnsupportedOperationException("type not supported: " + obj.getType().getFullyQualifiedTypeName());
  }

  // set parameters to the function call
  @Override
  public CxfConsumerFunctionCallRequest parameter(String name, OObject value) {
    params.add(OFunctionParameters.create(name, value));
    return this;
  }

  @Override
  public OFunctionRequest pBoolean(String name, boolean value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.BOOLEAN, value));
  }

  @Override
  public OFunctionRequest pByte(String name, UnsignedByte value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.BYTE, value));
  }

  @Override
  public OFunctionRequest pSByte(String name, byte value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.SBYTE, value));
  }

  @Override
  public OFunctionRequest pDateTime(String name, Calendar value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.DATETIME, value));
  }

  @Override
  public OFunctionRequest pDateTime(String name, Date value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.DATETIME, value));
  }

  @Override
  public OFunctionRequest pDateTime(String name, LocalDateTime value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.DATETIME, value));
  }

  @Override
  public OFunctionRequest pDecimal(String name, BigDecimal value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.DECIMAL, value));
  }

  @Override
  public OFunctionRequest pDouble(String name, double value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.DOUBLE, value));
  }

  @Override
  public OFunctionRequest pGuid(String name, Guid value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.GUID, value));
  }

  @Override
  public OFunctionRequest pInt16(String name, short value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.INT16, value));
  }

  @Override
  public OFunctionRequest pInt32(String name, int value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.INT32, value));
  }

  @Override
  public OFunctionRequest pInt64(String name, long value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.INT64, value));
  }

  @Override
  public OFunctionRequest pSingle(String name, float value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.SINGLE, value));
  }

  @Override
  public OFunctionRequest pTime(String name, Calendar value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.TIME, value));
  }

  @Override
  public OFunctionRequest pTime(String name, Date value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.TIME, value));
  }

  @Override
  public OFunctionRequest pTime(String name, LocalDateTime value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.TIME, value));
  }

  @Override
  public OFunctionRequest pString(String name, String value) {
    return parameter(name, OSimpleObjects.create(EdmSimpleType.STRING, value));
  }

  private class FunctionResultsIterator extends ReadOnlyIterator {

    private ODataCxfClient client;
    private ODataClientRequest request;
    private FormatParser parser;
    private OObject current = null;
    private Iterator iter = null;
    private boolean done = false;
    private int count = 0;

    public FunctionResultsIterator(ODataCxfClient client, ODataClientRequest request) {
      this.client = client;
      this.request = request;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected IterationResult advance() throws Exception {

      try {

        if (done || function.getReturnType() == null) {
          return IterationResult.done();
        }

        if (current == null) {
          HttpResponse response = client.callFunction(request);

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

          parser = FormatParserFactory.getParser(
              EdmType.getInstanceType(function.getReturnType()),
              client.getFormatType(),
              new Settings(
                  version,
                  getMetadata(),
                  getLastSegment(),
                  null, // entitykey
                  null, // fcMapping
                  true, // isResponse
                  function.getReturnType()));

          current = parser.parse(client.getFeedReader(response));

          if (function.getReturnType() instanceof EdmCollectionType) {
            iter = ((OCollection) current).iterator();
          } else {
            done = true;
            return IterationResult.next(current);
          }
        }

        if (iter.hasNext()) {
          count++;
          return IterationResult.next(iter.next());
        } else {
          done = true;
          return IterationResult.done();
        }

        /* TODO support paging, this code was from ConsumerQueryEntitiesRequest...we'll need something like this.
        // 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();
            }

        } */

      } finally {
        this.client.shuttdown();
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy