<commit_before>package net.dean.jraw.models;

import com.fasterxml.jackson.databind.JsonNode;
import net.dean.jraw.JrawUtils;
import net.dean.jraw.models.meta.JsonProperty;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * This class provides an abstract model for retrieving data from a JSON node, although not necessarily relating to the
 * Reddit API.
 */
public abstract class JsonModel {
    protected final JsonNode data;
    /** The maximum length of a result of a {@link JsonProperty} method in {@link #toString()} */
    private static final int MAX_STRING_LENGTH = 500;
    private static final String ELLIPSIS = "(...)";

    /**
     * Instantiates a new JsonModel
     *
     * @param dataNode The node to parse data from
     */
    public JsonModel(JsonNode dataNode) {
        this.data = dataNode;
    }

    /**
     * Retrieves a textual value from the JSON node.
     *
     * @param key The key to look up in the JSON node.
     * @return The textual value of the value of the Object returned by looking up the given key.
     */
    public String data(String key) {
        return data(key, String.class);
    }

    /**
     * <p>Retrieves a value from the JSON node (provided in the constructor) of type T. Supported types:
     *
     * <ul>
     *     <li>Classes that autobox/unbox to primitive types (Boolean, Double, Integer, Float, Long)
     *     <li>{@code java.lang.String}
     *     <li>{@code java.net.URI}
     *     <li>{@code java.net.URL}
     *     <li>{@code java.util.Date}
     * </ul>
     *
     * @param key The key to look up in the JSON node.
     * @param type The wanted return value. Supported values are any class representing a primitive data type, such as
     *             {@link Integer} or {@link Boolean}.
     * @param <T> The desired return data type
     * @return An object of type T in the JSON node
     * @throws IllegalArgumentException If the class given was not one mentioned above
     */
    @SuppressWarnings("unchecked")
    public <T> T data(String key, Class<T> type) {
        if (data == null)
            throw new NullPointerException("Trying to retrieve data from a null JsonNode");

        // Make sure the key is actually there
        if (!data.has(key)) {
            return null;
        }

        JsonNode node = data.get(key);

        if (node.isNull()) {
            return null;
        }

        T returnVal;

        // Try to return the desired value
        if (type.equals(Boolean.class))
            returnVal = (T) Boolean.valueOf(node.asBoolean());
        else if (type.equals(Double.class))
            returnVal = (T) Double.valueOf(node.asDouble());
        else if (type.equals(Integer.class))
            returnVal = (T) Integer.valueOf(node.asInt());
        else if (type.equals(Long.class))
            returnVal = (T) Long.valueOf(node.asLong());
        else if (type.equals(Float.class))
            returnVal = (T) Float.valueOf(node.asText());
        else if (type.equals(URL.class) || type.equals(URI.class)) {<commit_msg>Dissalow null inputs to JsonModel.data()<commit_after>package net.dean.jraw.models;

import com.fasterxml.jackson.databind.JsonNode;
import net.dean.jraw.JrawUtils;
import net.dean.jraw.models.meta.JsonProperty;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * This class provides an abstract model for retrieving data from a JSON node, although not necessarily relating to the
 * Reddit API.
 */
public abstract class JsonModel {
    protected final JsonNode data;
    /** The maximum length of a result of a {@link JsonProperty} method in {@link #toString()} */
    private static final int MAX_STRING_LENGTH = 500;
    private static final String ELLIPSIS = "(...)";

    /**
     * Instantiates a new JsonModel
     *
     * @param dataNode The node to parse data from
     */
    public JsonModel(JsonNode dataNode) {
        this.data = dataNode;
    }

    /**
     * Retrieves a textual value from the JSON node.
     *
     * @param key The key to look up in the JSON node.
     * @return The textual value of the value of the Object returned by looking up the given key.
     */
    public String data(String key) {
        return data(key, String.class);
    }

    /**
     * <p>Retrieves a value from the JSON node (provided in the constructor) of type T. Supported types:
     *
     * <ul>
     *     <li>Classes that autobox/unbox to primitive types (Boolean, Double, Integer, Float, Long)
     *     <li>{@code java.lang.String}
     *     <li>{@code java.net.URI}
     *     <li>{@code java.net.URL}
     *     <li>{@code java.util.Date}
     * </ul>
     *
     * @param key The key to look up in the JSON node. Must not be null.
     * @param type The wanted return value. Supported values are any class representing a primitive data type, such as
     *             {@link Integer} or {@link Boolean}. Must not be null.
     * @param <T> The desired return data type
     * @return An object of type T in the JSON node
     * @throws IllegalArgumentException If the class given was not one mentioned above
     */
    @SuppressWarnings("unchecked")
    public <T> T data(String key, Class<T> type) {
        if (key == null || type == null)
            throw new NullPointerException("Key or class type was null");
        if (data == null)
            throw new NullPointerException("Trying to retrieve data from a null JsonNode");

        // Make sure the key is actually there
        if (!data.has(key)) {
            return null;
        }

        JsonNode node = data.get(key);

        if (node.isNull()) {
            return null;
        }

        T returnVal;

        // Try to return the desired value
        if (type.equals(Boolean.class))
            returnVal = (T) Boolean.valueOf(node.asBoolean());
        else if (type.equals(Double.class))
            returnVal = (T) Double.valueOf(node.asDouble());
        else if (type.equals(Integer.class))
            returnVal = (T) Integer.valueOf(node.asInt());
        else if (type.equals(Long.class))
            returnVal = (T) Long.valueOf(node.asLong());
        else if (type.equals(Float.class))
            returnVal = (T) Float.valueOf(node.asText());
        else if (type.equals(URL.class) || type.equals(URI.class)) {
{'fraction_non_alphanumeric': 0.1084765856550089, 'fraction_numerical': 0.0008891523414344991, 'mean_word_length': 2.4896587383660806, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5556985', 'n_tokens_mistral': 1945, 'n_tokens_neox': 1920, 'n_words': 667}