Package com.adgear.anoa.avro

Source Code of com.adgear.anoa.avro.ThriftDataModified

/**
*
* Modified source code from the Apache Avro project, version 1.7.4 (http://avro.apache.org/)
*
*
* LICENSE:
*   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.
*
*
* NOTICE:
*   Apache Avro
*   Copyright 2010 The Apache Software Foundation
*
*   This product includes software developed at
*   The Apache Software Foundation (http://www.apache.org/).
*
*   C JSON parsing provided by Jansson and
*   written by Petri Lehtinen. The original software is
*   available from http://www.digip.org/jansson/.
*/

package com.adgear.anoa.avro;

import org.apache.avro.AvroRuntimeException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.thrift.ThriftData;
import org.apache.thrift.TBase;
import org.apache.thrift.TEnum;
import org.apache.thrift.TFieldRequirementType;
import org.apache.thrift.meta_data.EnumMetaData;
import org.apache.thrift.meta_data.FieldMetaData;
import org.apache.thrift.meta_data.FieldValueMetaData;
import org.apache.thrift.meta_data.ListMetaData;
import org.apache.thrift.meta_data.MapMetaData;
import org.apache.thrift.meta_data.SetMetaData;
import org.apache.thrift.meta_data.StructMetaData;
import org.apache.thrift.protocol.TType;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.NullNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* ThriftData modified with a few hacks.
*/
public class ThriftDataModified extends ThriftData {

  private static final ThriftDataModified INSTANCE = new ThriftDataModified();
  static private final Schema NULL = Schema.create(Schema.Type.NULL);
  static private final String THRIFT_PROP = "thrift";

  static public ThriftDataModified getModified() {
    return INSTANCE;
  }

  /**
   * Return a record schema given a thrift generated class.
   */
  @SuppressWarnings("unchecked")
  @Override
  public Schema getSchema(Class c) {
    Schema schema;
    try {
      if (TEnum.class.isAssignableFrom(c)) {    // enum
        List<String> symbols = new ArrayList<String>();
        for (Enum e : ((Class<? extends Enum>) c).getEnumConstants()) {
          symbols.add(e.name());
        }
        schema = Schema.createEnum(c.getName(), null, null, symbols);
      } else if (TBase.class.isAssignableFrom(c)) { // struct
        schema = Schema.createRecord(c.getName(), null, null, Throwable.class.isAssignableFrom(c));
        List<Schema.Field> fields = new ArrayList<>();
        for (FieldMetaData f : FieldMetaData.getStructMetaDataMap(c).values()) {
          Schema s = getSchema(f.valueMetaData);
          JsonNode defaultValue = null;
          if (f.requirementType == TFieldRequirementType.OPTIONAL) {
            if (s.getType() != Schema.Type.UNION) {
              s = nullable(s);
            }
            defaultValue = NullNode.getInstance();
          }
          fields.add(new Schema.Field(f.fieldName, s, null, defaultValue));
        }
        schema.setFields(fields);
      } else {
        throw new RuntimeException("Not a Thrift-generated class: " + c);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return schema;
  }

  private Schema getSchema(FieldValueMetaData f) {
    switch (f.type) {
      case TType.BOOL:
        return Schema.create(Schema.Type.BOOLEAN);
      case TType.BYTE:
        Schema b = Schema.create(Schema.Type.INT);
        b.addProp(THRIFT_PROP, "byte");
        return b;
      case TType.I16:
        Schema s = Schema.create(Schema.Type.INT);
        s.addProp(THRIFT_PROP, "short");
        return s;
      case TType.I32:
        return Schema.create(Schema.Type.INT);
      case TType.I64:
        return Schema.create(Schema.Type.LONG);
      case TType.DOUBLE:
        return Schema.create(Schema.Type.DOUBLE);
      case TType.ENUM:
        EnumMetaData enumMeta = (EnumMetaData) f;
        return nullable(getSchema(enumMeta.enumClass));
      case TType.LIST:
        ListMetaData listMeta = (ListMetaData) f;
        return nullable(Schema.createArray(getSchema(listMeta.elemMetaData)));
      case TType.MAP:
        MapMetaData mapMeta = (MapMetaData) f;
        if (mapMeta.keyMetaData.type != TType.STRING) {
          throw new AvroRuntimeException("Map keys must be strings: " + f);
        }
        Schema map = Schema.createMap(getSchema(mapMeta.valueMetaData));
        GenericData.setStringType(map, GenericData.StringType.String);
        return nullable(map);
      case TType.SET:
        SetMetaData setMeta = (SetMetaData) f;
        Schema set = Schema.createArray(getSchema(setMeta.elemMetaData));
        set.addProp(THRIFT_PROP, "set");
        return nullable(set);
      case TType.STRING:
        if (f.isBinary()) {
          return nullable(Schema.create(Schema.Type.BYTES));
        }
        Schema string = Schema.create(Schema.Type.STRING);
        GenericData.setStringType(string, GenericData.StringType.String);
        return nullable(string);
      case TType.STRUCT:
        StructMetaData structMeta = (StructMetaData) f;
        Schema record = getSchema(structMeta.structClass);
        return nullable(record);
      case TType.VOID:
        return NULL;
      default:
        throw new RuntimeException("Unexpected type in field: " + f);
    }
  }

  @SuppressWarnings("unchecked")
  private Schema nullable(Schema schema) {
    return Schema.createUnion(Arrays.asList(NULL, schema));
  }
}
TOP

Related Classes of com.adgear.anoa.avro.ThriftDataModified

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.