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

uk.num.numlib.internal.module.ModuleDNSQueries Maven / Gradle / Ivy

/*
 * Copyright (c) 2019. NUM Technology Ltd
 */

package uk.num.numlib.internal.module;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.num.numlib.exc.NumBadURLException;
import uk.num.numlib.exc.NumInvalidParameterException;
import uk.num.numlib.exc.NumInvalidRedirectException;
import uk.num.numlib.internal.ctx.AppContext;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Class to hold the DNS query strings for a module and domain name/URL/email address combination.
 *
 * @author tonywalmsley
 */
public class ModuleDNSQueries {
    private static final Logger LOG = LoggerFactory.getLogger(ModuleDNSQueries.class);
    /**
     * The module ID, e.g. "1"
     */
    private String moduleId;
    /**
     * The domain name, URL string or email address to be queried.
     */
    private String domainName;
    /**
     * The independent record query
     */
    private String independentRecordLocation;
    /**
     * The managed record query.
     */
    private String managedRecordLocation;
    /**
     * The pre-populated record query.
     */
    private String prepopulatedRecordLocation;
    /**
     * The populator query
     */
    private String populatorLocation;
    /**
     * The root/branch query flag.
     */
    private boolean rootQuery = true;

    /**
     * Constructor
     *
     * @param moduleId   the module ID string
     * @param domainName the domain name/URL string/email address.
     * @throws NumInvalidParameterException on error
     */
    public ModuleDNSQueries(final String moduleId, final String domainName) throws NumInvalidParameterException {
        if (moduleId == null || moduleId.trim()
                .length() == 0) {
            LOG.error("moduleId is null or empty");
            throw new NumInvalidParameterException("moduleId cannot be null or empty");
        }
        if (domainName == null || domainName.trim()
                .length() == 0) {
            LOG.error("domainName is null or empty");
            throw new NumInvalidParameterException("domainName cannot be null or empty");
        }
        LOG.trace("ModuleDNSQueries({}, {})", moduleId, domainName);
        this.moduleId = moduleId;
        this.domainName = domainName;
    }

    /**
     * Accessor
     *
     * @return true if this is a root query
     */
    public boolean isRootQuery() {
        return rootQuery;
    }

    /**
     * Build the DNS query Strings and set the root/branch flag.
     *
     * @param appContext An AppContext object
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     */
    public void initialise(final AppContext appContext) throws NumBadURLException, NumInvalidParameterException {
        LOG.trace("initialise()");
        if (domainName.startsWith("http")) {
            LOG.trace("initialise() - URL branch query");
            try {
                final URL url = new URL(domainName);
                rootQuery = url.getPath()
                        .isEmpty() || url.getPath()
                        .equals("/");

                independentRecordLocation = appContext.urlUtils.toIndependentRecordQuery(appContext, url, moduleId);
                managedRecordLocation = appContext.urlUtils.toManagedRecordQuery(appContext, url, moduleId);
                prepopulatedRecordLocation = appContext.urlUtils.toPrePopulatedRecordQuery(appContext, url, moduleId);
                populatorLocation = appContext.urlUtils.toPopulatorQuery(appContext, url, moduleId);
            } catch (MalformedURLException e) {
                LOG.error("Bad URL.", e);
                throw new NumBadURLException("The supplied URL cannot be parsed.");
            }
        } else if (domainName.contains("@")) {
            LOG.trace("initialise() - email branch query");
            rootQuery = false;
            independentRecordLocation = appContext.emailAddressUtils.toIndependentRecordQuery(appContext, domainName, moduleId);
            managedRecordLocation = appContext.emailAddressUtils.toManagedRecordQuery(appContext, domainName, moduleId);
            prepopulatedRecordLocation = appContext.emailAddressUtils.toPrePopulatedRecordQuery(appContext, domainName, moduleId);
            populatorLocation = appContext.emailAddressUtils.toPopulatorQuery(appContext, domainName, moduleId);
        } else {
            LOG.trace("initialise() - root query");
            rootQuery = true;
            independentRecordLocation = appContext.domainNameUtils.toIndependentRecordQuery(appContext, domainName, moduleId);
            managedRecordLocation = appContext.domainNameUtils.toManagedRecordQuery(appContext, domainName, moduleId);
            prepopulatedRecordLocation = appContext.domainNameUtils.toPrePopulatedRecordQuery(appContext, domainName, moduleId);
            populatorLocation = appContext.domainNameUtils.toPopulatorQuery(appContext, domainName, moduleId);
        }
    }

    /**
     * Accessor
     *
     * @return the module ID string
     */
    public String getModuleId() {
        return moduleId;
    }

    /**
     * Accessor
     *
     * @return the domain name/URL/email address
     */
    public String getDomainName() {
        return domainName;
    }

    /**
     * Accessor
     *
     * @return the independent record query string.
     */
    public String getIndependentRecordLocation() {
        return independentRecordLocation;
    }

    /**
     * Set the independent record location to a specific value.
     *
     * @param location the new independent record location
     */
    public void setIndependentRecordLocation(final String location) {
        independentRecordLocation = location;
    }

    /**
     * Accessor
     *
     * @return the managed record query string
     */
    public String getManagedRecordLocation() {
        return managedRecordLocation;
    }

    /**
     * Override the managed record location, usually due to a redirect
     *
     * @param location the new location
     */
    public void setManagedRecordLocation(final String location) {
        managedRecordLocation = location;
    }

    /**
     * Accessor
     *
     * @return the pre-populated record query string.
     */
    public String getPrepopulatedRecordLocation() {
        return prepopulatedRecordLocation;
    }

    /**
     * Override the prepopulated record location, usually due to a redirect
     *
     * @param location the prepopulated record location
     */
    public void setPrepopulatedRecordLocation(final String location) {
        prepopulatedRecordLocation = location;
    }

    /**
     * Accessor
     *
     * @return the populator query string
     */
    public String getPopulatorLocation() {
        return populatorLocation;
    }

    /**
     * Change the independent record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirectTo the root-relative branch record to use.
     * @throws NumInvalidParameterException on error
     * @throws NumBadURLException           on error
     * @throws NumInvalidRedirectException  on error
     */
    public void setRootRedirectIndependentRecordLocation(final AppContext appContext, final String redirectTo) throws
                                                                                                               NumInvalidParameterException,
                                                                                                               NumBadURLException,
                                                                                                               NumInvalidRedirectException {
        final String originalLocation = independentRecordLocation;
        String root = independentRecordLocation;
        if (!rootQuery) {
            root = getIndependentRootFromBranch(appContext, domainName);
        } else {
            if (StringUtils.isEmpty(redirectTo)) {
                throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
            }
        }
        if (StringUtils.isEmpty(redirectTo)) {
            independentRecordLocation = root;
        } else {
            independentRecordLocation = redirectTo + "." + root;
        }
        if (independentRecordLocation.equals(originalLocation)) {
            throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
        }
        rootQuery = false;
    }

