<commit_before>package siren;

import java.util.List;

/**
 * Represents a control inside of an action.
 * @author jonfreer
 * @since 8/13/17
 */
public class Field<T> {

    /**
     * Constructs an instance of {@link Field.Builder}.
     */
    public static class Builder<T> implements siren.Builder<Field<T>>{

        private String name;
        private FieldType type;
        private String title;
        private T value;

        /**
         * Adds the name provided to the current state of the builder.
         * @param name A name describing the control. Field names MUST be unique
         *             within the set of fields for an action. The behaviour of
         *             clients when parsing a Siren document that violates this
         *             constraint is undefined.
         * @return The builder this method is called on.
         */
        public Builder<T> name(String name){
            this.name = name;
            return this;
        }

        /**
         * Adds the title provided to the current state of the builder.
         * @param title Textual annotation of a field. Clients may use this as a label.
         * @return The builder this method is called on.
         */
        public Builder<T> title(String title){
            this.title = title;
            return this;
        }

        /**
         * Adds the type provided to the current state of the builder.
         * @param type The input type of the field. This is a subset of
         *             the input types specified by HTML5.
         * @return The builder this method is called on.
         */
        public Builder<T> type(FieldType type){
            this.type = type;
            return this;
        }

        /**
         * Adds the value provided to the current state of the builder.
         * @param value The value assigned to the field.
         * @return The builder this method is called on.
         */
        public Builder<T> value(T value){
            this.value = value;
            return this;
        }

        /**
         * Clears the state of the builder.
         */
        @Override
        public void clear() {
            this.name = null;
            this.title = null;
            this.value = null;
            this.type = null;
        }

        /**
         * Constructs an instance of {@link T} with the
         * current state of the builder.
         *
         * @return Instance of {@link T} with the current state of the builder.
         */
        @Override
        public Field<T> build() {
            return new Field<T>(this.name, this.type, this.title, this.value);
        }
    }

    /**
     * A name describing the control. Field names MUST be unique within the set of fields for an action.
     */
    private String name;

    /**
     * The input type of the field. This is a subset of the input types specified by HTML5.
     */
    private FieldType type;

    /**
     * Textual annotation of a field. Clients may use this as a label.
     */
    private String title;

    /**
     * The value assigned to the field.
     */
    private T value;

    /**
     * Constructs an instance of {@link Field}.
     * @param name The name describing the control. Field names MUST be unique
     *             within the set of fields for an action.
     */
    private Field(String name){
        if(name == null){
            throw new IllegalArgumentException("'name' cannot be null as it is required.");
        }
        this.name = name;
    }

    /**
     * Constructs an instance of {@link Field}.
     * @param name The name describing the control. Field names MUST be unique
     *             within the set of fields for an action.
     * @param type The input type of the field. This is a subset of the input
     *             types specified by HTML5.
     * @param title Textual annotation of a field. Clients may use this as a label.
     * @param value The value assigned to the field.
     */
    private Field(String name, FieldType type, String title, T value){
        this(name);

        //perform type checking on T to ensure it's either a number, a string, or a list (of FieldValue).
        boolean isShort, isInteger, isLong, isDouble,
                isFloat, isNumber, isString, isList;

        isFloat = value instanceof Float;
        isDouble = value instanceof Double;
        isInteger = value instanceof Integer;
        isLong = value instanceof Long;
        isShort = value instanceof Short;
        isNumber = isFloat || isDouble || isInteger || isLong || isShort;
        isString = value instanceof String;
        isList = value instanceof List;

        if(value != null && !isNumber && !isString && !isList){
            throw new IllegalArgumentException("'value' must be either a number, a string, or a list.");
        }

        this.title = title;
        this.value = value;
        this.type = type;
    }

    /**
     * Retrieves the name describing the control. Field names MUST be unique
     * within the set of fields for an action.
     * @return The name describing the control. Field names MUST be unique<commit_msg>Introduce equals and hashcode method to Field.<commit_after>package siren;

import java.util.List;

/**
 * Represents a control inside of an action.
 * @author jonfreer
 * @since 8/13/17
 */
public class Field<T> {

    /**
     * Constructs an instance of {@link Field.Builder}.
     */
    public static class Builder<T> implements siren.Builder<Field<T>>{

        private String name;
        private FieldType type;
        private String title;
        private T value;

        /**
         * Adds the name provided to the current state of the builder.
         * @param name A name describing the control. Field names MUST be unique
         *             within the set of fields for an action. The behaviour of
         *             clients when parsing a Siren document that violates this
         *             constraint is undefined.
         * @return The builder this method is called on.
         */
        public Builder<T> name(String name){
            this.name = name;
            return this;
        }

        /**
         * Adds the title provided to the current state of the builder.
         * @param title Textual annotation of a field. Clients may use this as a label.
         * @return The builder this method is called on.
         */
        public Builder<T> title(String title){
            this.title = title;
            return this;
        }

