/******************************************************************************* * Copyright (c) 2010-2014 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation *******************************************************************************/ package org.eclipse.skalli.model; import java.util.Arrays; import java.util.Collection; import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; /** * Denotes that an entity has validation issues. */ public class ValidationException extends Exception { private static final long serialVersionUID = 6730613810858572488L; private SortedSet<Issue> issues; /** * Constructs a new <code>ValidationException</code> with <code>null</code> as * its detail message. If {@link #addIssue(Issue) issues are assigned} subsequently * to this exception, the detail message is composed from the detail messages of the issue. */ public ValidationException() { super(); } /** * Constructs a new <code>ValidationException</code> with the given detail message. * If {@link #addIssue(Issue) issues are assigned} subsequently to this * exception, the detail message is composed from the given detail message and the * detail messages of the issue. */ public ValidationException(String message) { super(message); } /** * Constructs a new <code>ValidationException</code> with the specified cause and * a default detail message. * * @param cause the cause of this exception. */ public ValidationException(Throwable cause) { super(cause); } /** * Constructs a new <code>ValidationException</code> with the specified cause and * detail message. * * @param message the detail message of this exception. * @param cause the cause of this exception. */ public ValidationException(String message, Throwable cause) { super(message, cause); } /** * Creates a <code>ValidationException</code> with a single {@link Severity#FATAL} issue * that is related to a certain model extension. The issue is created with a default message. * * @param issuer the issuer that raises this issue, e.g. a validator. * @param entityId the unique identifier of an entity. * @param extension the class of a model extension, or <code>null</code>. */ public ValidationException(Class<? extends Issuer> issuer, UUID entityId, Class<? extends ExtensionEntityBase> extension) { this(issuer, entityId, extension, null, null); } /** * Creates a <code>ValidationException</code> with a single {@link Severity#FATAL} issue * that is related to a certain property of a model extension. The issue is created with a default message. * * @param issuer the issuer that raises this issue, e.g. a validator. * @param entityId the unique identifier of an entity. * @param extension the class of a model extension, or <code>null</code>. * @param propertyId the property that causes this validation issue, or <code>null</code>. */ public ValidationException(Class<? extends Issuer> issuer, UUID entityId, Class<? extends ExtensionEntityBase> extension, String propertyId) { this(issuer, entityId, extension, propertyId, null); } /** * Creates a <code>ValidationException</code> with a single {@link Severity#FATAL} issue * that is related to a certain property of a model extension. The issue is created with the given error message. * * @param issuer the issuer that raises this issue, e.g. a validator. * @param entityId the unique identifier of an entity. * @param extension the class of a model extension, or <code>null</code>. * @param propertyId the property that causes this validation issue, or <code>null</code>. * @param message the error message of the issue, or <code>null</code>. */ public ValidationException(Class<? extends Issuer> issuer, UUID entityId, Class<? extends ExtensionEntityBase> extension, String propertyId, String message) { this(new Issue(Severity.FATAL, issuer, entityId, extension, propertyId, message)); } /** * Creates a <code>ValidationException</code> from the given issues. * Note, it is recommended (but not checked!) that the issues all have {@link Severity#FATAL}. * * @param issues the issues to wrap as <code>ValidationException</code>. */ public ValidationException(Issue... issues) { this(null, issues); } /** * Creates a <code>ValidationException</code> from the given issues. * Note, it is recommended (but not checked!) that the issues all have {@link Severity#FATAL}. * * @param message the message of the exception. Note that the individual issues may have own messages. * @param issues the issues to wrap as <code>ValidationException</code>. */ public ValidationException(String message, Issue... issues) { this(message, Arrays.asList(issues)); } /** * Creates a <code>ValidationException</code> from the given collection of issues. * Note, that it is recommended (but not checked!) that the issues all have {@link Severity#FATAL}. * * @param issues the issues to wrap as <code>ValidationException</code>. */ public ValidationException(Collection<Issue> issues) { this(null, issues); } /** * Creates a <code>ValidationException</code> from the given collection ofissues. * Note, it is recommended (but not checked!) that the issues all have {@link Severity#FATAL}. * * @param message the message of the exception. Note that the individual issues may have own messages. * @param issues the issues to wrap as <code>ValidationException</code>. */ public ValidationException(String message, Collection<Issue> issues) { super(message); this.issues = new TreeSet<Issue>(issues); } /** * Adds the given <code>issue</code> to this <code>ValidationException</code>. * * @param issue the issue to add. */ public synchronized void addIssue(Issue issue) { if (issue != null) { if (issues == null) { issues = new TreeSet<Issue>(); } issues.add(issue); } } /** * Returns <code>true</code>, if issues have beed assigned to this <code>ValidationException</code>. */ public boolean hasIssues() { return issues != null && issues.size() > 0; } /** * Returns <code>true</code>, if {@link Severity#FATAL} issues have beed assigned * to this <code>ValidationException</code>. */ public boolean hasFatalIssues() { return getIssues(Severity.FATAL).size() > 0; } /** * Returns the issues assigned to this <code>ValidationException</code>. * @return a set of issues sorted by {@link Issue#compareTo(Issue)}, or an empty set. */ public SortedSet<Issue> getIssues() { if (issues == null) { return new TreeSet<Issue>(); } return issues; } /** * Returns issues that are equal of more serious than the given <code>minSeverity</code>. * * @param minSeverity the minimal severity of issues to include in the result. * @return a set of issues sorted by {@link Issue#compareTo(Issue)}, or an empty set. */ public SortedSet<Issue> getIssues(Severity minSeverity) { return Issue.filterBySeverity(issues, minSeverity); } /** * Composes the detail message string of this <code>ValidationException</code> from * the {@link Throwable#getMessage() detail message of the exception} and the * {@link Issue#getMessage() detail messages of the assigned issues}. The messages of the issues * are appended in form of a bulleted list (using <tt>"-"</tt> as bullet) in the order defined by * {@link Issue#compareTo(Issue)}. If the exception has no own detail message, then only the * list of issue messages is returned. If there is only a single issue assigned, then * {@link Issue#getMessage()} is returned without leading bullet. */ @Override public String getMessage() { return Issue.getMessage(super.getMessage(), issues); } }