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

nstream.adapter.avro.Avro Maven / Gradle / Ivy

The newest version!
// Copyright 2015-2024 Nstream, inc.
//
// Licensed under the Redis Source Available License 2.0 (RSALv2) Agreement;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://redis.com/legal/rsalv2-agreement/
//
// 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 nstream.adapter.avro;

import java.util.Map;
import nstream.adapter.common.ingress.AssemblyException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericArray;
import org.apache.avro.generic.GenericEnumSymbol;
import org.apache.avro.generic.GenericFixed;
import org.apache.avro.generic.GenericRecord;
import swim.structure.Form;
import swim.structure.Record;
import swim.structure.Text;
import swim.structure.Value;

public final class Avro {

  private Avro() {
  }

  // TODO: consider removing "headless" from name
  public static Record genericRecordStructureHeadless(GenericRecord gr) throws AssemblyException {
    final Schema schema = gr.getSchema();
    final Record result = Record.create(schema.getFields().size());
    for (Schema.Field field : schema.getFields()) {
      final String name = field.name();
      result.slot(name, genericObjectStructure(gr.get(name)));
    }
    return result;
  }

  public static Value genericObjectStructure(Object o) throws AssemblyException {
    // because of this, no need to null-check private methods
    if (o == null || o instanceof byte[]) {
      return Value.fromObject(o);
    } else if (o instanceof GenericRecord) {
      return genericRecordStructureHeadless((GenericRecord) o);
    } else if (o instanceof GenericEnumSymbol || o instanceof CharSequence) {
      return Text.from(o.toString());
    } else if (o.getClass().isArray()) {
      return moldSimpleArray(o, o.getClass().getComponentType());
    } else if (o instanceof GenericArray) {
      return moldGenericArray((GenericArray) o);
    } else if (o instanceof Map) {
      return moldMap((Map) o);
    } else if (o instanceof GenericFixed) {
      return Value.fromObject(((GenericFixed) o).bytes());
    } else {
      return Value.fromObject(o); // TODO: consider throwing a checked exception upon failure here
    }
  }

  private static Value moldSimpleArray(Object o, Class componentType) throws AssemblyException {
    final Form sanity = Form.forBuiltin(componentType);
    if (sanity != null) {
      return Form.forArray(componentType, sanity).mold(o).toValue();
    } else {
      throw new AssemblyException("Cannot mold array of type " + componentType);
    }
  }

  private static Value moldGenericArray(GenericArray o) throws AssemblyException {
    Record result = Record.create(o.size());
    for (Object v : o) {
      result = result.item(genericObjectStructure(v));
    }
    return result;
  }

  private static Value moldMap(Map o) throws AssemblyException {
    Record result = Record.create(o.size());
    for (Map.Entry entry : o.entrySet()) {
      result = result.slot(genericObjectStructure(entry.getKey()),
          genericObjectStructure(entry.getValue()));
    }
    return result;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy