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.client; 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.forgerock.util.Reject; 031 032 033 034/** 035 * This exception is thrown when the client or server refuses to 036 * create, delete, or modify a managed object due to one or more 037 * constraints that cannot be satisfied. 038 * <p> 039 * Operations can be rejected either by a client-side constraint 040 * violation triggered by {@link ClientConstraintHandler}, or by a 041 * server-side error. 042 * <p> 043 * For example, the Directory Server might not be able perform an 044 * operation due to some OS related problem, such as lack of disk 045 * space, or missing files. 046 */ 047public class OperationRejectedException extends AdminClientException { 048 049 /** 050 * The type of operation that caused this exception. 051 */ 052 public enum OperationType { 053 /** 054 * A managed object could not be created. 055 */ 056 CREATE, 057 058 /** 059 * A managed object could not be deleted. 060 */ 061 DELETE, 062 063 /** 064 * A managed object could not be modified. 065 */ 066 MODIFY; 067 } 068 069 /** 070 * Serialization ID. 071 */ 072 private static final long serialVersionUID = 8547688890613079044L; 073 074 075 076 /** Gets the default message. */ 077 private static LocalizableMessage getDefaultMessage(Collection<LocalizableMessage> messages) { 078 Reject.ifNull(messages); 079 Reject.ifFalse(!messages.isEmpty()); 080 081 if (messages.size() == 1) { 082 return ERR_OPERATION_REJECTED_EXCEPTION_SINGLE.get(messages.iterator() 083 .next()); 084 } else { 085 return ERR_OPERATION_REJECTED_EXCEPTION_PLURAL 086 .get(getSingleMessage(messages)); 087 } 088 } 089 090 091 092 /** Merge the messages into a single message. */ 093 private static LocalizableMessage getSingleMessage(Collection<LocalizableMessage> messages) { 094 if (messages.size() == 1) { 095 return messages.iterator().next(); 096 } else { 097 LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); 098 099 boolean isFirst = true; 100 for (LocalizableMessage m : messages) { 101 if (!isFirst) { 102 builder.append("; "); 103 } 104 builder.append(m); 105 isFirst = false; 106 } 107 108 return builder.toMessage(); 109 } 110 } 111 112 /** The messages describing the constraint violations that occurred. */ 113 private final Collection<LocalizableMessage> messages; 114 115 /** The type of operation that caused this exception. */ 116 private final OperationType type; 117 118 /** The user friendly name of the component that caused this exception. */ 119 private final LocalizableMessage ufn; 120 121 122 123 /** 124 * Creates a new operation rejected exception with a default 125 * message. 126 * 127 * @param type 128 * The type of operation that caused this exception. 129 * @param ufn 130 * The user friendly name of the component that caused this 131 * exception. 132 */ 133 public OperationRejectedException(OperationType type, LocalizableMessage ufn) { 134 this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get()); 135 } 136 137 138 139 /** 140 * Creates a new operation rejected exception with the provided 141 * messages. 142 * 143 * @param type 144 * The type of operation that caused this exception. 145 * @param ufn 146 * The user friendly name of the component that caused this 147 * exception. 148 * @param messages 149 * The messages describing the constraint violations that 150 * occurred (must be non-<code>null</code> and 151 * non-empty). 152 */ 153 public OperationRejectedException(OperationType type, LocalizableMessage ufn, 154 Collection<LocalizableMessage> messages) { 155 super(getDefaultMessage(messages)); 156 157 this.messages = new ArrayList<>(messages); 158 this.type = type; 159 this.ufn = ufn; 160 } 161 162 163 164 /** 165 * Creates a new operation rejected exception with the provided 166 * message. 167 * 168 * @param type 169 * The type of operation that caused this exception. 170 * @param ufn 171 * The user friendly name of the component that caused this 172 * exception. 173 * @param message 174 * The message describing the constraint violation that 175 * occurred. 176 */ 177 public OperationRejectedException(OperationType type, LocalizableMessage ufn, 178 LocalizableMessage message) { 179 this(type, ufn, Collections.singleton(message)); 180 } 181 182 183 184 /** 185 * Gets an unmodifiable collection view of the messages describing 186 * the constraint violations that occurred. 187 * 188 * @return Returns an unmodifiable collection view of the messages 189 * describing the constraint violations that occurred. 190 */ 191 public Collection<LocalizableMessage> getMessages() { 192 return Collections.unmodifiableCollection(messages); 193 } 194 195 196 197 /** 198 * Creates a single message listing all the messages combined into a 199 * single list separated by semi-colons. 200 * 201 * @return Returns a single message listing all the messages 202 * combined into a single list separated by semi-colons. 203 */ 204 public LocalizableMessage getMessagesAsSingleMessage() { 205 return getSingleMessage(messages); 206 } 207 208 209 210 /** 211 * Gets the type of operation that caused this exception. 212 * 213 * @return Returns the type of operation that caused this exception. 214 */ 215 public OperationType getOperationType() { 216 return type; 217 } 218 219 220 221 /** 222 * Gets the user friendly name of the component that caused this 223 * exception. 224 * 225 * @return Returns the user friendly name of the component that 226 * caused this exception. 227 */ 228 public LocalizableMessage getUserFriendlyName() { 229 return ufn; 230 } 231 232}