001/*
002 * JDrupes Builder
003 * Copyright (C) 2025 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.builder.api;
020
021/// Represents an exception that occurs during the build. Terminates the
022/// current build when thrown.
023///
024@SuppressWarnings("serial")
025public class BuildException extends RuntimeException {
026
027    private Builder builder;
028
029    public static class Builder {
030        private ResourceProvider resourceProvider;
031        private Throwable cause;
032        private String message;
033
034        public Builder cause(Throwable cause) {
035            this.cause = cause;
036            return this;
037        }
038
039        public BuildException msg(String format, Object... args) {
040            message = String.format(format, args);
041            return new BuildException(this);
042        }
043
044        public BuildException forwardOnly() {
045            return new BuildException(this);
046        }
047    }
048
049    public static Builder from(ResourceProvider provider) {
050        return new Builder();
051    }
052
053    @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
054    private BuildException(Builder builder) {
055        super(builder.message);
056        if (builder.cause != null) {
057            initCause(builder.cause);
058        }
059        this.builder = builder;
060    }
061
062    /// Instantiates a new build exception.
063    ///
064    /// @param message the message
065    /// @param cause the cause
066    ///
067    public BuildException(String message, Throwable cause) {
068        super(message, cause);
069    }
070
071    /// Instantiates a new build exception.
072    ///
073    /// @param message the message
074    ///
075    public BuildException(String message) {
076        super(message);
077    }
078
079    /// Instantiates a new build exception.
080    ///
081    /// @param cause the cause
082    ///
083    public BuildException(Throwable cause) {
084        super(cause);
085    }
086
087    /// Convenience method for creating a new build exception.
088    ///
089    /// @param format the format
090    /// @param args the args
091    /// @return the builds the exception
092    ///
093    @SuppressWarnings("PMD.ShortMethodName")
094    public static BuildException of(String format, Object... args) {
095        return of(null, format, args);
096    }
097
098    /// Convenience method for creating a new build exception.
099    ///
100    /// @param cause the cause
101    /// @param format the format
102    /// @param args the args
103    /// @return the builds the exception
104    ///
105    @SuppressWarnings("PMD.ShortMethodName")
106    public static BuildException of(Throwable cause, String format,
107            Object... args) {
108        var message = String.format(format, args);
109        if (cause == null) {
110            return new BuildException(message);
111        }
112        return new BuildException(message, cause);
113    }
114}