        /**
         * Adds the type provided to the current state of the builder.
         * @param type The input type of the field. This is a subset of
         *             the input types specified by HTML5.
         * @return The builder this method is called on.
         */
        public Builder<T> type(FieldType type){
            this.type = type;
            return this;
        }

        /**
         * Adds the value provided to the current state of the builder.
         * @param value The value assigned to the field.
         * @return The builder this method is called on.
         */
        public Builder<T> value(T value){
            this.value = value;
            return this;
        }

        /**
         * Clears the state of the builder.
         */
        @Override
        public void clear() {
            this.name = null;
            this.title = null;
            this.value = null;
            this.type = null;
        }

        /**
         * Constructs an instance of {@link T} with the
         * current state of the builder.
         *
         * @return Instance of {@link T} with the current state of the builder.
         */
        @Override
        public Field<T> build() {
            return new Field<T>(this.name, this.type, this.title, this.value);
        }
    }

    /**
     * A name describing the control. Field names MUST be unique within the set of fields for an action.
     */
    private String name;

    /**
     * The input type of the field. This is a subset of the input types specified by HTML5.
     */
    private FieldType type;

    /**
     * Textual annotation of a field. Clients may use this as a label.
     */
    private String title;

    /**
     * The value assigned to the field.
     */
    private T value;

    /**
     * Constructs an instance of {@link Field}.
     * @param name The name describing the control. Field names MUST be unique
     *             within the set of fields for an action.
     */
    private Field(String name){
        if(name == null){
            throw new IllegalArgumentException("'name' cannot be null as it is required.");
        }
        this.name = name;
    }

    /**
     * Constructs an instance of {@link Field}.
     * @param name The name describing the control. Field names MUST be unique
     *             within the set of fields for an action.
     * @param type The input type of the field. This is a subset of the input
     *             types specified by HTML5.
     * @param title Textual annotation of a field. Clients may use this as a label.
     * @param value The value assigned to the field.
     */
    private Field(String name, FieldType type, String title, T value){
        this(name);

        //perform type checking on T to ensure it's either a number, a string, or a list (of FieldValue).
        boolean isShort, isInteger, isLong, isDouble,
                isFloat, isNumber, isString, isList;

        isFloat = value instanceof Float;
        isDouble = value instanceof Double;
        isInteger = value instanceof Integer;
        isLong = value instanceof Long;
        isShort = value instanceof Short;
        isNumber = isFloat || isDouble || isInteger || isLong || isShort;
        isString = value instanceof String;
        isList = value instanceof List;

        if(value != null && !isNumber && !isString && !isList){
            throw new IllegalArgumentException("'value' must be either a number, a string, or a list.");
        }

        this.title = title;
        this.value = value;
        this.type = type;
    }

    /**
     * Determines if the instance of {@link Object} provided is
     * equal to the calling {@link Field} instance.
     * @param obj The instance of {@link Field} being examined.
     * @return {@code true} if the instances are equal; {@code false} otherwise.
     */
    @Override
    public boolean equals(Object obj){

        if(obj == null || obj.getClass() != this.getClass()) return false;

        Field<T> field = (Field<T>)obj;

        boolean sameName =
            this.name == null && field.name == null ||
            this.name != null && field.name != null &&
            this.name.equals(field.name);

        boolean sameTitle =
            this.title == null && field.title == null ||
            this.title != null && field.title != null &&
            this.title.equals(field.title);

        boolean sameValue =
            this.value == null && field.value == null ||
            this.value != null && field.value != null &&
            this.value.equals(field.value);

        boolean sameType =
            this.type == null && field.type == null ||
            this.type != null && field.type != null &&
            this.type.equals(field.type);

        return sameName && sameTitle && sameValue && sameType;
    }

    /**
     * Generates hashcode represented as an integer for the calling {@link Field} instance.
     * @return The hashcode for the calling {@link Field} instance.
     */
    @Override
    public int hashCode(){

        final int PRIME = 31;
        int hashCode = 1;

        if(this.name != null){
            hashCode *= PRIME + this.name.hashCode();
        }

        if(this.title != null){
            hashCode *= PRIME + this.title.hashCode();
        }

        if(this.value != null){
            hashCode *= PRIME + this.value.hashCode();
        }

        if(this.type != null){
            hashCode *= PRIME + this.type.hashCode();
        }

        return hashCode;
    }

    /**
     * Retrieves the name describing the control. Field names MUST be unique
     * within the set of fields for an action.
     * @return The name describing the control. Field names MUST be unique
{'fraction_non_alphanumeric': 0.08610885458976442, 'fraction_numerical': 0.0015434606011372868, 'mean_word_length': 1.7566054635020152, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7366962', 'n_tokens_mistral': 3173, 'n_tokens_neox': 3078, 'n_words': 1318}