001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2015 ForgeRock AS.
016 */
017
018package org.opends.server.admin.server;
019
020
021
022import static org.opends.messages.AdminMessages.*;
023
024import java.util.ArrayList;
025import java.util.Collection;
026import java.util.Collections;
027
028import org.forgerock.i18n.LocalizableMessage;
029import org.forgerock.i18n.LocalizableMessageBuilder;
030import org.opends.server.admin.DecodingException;
031import org.forgerock.util.Reject;
032
033
034
035/**
036 * This exception is thrown when the server refuses to use or delete a
037 * managed object due to one or more constraints that cannot be
038 * satisfied.
039 */
040public class ConstraintViolationException extends DecodingException {
041
042  /**
043   * Serialization ID.
044   */
045  private static final long serialVersionUID = -4902443848460011875L;
046
047  /** The server managed object. */
048  private final ServerManagedObject<?> managedObject;
049
050
051
052  /** Gets the default message. */
053  private static LocalizableMessage getDefaultMessage(Collection<LocalizableMessage> messages) {
054    Reject.ifNull(messages);
055    Reject.ifFalse(!messages.isEmpty());
056
057    if (messages.size() == 1) {
058      return ERR_CONSTRAINT_VIOLATION_EXCEPTION_SINGLE.get(messages.iterator()
059          .next());
060    } else {
061      return ERR_CONSTRAINT_VIOLATION_EXCEPTION_PLURAL
062          .get(getSingleMessage(messages));
063    }
064  }
065
066
067
068  /** Merge the messages into a single message. */
069  private static LocalizableMessage getSingleMessage(Collection<LocalizableMessage> messages) {
070    if (messages.size() == 1) {
071      return messages.iterator().next();
072    } else {
073      LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
074
075      boolean isFirst = true;
076      for (LocalizableMessage m : messages) {
077        if (!isFirst) {
078          builder.append(";  ");
079        }
080        builder.append(m);
081        isFirst = false;
082      }
083
084      return builder.toMessage();
085    }
086  }
087
088  /** The messages describing the constraint violations that occurred. */
089  private final Collection<LocalizableMessage> messages;
090
091
092
093  /**
094   * Creates a new constraint violation exception with the provided
095   * messages.
096   *
097   * @param managedObject
098   *          The server managed object which caused the constraint
099   *          violations.
100   * @param messages
101   *          The messages describing the constraint violations that
102   *          occurred (must be non-<code>null</code> and
103   *          non-empty).
104   */
105  public ConstraintViolationException(ServerManagedObject<?> managedObject,
106      Collection<LocalizableMessage> messages) {
107    super(getDefaultMessage(messages));
108
109    this.managedObject = managedObject;
110    this.messages = new ArrayList<>(messages);
111  }
112
113
114
115  /**
116   * Creates a new constraint violation exception with the provided
117   * message.
118   *
119   * @param managedObject
120   *          The server managed object which caused the constraint
121   *          violations.
122   * @param message
123   *          The message describing the constraint violation that
124   *          occurred.
125   */
126  public ConstraintViolationException(ServerManagedObject<?> managedObject,
127      LocalizableMessage message) {
128    this(managedObject, Collections.singleton(message));
129  }
130
131
132
133  /**
134   * Gets an unmodifiable collection view of the messages describing
135   * the constraint violations that occurred.
136   *
137   * @return Returns an unmodifiable collection view of the messages
138   *         describing the constraint violations that occurred.
139   */
140  public Collection<LocalizableMessage> getMessages() {
141    return Collections.unmodifiableCollection(messages);
142  }
143
144
145
146  /**
147   * Creates a single message listing all the messages combined into a
148   * single list separated by semi-colons.
149   *
150   * @return Returns a single message listing all the messages
151   *         combined into a single list separated by semi-colons.
152   */
153  public LocalizableMessage getMessagesAsSingleMessage() {
154    return getSingleMessage(messages);
155  }
156
157
158
159  /**
160   * Gets the server managed object which caused the constraint
161   * violations.
162   *
163   * @return Returns the server managed object which caused the
164   *         constraint violations.
165   */
166  public ServerManagedObject<?> getManagedObject() {
167    return managedObject;
168  }
169}