DuplicateValueException.java
package org.klojang.check.extra;
import org.klojang.check.Check;
import org.klojang.check.CommonExceptions;
import java.util.Collection;
import static java.util.stream.Collectors.joining;
import static org.klojang.check.extra.DuplicateValueException.Usage.VALUE;
/**
* Indicates that insertion into a {@linkplain java.util.Map Map}, {@linkplain java.util.Set Set} or some
* other uniqueness-enforcing data structure failed because the value to be inserted turned out to be a
* duplicate. Klojang Check does not itself ever throw a {@code DuplicateValueException}, but the error
* condition it represents is general and important enough to merit inclusion as a common exception in the
* {@link CommonExceptions} class.
*
* <blockquote><pre>{@code
* Check.that(arg).isNot(keyIn(), map, duplicateKey(arg));
* }</pre></blockquote>
*
* @see CommonExceptions#duplicateKey(Object)
*/
public class DuplicateValueException extends RuntimeException {
/**
* Symbolic constants for the intended usage of the value.
*/
public enum Usage {
/**
* The value was meant to be used as a map key.
*/
KEY,
/**
* The value was meant to be inserted into a {@code Set}.
*/
ELEMENT,
/**
* The value was meant to be used for some other uniqueness-enforcing purpose.
*/
VALUE;
private String description() {
return name().toLowerCase();
}
}
/**
* Default constructor.
*/
public DuplicateValueException() {
this(VALUE);
}
/**
* Creates a new {@code DuplicateValueException} with the specified message.
*
* @param message the message
*/
public DuplicateValueException(String message) {
super(message);
}
/**
* Creates a new {@code DuplicateValueException}.
*
* @param usage the intended usage of the value
*/
public DuplicateValueException(Usage usage) {
super(createMessage(usage));
}
/**
* Creates a new {@code DuplicateValueException} for the specified value.
*
* @param usage the intended usage of the value
* @param duplicate the duplicate value.
*/
public DuplicateValueException(Usage usage, Object duplicate) {
super(createMessage(usage, duplicate));
}
/**
* Creates a new {@code DuplicateValueException} for the specified values.
*
* @param usage the intended usage of the values
* @param duplicates the duplicate values.
*/
public DuplicateValueException(Usage usage, Collection<Object> duplicates) {
super(createMessage(usage, duplicates));
}
private static String createMessage(Usage usage) {
Check.notNull(usage, "usage");
return "duplicate " + usage.description();
}
private static String createMessage(Usage usage, Object duplicate) {
Check.notNull(usage, "usage");
return "duplicate " + usage.description() + ": " + duplicate;
}
private static String createMessage(Usage usage, Collection<Object> duplicates) {
Check.notNull(usage, "usage");
Check.notNull(usage, "duplicates");
String str = duplicates.stream().map(String::valueOf).collect(joining(", "));
return "duplicate " + usage.description() + "s: " + str;
}
}