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

com.adgear.anoa.read.ThriftReader Maven / Gradle / Ivy

Go to download

Core classes for Anoa library, which aims to be a safe, convenient and fast record de/serialization wrapper for the Avro, Thrift and Jackson libraries, using the functional idioms of Java 8. The anoa-core module tries to keep upstream dependencies to a minimum.

There is a newer version: 3.1.2
Show newest version
package com.adgear.anoa.read;

import com.adgear.anoa.AnoaJacksonTypeException;
import com.adgear.anoa.AnoaReflectionUtils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import org.apache.thrift.TBase;
import org.apache.thrift.TFieldIdEnum;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

class ThriftReader> extends AbstractReader {

  final private List> fieldWrappers;
  final private Map>> fieldLookUp;
  final private T instance;
  final private int nRequired;

  ThriftReader(Class thriftClass) {
    try {
      this.instance = thriftClass.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
      throw new RuntimeException(e);
    }
    instance.clear();
    this.fieldWrappers = new ArrayList<>();
    AnoaReflectionUtils.getThriftMetaDataMap(thriftClass).forEach(
        (k, v) -> fieldWrappers.add(new ThriftFieldWrapper<>(k, v)));
    this.fieldLookUp = new HashMap<>(fieldWrappers.size());
    fieldWrappers.stream().forEach(
        w -> fieldLookUp.put(w.tFieldIdEnum.getFieldName(), Optional.of(w)));
    this.nRequired = (int) fieldWrappers.stream().filter(w -> w.isRequired).count();
  }

  @Override
  protected T read(JsonParser jacksonParser) throws IOException {
    if (jacksonParser.getCurrentToken() == JsonToken.START_OBJECT) {
      final ThriftRecordWrapper recordWrapper = newWrappedInstance();
      doMap(jacksonParser, (fieldName, p) -> {
        Optional> cacheValue = fieldLookUp.get(fieldName);
        if (cacheValue == null) {
          Optional>>> found = fieldLookUp.entrySet().stream()
              .filter(e -> (0 == fieldName.compareToIgnoreCase(e.getKey())))
              .findAny();
          cacheValue = found.isPresent() ? found.get().getValue() : Optional.empty();
          fieldLookUp.put(fieldName, cacheValue);
        }
        if (cacheValue.isPresent()) {
          final ThriftFieldWrapper fieldWrapper = cacheValue.get();
          recordWrapper.put(fieldWrapper, fieldWrapper.reader.read(p));
        } else {
          gobbleValue(p);
        }
      });
      return recordWrapper.get();
    } else {
      gobbleValue(jacksonParser);
      return null;
    }
  }


  @Override
  protected T readStrict(JsonParser jacksonParser) throws AnoaJacksonTypeException, IOException {
    switch (jacksonParser.getCurrentToken()) {
      case VALUE_NULL:
        return null;
      case START_OBJECT:
        final ThriftRecordWrapper recordWrapper = newWrappedInstance();
        doMap(jacksonParser, (fieldName, p) -> {
          final Optional> cacheValue =
              fieldLookUp.computeIfAbsent(fieldName, __ -> Optional.>empty());
          if (cacheValue.isPresent()) {
            final ThriftFieldWrapper fieldWrapper = cacheValue.get();
            recordWrapper.put(fieldWrapper, fieldWrapper.reader.readStrict(p));
          } else {
            gobbleValue(p);
          }
        });
        return recordWrapper.get();
      default:
        throw new AnoaJacksonTypeException("Token is not '{': " + jacksonParser.getCurrentToken());
    }
  }

  @SuppressWarnings("unchecked")
  protected ThriftRecordWrapper newWrappedInstance() {
    return new ThriftRecordWrapper<>((T) instance.deepCopy(), fieldWrappers, nRequired);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy