<commit_before>package net.twasi.core.plugin.api.variables.objectvariables;

import net.twasi.core.interfaces.api.TwasiInterface;
import net.twasi.core.models.Message.TwasiMessage;
import net.twasi.core.plugin.api.TwasiUserPlugin;
import net.twasi.core.plugin.api.variables.TwasiVariableBase;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class TwasiObjectVariable<T> extends TwasiVariableBase {

    public TwasiObjectVariable(TwasiUserPlugin owner) {
        super(owner);
    }

    @Override
    public final String process(String name, TwasiInterface inf, String[] params, TwasiMessage message) {
        String path;
        if (params.length == 0) {
            if (getClass().isAnnotationPresent(Properties.class)) {
                Properties properties = getClass().getAnnotation(Properties.class);
                path = properties.key();
            } else return "NO_FIELD_PRESENT";
        } else path = params[0];
        try {
            List<String> actualParams = new ArrayList<>(Arrays.asList(params).subList(1, params.length));
            return resolveFields(path, getObject(name, inf, actualParams, message));
        } catch (Exception e) {
            return "ERROR";
        } catch (ForbiddenException e) {
            return "FORBIDDEN";
        }
    }

    public abstract T getObject(String name, TwasiInterface inf, List<String> params, TwasiMessage message);

    private String resolveFields(String fields, T object) throws Exception, ForbiddenException {
        String[] splitted = fields.split(".");
        Object currentObject = object;

        for (String part : splitted) {
            currentObject = resolveField(part, currentObject);
        }

        return resolveObject(currentObject);
    }

    private Object resolveField(String field, Object object) throws Exception, ForbiddenException {
        boolean found = false;
        String exactName = null;

        Class clazz = object.getClass();

        // Try to resolve as field
        outerLoop:
        for (boolean insensitive : Arrays.asList(false, true)) // first case sensitive, then case insensitive
            for (Field f : object.getClass().getFields()) {
                // Get name
                String name = f.getName();

                // Test for match
                if (!((insensitive && name.equalsIgnoreCase(field)) || (!insensitive && name.equals(field))))
                    continue;

                // Check whether resolving this object is allowed
                if (!f.isAnnotationPresent(Resolvable.class) || !clazz.isAnnotationPresent(Resolvable.class) || (clazz.isAnnotationPresent(Resolvable.class) && clazz.isAnnotationPresent(Protected.class)))
                    throw new ForbiddenException();

                // Break loop to resolve
                found = true;<commit_msg>+ Handle null and exceptions for TwasiObjectVariable<commit_after>package net.twasi.core.plugin.api.variables.objectvariables;

import net.twasi.core.interfaces.api.TwasiInterface;
import net.twasi.core.models.Message.TwasiMessage;
import net.twasi.core.plugin.api.TwasiUserPlugin;
import net.twasi.core.plugin.api.variables.TwasiVariableBase;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class TwasiObjectVariable<T> extends TwasiVariableBase {

    public TwasiObjectVariable(TwasiUserPlugin owner) {
        super(owner);
    }

    @Override
    public final String process(String name, TwasiInterface inf, String[] params, TwasiMessage message) {
        String path;
        if (params.length == 0) {
            if (getClass().isAnnotationPresent(Properties.class)) {
                Properties properties = getClass().getAnnotation(Properties.class);
                path = properties.key();
            } else return "NO_FIELD_PRESENT";
        } else path = params[0];
        try {
            List<String> actualParams = new ArrayList<>(Arrays.asList(params).subList(1, params.length));
            return resolveFields(path, getObject(name, inf, actualParams, message));
        } catch (Exception e) {
            return "ERROR";
        } catch (ForbiddenException e) {
            return "FORBIDDEN";
        }
    }

    public abstract T getObject(String name, TwasiInterface inf, List<String> params, TwasiMessage message);

    public String handleNullObject() {
        return "NULL";
    }

    public String handleException(Exception e) {
        return "ERROR";
    }

    private String resolveFields(String fields, T object) throws Exception, ForbiddenException {
        try {
            String[] splitted = fields.split(".");
            Object currentObject = object;

            if (currentObject == null) return handleNullObject();

            for (String part : splitted) {
                currentObject = resolveField(part, currentObject);
            }

            return resolveObject(currentObject);
        } catch (Exception e) {
            return handleException(e);
        }
    }

    private Object resolveField(String field, Object object) throws Exception, ForbiddenException {
        boolean found = false;
        String exactName = null;

        Class clazz = object.getClass();

        // Try to resolve as field
        outerLoop:
        for (boolean insensitive : Arrays.asList(false, true)) // first case sensitive, then case insensitive
            for (Field f : object.getClass().getFields()) {
                // Get name
                String name = f.getName();

                // Test for match
                if (!((insensitive && name.equalsIgnoreCase(field)) || (!insensitive && name.equals(field))))
                    continue;

                // Check whether resolving this object is allowed
                if (!f.isAnnotationPresent(Resolvable.class) || !clazz.isAnnotationPresent(Resolvable.class) || (clazz.isAnnotationPresent(Resolvable.class) && clazz.isAnnotationPresent(Protected.class)))
                    throw new ForbiddenException();

                // Break loop to resolve
                found = true;
{'fraction_non_alphanumeric': 0.09960462287104623, 'fraction_numerical': 0.0009124087591240876, 'mean_word_length': 2.6236914600550962, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '144811', 'n_tokens_mistral': 1698, 'n_tokens_neox': 1687, 'n_words': 425}