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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009-2010 Sun Microsystems, Inc. 025 * Portions copyright 2011-2015 ForgeRock AS. 026 */ 027package org.forgerock.opendj.ldap; 028 029import java.io.IOException; 030 031import org.forgerock.opendj.ldap.responses.Responses; 032import org.forgerock.opendj.ldap.responses.Result; 033 034/** 035 * Thrown when the result code returned in a Result indicates that the Request 036 * was unsuccessful. This class can be sub-classed in order to implement 037 * application specific exceptions. 038 */ 039@SuppressWarnings("serial") 040public class LdapException extends IOException { 041 042 /** 043 * Creates a new LDAP exception with the provided result code and an 044 * empty diagnostic message. 045 * 046 * @param resultCode 047 * The result code. 048 * @return The new LDAP exception. 049 * @throws IllegalArgumentException 050 * If the provided result code does not represent a failure. 051 * @throws NullPointerException 052 * If {@code resultCode} was {@code null}. 053 */ 054 public static LdapException newLdapException(ResultCode resultCode) { 055 return newLdapException(resultCode, null, null); 056 } 057 058 /** 059 * Creates a new LDAP exception with the provided result code and 060 * diagnostic message. 061 * 062 * @param resultCode 063 * The result code. 064 * @param diagnosticMessage 065 * The diagnostic message, which may be empty or {@code null} 066 * indicating that none was provided. 067 * @return The new LDAP exception. 068 * @throws IllegalArgumentException 069 * If the provided result code does not represent a failure. 070 * @throws NullPointerException 071 * If {@code resultCode} was {@code null}. 072 */ 073 public static LdapException newLdapException(ResultCode resultCode, 074 CharSequence diagnosticMessage) { 075 return newLdapException(resultCode, diagnosticMessage, null); 076 } 077 078 /** 079 * Creates a new LDAP exception with the provided result code and 080 * cause. The diagnostic message will be taken from the cause, if provided. 081 * 082 * @param resultCode 083 * The result code. 084 * @param cause 085 * The throwable cause, which may be {@code null} indicating that 086 * none was provided. 087 * @return The new LDAP exception. 088 * @throws IllegalArgumentException 089 * If the provided result code does not represent a failure. 090 * @throws NullPointerException 091 * If {@code resultCode} was {@code null}. 092 */ 093 public static LdapException newLdapException(ResultCode resultCode, Throwable cause) { 094 return newLdapException(resultCode, null, cause); 095 } 096 097 /** 098 * Creates a new LDAP exception with the provided result code, 099 * diagnostic message, and cause. 100 * 101 * @param resultCode 102 * The result code. 103 * @param diagnosticMessage 104 * The diagnostic message, which may be empty or {@code null} 105 * indicating that none was provided. 106 * @param cause 107 * The throwable cause, which may be {@code null} indicating that 108 * none was provided. 109 * @return The new LDAP exception. 110 * @throws IllegalArgumentException 111 * If the provided result code does not represent a failure. 112 * @throws NullPointerException 113 * If {@code resultCode} was {@code null}. 114 */ 115 public static LdapException newLdapException(ResultCode resultCode, 116 CharSequence diagnosticMessage, Throwable cause) { 117 final Result result = Responses.newResult(resultCode); 118 if (diagnosticMessage != null) { 119 result.setDiagnosticMessage(diagnosticMessage.toString()); 120 } else if (cause != null) { 121 result.setDiagnosticMessage(cause.getLocalizedMessage()); 122 } 123 result.setCause(cause); 124 return newLdapException(result); 125 } 126 127 /** 128 * Creates a new LDAP exception using the provided result. 129 * 130 * @param result 131 * The result whose result code indicates a failure. 132 * @return The LDAP exception wrapping the provided result. 133 * @throws IllegalArgumentException 134 * If the provided result does not represent a failure. 135 * @throws NullPointerException 136 * If {@code result} was {@code null}. 137 */ 138 public static LdapException newLdapException(final Result result) { 139 if (!result.getResultCode().isExceptional()) { 140 throw new IllegalArgumentException("Attempted to wrap a successful result: " + result); 141 } 142 143 switch (result.getResultCode().asEnum()) { 144 case ASSERTION_FAILED: 145 return new AssertionFailureException(result); 146 case AUTH_METHOD_NOT_SUPPORTED: 147 case CLIENT_SIDE_AUTH_UNKNOWN: 148 case INAPPROPRIATE_AUTHENTICATION: 149 case INVALID_CREDENTIALS: 150 return new AuthenticationException(result); 151 case AUTHORIZATION_DENIED: 152 case CONFIDENTIALITY_REQUIRED: 153 case INSUFFICIENT_ACCESS_RIGHTS: 154 case STRONG_AUTH_REQUIRED: 155 return new AuthorizationException(result); 156 case CLIENT_SIDE_USER_CANCELLED: 157 case CANCELLED: 158 return new CancelledResultException(result); 159 case CLIENT_SIDE_SERVER_DOWN: 160 case CLIENT_SIDE_CONNECT_ERROR: 161 case CLIENT_SIDE_DECODING_ERROR: 162 case CLIENT_SIDE_ENCODING_ERROR: 163 return new ConnectionException(result); 164 case ATTRIBUTE_OR_VALUE_EXISTS: 165 case NO_SUCH_ATTRIBUTE: 166 case CONSTRAINT_VIOLATION: 167 case ENTRY_ALREADY_EXISTS: 168 case INVALID_ATTRIBUTE_SYNTAX: 169 case INVALID_DN_SYNTAX: 170 case NAMING_VIOLATION: 171 case NOT_ALLOWED_ON_NONLEAF: 172 case NOT_ALLOWED_ON_RDN: 173 case OBJECTCLASS_MODS_PROHIBITED: 174 case OBJECTCLASS_VIOLATION: 175 case UNDEFINED_ATTRIBUTE_TYPE: 176 return new ConstraintViolationException(result); 177 case REFERRAL: 178 return new ReferralException(result); 179 case NO_SUCH_OBJECT: 180 case CLIENT_SIDE_NO_RESULTS_RETURNED: 181 return new EntryNotFoundException(result); 182 case CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED: 183 return new MultipleEntriesFoundException(result); 184 case CLIENT_SIDE_TIMEOUT: 185 case TIME_LIMIT_EXCEEDED: 186 return new TimeoutResultException(result); 187 default: 188 return new LdapException(result); 189 } 190 } 191 192 private static String getMessage(final Result result) { 193 if (result.getDiagnosticMessage() == null || result.getDiagnosticMessage().isEmpty()) { 194 return result.getResultCode().toString(); 195 } else { 196 return result.getResultCode() + ": " + result.getDiagnosticMessage(); 197 } 198 } 199 200 private final Result result; 201 202 /** 203 * Creates a new LDAP exception using the provided result. 204 * 205 * @param result 206 * The error result. 207 */ 208 protected LdapException(final Result result) { 209 super(getMessage(result), result.getCause()); 210 this.result = result; 211 } 212 213 /** 214 * Returns the error result which caused this exception to be thrown. The 215 * type of result returned corresponds to the expected result type of the 216 * original request. 217 * 218 * @return The error result which caused this exception to be thrown. 219 */ 220 public final Result getResult() { 221 return result; 222 } 223}