001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.beans.factory.parsing;
018
019import org.springframework.lang.Nullable;
020import org.springframework.util.Assert;
021
022/**
023 * Represents a problem with a bean definition configuration.
024 * Mainly serves as common argument passed into a {@link ProblemReporter}.
025 *
026 * <p>May indicate a potentially fatal problem (an error) or just a warning.
027 *
028 * @author Rob Harrop
029 * @author Juergen Hoeller
030 * @since 2.0
031 * @see ProblemReporter
032 */
033public class Problem {
034
035        private final String message;
036
037        private final Location location;
038
039        @Nullable
040        private final ParseState parseState;
041
042        @Nullable
043        private final Throwable rootCause;
044
045
046        /**
047         * Create a new instance of the {@link Problem} class.
048         * @param message a message detailing the problem
049         * @param location the location within a bean configuration source that triggered the error
050         */
051        public Problem(String message, Location location) {
052                this(message, location, null, null);
053        }
054
055        /**
056         * Create a new instance of the {@link Problem} class.
057         * @param message a message detailing the problem
058         * @param parseState the {@link ParseState} at the time of the error
059         * @param location the location within a bean configuration source that triggered the error
060         */
061        public Problem(String message, Location location, ParseState parseState) {
062                this(message, location, parseState, null);
063        }
064
065        /**
066         * Create a new instance of the {@link Problem} class.
067         * @param message a message detailing the problem
068         * @param rootCause the underlying exception that caused the error (may be {@code null})
069         * @param parseState the {@link ParseState} at the time of the error
070         * @param location the location within a bean configuration source that triggered the error
071         */
072        public Problem(String message, Location location, @Nullable ParseState parseState, @Nullable Throwable rootCause) {
073                Assert.notNull(message, "Message must not be null");
074                Assert.notNull(location, "Location must not be null");
075                this.message = message;
076                this.location = location;
077                this.parseState = parseState;
078                this.rootCause = rootCause;
079        }
080
081
082        /**
083         * Get the message detailing the problem.
084         */
085        public String getMessage() {
086                return this.message;
087        }
088
089        /**
090         * Get the location within a bean configuration source that triggered the error.
091         */
092        public Location getLocation() {
093                return this.location;
094        }
095
096        /**
097         * Get the description of the bean configuration source that triggered the error,
098         * as contained within this Problem's Location object.
099         * @see #getLocation()
100         */
101        public String getResourceDescription() {
102                return getLocation().getResource().getDescription();
103        }
104
105        /**
106         * Get the {@link ParseState} at the time of the error (may be {@code null}).
107         */
108        @Nullable
109        public ParseState getParseState() {
110                return this.parseState;
111        }
112
113        /**
114         * Get the underlying exception that caused the error (may be {@code null}).
115         */
116        @Nullable
117        public Throwable getRootCause() {
118                return this.rootCause;
119        }
120
121
122        @Override
123        public String toString() {
124                StringBuilder sb = new StringBuilder();
125                sb.append("Configuration problem: ");
126                sb.append(getMessage());
127                sb.append("\nOffending resource: ").append(getResourceDescription());
128                if (getParseState() != null) {
129                        sb.append('\n').append(getParseState());
130                }
131                return sb.toString();
132        }
133
134}