001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.admin.client;
029
030
031
032 import static org.opends.messages.AdminMessages.*;
033
034 import java.util.ArrayList;
035 import java.util.Collection;
036 import java.util.Collections;
037
038 import org.opends.messages.Message;
039 import org.opends.messages.MessageBuilder;
040 import org.opends.server.util.Validator;
041
042
043
044 /**
045 * This exception is thrown when the client or server refuses to
046 * create, delete, or modify a managed object due to one or more
047 * constraints that cannot be satisfied.
048 * <p>
049 * Operations can be rejected either by a client-side constraint
050 * violation triggered by {@link ClientConstraintHandler}, or by a
051 * server-side error.
052 * <p>
053 * For example, the Directory Server might not be able perform an
054 * operation due to some OS related problem, such as lack of disk
055 * space, or missing files.
056 */
057 public class OperationRejectedException extends AdminClientException {
058
059 /**
060 * The type of operation that caused this exception.
061 */
062 public enum OperationType {
063 /**
064 * A managed object could not be created.
065 */
066 CREATE,
067
068 /**
069 * A managed object could not be deleted.
070 */
071 DELETE,
072
073 /**
074 * A managed object could not be modified.
075 */
076 MODIFY;
077 }
078
079 /**
080 * Serialization ID.
081 */
082 private static final long serialVersionUID = 8547688890613079044L;
083
084
085
086 // Gets the default message.
087 private static Message getDefaultMessage(Collection<Message> messages) {
088 Validator.ensureNotNull(messages);
089 Validator.ensureTrue(!messages.isEmpty());
090
091 if (messages.size() == 1) {
092 return ERR_OPERATION_REJECTED_EXCEPTION_SINGLE.get(messages.iterator()
093 .next());
094 } else {
095 return ERR_OPERATION_REJECTED_EXCEPTION_PLURAL
096 .get(getSingleMessage(messages));
097 }
098 }
099
100
101
102 // Merge the messages into a single message.
103 private static Message getSingleMessage(Collection<Message> messages) {
104 if (messages.size() == 1) {
105 return messages.iterator().next();
106 } else {
107 MessageBuilder builder = new MessageBuilder();
108
109 boolean isFirst = true;
110 for (Message m : messages) {
111 if (!isFirst) {
112 builder.append("; ");
113 }
114 builder.append(m);
115 isFirst = false;
116 }
117
118 return builder.toMessage();
119 }
120 }
121
122 // The messages describing the constraint violations that occurred.
123 private final Collection<Message> messages;
124
125 // The type of operation that caused this exception.
126 private final OperationType type;
127
128 // The user friendly name of the component that caused this
129 // exception.
130 private final Message ufn;
131
132
133
134 /**
135 * Creates a new operation rejected exception with a default
136 * message.
137 *
138 * @param type
139 * The type of operation that caused this exception.
140 * @param ufn
141 * The user friendly name of the component that caused this
142 * exception.
143 */
144 public OperationRejectedException(OperationType type, Message ufn) {
145 this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get());
146 }
147
148
149
150 /**
151 * Creates a new operation rejected exception with the provided
152 * messages.
153 *
154 * @param type
155 * The type of operation that caused this exception.
156 * @param ufn
157 * The user friendly name of the component that caused this
158 * exception.
159 * @param messages
160 * The messages describing the constraint violations that
161 * occurred (must be non-<code>null</code> and
162 * non-empty).
163 */
164 public OperationRejectedException(OperationType type, Message ufn,
165 Collection<Message> messages) {
166 super(getDefaultMessage(messages));
167
168 this.messages = new ArrayList<Message>(messages);
169 this.type = type;
170 this.ufn = ufn;
171 }
172
173
174
175 /**
176 * Creates a new operation rejected exception with the provided
177 * message.
178 *
179 * @param type
180 * The type of operation that caused this exception.
181 * @param ufn
182 * The user friendly name of the component that caused this
183 * exception.
184 * @param message
185 * The message describing the constraint violation that
186 * occurred.
187 */
188 public OperationRejectedException(OperationType type, Message ufn,
189 Message message) {
190 this(type, ufn, Collections.singleton(message));
191 }
192
193
194
195 /**
196 * Gets an unmodifiable collection view of the messages describing
197 * the constraint violations that occurred.
198 *
199 * @return Returns an unmodifiable collection view of the messages
200 * describing the constraint violations that occurred.
201 */
202 public Collection<Message> getMessages() {
203 return Collections.unmodifiableCollection(messages);
204 }
205
206
207
208 /**
209 * Creates a single message listing all the messages combined into a
210 * single list separated by semi-colons.
211 *
212 * @return Returns a single message listing all the messages
213 * combined into a single list separated by semi-colons.
214 */
215 public Message getMessagesAsSingleMessage() {
216 return getSingleMessage(messages);
217 }
218
219
220
221 /**
222 * Gets the type of operation that caused this exception.
223 *
224 * @return Returns the type of operation that caused this exception.
225 */
226 public OperationType getOperationType() {
227 return type;
228 }
229
230
231
232 /**
233 * Gets the user friendly name of the component that caused this
234 * exception.
235 *
236 * @return Returns the user friendly name of the component that
237 * caused this exception.
238 */
239 public Message getUserFriendlyName() {
240 return ufn;
241 }
242
243 }