co.cask.cdap.internal.io.ReflectionPutWriter.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.internal.io.ReflectionPutWriter.java

Source

/*
 * Copyright  2015 Cask Data, Inc.
 *
 * Licensed 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 co.cask.cdap.internal.io;

import co.cask.cdap.api.common.Bytes;
import co.cask.cdap.api.data.schema.Schema;
import co.cask.cdap.api.dataset.table.Put;
import co.cask.cdap.api.dataset.table.Table;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Encodes an object as a {@link Put} for storing it into a {@link Table}. Assumes that objects to write are
 * records. Fields of simple types are encoded as columns in the table. Complex types (arrays, maps, records, enums),
 * are not supported.
 *
 * @param <T> the type of object to encode as a {@link Put}
 */
public class ReflectionPutWriter<T> extends ReflectionWriter<Put, T> {
    private final List<String> fieldNames;
    private int index;

    public ReflectionPutWriter(Schema schema) {
        super(schema);
        Preconditions.checkArgument(schema.getType() == Schema.Type.RECORD, "Schema must be a record.");
        List<Schema.Field> schemaFields = schema.getFields();
        int numFields = schemaFields.size();
        Preconditions.checkArgument(numFields > 0, "Record must contain at least one field.");
        this.fieldNames = Lists.newArrayListWithCapacity(numFields);
        for (Schema.Field schemaField : schemaFields) {
            this.fieldNames.add(schemaField.getName());
        }
        this.index = 0;
    }

    private String nextField() {
        String name = fieldNames.get(index);
        index++;
        return name;
    }

    @Override
    public void write(T object, Put put) throws IOException {
        index = 0;
        seenRefs = Sets.newIdentityHashSet();
        super.writeRecord(put, object, schema);
    }

    @Override
    protected void writeNull(Put put) throws IOException {
        nextField();
    }

    @Override
    protected void writeBool(Put put, Boolean val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeInt(Put put, int val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeLong(Put put, long val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeFloat(Put put, Float val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeDouble(Put put, Double val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeString(Put put, String val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeBytes(Put put, ByteBuffer val) throws IOException {
        put.add(nextField(), Bytes.toBytes(val));
    }

    @Override
    protected void writeBytes(Put put, byte[] val) throws IOException {
        put.add(nextField(), val);
    }

    @Override
    protected void writeEnum(Put put, String val, Schema schema) throws IOException {
        throw new UnsupportedOperationException("Enums are not supported.");
    }

    @Override
    protected void writeArray(Put put, Collection<?> val, Schema componentSchema) throws IOException {
        throw new UnsupportedOperationException("Arrays are not supported.");
    }

    @Override
    protected void writeArray(Put put, Object val, Schema componentSchema) throws IOException {
        throw new UnsupportedOperationException("Arrays are not supported.");
    }

    @Override
    protected void writeMap(Put put, Map<?, ?> val, Map.Entry<Schema, Schema> mapSchema) throws IOException {
        throw new UnsupportedOperationException("Maps are not supported.");
    }

    @Override
    protected void writeRecord(Put put, Object record, Schema recordSchema) throws IOException {
        throw new UnsupportedOperationException("Records are not supported.");
    }

    @Override
    protected void writeUnion(Put put, Object val, Schema schema) throws IOException {
        // only support unions if its for a nullable.
        if (!schema.isNullable()) {
            throw new UnsupportedOperationException("Unions that do not represent nullables are not supported.");
        }

        if (val != null) {
            seenRefs.remove(val);
            write(put, val, schema.getNonNullable());
        } else {
            // if the value is null, we want to generate a put with value null, to make sure to delete any existing values.
            put.add(nextField(), (byte[]) null);
        }
    }
}