<commit_before>package run.var.teamcity.cloud.docker.util;


import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * A JSON node abstraction. This is just an overlay to a JSON backend. It provides a relatively strict validation, and
 * does not assume mutability of the nodes.
 *
 * <p>The current JSON backend is Jackson.</p>
 *
 * @param <N> <em>this</em> node type
 */
abstract class AbstractNode<N extends AbstractNode> {

    final static JsonFactory JSON_FACTORY = new JsonFactory();
    final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(JSON_FACTORY);

    final JsonNode node;

    AbstractNode(JsonNode node) {
        this.node = node;
    }

    /**
     * Returns all children nodes of this array.
     *
     * @return the list of children nodes
     *
     * @throws UnsupportedOperationException if this node is not an array
     */
    @NotNull
    public List<N> getArrayValues() {
        checkArray();
        List<N> arrayValues = new ArrayList<>(node.size());
        for (JsonNode child : node) {
            arrayValues.add(newNode(child));
        }

        return arrayValues;
    }

    /**
     * Returns all key/node mappings of this object.
     *
     * @return the key/node mappings
     *
     * @throws UnsupportedOperationException if this node is not an object
     */
    @NotNull
    public Map<String, N> getObjectValues() {
        checkObject();
        Map<String, N> objectValues = new LinkedHashMap<>(node.size());
        Iterator<String> fieldNames = node.fieldNames();
        while(fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            objectValues.put(fieldName, newNode(node.get(fieldName)));
        }

        return objectValues;
    }


    /**
     * Helper method to cast the backend node as an object node.
     *
     * @return the backend node as an object node
     *
     * @throws UnsupportedOperationException if this node is not an object
     */
    @NotNull
    final ObjectNode getObjectNode() {
        checkObject();
        return (ObjectNode) node;
    }

    /**
     * Helper method to cast the backend node as an array node
     *
     * @return the backend node as an array node
     *
     * @throws UnsupportedOperationException if this node is not an array
     */
    final ArrayNode getArrayNode() {
        checkArray();
        return (ArrayNode) node;
    }

    /**
     * Gets the child object node with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the child node
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists or is
     * not an object
     */
    @NotNull
    public N getObject(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        JsonNode object = node.get(fieldName);
        if (!(object instanceof ObjectNode)) {
            throw new UnsupportedOperationException("Child field not found or not an object: " + node + " / " +
                    fieldName);
        }
        return newNode(object);
    }

