001/*
002 * Copyright 2012-2018 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 *      http://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.boot.context.properties.bind;
018
019import org.springframework.boot.context.properties.source.ConfigurationProperty;
020import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
021import org.springframework.boot.origin.Origin;
022import org.springframework.boot.origin.OriginProvider;
023
024/**
025 * Exception thrown when binding fails.
026 *
027 * @author Phillip Webb
028 * @author Madhura Bhave
029 * @since 2.0.0
030 */
031public class BindException extends RuntimeException implements OriginProvider {
032
033        private final Bindable<?> target;
034
035        private final ConfigurationProperty property;
036
037        private final ConfigurationPropertyName name;
038
039        BindException(ConfigurationPropertyName name, Bindable<?> target,
040                        ConfigurationProperty property, Throwable cause) {
041                super(buildMessage(name, target), cause);
042                this.name = name;
043                this.target = target;
044                this.property = property;
045        }
046
047        /**
048         * Return the name of the configuration property being bound.
049         * @return the configuration property name
050         */
051        public ConfigurationPropertyName getName() {
052                return this.name;
053        }
054
055        /**
056         * Return the target being bound.
057         * @return the bind target
058         */
059        public Bindable<?> getTarget() {
060                return this.target;
061        }
062
063        /**
064         * Return the configuration property name of the item that was being bound.
065         * @return the configuration property name
066         */
067        public ConfigurationProperty getProperty() {
068                return this.property;
069        }
070
071        @Override
072        public Origin getOrigin() {
073                return Origin.from(this.name);
074        }
075
076        private static String buildMessage(ConfigurationPropertyName name,
077                        Bindable<?> target) {
078                StringBuilder message = new StringBuilder();
079                message.append("Failed to bind properties");
080                message.append((name != null) ? " under '" + name + "'" : "");
081                message.append(" to ").append(target.getType());
082                return message.toString();
083        }
084
085}