All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.num.numlib.internal.ctx.NumAPIContextBase Maven / Gradle / Ivy

package uk.num.numlib.internal.ctx;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.num.numlib.api.NumAPICallbacks;
import uk.num.numlib.api.NumAPIContext;
import uk.num.numlib.api.RequiredUserVariable;
import uk.num.numlib.exc.*;
import uk.num.numlib.internal.module.ModuleConfig;
import uk.num.numlib.internal.module.ModuleDNSQueries;

/**
 * A base class implementation of NumAPIContext.
 *
 * @author tonywalmsley
 */
public class NumAPIContextBase implements NumAPIContext {
    private static final int MAX_NUM_REDIRECTS = 3;
    private static final Logger LOG = LoggerFactory.getLogger(NumAPIContextBase.class);
    /**
     * The DNS query Strings for the current module and domain name/email/URL.
     */
    private ModuleDNSQueries moduleDNSQueries;
    /**
     * The module configuration data.
     */
    private ModuleConfig moduleConfig;

    /**
     * Count redirects so we don't redirect forever.
     */
    private int redirectCount = 0;
    /**
     * The location currently being checked for a NUM record.
     */
    private NumAPICallbacks.Location location;

    /**
     * Accessor for the current query location.
     *
     * @return the current query location
     */
    public NumAPICallbacks.Location getLocation() {
        return location;
    }

    /**
     * Used to keep track of the current query location
     *
     * @param location the current query location
     */
    @Override
    public void setLocation(final NumAPICallbacks.Location location) {
        this.location = location;
    }

    /**
     * Count redirects and return the current number of redirects.
     *
     * @return the current number of redirects
     */
    private int incrementRedirectCount() {
        this.redirectCount++;
        return this.redirectCount;
    }

    /**
     * Accessor
     *
     * @return The ModuleConfig object.
     */
    public ModuleConfig getModuleConfig() {
        return moduleConfig;
    }

    /**
     * Accessor
     *
     * @param moduleConfig The ModuleConfig object.
     */
    public void setModuleConfig(final ModuleConfig moduleConfig) {
        this.moduleConfig = moduleConfig;
    }

    /**
     * Accessor
     *
     * @return The ModuleDNSQueries object.
     */
    public ModuleDNSQueries getModuleDNSQueries() {
        return moduleDNSQueries;
    }

    /**
     * Accessor
     *
     * @param moduleDNSQueries The ModuleDNSQueries object.
     */
    public void setModuleDNSQueries(final ModuleDNSQueries moduleDNSQueries) {
        this.moduleDNSQueries = moduleDNSQueries;
    }

    /**
     * Modules can have required user variables that must be supplied before the NUM record csn be retrieved.
     *
     * @return An array of objects.
     */
    @Override
    public RequiredUserVariable[] getRequiredUserVariables() {
        return moduleConfig.getModule()
                .getRuv();
    }

    /**
     * Update the required user variables with values obtained from the client.
     *
     * @param requiredUserVariables The RequiredUserVariable array with the value fields populated.
     * @throws NumUserVariablesException on error
     */
    @Override
    public void setRequiredUserVariables(final RequiredUserVariable[] requiredUserVariables) throws
                                                                                             NumUserVariablesException {

        // Validate that the user variables have been entered.
        final StringBuilder errors = new StringBuilder();
        boolean errorsFound = false;

        for (final RequiredUserVariable v : requiredUserVariables) {
            if (v.getValue() == null || v.getValue()
                    .trim()
                    .length() == 0) {
                errorsFound = true;
                errors.append("Variable '");
                errors.append(v.getKey());
                errors.append("' should not be null or empty.\n");
                LOG.trace("Required User Variable: key={}, prompt={}, value={}", v.getKey(), v.getPrompt(), v.getValue());
            }
        }

        if (errorsFound) {
            LOG.error("Error in Required User Variables: {}", errors.toString());
            throw new NumUserVariablesException("Error in Required User Variables: " + errors.toString());
        }

        // All looks fine so store the variables.
        moduleConfig.getModule()
                .setRuv(requiredUserVariables);
    }

    /**
     * Update the independent query for the supplied redirect
     *
     * @param appContext the AppContext
     * @param redirectTo the supplied redirect
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     * @throws NumInvalidRedirectException  on error
     */
    private void handleIndependentQueryRedirect(final AppContext appContext, final String redirectTo) throws
                                                                                                      NumBadURLException,
                                                                                                      NumInvalidParameterException,
                                                                                                      NumInvalidRedirectException {

        final String location = moduleDNSQueries.getIndependentRecordLocation();
        LOG.trace("Redirecting independent record query from '{}' to : '{}'", location, redirectTo);

        if (redirectTo.startsWith(".")) {
            moduleDNSQueries.setRootRedirectIndependentRecordLocation(appContext, redirectTo.substring(1));
        } else if (redirectTo.startsWith("^")) {
            // Count the ^ symbols
            int hats = 0;
            while (redirectTo.charAt(hats) == '^' && hats < redirectTo.length()) {
                hats++;
            }

            moduleDNSQueries.setRelativeRedirectIndependentRecordLocation(appContext, redirectTo.substring(hats), hats);
        } else {
            moduleDNSQueries.setIndependentRecordLocation(redirectTo + "." + location);
        }
        LOG.trace("Redirected independent record query new value : '{}'", moduleDNSQueries.getIndependentRecordLocation());
    }