    /**
     * Gets the child object node with the specified name.
     *
     * @param fieldName the child field name
     * @param def the default value to be used if the child node does not exists
     *
     * @return the child node or the provided default value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node or the child node is not an object
     */
    public N getObject(@NotNull String fieldName, @Nullable N def) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        if (def != null && ! ((AbstractNode) def).isObject()) {
            throw new IllegalArgumentException("Default node value is not an object.");
        }
        JsonNode object = node.get(fieldName);
        if (object == null) {
            return def;
        }
        return getObject(fieldName);
    }

    /**
     * Gets the child array node with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the child node
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists or is
     * not an array
     */
    public N getArray(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        JsonNode object = node.get(fieldName);
        if (!(object instanceof ArrayNode)) {
            throw new UnsupportedOperationException("Child field not found or not an array: " + node + " / " +
                    fieldName);
        }
        return newNode(object);
    }

    /**
     * Gets the child array node with the specified name.
     *
     * @param fieldName the child field name
     * @param def the default value to be used if the child node does not exists
     *
     * @return the child node or the provided default value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node is not an array
     */
    public N getArray(@NotNull String fieldName, @Nullable N def) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        if (def != null && !((AbstractNode) def).isArray()) {
            throw new IllegalArgumentException("Default node value is not an array.");
        }
        JsonNode object = node.get(fieldName);
        if (object == null) {
            return def;
        }

        return getArray(fieldName);
    }

    /**
     * Gets the child integer value with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the integer value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists
     * or is not an integer value node
     */
    public int getAsInt(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();<commit_msg>Node: fix testing for null nodes<commit_after>package run.var.teamcity.cloud.docker.util;


import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * A JSON node abstraction. This is just an overlay to a JSON backend. It provides a relatively strict validation, and
 * does not assume mutability of the nodes.
 *
 * <p>The current JSON backend is Jackson.</p>
 *
 * @param <N> <em>this</em> node type
 */
abstract class AbstractNode<N extends AbstractNode> {

    final static JsonFactory JSON_FACTORY = new JsonFactory();
    final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(JSON_FACTORY);

    final JsonNode node;

    AbstractNode(JsonNode node) {
        this.node = node;
    }

    /**
     * Returns all children nodes of this array.
     *
     * @return the list of children nodes
     *
     * @throws UnsupportedOperationException if this node is not an array
     */
    @NotNull
    public List<N> getArrayValues() {
        checkArray();
        List<N> arrayValues = new ArrayList<>(node.size());
        for (JsonNode child : node) {
            arrayValues.add(newNode(child));
        }

        return arrayValues;
    }

    /**
     * Returns all key/node mappings of this object.
     *
     * @return the key/node mappings
     *
     * @throws UnsupportedOperationException if this node is not an object
     */
    @NotNull
    public Map<String, N> getObjectValues() {
        checkObject();
        Map<String, N> objectValues = new LinkedHashMap<>(node.size());
        Iterator<String> fieldNames = node.fieldNames();
        while(fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            objectValues.put(fieldName, newNode(node.get(fieldName)));
        }

        return objectValues;
    }


    /**
     * Helper method to cast the backend node as an object node.
     *
     * @return the backend node as an object node
     *
     * @throws UnsupportedOperationException if this node is not an object
     */
    @NotNull
    final ObjectNode getObjectNode() {
        checkObject();
        return (ObjectNode) node;
    }

    /**
     * Helper method to cast the backend node as an array node
     *
     * @return the backend node as an array node
     *
     * @throws UnsupportedOperationException if this node is not an array
     */
    final ArrayNode getArrayNode() {
        checkArray();
        return (ArrayNode) node;
    }

    /**
     * Gets the child object node with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the child node
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists or is
     * not an object
     */
    @NotNull
    public N getObject(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        JsonNode object = node.get(fieldName);
        if (!(object instanceof ObjectNode)) {
            throw new UnsupportedOperationException("Child field not found or not an object: " + node + " / " +
                    fieldName);
        }
        return newNode(object);
    }

    /**
     * Gets the child object node with the specified name.
     *
     * @param fieldName the child field name
     * @param def the default value to be used if the child node does not exists
     *
     * @return the child node or the provided default value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node or the child node is not an object
     */
    public N getObject(@NotNull String fieldName, @Nullable N def) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        if (def != null && ! ((AbstractNode) def).isObject()) {
            throw new IllegalArgumentException("Default node value is not an object.");
        }
        JsonNode object = node.get(fieldName);
        if (object == null || object instanceof NullNode) {
            return def;
        }
        return getObject(fieldName);
    }

    /**
     * Gets the child array node with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the child node
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists or is
     * not an array
     */
    public N getArray(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        JsonNode object = node.get(fieldName);
        if (!(object instanceof ArrayNode)) {
            throw new UnsupportedOperationException("Child field not found or not an array: " + node + " / " +
                    fieldName);
        }
        return newNode(object);
    }

    /**
     * Gets the child array node with the specified name.
     *
     * @param fieldName the child field name
     * @param def the default value to be used if the child node does not exists
     *
     * @return the child node or the provided default value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node is not an array
     */
    public N getArray(@NotNull String fieldName, @Nullable N def) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
        if (def != null && !((AbstractNode) def).isArray()) {
            throw new IllegalArgumentException("Default node value is not an array.");
        }
        JsonNode object = node.get(fieldName);
        if (object == null || object instanceof NullNode) {
            return def;
        }

        return getArray(fieldName);
    }

    /**
     * Gets the child integer value with the specified name.
     *
     * @param fieldName the child field name
     *
     * @return the integer value
     *
     * @throws NullPointerException if {@code fieldName} is {@code null}
     * @throws UnsupportedOperationException if this node is not an object, or if the child node does not exists
     * or is not an integer value node
     */
    public int getAsInt(@NotNull String fieldName) {
        DockerCloudUtils.requireNonNull(fieldName, "Field name cannot be null.");
        checkObject();
{'fraction_non_alphanumeric': 0.08796757218034419, 'fraction_numerical': 0.0, 'mean_word_length': 2.5078573210276875, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 11}, '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': '377547', 'n_tokens_mistral': 3723, 'n_tokens_neox': 3635, 'n_words': 1366}