    /**
     * Change the independent record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the relative branch record to use.
     * @param levels     the number of levels to go up before adding the redirect location
     * @throws NumInvalidRedirectException  on error
     * @throws NumInvalidParameterException on error
     * @throws NumBadURLException           on error
     */
    public void setRelativeRedirectIndependentRecordLocation(final AppContext appContext, final String redirect, final int levels) throws
                                                                                                                                   NumInvalidRedirectException,
                                                                                                                                   NumInvalidParameterException,
                                                                                                                                   NumBadURLException {
        if (rootQuery) {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        String root;
        root = getIndependentRootFromBranch(appContext, domainName);

        final String[] parts = independentRecordLocation.split("\\.");
        if (levels < parts.length) {
            StringBuilder builder = new StringBuilder();
            builder.append(redirect);
            builder.append(".");
            for (int i = levels; i < parts.length; i++) {
                builder.append(parts[i]);
                builder.append(".");
            }
            independentRecordLocation = builder.toString();
            if (!independentRecordLocation.endsWith(root)) {
                throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
            }
        } else {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        rootQuery = false;
    }

    /**
     * Given a branch domain get the independent root for it.
     *
     * @param appContext the AppContext
     * @param branch     the branch domain.
     * @return the root domain
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     */
    private String getIndependentRootFromBranch(final AppContext appContext, final String branch) throws
                                                                                                  NumBadURLException,
                                                                                                  NumInvalidParameterException {
        if (domainName.contains("@")) {
            final String[] parts = domainName.split("@");
            return appContext.domainNameUtils
                    .toIndependentRecordQuery(appContext, parts[1], moduleId);
        } else if (domainName.startsWith("http")) {
            try {
                final URL url = new URL(domainName);
                return appContext.domainNameUtils
                        .toIndependentRecordQuery(appContext, url.getHost(), moduleId);
            } catch (MalformedURLException e) {
                throw new NumBadURLException(domainName);
            }
        }
        return branch;
    }

    /**
     * Given a branch domain get the managed root for it.
     *
     * @param appContext the AppContext
     * @param branch     the branch domain.
     * @return the root domain
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     */
    private String getManagedRootFromBranch(final AppContext appContext, final String branch) throws NumBadURLException,
                                                                                                     NumInvalidParameterException {
        if (domainName.contains("@")) {
            final String[] parts = domainName.split("@");
            return appContext.domainNameUtils
                    .toManagedRecordQuery(appContext, parts[1], moduleId);
        } else if (domainName.startsWith("http")) {
            try {
                final URL url = new URL(domainName);
                return appContext.domainNameUtils
                        .toManagedRecordQuery(appContext, url.getHost(), moduleId);
            } catch (MalformedURLException e) {
                throw new NumBadURLException(domainName);
            }
        } else {
            return appContext.domainNameUtils
                    .toManagedRecordQuery(appContext, branch, moduleId);
        }
    }

    /**
     * Change the managed record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the root-relative branch record to use.
     * @throws NumInvalidParameterException on error
     * @throws NumBadURLException           on error
     * @throws NumInvalidRedirectException  on error
     */
    public void setRootRedirectManagedRecordLocation(final AppContext appContext, final String redirect) throws
                                                                                                         NumInvalidParameterException,
                                                                                                         NumBadURLException,
                                                                                                         NumInvalidRedirectException {
        final String originalLocation = managedRecordLocation;
        String root = managedRecordLocation;
        if (!rootQuery) {
            root = getManagedRootFromBranch(appContext, domainName);
        } else {
            if (StringUtils.isEmpty(redirect)) {
                throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
            }
        }
        if (StringUtils.isEmpty(redirect)) {
            managedRecordLocation = root;
        } else {
            managedRecordLocation = redirect + "." + root;
        }
        if (managedRecordLocation.equals(originalLocation)) {
            throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
        }
        rootQuery = false;
    }

    /**
     * Change the managed record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the relative branch record to use.
     * @param levels     the number of levels to go up before adding the redirect location
     * @throws NumInvalidRedirectException  on error
     * @throws NumInvalidParameterException on error
     * @throws NumBadURLException           on error
     */
    public void setRelativeRedirectManagedRecordLocation(final AppContext appContext, final String redirect, final int levels) throws
                                                                                                                               NumInvalidRedirectException,
                                                                                                                               NumInvalidParameterException,
                                                                                                                               NumBadURLException {
        if (rootQuery) {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        String root;
        root = getManagedRootFromBranch(appContext, domainName);

        final String[] parts = managedRecordLocation.split("\\.");
        if (levels < parts.length) {
            StringBuilder builder = new StringBuilder();
            builder.append(redirect);
            builder.append(".");
            for (int i = levels; i < parts.length; i++) {
                builder.append(parts[i]);
                builder.append(".");
            }
            managedRecordLocation = builder.toString();
            if (!managedRecordLocation.endsWith(root)) {
                throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
            }
        } else {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        rootQuery = false;

    }

    /**
     * Change the pre-populated record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the root-relative branch record to use.
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     * @throws NumInvalidRedirectException  on error
     */
    public void setRootRedirectPrepopulatedRecordLocation(final AppContext appContext, final String redirect) throws
                                                                                                              NumBadURLException,
                                                                                                              NumInvalidParameterException,
                                                                                                              NumInvalidRedirectException {
        final String originalLocation = prepopulatedRecordLocation;
        String root = prepopulatedRecordLocation;
        if (!rootQuery) {
            root = getPrepopulatedRootFromBranch(appContext, domainName);
        } else {
            if (StringUtils.isEmpty(redirect)) {
                throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
            }
        }
        if (StringUtils.isEmpty(redirect)) {
            prepopulatedRecordLocation = root;
        } else {
            prepopulatedRecordLocation = redirect + "." + root;
        }
        if (prepopulatedRecordLocation.equals(originalLocation)) {
            throw new NumInvalidRedirectException("Cannot redirect back to the same location.");
        }
        rootQuery = false;

    }

    /**
     * Given a branch domain get the pre-populated root for it.
     *
     * @param appContext the AppContext
     * @param branch     the branch domain.
     * @return the root domain
     * @throws NumInvalidParameterException on error
     * @throws NumBadURLException           on error
     */
    private String getPrepopulatedRootFromBranch(final AppContext appContext, final String branch) throws
                                                                                                   NumInvalidParameterException,
                                                                                                   NumBadURLException {
        if (branch.contains("@")) {
            final String[] parts = branch.split("@");
            return appContext.domainNameUtils
                    .toPrePopulatedRecordQuery(appContext, parts[1], moduleId);
        } else if (branch.startsWith("http")) {
            try {
                final URL url = new URL(branch);
                return appContext.domainNameUtils
                        .toPrePopulatedRecordQuery(appContext, url.getHost(), moduleId);
            } catch (MalformedURLException e) {
                throw new NumBadURLException(branch);
            }
        } else {
            return appContext.domainNameUtils
                    .toPrePopulatedRecordQuery(appContext, branch, moduleId);
        }
    }

    /**
     * Change the pre-poulated record location due to a redirect.
     *
     * @param appContext the AppContext
     * @param redirect   the relative branch record to use.
     * @param levels     the number of levels to go up before adding the redirect location
     * @throws NumBadURLException           on error
     * @throws NumInvalidParameterException on error
     * @throws NumInvalidRedirectException  on error
     */
    public void setRelativeRedirectPrepopulatedRecordLocation(final AppContext appContext, final String redirect, final int levels) throws
                                                                                                                                    NumBadURLException,
                                                                                                                                    NumInvalidParameterException,
                                                                                                                                    NumInvalidRedirectException {
        if (rootQuery) {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        String root;
        root = getPrepopulatedRootFromBranch(appContext, domainName);

        final String[] parts = prepopulatedRecordLocation.split("\\.");
        if (levels < parts.length) {
            StringBuilder builder = new StringBuilder();
            builder.append(redirect);
            builder.append(".");
            for (int i = levels; i < parts.length; i++) {
                builder.append(parts[i]);
                builder.append(".");
            }
            prepopulatedRecordLocation = builder.toString();
            if (!prepopulatedRecordLocation.endsWith(root)) {
                throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
            }
        } else {
            throw new NumInvalidRedirectException("Too many ^ symbols in redirect instruction");
        }

        rootQuery = false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy