// Path: src/main/java/com/nfl/glitr/exception/GlitrException.java
// public class GlitrException extends RuntimeException {
// 
//     public GlitrException(String message) {
//         super(message);
//     }
// 
//     public GlitrException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }


import com.nfl.glitr.exception.GlitrException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
package com.nfl.glitr.registry.datafetcher.query;



public class OverrideDataFetcher implements DataFetcher {

    private static final Logger logger = LoggerFactory.getLogger(OverrideDataFetcher.class);

    private Object override;
    private Method overrideMethod;


    /**
     * This constructor is used for getter overrides placed in the class itself
     *
     * @param name  field name
     * @param clazz schema class
     */
    public OverrideDataFetcher(String name, Class clazz) {
        overrideMethod = findMethod("get" + StringUtils.capitalize(name), clazz);
        if (overrideMethod != null) {
            return;
        }
        overrideMethod = findMethod("is" + StringUtils.capitalize(name), clazz);
    }

    /**
     * This constructor is used for getter overrides outside of the reference class
     *
     * @param name     field name
     * @param override override object
     */
    public OverrideDataFetcher(String name, Object override) {
        this(name, override.getClass());
        this.override = override;
    }

    @Override
    public Object get(DataFetchingEnvironment environment) {
        if (overrideMethod == null) {
            return null;
        }

        Object obj = override == null ? environment.getSource() : override;

        try {
            return overrideMethod.invoke(obj, environment);
        } catch (InvocationTargetException e) {

            // If the override method threw a RuntimeException just send it up
            if (e.getTargetException() instanceof RuntimeException) {
                logger.debug("Something went wrong - Unable to fetch result for overrideMethod={{}} of {}", overrideMethod.getName(), obj.getClass().getSimpleName(), e.getTargetException());
                throw (RuntimeException) e.getTargetException();
            }

            // Otherwise, wrap it up in a Glitr Exception
            logger.debug("Something went wrong - Unable to fetch result for overrideMethod={{}} of {}", overrideMethod.getName(), obj.getClass().getSimpleName());
// Path: src/main/java/com/nfl/glitr/exception/GlitrException.java
// public class GlitrException extends RuntimeException {
// 
//     public GlitrException(String message) {
//         super(message);
//     }
// 
//     public GlitrException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }


// Path: src/main/java/com/nfl/glitr/registry/datafetcher/query/OverrideDataFetcher.java
import com.nfl.glitr.exception.GlitrException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

package com.nfl.glitr.registry.datafetcher.query;



public class OverrideDataFetcher implements DataFetcher {

    private static final Logger logger = LoggerFactory.getLogger(OverrideDataFetcher.class);

    private Object override;
    private Method overrideMethod;


    /**
     * This constructor is used for getter overrides placed in the class itself
     *
     * @param name  field name
     * @param clazz schema class
     */
    public OverrideDataFetcher(String name, Class clazz) {
        overrideMethod = findMethod("get" + StringUtils.capitalize(name), clazz);
        if (overrideMethod != null) {
            return;
        }
        overrideMethod = findMethod("is" + StringUtils.capitalize(name), clazz);
    }

    /**
     * This constructor is used for getter overrides outside of the reference class
     *
     * @param name     field name
     * @param override override object
     */
    public OverrideDataFetcher(String name, Object override) {
        this(name, override.getClass());
        this.override = override;
    }

    @Override
    public Object get(DataFetchingEnvironment environment) {
        if (overrideMethod == null) {
            return null;
        }

        Object obj = override == null ? environment.getSource() : override;

        try {
            return overrideMethod.invoke(obj, environment);
        } catch (InvocationTargetException e) {

            // If the override method threw a RuntimeException just send it up
            if (e.getTargetException() instanceof RuntimeException) {
                logger.debug("Something went wrong - Unable to fetch result for overrideMethod={{}} of {}", overrideMethod.getName(), obj.getClass().getSimpleName(), e.getTargetException());
                throw (RuntimeException) e.getTargetException();
            }

            // Otherwise, wrap it up in a Glitr Exception
            logger.debug("Something went wrong - Unable to fetch result for overrideMethod={{}} of {}", overrideMethod.getName(), obj.getClass().getSimpleName());
            throw new GlitrException("Overwrite method exception", e.getTargetException());