001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2017 MicroBean. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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 014 * implied. See the License for the specific language governing 015 * permissions and limitations under the License. 016 */ 017package org.microbean.configuration.api; 018 019import java.io.Serializable; // for javadoc only 020 021import java.util.Collection; 022import java.util.Collections; 023import java.util.Map; 024 025/** 026 * A {@link ConfigurationException} indicating that conflicting {@link 027 * ConfigurationValue}s were found for a given configuration property 028 * request. 029 * 030 * @author <a href="http://about.me/lairdnelson" 031 * target="_parent">Laird Nelson</a> 032 * 033 * @see ConfigurationValue 034 */ 035public class AmbiguousConfigurationValuesException extends ConfigurationException { 036 037 038 /* 039 * Static fields. 040 */ 041 042 043 /** 044 * The version of this class for {@linkplain Serializable 045 * serialization} purposes. 046 */ 047 private static final long serialVersionUID = 1L; 048 049 050 /* 051 * Instance fields. 052 */ 053 054 055 /** 056 * A {@link Collection} of conflicting {@link ConfigurationValue}s. 057 * 058 * <p>This field is never {@code null} but may be {@linkplain 059 * Collection#isEmpty() empty}.</p> 060 */ 061 private final Collection<? extends ConfigurationValue> values; 062 063 /** 064 * The configuration coordinates in effect at the time conflicting 065 * values were found. 066 * 067 * <p>This field is never {@code null}.</p> 068 */ 069 private final Map<? extends String, ? extends String> configurationCoordinates; 070 071 /** 072 * The name of the configuration property for which a value was requested. 073 * 074 * <p>This field is never {@code null}.</p> 075 */ 076 private final String name; 077 078 079 /* 080 * Constructors. 081 */ 082 083 084 /** 085 * Creates a new {@link AmbiguousConfigurationValuesException}. 086 * 087 * @param message the error message; may be {@code null} 088 * 089 * @param cause the {@link Throwable} that caused this {@link 090 * AmbiguousConfigurationValuesException} to be created; may be 091 * {@code null} 092 * 093 * @param configurationCoordinates the configuration coordinates in 094 * effect at the time conflicting values were found; may be {@code 095 * null} 096 * 097 * @param name the name of the configuration property for which a 098 * value was requested; must not be {@code null} 099 * 100 * @param values the conflicting values; may be {@code null} 101 * 102 * @exception NullPointerException if {@code name} is {@code null} 103 */ 104 public AmbiguousConfigurationValuesException(final String message, 105 final Throwable cause, 106 final Map<? extends String, ? extends String> configurationCoordinates, 107 final String name, 108 final Collection<? extends ConfigurationValue> values) { 109 super(message, cause); 110 if (name == null) { 111 final NullPointerException throwMe = new NullPointerException(); 112 throwMe.addSuppressed(this); 113 throw throwMe; 114 } 115 this.configurationCoordinates = configurationCoordinates == null ? Collections.emptyMap() : Collections.unmodifiableMap(configurationCoordinates); 116 this.name = name; 117 this.values = values == null ? Collections.emptySet() : values; 118 } 119 120 /** 121 * Returns the {@link Collection} of conflicting values that caused 122 * this {@link AmbiguousConfigurationValuesException} to be created. 123 * 124 * <p>This method will never return {@code null}.</p> 125 * 126 * @return a non-{@code null} {@link Collection} of {@link 127 * ConfigurationValue}s 128 */ 129 public final Collection<? extends ConfigurationValue> getValues() { 130 return this.values; 131 } 132 133 /** 134 * Returns a {@link Map} representing the configuration coordinates 135 * in effect when this {@link AmbiguousConfigurationValuesException} 136 * was created. 137 * 138 * <p>This method never returns {@code null}.</p> 139 * 140 * @return a non-{@code null} {@link Map} of configuration 141 * coordinates 142 */ 143 public final Map<? extends String, ? extends String> getCoordinates() { 144 return this.configurationCoordinates; 145 } 146 147 /** 148 * Returns the name of the configuration property for which a value was requested. 149 * 150 * <p>This method never returns {@code null}.</p> 151 * 152 * @return the name of the configuration property for which a value 153 * was requested; never {@code null} 154 */ 155 public final String getName() { 156 return this.name; 157 } 158 159 /** 160 * Returns a non-{@code null} {@link String} representation of this 161 * {@link AmbiguousConfigurationValuesException}. 162 * 163 * <p>This method never returns {@code null}.</p> 164 * 165 * <p>Overrides of this method must not return {@code null}.</p> 166 * 167 * @return a non-{@code null} {@link String} representation of this 168 * {@link AmbiguousConfigurationValuesException} 169 */ 170 @Override 171 public String toString() { 172 final StringBuilder sb = new StringBuilder(super.toString()); 173 sb.append(" "); 174 sb.append(this.getCoordinates()); 175 sb.append(" "); 176 sb.append(this.getName()); 177 sb.append(" \u27a1 "); 178 sb.append(this.getValues()); 179 return sb.toString(); 180 } 181 182}