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.util.Assert;
020
021/**
022 * Represents a problem with a bean definition configuration.
023 * Mainly serves as common argument passed into a {@link ProblemReporter}.
024 *
025 * <p>May indicate a potentially fatal problem (an error) or just a warning.
026 *
027 * @author Rob Harrop
028 * @author Juergen Hoeller
029 * @since 2.0
030 * @see ProblemReporter
031 */
032public class Problem {
033
034        private final String message;
035
036        private final Location location;
037
038        private final ParseState parseState;
039
040        private final Throwable rootCause;
041
042
043        /**
044         * Create a new instance of the {@link Problem} class.
045         * @param message a message detailing the problem
046         * @param location the location within a bean configuration source that triggered the error
047         */
048        public Problem(String message, Location location) {
049                this(message, location, null, null);
050        }
051
052        /**
053         * Create a new instance of the {@link Problem} class.
054         * @param message a message detailing the problem
055         * @param parseState the {@link ParseState} at the time of the error
056         * @param location the location within a bean configuration source that triggered the error
057         */
058        public Problem(String message, Location location, ParseState parseState) {
059                this(message, location, parseState, null);
060        }
061
062        /**
063         * Create a new instance of the {@link Problem} class.
064         * @param message a message detailing the problem
065         * @param rootCause the underlying exception that caused the error (may be {@code null})
066         * @param parseState the {@link ParseState} at the time of the error
067         * @param location the location within a bean configuration source that triggered the error
068         */
069        public Problem(String message, Location location, ParseState parseState, Throwable rootCause) {
070                Assert.notNull(message, "Message must not be null");
071                Assert.notNull(location, "Location must not be null");
072                this.message = message;
073                this.location = location;
074                this.parseState = parseState;
075                this.rootCause = rootCause;
076        }
077
078
079        /**
080         * Get the message detailing the problem.
081         */
082        public String getMessage() {
083                return this.message;
084        }
085
086        /**
087         * Get the location within a bean configuration source that triggered the error.
088         */
089        public Location getLocation() {
090                return this.location;
091        }
092
093        /**
094         * Get the description of the bean configuration source that triggered the error,
095         * as contained within this Problem's Location object.
096         * @see #getLocation()
097         */
098        public String getResourceDescription() {
099                return getLocation().getResource().getDescription();
100        }
101
102        /**
103         * Get the {@link ParseState} at the time of the error (may be {@code null}).
104         */
105        public ParseState getParseState() {
106                return this.parseState;
107        }
108
109        /**
110         * Get the underlying exception that caused the error (may be {@code null}).
111         */
112        public Throwable getRootCause() {
113                return this.rootCause;
114        }
115
116
117        @Override
118        public String toString() {
119                StringBuilder sb = new StringBuilder();
120                sb.append("Configuration problem: ");
121                sb.append(getMessage());
122                sb.append("\nOffending resource: ").append(getResourceDescription());
123                if (getParseState() != null) {
124                        sb.append('\n').append(getParseState());
125                }
126                return sb.toString();
127        }
128
129}