    /**
     * Update the managed query for the supplied redirect
     *
     * @param appContext the AppContext
     * @param redirectTo the supplied redirect
     * @throws NumBadURLException           on error
     * @throws NumInvalidRedirectException  on error
     * @throws NumInvalidParameterException on error
     */
    private void handleManagedQueryRedirect(final AppContext appContext, final String redirectTo) throws
                                                                                                  NumBadURLException,
                                                                                                  NumInvalidRedirectException,
                                                                                                  NumInvalidParameterException {
        final String location = moduleDNSQueries.getManagedRecordLocation();
        LOG.trace("Redirecting managed record query from '{}' to : '{}'", location, redirectTo);

        if (redirectTo.startsWith(".")) {
            moduleDNSQueries.setRootRedirectManagedRecordLocation(appContext, redirectTo.substring(1));
        } else if (redirectTo.startsWith("^")) {
            // Count the ^ symbols
            int hats = 0;
            while (redirectTo.charAt(hats) == '^' && hats < redirectTo.length()) {
                hats++;
            }

            moduleDNSQueries.setRelativeRedirectManagedRecordLocation(appContext, redirectTo.substring(hats), hats);
        } else {
            moduleDNSQueries.setManagedRecordLocation(redirectTo + "." + location);
        }
        LOG.trace("Redirected managed record query new value : '{}'", moduleDNSQueries.getManagedRecordLocation());
    }

    /**
     * Update the pre-populated query for the supplied redirect
     *
     * @param appContext the AppContext
     * @param redirectTo the supplied redirect
     * @throws NumBadURLException           on error
     * @throws NumInvalidRedirectException  on error
     * @throws NumInvalidParameterException on error
     */
    private void handlePrepopulatedQueryRedirect(final AppContext appContext, final String redirectTo) throws
                                                                                                       NumBadURLException,
                                                                                                       NumInvalidRedirectException,
                                                                                                       NumInvalidParameterException {
        final String location = moduleDNSQueries.getPrepopulatedRecordLocation();
        LOG.trace("Redirecting populated record query from '{}' to : '{}'", location, redirectTo);

        if (redirectTo.startsWith(".")) {
            moduleDNSQueries.setRootRedirectPrepopulatedRecordLocation(appContext, redirectTo.substring(1));
        } else if (redirectTo.startsWith("^")) {
            // Count the ^ symbols
            int hats = 0;
            while (redirectTo.charAt(hats) == '^' && hats < redirectTo.length()) {
                hats++;
            }

            moduleDNSQueries.setRelativeRedirectPrepopulatedRecordLocation(appContext, redirectTo.substring(hats), hats);
        } else {
            moduleDNSQueries.setPrepopulatedRecordLocation(redirectTo + "." + location);
        }
        LOG.trace("Redirected populated record query new value : '{}'", moduleDNSQueries.getPrepopulatedRecordLocation());
    }

    /**
     * Update the DNS queries for the supplied lookup redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the supplied redirect location
     * @throws NumBadURLException           on error
     * @throws NumInvalidRedirectException  on error
     * @throws NumInvalidParameterException on error
     */
    private void handleLookupRedirect(final AppContext appContext, final String redirect) throws NumBadURLException,
                                                                                                 NumInvalidRedirectException,
                                                                                                 NumInvalidParameterException {
        LOG.trace("Lookup redirect - updating independent, managed, and populated DNS queries.");
        handleIndependentQueryRedirect(appContext, redirect);
        handleManagedQueryRedirect(appContext, redirect);
        handlePrepopulatedQueryRedirect(appContext, redirect);
    }

    /**
     * Get the query location based on the current location that is being tried.
     *
     * @return a DNS query string for the current location.
     */
    public String getRecordLocation() {
        switch (location) {
            case INDEPENDENT:
                return moduleDNSQueries.getIndependentRecordLocation();
            case MANAGED:
                return moduleDNSQueries.getManagedRecordLocation();
            case POPULATOR:
                return moduleDNSQueries.getPopulatorLocation();
            case STOP:
                return "STOP";
            case POPULATED:
                return moduleDNSQueries.getPrepopulatedRecordLocation();
            default:
                return "STOP";
        }
    }

    /**
     * Update the relevant query for the supplied redirect
     *
     * @param appContext the AppContext
     * @param redirect   the supplied redirect
     * @param context    the NumAPIContextBase
     * @throws NumBadURLException                   on error
     * @throws NumInvalidRedirectException          on error
     * @throws NumInvalidParameterException         on error
     * @throws NumMaximumRedirectsExceededException on Error
     */
    public void handleQueryRedirect(final AppContext appContext, final String redirect, final NumAPIContextBase context) throws
                                                                                                                         NumBadURLException,
                                                                                                                         NumInvalidRedirectException,
                                                                                                                         NumInvalidParameterException,
                                                                                                                         NumMaximumRedirectsExceededException {
        LOG.info("Query Redirected to: {}", redirect);
        int redirectCount = context.incrementRedirectCount();
        if (redirectCount >= MAX_NUM_REDIRECTS) {
            LOG.error("Maximum Redirects Exceeded. (max={})", MAX_NUM_REDIRECTS);
            throw new NumMaximumRedirectsExceededException();
        }

        switch (location) {
            case INDEPENDENT:
                handleIndependentQueryRedirect(appContext, redirect);
            case MANAGED:
                handleManagedQueryRedirect(appContext, redirect);
            case POPULATED:
                handlePrepopulatedQueryRedirect(appContext, redirect);
            default:
                break;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy