Package org.apache.drill.exec.vector.complex.fn

Source Code of org.apache.drill.exec.vector.complex.fn.JsonReader

/**
* 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.exec.vector.complex.fn;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.UnpooledByteBufAllocator;

import java.io.IOException;
import java.io.Reader;

import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.BitHolder;
import org.apache.drill.exec.expr.holders.Float8Holder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter;
import org.apache.drill.exec.vector.complex.writer.BaseWriter.ListWriter;
import org.apache.drill.exec.vector.complex.writer.BaseWriter.MapWriter;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.google.common.base.Charsets;

public class JsonReader {
  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(JsonReader.class);


  private final JsonFactory factory = new JsonFactory();
  private JsonParser parser;

  public JsonReader() throws JsonParseException, IOException {
    factory.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    factory.configure(Feature.ALLOW_COMMENTS, true);
  }

  public boolean write(Reader reader, ComplexWriter writer) throws JsonParseException, IOException {

    parser = factory.createJsonParser(reader);
    reader.mark(1024*128);
    JsonToken t = parser.nextToken();
    while(!parser.hasCurrentToken()) t = parser.nextToken();


    switch (t) {
    case START_OBJECT:
      writeData(writer.rootAsMap());
      break;
    case START_ARRAY:
      writeData(writer.rootAsList());
      break;
    case NOT_AVAILABLE:
      return false;
    default:
      throw new JsonParseException(
          String.format("Failure while parsing JSON.  Found token of [%s]  Drill currently only supports parsing "
              + "json strings that contain either lists or maps.  The root object cannot be a scalar.",
              t),
          parser.getCurrentLocation());
    }

    return true;
  }


  private void writeData(MapWriter map) throws JsonParseException, IOException {
    //
    map.start();
    outside: while(true){
      JsonToken t = parser.nextToken();
      if(t == JsonToken.NOT_AVAILABLE || t == JsonToken.END_OBJECT) return;

      assert t == JsonToken.FIELD_NAME : String.format("Expected FIELD_NAME but got %s.", t.name());
      final String fieldName = parser.getText();


      switch(parser.nextToken()){
      case START_ARRAY:
        writeData(map.list(fieldName));
        break;
      case START_OBJECT:
        writeData(map.map(fieldName));
        break;
      case END_OBJECT:
        break outside;

      case VALUE_EMBEDDED_OBJECT:
      case VALUE_FALSE: {
        BitHolder h = new BitHolder();
        h.value = 0;
        map.bit(fieldName).write(h);
        break;
      }
      case VALUE_TRUE: {
        BitHolder h = new BitHolder();
        h.value = 1;
        map.bit(fieldName).write(h);
        break;
      }
      case VALUE_NULL:
        // do nothing as we don't have a type.
        break;
      case VALUE_NUMBER_FLOAT:
        Float8Holder fh = new Float8Holder();
        fh.value = parser.getDoubleValue();
        map.float8(fieldName).write(fh);
        break;
      case VALUE_NUMBER_INT:
        BigIntHolder bh = new BigIntHolder();
        bh.value = parser.getLongValue();
        map.bigInt(fieldName).write(bh);
        break;
      case VALUE_STRING:
        VarCharHolder vh = new VarCharHolder();
        String value = parser.getText();
        byte[] b = value.getBytes(Charsets.UTF_8);
        ByteBuf d = UnpooledByteBufAllocator.DEFAULT.buffer(b.length);
        d.setBytes(0, b);
        vh.buffer = d;
        vh.start = 0;
        vh.end = b.length;
        map.varChar(fieldName).write(vh);
        break;

      default:
        throw new IllegalStateException("Unexpected token " + parser.getCurrentToken());

      }

    }
    map.end();

  }

  private void writeData(ListWriter list) throws JsonParseException, IOException {
    list.start();
    outside: while(true){

      switch(parser.nextToken()){
      case START_ARRAY:
        writeData(list.list());
        break;
      case START_OBJECT:
        writeData(list.map());
        break;
      case END_ARRAY:
      case END_OBJECT:
        break outside;

      case VALUE_EMBEDDED_OBJECT:
      case VALUE_FALSE:{
        BitHolder h = new BitHolder();
        h.value = 0;
        list.bit().write(h);
        break;
      }
      case VALUE_TRUE: {
        BitHolder h = new BitHolder();
        h.value = 1;
        list.bit().write(h);
        break;
      }
      case VALUE_NULL:
        // do nothing as we don't have a type.
        break;
      case VALUE_NUMBER_FLOAT:
        Float8Holder fh = new Float8Holder();
        fh.value = parser.getDoubleValue();
        list.float8().write(fh);
        break;
      case VALUE_NUMBER_INT:
        BigIntHolder bh = new BigIntHolder();
        bh.value = parser.getLongValue();
        list.bigInt().write(bh);
        break;
      case VALUE_STRING:
        VarCharHolder vh = new VarCharHolder();
        String value = parser.getText();
        byte[] b = value.getBytes(Charsets.UTF_8);
        ByteBuf d = UnpooledByteBufAllocator.DEFAULT.buffer(b.length);
        d.setBytes(0, b);
        vh.buffer = d;
        vh.start = 0;
        vh.end = b.length;
        list.varChar().write(vh);
        break;
      default:
        throw new IllegalStateException("Unexpected token " + parser.getCurrentToken());
      }
    }
    list.end();
   
   
  }
}
TOP

Related Classes of org.apache.drill.exec.vector.complex.fn.JsonReader

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.