Package org.apache.drill.common.logical.data

Source Code of org.apache.drill.common.logical.data.Sequence$De

/**
* 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.drill.common.logical.data;

import java.io.IOException;
import java.util.Iterator;

import org.apache.drill.common.logical.data.Sequence.De;
import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.google.common.collect.Iterators;

/**
* Describes a list of operators where each operator only has one input and that
* input is the operator that came before.
*
*/
@JsonDeserialize(using = De.class)
@JsonTypeName("sequence")
public class Sequence extends LogicalOperatorBase {
  static final Logger logger = LoggerFactory.getLogger(Sequence.class);

  private Sequence() {}

  public boolean openTop;
  public LogicalOperator input;
  @JsonProperty("do")
  public LogicalOperator[] stream;

    @Override
    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
        return logicalVisitor.visitSequence(this, value);
    }

    @Override
    public Iterator<LogicalOperator> iterator() {
        return Iterators.singletonIterator(stream[stream.length - 1]);
    }

    public static class De extends StdDeserializer<LogicalOperator> {

    protected De() {
      super(Sequence.class);
    }

    @Override
    public LogicalOperator deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
        JsonProcessingException {
      ObjectIdGenerator<Integer> idGenerator = new ObjectIdGenerators.IntSequenceGenerator();
      JsonLocation start = jp.getCurrentLocation();
      JsonToken t = jp.getCurrentToken();
      LogicalOperator parent = null;
      LogicalOperator first = null;
      LogicalOperator prev = null;
      Integer id = null;

      while (true) {
        String fieldName = jp.getText();
        t = jp.nextToken();
        switch (fieldName) { // switch on field names.
        case "@id":
          id = _parseIntPrimitive(jp, ctxt);
          break;
        case "input":
          JavaType tp = ctxt.constructType(LogicalOperator.class);
          JsonDeserializer<Object> d = ctxt.findRootValueDeserializer(tp);
          parent = (LogicalOperator) d.deserialize(jp, ctxt);
          break;

        case "do":
          if (!jp.isExpectedStartArrayToken()) {
            throwE(
                jp,
                "The do parameter of sequence should be an array of SimpleOperators.  Expected a JsonToken.START_ARRAY token but received a "
                    + t.name() + "token.");
          }

          int pos = 0;
          while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
            // logger.debug("Reading sequence child {}.", pos);
            JsonLocation l = jp.getCurrentLocation(); // get current location
                                                      // first so we can
                                                      // correctly reference the
                                                      // start of the object in
                                                      // the case that the type
                                                      // is wrong.
            LogicalOperator o = jp.readValueAs(LogicalOperator.class);

            if (pos == 0) {
              if (!(o instanceof SingleInputOperator) && !(o instanceof SourceOperator)) {
                throwE(
                    l,
                    "The first operator in a sequence must be either a ZeroInput or SingleInput operator.  The provided first operator was not. It was of type "
                        + o.getClass().getName());
              }
              first = o;
            } else {
              if (!(o instanceof SingleInputOperator)) {
                throwE(l, "All operators after the first must be single input operators.  The operator at position "
                    + pos + " was not. It was of type " + o.getClass().getName());
              }
              SingleInputOperator now = (SingleInputOperator) o;
              now.setInput(prev);
            }
            prev = o;

            pos++;
          }
          break;
        default:
          throwE(jp, "Unknown field name provided for Sequence: " + jp.getText());
        }

        t = jp.nextToken();
        if (t == JsonToken.END_OBJECT) {
          break;
        }
      }

      if (first == null) {
        throwE(start, "A sequence must include at least one operator.");
      }
      if ((parent == null && first instanceof SingleInputOperator)
          || (parent != null && first instanceof SourceOperator)) {
        throwE(start,
            "A sequence must either start with a ZeroInputOperator or have a provided input. It cannot have both or neither.");
      }

      if (parent != null && first instanceof SingleInputOperator) {
        ((SingleInputOperator) first).setInput(parent);
      }

      // set input reference.
      if (id != null) {

        ReadableObjectId rid = ctxt.findObjectId(id, idGenerator);
        rid.bindItem(prev);
        // logger.debug("Binding id {} to item {}.", rid.id, rid.item);

      }

      return first;
    }

  }

  private static void throwE(JsonLocation l, String e) throws JsonParseException {
    throw new JsonParseException(e, l);
  }

  private static void throwE(JsonParser jp, String e) throws JsonParseException {
    throw new JsonParseException(e, jp.getCurrentLocation());
  }

}
TOP

Related Classes of org.apache.drill.common.logical.data.Sequence$De

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.