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

io.permazen.core.Field Maven / Gradle / Ivy


/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.core;

import com.google.common.base.Preconditions;
import com.google.common.reflect.TypeToken;

import io.permazen.core.util.ObjIdMap;
import io.permazen.util.ByteWriter;
import io.permazen.util.UnsignedIntEncoder;

/**
 * Represents a field in an {@link ObjType} or a ({@linkplain SimpleField simple}) sub-field of a {@link ComplexField}.
 *
 * @param  Java type for the field's values
 */
public abstract class Field extends SchemaItem {

    final TypeToken typeToken;
    final byte[] encodedStorageId;

    /**
     * Constructor.
     *
     * @param name the name of the field
     * @param storageId field storage ID
     * @param schema schema version
     * @param typeToken Java type for the field's values
     * @throws IllegalArgumentException if any parameter is null
     * @throws IllegalArgumentException if {@code name} is invalid
     * @throws IllegalArgumentException if {@code storageId} is non-positive
     */
    Field(String name, int storageId, Schema schema, TypeToken typeToken) {
        super(name, storageId, schema);
        Preconditions.checkArgument(typeToken != null, "null typeToken");
        this.typeToken = typeToken;
        this.encodedStorageId = UnsignedIntEncoder.encode(this.storageId);
    }

// Public methods

    /**
     * Get the Java type corresponding to this field.
     *
     * @return this field's type
     */
    public TypeToken getTypeToken() {
        return this.typeToken;
    }

    /**
     * Get the value of this field in the given object.
     * Does not alter the schema version of the object.
     *
     * @param tx transaction
     * @param id object id
     * @return this field's value in the specified object
     * @throws DeletedObjectException if no object with ID equal to {@code id} is found
     * @throws UnknownTypeException if {@code id} specifies an unknown object type
     * @throws UnknownFieldException if this field does not exist in the specified object
     * @throws StaleTransactionException if this transaction is no longer usable
     * @throws IllegalArgumentException if either parameter is null
     * @throws IllegalArgumentException if this field is a sub-field of a {@link ComplexField}
     */
    public abstract T getValue(Transaction tx, ObjId id);

    /**
     * Determine if this field in the specified object has its default value in the specified {@link Transaction}.
     *
     * @param tx {@link Transaction} containing field state
     * @param id object ID
     * @return true if this field is set to its initial default value in object {@code id}, otherwise false
     * @throws DeletedObjectException if no object with ID equal to {@code id} is found
     * @throws UnknownTypeException if {@code id} specifies an unknown object type
     * @throws StaleTransactionException if this transaction is no longer usable
     * @throws IllegalArgumentException if either parameter is null
     * @throws IllegalArgumentException if this field is a sub-field of a {@link ComplexField}
     */
    public abstract boolean hasDefaultValue(Transaction tx, ObjId id);

    /**
     * Apply visitor pattern.
     *
     * @param target target to invoke
     * @param  visitor return type
     * @return value from the method of {@code target} corresponding to this instance's type
     * @throws NullPointerException if {@code target} is null
     */
    public abstract  R visit(FieldSwitch target);

// Non-public methods

    /**
     * Copy field value between transactions.
     *
     * 

* This method assumes both objects exist and both transactions are locked. */ abstract void copy(ObjId srcId, ObjId dstId, Transaction srcTx, Transaction dstTx, ObjIdMap objectIdMap); /** * Build the key (or key prefix) for this field in the given object. */ byte[] buildKey(ObjId id) { final ByteWriter writer = new ByteWriter(ObjId.NUM_BYTES + this.encodedStorageId.length); id.writeTo(writer); writer.write(this.encodedStorageId); return writer.getBytes(); } /** * Build the key (or key prefix) for a field with the given storage ID in the given object. */ static byte[] buildKey(ObjId id, int storageId) { final ByteWriter writer = new ByteWriter(ObjId.NUM_BYTES + UnsignedIntEncoder.encodeLength(storageId)); id.writeTo(writer); UnsignedIntEncoder.write(writer, storageId); return writer.getBytes(); } /** * Determine if the given {@link Field} is equivalent to this one, or should be reset on an upgrade. */ abstract boolean isUpgradeCompatible(Field field); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy