    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *     http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.mail;
    019
    020import java.io.OutputStreamWriter;
    021import java.io.PrintStream;
    022import java.io.PrintWriter;
    023import java.nio.charset.Charset;
    024import java.util.Collection;
    025import java.util.concurrent.Callable;
    026import java.util.function.Supplier;
    027
    028/**
    029 * Exception thrown when a checked error occurs in commons-email.
    030 * <p>
    031 * Adapted from FunctorException in Commons Collections.
    032 * </p>
    033 * <p>
    034 * Emulation support for nested exceptions has been removed in {@code Email 1.3}, supported by JDK 1.4 and above.
    035 * </p>
    036 *
    037 * @since 1.0
    038 */
    039public class EmailException extends Exception {
    040
    041    /** Serializable version identifier. */
    042    private static final long serialVersionUID = 5550674499282474616L;
    043
    044    static <V> V call(final Callable<V> callable) throws EmailException {
    045        try {
    046            return callable.call();
    047        } catch (final Exception e) {
    048            throw new EmailException(e);
    049        }
    050    }
    051
    052    static <T> T check(final Supplier<Boolean> test, final T subject, final Supplier<String> message) throws EmailException {
    053        if (test.get()) {
    054            throw new EmailException(message.get());
    055        }
    056        return subject;
    057    }
    058
    059    static <T> Collection<T> checkNonEmpty(final Collection<T> value, final Supplier<String> message) throws EmailException {
    060        return check(() -> EmailUtils.isEmpty(value), value, message);
    061    }
    062
    063    static String checkNonEmpty(final String value, final Supplier<String> message) throws EmailException {
    064        return check(() -> EmailUtils.isEmpty(value), value, message);
    065    }
    066
    067    static <T> T[] checkNonEmpty(final T[] value, final Supplier<String> message) throws EmailException {
    068        return check(() -> EmailUtils.isEmpty(value), value, message);
    069    }
    070
    071    static <T> T checkNonNull(final T test, final Supplier<String> message) throws EmailException {
    072        if (test == null) {
    073            throw new EmailException(message.get());
    074        }
    075        return test;
    076    }
    077
    078    /**
    079     * Constructs a new {@code EmailException} with no detail message.
    080     */
    081    public EmailException() {
    082    }
    083
    084    /**
    085     * Constructs a new {@code EmailException} with specified detail message.
    086     *
    087     * @param msg the error message.
    088     */
    089    public EmailException(final String msg) {
    090        super(msg);
    091    }
    092
    093    /**
    094     * Constructs a new {@code EmailException} with specified detail message and nested {@code Throwable} root cause.
    095     *
    096     * @param msg       the error message.
    097     * @param rootCause the exception or error that caused this exception to be thrown.
    098     */
    099    public EmailException(final String msg, final Throwable rootCause) {
    100        super(msg, rootCause);
    101    }
    102
    103    /**
    104     * Constructs a new {@code EmailException} with specified nested {@code Throwable} root cause.
    105     *
    106     * @param rootCause the exception or error that caused this exception to be thrown.
    107     */
    108    public EmailException(final Throwable rootCause) {
    109        super(rootCause);
    110    }
    111
    112    /**
    113     * Prints the stack trace of this exception to the standard error stream.
    114     */
    115    @Override
    116    public void printStackTrace() {
    117        printStackTrace(System.err);
    118    }
    119
    120    /**
    121     * Prints the stack trace of this exception to the specified stream.
    122     *
    123     * @param out the {@code PrintStream} to use for output
    124     */
    125    @Override
    126    public void printStackTrace(final PrintStream out) {
    127        synchronized (out) {
    128            final PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, Charset.defaultCharset()), false);
    129            printStackTrace(pw);
    130            // Flush the PrintWriter before it's GC'ed.
    131            pw.flush();
    132        }
    133    }
    134
    135    /**
    136     * Prints the stack trace of this exception to the specified writer.
    137     *
    138     * @param out the {@code PrintWriter} to use for output
    139     */
    140    @Override
    141    public void printStackTrace(final PrintWriter out) {
    142        synchronized (out) {
    143            super.printStackTrace(out);
    144        }
    145    }
    146}