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

com.crashnote.core.config.helper.ConfigException Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/**
 *   Copyright (C) 2011-2012 Typesafe Inc. 
 */
package com.crashnote.core.config.helper;


/**
 * All exceptions thrown by the library are subclasses of
 * ConfigException.
 */
public abstract class ConfigException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    final private ConfigOrigin origin;

    protected ConfigException(final ConfigOrigin origin, final String message,
            final Throwable cause) {
        super(origin.description() + ": " + message, cause);
        this.origin = origin;
    }

    protected ConfigException(final ConfigOrigin origin, final String message) {
        this(origin.description() + ": " + message, null);
    }

    protected ConfigException(final String message, final Throwable cause) {
        super(message, cause);
        this.origin = null;
    }

    protected ConfigException(final String message) {
        this(message, null);
    }

    /**
     * Returns an "origin" (such as a filename and line number) for the
     * exception, or null if none is available. If there's no sensible origin
     * for a given exception, or the kind of exception doesn't meaningfully
     * relate to a particular origin file, this returns null. Never assume this
     * will return non-null, it can always return null.
     *
     * @return origin of the problem, or null if unknown/inapplicable
     */
    public ConfigOrigin origin() {
        return origin;
    }

    /**
     * Exception indicating that the type of a value does not match the type you
     * requested.
     *
     */
    public static class WrongType extends ConfigException {
        private static final long serialVersionUID = 1L;

        public WrongType(final ConfigOrigin origin, final String path, final String expected, final String actual,
                final Throwable cause) {
            super(origin, path + " has type " + actual + " rather than " + expected, cause);
        }

        public WrongType(final ConfigOrigin origin, final String path, final String expected, final String actual) {
            this(origin, path, expected, actual, null);
        }

        public WrongType(final ConfigOrigin origin, final String message, final Throwable cause) {
            super(origin, message, cause);
        }

        public WrongType(final ConfigOrigin origin, final String message) {
            super(origin, message, null);
        }
    }

    /**
     * Exception indicates that the setting was never set to anything, not even
     * null.
     */
    public static class Missing extends ConfigException {
        private static final long serialVersionUID = 1L;

        public Missing(final String path, final Throwable cause) {
            super("No configuration setting found for key '" + path + "'",
                    cause);
        }

        public Missing(final String path) {
            this(path, null);
        }

        protected Missing(final ConfigOrigin origin, final String message, final Throwable cause) {
            super(origin, message, cause);
        }

        protected Missing(final ConfigOrigin origin, final String message) {
            this(origin, message, null);
        }
    }

    /**
     * Exception indicates that the setting was treated as missing because it
     * was set to null.
     */
    public static class Null extends Missing {
        private static final long serialVersionUID = 1L;

        private static String makeMessage(final String path, final String expected) {
            if (expected != null) {
                return "Configuration key '" + path
                        + "' is set to null but expected " + expected;
            } else {
                return "Configuration key '" + path + "' is null";
            }
        }

        public Null(final ConfigOrigin origin, final String path, final String expected,
                final Throwable cause) {
            super(origin, makeMessage(path, expected), cause);
        }

        public Null(final ConfigOrigin origin, final String path, final String expected) {
            this(origin, path, expected, null);
        }
    }

    /**
     * Exception indicating that a value was messed up, for example you may have
     * asked for a duration and the value can't be sensibly parsed as a
     * duration.
     *
     */
    public static class BadValue extends ConfigException {
        private static final long serialVersionUID = 1L;

        public BadValue(final ConfigOrigin origin, final String path, final String message,
                final Throwable cause) {
            super(origin, "Invalid value at '" + path + "': " + message, cause);
        }

        public BadValue(final ConfigOrigin origin, final String path, final String message) {
            this(origin, path, message, null);
        }

        public BadValue(final String path, final String message, final Throwable cause) {
            super("Invalid value at '" + path + "': " + message, cause);
        }

        public BadValue(final String path, final String message) {
            this(path, message, null);
        }
    }

    /**
     * Exception indicating that a path expression was invalid. Try putting
     * double quotes around path elements that contain "special" characters.
     *
     */
    public static class BadPath extends ConfigException {
        private static final long serialVersionUID = 1L;

        public BadPath(final ConfigOrigin origin, final String path, final String message,
                final Throwable cause) {
            super(origin,
                    path != null ? ("Invalid path '" + path + "': " + message)
                            : message, cause);
        }

        public BadPath(final ConfigOrigin origin, final String path, final String message) {
            this(origin, path, message, null);
        }

        public BadPath(final String path, final String message, final Throwable cause) {
            super(path != null ? ("Invalid path '" + path + "': " + message)
                    : message, cause);
        }

        public BadPath(final String path, final String message) {
            this(path, message, null);
        }

        public BadPath(final ConfigOrigin origin, final String message) {
            this(origin, null, message);
        }
    }

    /**
     * Exception indicating that there's a bug in something (possibly the
     * library itself) or the runtime environment is broken. This exception
     * should never be handled; instead, something should be fixed to keep the
     * exception from occurring. This exception can be thrown by any method in
     * the library.
     */
    public static class BugOrBroken extends ConfigException {
        private static final long serialVersionUID = 1L;

        public BugOrBroken(final String message, final Throwable cause) {
            super(message, cause);
        }

        public BugOrBroken(final String message) {
            this(message, null);
        }
    }

    /**
     * Exception indicating that there was an IO error.
     *
     */
    public static class IO extends ConfigException {
        private static final long serialVersionUID = 1L;

        public IO(final ConfigOrigin origin, final String message, final Throwable cause) {
            super(origin, message, cause);
        }

        public IO(final ConfigOrigin origin, final String message) {
            this(origin, message, null);
        }
    }

    /**
     * Exception indicating that there was a parse error.
     *
     */
    public static class Parse extends ConfigException {
        private static final long serialVersionUID = 1L;

        public Parse(final ConfigOrigin origin, final String message, final Throwable cause) {
            super(origin, message, cause);
        }

        public Parse(final ConfigOrigin origin, final String message) {
            this(origin, message, null);
        }
    }

    /**
     * Exception indicating that a substitution did not resolve to anything.
     * Thrown by {@link Config#resolve}.
     */
    public static class UnresolvedSubstitution extends Parse {
        private static final long serialVersionUID = 1L;

        public UnresolvedSubstitution(final ConfigOrigin origin, final String detail, final Throwable cause) {
            super(origin, "Could not resolve substitution to a value: " + detail, cause);
        }

        public UnresolvedSubstitution(final ConfigOrigin origin, final String detail) {
            this(origin, detail, null);
        }
    }

    /**
     * Exception indicating that you tried to use a function that requires
     * substitutions to be resolved, but substitutions have not been resolved
     * (that is, {@link Config#resolve} was not called). This is always a bug in
     * either application code or the library; it's wrong to write a handler for
     * this exception because you should be able to fix the code to avoid it by
     * adding calls to {@link Config#resolve}.
     */
    public static class NotResolved extends BugOrBroken {
        private static final long serialVersionUID = 1L;

        public NotResolved(final String message, final Throwable cause) {
            super(message, cause);
        }

        public NotResolved(final String message) {
            this(message, null);
        }
    }

    /**
     * Information about a problem that occurred in {@link Config#checkValid}. A
     * {@link ConfigException.ValidationFailed} exception thrown from
     * checkValid() includes a list of problems encountered.
     */
    public static class ValidationProblem {

        final private String path;
        final private ConfigOrigin origin;
        final private String problem;

        public ValidationProblem(final String path, final ConfigOrigin origin, final String problem) {
            this.path = path;
            this.origin = origin;
            this.problem = problem;
        }

        /** Returns the config setting causing the problem. */
        public String path() {
            return path;
        }

        /**
         * Returns where the problem occurred (origin may include info on the
         * file, line number, etc.).
         */
        public ConfigOrigin origin() {
            return origin;
        }

        /** Returns a description of the problem. */
        public String problem() {
            return problem;
        }
    }

    /**
     * Exception indicating that {@link Config#checkValid} found validity
     * problems. The problems are available via the {@link #problems()} method.
     * The getMessage() of this exception is a potentially very
     * long string listing all the problems found.
     */
    public static class ValidationFailed extends ConfigException {
        private static final long serialVersionUID = 1L;

        final private Iterable problems;

        public ValidationFailed(final Iterable problems) {
            super(makeMessage(problems), null);
            this.problems = problems;
        }

        public Iterable problems() {
            return problems;
        }

        private static String makeMessage(final Iterable problems) {
            final StringBuilder sb = new StringBuilder();
            for (final ValidationProblem p : problems) {
                sb.append(p.origin().description());
                sb.append(": ");
                sb.append(p.path());
                sb.append(": ");
                sb.append(p.problem());
                sb.append(", ");
            }
            if (sb.length() == 0)
                throw new ConfigException.BugOrBroken(
                        "ValidationFailed must have a non-empty list of problems");
            sb.setLength(sb.length() - 2); // chop comma and space

            return sb.toString();
        }
    }

    /**
     * Exception that doesn't fall into any other category.
     */
    public static class Generic extends ConfigException {
        private static final long serialVersionUID = 1L;

        public Generic(final String message, final Throwable cause) {
            super(message, cause);
        }

        public Generic(final String message) {
            this(message, null);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy