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    }