Author: akarasulu Date: Wed Nov 3 16:50:45 2004 New Revision: 56542 Modified: incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java Log: Changes ...
ExceptionUtils -------------- o formated exception utils ResultCodeEnum -------------- o switched out mutable unsafe String[] constants for unmodifiable Sets o added better documentation for constants o added mapping method to get a ResultCodeEnum from a Throwable o added a way to best estimate the result code based on the operation at hand and the Throwable encountered - basically this takes the set of resolved result codes for an exception and takes the intersection with the result codes for the operation; non error based codes are removed; if anything is left then it is returned otherwise the OTHER code is returned Modified: incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java ============================================================================== --- incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java (original) +++ incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/message/ResultCodeEnum.java Wed Nov 3 16:50:45 2004 @@ -17,7 +17,15 @@ package org.apache.ldap.common.message ; -import org.apache.ldap.common.util.ValuedEnum ; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.util.Iterator; +import javax.naming.*; +import javax.naming.directory.*; + +import org.apache.ldap.common.util.ValuedEnum ; +import org.apache.ldap.common.exception.LdapException; /** @@ -31,54 +39,55 @@ * are the definitions and values for error codes from section 4.1.10 of <a * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a>: * <pre><code> - * resultCode ENUMERATED { - * success (0), - * operationsError (1), - * protocolError (2), - * timeLimitExceeded (3), - * sizeLimitExceeded (4), - * compareFalse (5), - * compareTrue (6), - * authMethodNotSupported (7), - * strongAuthRequired (8), - * -- 9 reserved -- - * referral (10), -- new - * adminLimitExceeded (11), -- new - * unavailableCriticalExtension (12), -- new - * confidentialityRequired (13), -- new - * saslBindInProgress (14), -- new - * noSuchAttribute (16), - * undefinedAttributeType (17), - * inappropriateMatching (18), - * constraintViolation (19), - * attributeOrValueExists (20), - * invalidAttributeSyntax (21), - * -- 22-31 unused -- - * noSuchObject (32), - * aliasProblem (33), - * invalidDNSyntax (34), - * -- 35 reserved for undefined isLeaf -- - * aliasDereferencingProblem (36), - * -- 37-47 unused -- - * inappropriateAuthentication (48), - * invalidCredentials (49), - * insufficientAccessRights (50), - * busy (51), - * unavailable (52), - * unwillingToPerform (53), - * loopDetect (54), - * -- 55-63 unused -- - * namingViolation (64), - * objectClassViolation (65), - * notAllowedOnNonLeaf (66), - * notAllowedOnRDN (67), - * entryAlreadyExists (68), - * objectClassModsProhibited (69), - * -- 70 reserved for CLDAP -- - * affectsMultipleDSAs (71), -- new - * -- 72-79 unused -- - * other (80) }, - * -- 81-90 reserved for APIs -- + * resultCode + * ENUMERATED { + * success (0), + * operationsError (1), + * protocolError (2), + * timeLimitExceeded (3), + * sizeLimitExceeded (4), + * compareFalse (5), + * compareTrue (6), + * authMethodNotSupported (7), + * strongAuthRequired (8), + * partialResults (9), -- new + * referral (10), -- new + * adminLimitExceeded (11), -- new + * unavailableCriticalExtension (12), -- new + * confidentialityRequired (13), -- new + * saslBindInProgress (14), -- new + * noSuchAttribute (16), + * undefinedAttributeType (17), + * inappropriateMatching (18), + * constraintViolation (19), + * attributeOrValueExists (20), + * invalidAttributeSyntax (21), + * -- 22-31 unused -- + * noSuchObject (32), + * aliasProblem (33), + * invalidDNSyntax (34), + * -- 35 reserved for undefined isLeaf -- + * aliasDereferencingProblem (36), + * -- 37-47 unused -- + * inappropriateAuthentication (48), + * invalidCredentials (49), + * insufficientAccessRights (50), + * busy (51), + * unavailable (52), + * unwillingToPerform (53), + * loopDetect (54), + * -- 55-63 unused -- + * namingViolation (64), + * objectClassViolation (65), + * notAllowedOnNonLeaf (66), + * notAllowedOnRDN (67), + * entryAlreadyExists (68), + * objectClassModsProhibited (69), + * -- 70 reserved for CLDAP -- + * affectsMultipleDSAs (71), -- new + * -- 72-79 unused -- + * other (80) }, + * -- 81-90 reserved for APIs -- * </code></pre> * All the result codes with the exception of success, compareFalse and * compareTrue are to be treated as meaning the operation could not be @@ -173,9 +182,7 @@ public static final int COMPARETRUE_VAL = 6; public static final int AUTHMETHODNOTSUPPORTED_VAL = 7; public static final int STRONGAUTHREQUIRED_VAL = 8; - - // -- 9 reserved -- - + public static final int PARTIALRESULTS_VAL = 9; public static final int REFERRAL_VAL = 10; public static final int ADMINLIMITEXCEEDED_VAL = 11; public static final int UNAVAILABLECRITICALEXTENSION_VAL = 12; @@ -245,6 +252,18 @@ // operation request. // ------------------------------------------------------------------------ + + /** + * Servers sends this result code to LDAP v2 clients to refer them to + * another LDAP server. When sending this code to a client, the server + * includes a newline-delimited list of LDAP URLs that identify another + * LDAP server. If the client identifies itself as an LDAP v3 client in + * the request, servers send an REFERRAL result code instead of this + * result code. + */ + public static final ResultCodeEnum PARTIALRESULTS = + new ResultCodeEnum( "PARTIALRESULTS", PARTIALRESULTS_VAL ) ; + /** * It is returned when the client operation completed successfully without * errors. This code is one of 5 result codes that may be returned in @@ -762,32 +781,64 @@ * If the server can return an error, which is more specific than the * following general errors, then the specific error should be returned * instead. This array only contains the OTHER error code at the present - * time. + * time. The set contains: + * <ul> + * <li><a href="OTHER">OTHER</a></li> + * </ul> */ - public static final ResultCodeEnum[] GENERAL_CODES = {OTHER} ; + public static final Set GENERAL_CODES = Collections.singleton( OTHER ) ; /** * Five result codes that may be returned in LDAPResult are not used to * indicate an error. The first three codes, indicate to the client that * no further action is required in order to satisfy their request. In * contrast, the last two errors require further action by the client in - * order to complete their original operation request. - */ - public static final ResultCodeEnum[] NON_ERRONEOUS_CODES = - { - SUCCESS, COMPARETRUE, COMPAREFALSE, REFERRAL, SASLBINDINPROGRESS - } ; + * order to complete their original operation request. The set contains: + * <ul> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#COMPARETRUE">COMPARETRUE</a></li> + * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li> + * </ul> + */ + public static final Set NON_ERRONEOUS_CODES; + static + { + HashSet set = new HashSet(); + set.add( SUCCESS ); + set.add( COMPARETRUE ); + set.add( COMPAREFALSE ); + set.add( REFERRAL ); + set.add( SASLBINDINPROGRESS ); + NON_ERRONEOUS_CODES = Collections.unmodifiableSet( set ); + } /** * Contains the set of error codes associated with attribute problems. An * attribute error reports a problem related to an attribute specified by - * the client in their request message. - */ - public static final ResultCodeEnum[] ATTRIBUTE_CODES = - { - NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE, INAPPROPRIATEMATCHING, - CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS, INVALIDATTRIBUTESYNTAX - } ; + * the client in their request message. The set contains: + * <ul> + * <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li> + * <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li> + * <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * </ul> + */ + public static final Set ATTRIBUTE_CODES; + static + { + HashSet set = new HashSet(); + set.add( NOSUCHATTRIBUTE ); + set.add( UNDEFINEDATTRIBUTETYPE ); + set.add( INAPPROPRIATEMATCHING ); + set.add( CONSTRAINTVIOLATION ); + set.add( ATTRIBUTEORVALUEEXISTS ); + set.add( INVALIDATTRIBUTESYNTAX ); + ATTRIBUTE_CODES = Collections.unmodifiableSet( set ); + } /** * Stores the set of error codes associated with name problems. A name @@ -801,175 +852,721 @@ * dereferenced of the resulting name, as defined in section 12.5 of X.511 * [X511]. The matchedDN field is to be set to a zero length string with * all other result codes [RFC2251, Section 4.1.10]. - */ - public static final ResultCodeEnum[] NAME_CODES = - { - NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX - } ; + * The set contains: + * <ul> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * </ul> + */ + public static final Set NAME_CODES; + static + { + HashSet set = new HashSet(); + set.add( NOSUCHOBJECT ); + set.add( ALIASPROBLEM ); + set.add( INVALIDDNSYNTAX ); + NAME_CODES = Collections.unmodifiableSet( set ); + } /** * Stores all the result codes associated with security related problems. A * security error reports a problem in carrying out an operation for - * security reasons [X511, Section 12.7]. - */ - public static final ResultCodeEnum[] SECURITY_CODES = - { - INVALIDCREDENTIALS, STRONGAUTHREQUIRED, AUTHMETHODNOTSUPPORTED, - CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS, - ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION - } ; + * security reasons [X511, Section 12.7]. The set contains: + * <ul> + * <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li> + * <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li> + * </ul> + */ + public static final Set SECURITY_CODES; + static + { + HashSet set = new HashSet(); + set.add( INVALIDCREDENTIALS ); + set.add( STRONGAUTHREQUIRED ); + set.add( AUTHMETHODNOTSUPPORTED ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( ALIASDEREFERENCINGPROBLEM ); + set.add( INAPPROPRIATEAUTHENTICATION ); + SECURITY_CODES = Collections.unmodifiableSet( set ); + } /** * A service error reports a problem related to the provision of the - * service [X511, Section 12.8]. This array stores all error codes + * service [X511, Section 12.8]. This set stores all error codes * related to service problems. - */ - public static final ResultCodeEnum[] SERVICE_CODES = - { - BUSY, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR, OPERATIONSERROR, - TIMELIMITEXCEEDED, SIZELIMITEXCEEDED, ADMINLIMITEXCEEDED, - UNWILLINGTOPERFORM, UNAVAILABLECRITICALEXTENSION - } ; + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set SERVICE_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( PROTOCOLERROR ); + set.add( OPERATIONSERROR ); + set.add( TIMELIMITEXCEEDED ); + set.add( SIZELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( UNWILLINGTOPERFORM ); + set.add( UNAVAILABLECRITICALEXTENSION ); + SERVICE_CODES = Collections.unmodifiableSet( set ); + } /** * An update error reports problems related to attempts to add, delete, or - * modify information in the DIB [X511, Section 12.9]. This array + * modify information in the DIB [X511, Section 12.9]. This set * contains the category of update errors. - */ - public static final ResultCodeEnum[] UPDATE_CODES = - { - NAMINGVIOLATION, OBJECTCLASSVIOLATION, NOTALLOWEDONNONLEAF, - NOTALLOWEDONRDN, ENTRYALREADYEXISTS, OBJECTCLASSMODSPROHIBITED, - AFFECTSMULTIPLEDSAS - } ; + * <ul> + * <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li> + * <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li> + * <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li> + * <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li> + * <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li> + * </ul> + */ + public static final Set UPDATE_CODES; + static + { + HashSet set = new HashSet(); + set.add( NAMINGVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( NOTALLOWEDONNONLEAF ); + set.add( NOTALLOWEDONRDN ); + set.add( ENTRYALREADYEXISTS ); + set.add( OBJECTCLASSMODSPROHIBITED ); + set.add( AFFECTSMULTIPLEDSAS ); + UPDATE_CODES = Collections.unmodifiableSet( set ); + } // ------------------------------------------------------------------------ // Result Codes Categorized by Request Type // ------------------------------------------------------------------------ - /** Array of result code enumerations common to all operations. */ - public static final ResultCodeEnum[] COMMON_CODES = - { - BUSY, OTHER, REFERRAL, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR, - TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, - UNWILLINGTOPERFORM, CONFIDENTIALITYREQUIRED, - UNAVAILABLECRITICALEXTENSION - } ; - - /** Array of result code enumerations resulting from bind operations. */ - public static final ResultCodeEnum[] BIND_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, PROTOCOLERROR, - INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, - UNWILLINGTOPERFORM, SASLBINDINPROGRESS, STRONGAUTHREQUIRED, - INVALIDCREDENTIALS, AUTHMETHODNOTSUPPORTED, CONFIDENTIALITYREQUIRED, - INAPPROPRIATEAUTHENTICATION, UNAVAILABLECRITICALEXTENSION - } ; + /** + * A set of result code enumerations common to all operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set COMMON_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( PROTOCOLERROR ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( UNAVAILABLECRITICALEXTENSION ); + COMMON_CODES = Collections.unmodifiableSet( set ); + } - /** Array of result code enumerations resulting from search operations. */ - public static final ResultCodeEnum[] SEARCH_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT, - ALIASPROBLEM, PROTOCOLERROR, INVALIDDNSYNTAX, SIZELIMITEXCEEDED, - TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, - UNWILLINGTOPERFORM, INAPPROPRIATEMATCHING, CONFIDENTIALITYREQUIRED, - INSUFFICIENTACCESSRIGHTS, ALIASDEREFERENCINGPROBLEM, - UNAVAILABLECRITICALEXTENSION - } ; + /** + * A set of result code enumerations that may result from bind operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li> + * <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set BIND_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( PROTOCOLERROR ); + set.add( INVALIDDNSYNTAX ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( UNWILLINGTOPERFORM ); + set.add( SASLBINDINPROGRESS ); + set.add( STRONGAUTHREQUIRED ); + set.add( INVALIDCREDENTIALS ); + set.add( AUTHMETHODNOTSUPPORTED ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INAPPROPRIATEAUTHENTICATION ); + set.add( UNAVAILABLECRITICALEXTENSION ); + BIND_CODES = Collections.unmodifiableSet( set ); + } - /** Array of result code enumerations resulting from modify operations. */ - public static final ResultCodeEnum[] MODIFY_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT, - PROTOCOLERROR, INVALIDDNSYNTAX, NOTALLOWEDONRDN, NOSUCHATTRIBUTE, - TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, - UNWILLINGTOPERFORM, CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION, - INVALIDATTRIBUTESYNTAX, UNDEFINEDATTRIBUTETYPE, ATTRIBUTEORVALUEEXISTS, - CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS, - OBJECTCLASSMODSPROHIBITED, UNAVAILABLECRITICALEXTENSION - } ; + /** + * A set of result code enumerations that may result from search operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set SEARCH_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( NOSUCHOBJECT ); + set.add( ALIASPROBLEM ); + set.add( PROTOCOLERROR ); + set.add( INVALIDDNSYNTAX ); + set.add( SIZELIMITEXCEEDED ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( INAPPROPRIATEMATCHING ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( ALIASDEREFERENCINGPROBLEM ); + set.add( UNAVAILABLECRITICALEXTENSION ); + SEARCH_CODES = Collections.unmodifiableSet( set ); + } - /** Array of result code enumerations resulting from add operations. */ - public static final ResultCodeEnum[] ADD_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT, - PROTOCOLERROR, NAMINGVIOLATION, INVALIDDNSYNTAX, TIMELIMITEXCEEDED, - ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, UNWILLINGTOPERFORM, - ENTRYALREADYEXISTS, CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION, - INVALIDATTRIBUTESYNTAX, ATTRIBUTEORVALUEEXISTS, UNDEFINEDATTRIBUTETYPE, - CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS, - UNAVAILABLECRITICALEXTENSION - } ; + /** + * A set of result code enumerations that may result from modify operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li> + * <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li> + * <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set MODIFY_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( NOSUCHOBJECT ); + set.add( PROTOCOLERROR ); + set.add( INVALIDDNSYNTAX ); + set.add( NOTALLOWEDONRDN ); + set.add( NOSUCHATTRIBUTE ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( CONSTRAINTVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( INVALIDATTRIBUTESYNTAX ); + set.add( UNDEFINEDATTRIBUTETYPE ); + set.add( ATTRIBUTEORVALUEEXISTS ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( OBJECTCLASSMODSPROHIBITED ); + set.add( UNAVAILABLECRITICALEXTENSION ); + MODIFY_CODES = Collections.unmodifiableSet( set ); + } - /** Array of result code enumerations resulting from delete operations. */ - public static final ResultCodeEnum[] DELETE_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT, - PROTOCOLERROR, INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, - STRONGAUTHREQUIRED, UNWILLINGTOPERFORM, NOTALLOWEDONNONLEAF, - CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS, - UNAVAILABLECRITICALEXTENSION + /** + * A set of result code enumerations that may result from add operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li> + * <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set ADD_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( NOSUCHOBJECT ); + set.add( PROTOCOLERROR ); + set.add( NAMINGVIOLATION ); + set.add( INVALIDDNSYNTAX ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( ENTRYALREADYEXISTS ); + set.add( CONSTRAINTVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( INVALIDATTRIBUTESYNTAX ); + set.add( ATTRIBUTEORVALUEEXISTS ); + set.add( UNDEFINEDATTRIBUTETYPE ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( UNAVAILABLECRITICALEXTENSION ); + ADD_CODES = Collections.unmodifiableSet( set ); } ; - /** Array of result code enumerations resulting from modifyDn operations. */ - public static final ResultCodeEnum[] MODIFYDN_CODES = - { - BUSY, OTHER, SUCCESS, REFERRAL, LOOPDETECT, UNAVAILABLE, NOSUCHOBJECT, - PROTOCOLERROR, INVALIDDNSYNTAX, NAMINGVIOLATION, TIMELIMITEXCEEDED, - ENTRYALREADYEXISTS, ADMINLIMITEXCEEDED, STRONGAUTHREQUIRED, - UNWILLINGTOPERFORM, NOTALLOWEDONNONLEAF, AFFECTSMULTIPLEDSAS, - CONSTRAINTVIOLATION, OBJECTCLASSVIOLATION, CONFIDENTIALITYREQUIRED, - INSUFFICIENTACCESSRIGHTS, UNAVAILABLECRITICALEXTENSION + /** + * A set of result code enumerations that may result from delete operations. + * The set may contain: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set DELETE_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( NOSUCHOBJECT ); + set.add( PROTOCOLERROR ); + set.add( INVALIDDNSYNTAX ); + set.add( TIMELIMITEXCEEDED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( NOTALLOWEDONNONLEAF ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( UNAVAILABLECRITICALEXTENSION ); + DELETE_CODES = Collections.unmodifiableSet( set ); } ; - /** Array of result code enumerations resulting from compare operations. */ - public static final ResultCodeEnum[] COMPARE_CODES = - { - BUSY, OTHER, REFERRAL, LOOPDETECT, UNAVAILABLE, COMPARETRUE, - COMPAREFALSE, NOSUCHOBJECT, PROTOCOLERROR, NOSUCHATTRIBUTE, - INVALIDDNSYNTAX, TIMELIMITEXCEEDED, ADMINLIMITEXCEEDED, - STRONGAUTHREQUIRED, UNWILLINGTOPERFORM, INVALIDATTRIBUTESYNTAX, - CONFIDENTIALITYREQUIRED, INSUFFICIENTACCESSRIGHTS, - UNAVAILABLECRITICALEXTENSION - } ; + /** + * A set of result code enumerations resulting from modifyDn operations. + * The set contains: + * <ul> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li> + * <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * </ul> + */ + public static final Set MODIFYDN_CODES; + static + { + HashSet set = new HashSet(); + set.add( BUSY ); + set.add( OTHER ); + set.add( SUCCESS ); + set.add( REFERRAL ); + set.add( LOOPDETECT ); + set.add( UNAVAILABLE ); + set.add( NOSUCHOBJECT ); + set.add( PROTOCOLERROR ); + set.add( INVALIDDNSYNTAX ); + set.add( NAMINGVIOLATION ); + set.add( TIMELIMITEXCEEDED ); + set.add( ENTRYALREADYEXISTS ); + set.add( ADMINLIMITEXCEEDED ); + set.add( STRONGAUTHREQUIRED ); + set.add( UNWILLINGTOPERFORM ); + set.add( NOTALLOWEDONNONLEAF ); + set.add( AFFECTSMULTIPLEDSAS ); + set.add( CONSTRAINTVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( UNAVAILABLECRITICALEXTENSION ); + MODIFYDN_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of result code enumerations that may result from compare + * operations. The set contains: + * <ul> + * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li> + * <li><a href="#COMPARETRUE">COMPARETRUE</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * </ul> + */ + public static final Set COMPARE_CODES; + static + { + HashSet set = new HashSet(); + set.add( OPERATIONSERROR ); + set.add( PROTOCOLERROR ); + set.add( TIMELIMITEXCEEDED ); + set.add( COMPAREFALSE ); + set.add( COMPARETRUE ); + set.add( STRONGAUTHREQUIRED ); + set.add( ADMINLIMITEXCEEDED ); + set.add( UNAVAILABLECRITICALEXTENSION ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( NOSUCHATTRIBUTE ); + set.add( INVALIDATTRIBUTESYNTAX ); + set.add( NOSUCHOBJECT ); + set.add( INVALIDDNSYNTAX ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( BUSY ); + set.add( UNAVAILABLE ); + set.add( UNWILLINGTOPERFORM ); + set.add( LOOPDETECT ); + set.add( REFERRAL ); + set.add( OTHER ); + COMPARE_CODES = Collections.unmodifiableSet( set ); + } - /** Array of result code enumerations resulting from extended operations. */ - public static final ResultCodeEnum[] EXTENDED_CODES = - { - SUCCESS, OPERATIONSERROR, PROTOCOLERROR, TIMELIMITEXCEEDED, - SIZELIMITEXCEEDED, COMPAREFALSE, COMPARETRUE, AUTHMETHODNOTSUPPORTED, - STRONGAUTHREQUIRED, REFERRAL, ADMINLIMITEXCEEDED, - UNAVAILABLECRITICALEXTENSION, CONFIDENTIALITYREQUIRED, - SASLBINDINPROGRESS, NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE, - INAPPROPRIATEMATCHING, CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS, - INVALIDATTRIBUTESYNTAX, NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX, - ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION, - INVALIDCREDENTIALS, INSUFFICIENTACCESSRIGHTS, BUSY, UNAVAILABLE, - UNWILLINGTOPERFORM, LOOPDETECT, NAMINGVIOLATION, OBJECTCLASSVIOLATION, - NOTALLOWEDONNONLEAF, NOTALLOWEDONRDN, ENTRYALREADYEXISTS, - OBJECTCLASSMODSPROHIBITED, AFFECTSMULTIPLEDSAS, OTHER, - } ; + /** + * A set of result code enumerations that could result from extended + * operations. The set contains: + * <ul> + * <li></li> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li> + * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li> + * <li><a href="#COMPARETRUE">COMPARETRUE</a></li> + * <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li> + * <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li> + * <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li> + * <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li> + * <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li> + * <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li> + * <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li> + * <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li> + * <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li> + * <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * </ul> + */ + public static final Set EXTENDED_CODES; + static + { + HashSet set = new HashSet(); + set.add( SUCCESS ); + set.add( OPERATIONSERROR ); + set.add( PROTOCOLERROR ); + set.add( TIMELIMITEXCEEDED ); + set.add( SIZELIMITEXCEEDED ); + set.add( COMPAREFALSE ); + set.add( COMPARETRUE ); + set.add( AUTHMETHODNOTSUPPORTED ); + set.add( STRONGAUTHREQUIRED ); + set.add( REFERRAL ); + set.add( ADMINLIMITEXCEEDED ); + set.add( UNAVAILABLECRITICALEXTENSION ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( SASLBINDINPROGRESS ); + set.add( NOSUCHATTRIBUTE ); + set.add( UNDEFINEDATTRIBUTETYPE ); + set.add( INAPPROPRIATEMATCHING ); + set.add( CONSTRAINTVIOLATION ); + set.add( ATTRIBUTEORVALUEEXISTS ); + set.add( INVALIDATTRIBUTESYNTAX ); + set.add( NOSUCHOBJECT ); + set.add( ALIASPROBLEM ); + set.add( INVALIDDNSYNTAX ); + set.add( ALIASDEREFERENCINGPROBLEM ); + set.add( INAPPROPRIATEAUTHENTICATION ); + set.add( INVALIDCREDENTIALS ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( BUSY ); + set.add( UNAVAILABLE ); + set.add( UNWILLINGTOPERFORM ); + set.add( LOOPDETECT ); + set.add( NAMINGVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( NOTALLOWEDONNONLEAF ); + set.add( NOTALLOWEDONRDN ); + set.add( ENTRYALREADYEXISTS ); + set.add( OBJECTCLASSMODSPROHIBITED ); + set.add( AFFECTSMULTIPLEDSAS ); + set.add( OTHER ); + EXTENDED_CODES = Collections.unmodifiableSet( set ); + } // ------------------------------------------------------------------------ // All Result Codes // ------------------------------------------------------------------------ - /** Array of all result code enumerations. */ - public static final ResultCodeEnum[] ALL_CODES = - { - SUCCESS, OPERATIONSERROR, PROTOCOLERROR, TIMELIMITEXCEEDED, - SIZELIMITEXCEEDED, COMPAREFALSE, COMPARETRUE, AUTHMETHODNOTSUPPORTED, - STRONGAUTHREQUIRED, REFERRAL, ADMINLIMITEXCEEDED, - UNAVAILABLECRITICALEXTENSION, CONFIDENTIALITYREQUIRED, - SASLBINDINPROGRESS, NOSUCHATTRIBUTE, UNDEFINEDATTRIBUTETYPE, - INAPPROPRIATEMATCHING, CONSTRAINTVIOLATION, ATTRIBUTEORVALUEEXISTS, - INVALIDATTRIBUTESYNTAX, NOSUCHOBJECT, ALIASPROBLEM, INVALIDDNSYNTAX, - ALIASDEREFERENCINGPROBLEM, INAPPROPRIATEAUTHENTICATION, - INVALIDCREDENTIALS, INSUFFICIENTACCESSRIGHTS, BUSY, UNAVAILABLE, - UNWILLINGTOPERFORM, LOOPDETECT, NAMINGVIOLATION, OBJECTCLASSVIOLATION, - NOTALLOWEDONNONLEAF, NOTALLOWEDONRDN, ENTRYALREADYEXISTS, - OBJECTCLASSMODSPROHIBITED, AFFECTSMULTIPLEDSAS, OTHER - } ; + /** + * Set of all result code enumerations. The set contains: + * <ul> + * <li><a href="#SUCCESS">SUCCESS</a></li> + * <li><a href="#OPERATIONSERROR">OPERATIONSERROR</a></li> + * <li><a href="#PROTOCOLERROR">PROTOCOLERROR</a></li> + * <li><a href="#TIMELIMITEXCEEDED">TIMELIMITEXCEEDED</a></li> + * <li><a href="#SIZELIMITEXCEEDED">SIZELIMITEXCEEDED</a></li> + * <li><a href="#COMPAREFALSE">COMPAREFALSE</a></li> + * <li><a href="#COMPARETRUE">COMPARETRUE</a></li> + * <li><a href="#AUTHMETHODNOTSUPPORTED">AUTHMETHODNOTSUPPORTED</a></li> + * <li><a href="#STRONGAUTHREQUIRED">STRONGAUTHREQUIRED</a></li> + * <li><a href="#PARTIALRESULTS">PARTIALRESULTS</a></li> + * <li><a href="#REFERRAL">REFERRAL</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">ADMINLIMITEXCEEDED</a></li> + * <li><a href="#UNAVAILABLECRITICALEXTENSION">UNAVAILABLECRITICALEXTENSION</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">CONFIDENTIALITYREQUIRED</a></li> + * <li><a href="#SASLBINDINPROGRESS">SASLBINDINPROGRESS</a></li> + * <li><a href="#NOSUCHATTRIBUTE">NOSUCHATTRIBUTE</a></li> + * <li><a href="#UNDEFINEDATTRIBUTETYPE">UNDEFINEDATTRIBUTETYPE</a></li> + * <li><a href="#INAPPROPRIATEMATCHING">INAPPROPRIATEMATCHING</a></li> + * <li><a href="#CONSTRAINTVIOLATION">CONSTRAINTVIOLATION</a></li> + * <li><a href="#ATTRIBUTEORVALUEEXISTS">ATTRIBUTEORVALUEEXISTS</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">INVALIDATTRIBUTESYNTAX</a></li> + * <li><a href="#NOSUCHOBJECT">NOSUCHOBJECT</a></li> + * <li><a href="#ALIASPROBLEM">ALIASPROBLEM</a></li> + * <li><a href="#INVALIDDNSYNTAX">INVALIDDNSYNTAX</a></li> + * <li><a href="#ALIASDEREFERENCINGPROBLEM">ALIASDEREFERENCINGPROBLEM</a></li> + * <li><a href="#INAPPROPRIATEAUTHENTICATION">INAPPROPRIATEAUTHENTICATION</a></li> + * <li><a href="#INVALIDCREDENTIALS">INVALIDCREDENTIALS</a></li> + * <li><a href="#INSUFFICIENTACCESSRIGHTS">INSUFFICIENTACCESSRIGHTS</a></li> + * <li><a href="#BUSY">BUSY</a></li> + * <li><a href="#UNAVAILABLE">UNAVAILABLE</a></li> + * <li><a href="#UNWILLINGTOPERFORM">UNWILLINGTOPERFORM</a></li> + * <li><a href="#LOOPDETECT">LOOPDETECT</a></li> + * <li><a href="#NAMINGVIOLATION">NAMINGVIOLATION</a></li> + * <li><a href="#OBJECTCLASSVIOLATION">OBJECTCLASSVIOLATION</a></li> + * <li><a href="#NOTALLOWEDONNONLEAF">NOTALLOWEDONNONLEAF</a></li> + * <li><a href="#NOTALLOWEDONRDN">NOTALLOWEDONRDN</a></li> + * <li><a href="#ENTRYALREADYEXISTS">ENTRYALREADYEXISTS</a></li> + * <li><a href="#OBJECTCLASSMODSPROHIBITED">OBJECTCLASSMODSPROHIBITED</a></li> + * <li><a href="#AFFECTSMULTIPLEDSAS">AFFECTSMULTIPLEDSAS</a></li> + * <li><a href="#OTHER">OTHER</a></li> + * </ul> + */ + public static final Set ALL_CODES; + static + { + HashSet set = new HashSet(); + set.add( SUCCESS ); + set.add( OPERATIONSERROR ); + set.add( PROTOCOLERROR ); + set.add( TIMELIMITEXCEEDED ); + set.add( SIZELIMITEXCEEDED ); + set.add( COMPAREFALSE ); + set.add( COMPARETRUE ); + set.add( AUTHMETHODNOTSUPPORTED ); + set.add( STRONGAUTHREQUIRED ); + set.add( PARTIALRESULTS ); + set.add( REFERRAL ); + set.add( ADMINLIMITEXCEEDED ); + set.add( UNAVAILABLECRITICALEXTENSION ); + set.add( CONFIDENTIALITYREQUIRED ); + set.add( SASLBINDINPROGRESS ); + set.add( NOSUCHATTRIBUTE ); + set.add( UNDEFINEDATTRIBUTETYPE ); + set.add( INAPPROPRIATEMATCHING ); + set.add( CONSTRAINTVIOLATION ); + set.add( ATTRIBUTEORVALUEEXISTS ); + set.add( INVALIDATTRIBUTESYNTAX ); + set.add( NOSUCHOBJECT ); + set.add( ALIASPROBLEM ); + set.add( INVALIDDNSYNTAX ); + set.add( ALIASDEREFERENCINGPROBLEM ); + set.add( INAPPROPRIATEAUTHENTICATION ); + set.add( INVALIDCREDENTIALS ); + set.add( INSUFFICIENTACCESSRIGHTS ); + set.add( BUSY ); + set.add( UNAVAILABLE ); + set.add( UNWILLINGTOPERFORM ); + set.add( LOOPDETECT ); + set.add( NAMINGVIOLATION ); + set.add( OBJECTCLASSVIOLATION ); + set.add( NOTALLOWEDONNONLEAF ); + set.add( NOTALLOWEDONRDN ); + set.add( ENTRYALREADYEXISTS ); + set.add( OBJECTCLASSMODSPROHIBITED ); + set.add( AFFECTSMULTIPLEDSAS ); + set.add( OTHER ); + ALL_CODES = Collections.unmodifiableSet( set ); + } // ------------------------------------------------------------------------ // Constructors @@ -995,10 +1592,10 @@ * * @see #GENERAL_CODES */ - public static ResultCodeEnum[] getGeneralCodes() + public static Set getGeneralCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) GENERAL_CODES.clone() ; + return GENERAL_CODES; } @@ -1010,10 +1607,10 @@ * * @see #NON_ERRONEOUS_CODES */ - public static ResultCodeEnum[] getNonErroneousCodes() + public static Set getNonErroneousCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) NON_ERRONEOUS_CODES.clone() ; + return NON_ERRONEOUS_CODES; } @@ -1025,10 +1622,10 @@ * * @see #ATTRIBUTE_CODES */ - public static ResultCodeEnum[] getAttributeCodes() + public static Set getAttributeCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) ATTRIBUTE_CODES.clone() ; + return ATTRIBUTE_CODES; } @@ -1040,10 +1637,10 @@ * * @see #NAME_CODES */ - public static ResultCodeEnum[] getNameCodes() + public static Set getNameCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) NAME_CODES.clone() ; + return NAME_CODES; } @@ -1055,10 +1652,10 @@ * * @see #SECURITY_CODES */ - public static ResultCodeEnum[] getSecurityCodes() + public static Set getSecurityCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) SECURITY_CODES.clone() ; + return SECURITY_CODES; } @@ -1070,10 +1667,10 @@ * * @see #SERVICE_CODES */ - public static ResultCodeEnum[] getServiceCodes() + public static Set getServiceCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) SERVICE_CODES.clone() ; + return SERVICE_CODES; } @@ -1085,10 +1682,10 @@ * * @see #UPDATE_CODES */ - public static ResultCodeEnum[] getUpdateCodes() + public static Set getUpdateCodes() { // Must clone to prevent array content alterations - return ( ResultCodeEnum[] ) UPDATE_CODES.clone() ; + return UPDATE_CODES; } @@ -1099,9 +1696,9 @@ * * @see #COMMON_CODES */ - public static ResultCodeEnum[] getCommonCodes() + public static Set getCommonCodes() { - return ( ResultCodeEnum[] ) COMMON_CODES.clone() ; + return COMMON_CODES; } @@ -1113,9 +1710,9 @@ * * @see #BIND_CODES */ - public static ResultCodeEnum[] getBindCodes() + public static Set getBindCodes() { - return ( ResultCodeEnum[] ) BIND_CODES.clone() ; + return BIND_CODES; } @@ -1127,9 +1724,9 @@ * * @see #SEARCH_CODES */ - public static ResultCodeEnum[] getSearchCodes() + public static Set getSearchCodes() { - return ( ResultCodeEnum[] ) SEARCH_CODES.clone() ; + return SEARCH_CODES; } @@ -1141,9 +1738,9 @@ * * @see #MODIFY_CODES */ - public static ResultCodeEnum[] getModifyCodes() + public static Set getModifyCodes() { - return ( ResultCodeEnum[] ) MODIFY_CODES.clone() ; + return MODIFY_CODES; } @@ -1154,9 +1751,9 @@ * * @see #ADD_CODES */ - public static ResultCodeEnum[] getAddCodes() + public static Set getAddCodes() { - return ( ResultCodeEnum[] ) ADD_CODES.clone() ; + return ADD_CODES; } @@ -1168,9 +1765,9 @@ * * @see #DELETE_CODES */ - public static ResultCodeEnum[] getDeleteCodes() + public static Set getDeleteCodes() { - return ( ResultCodeEnum[] ) DELETE_CODES.clone() ; + return DELETE_CODES; } @@ -1182,9 +1779,9 @@ * * @see #MODIFYDN_CODES */ - public static ResultCodeEnum[] getModifyDnCodes() + public static Set getModifyDnCodes() { - return ( ResultCodeEnum[] ) MODIFYDN_CODES.clone() ; + return MODIFYDN_CODES; } @@ -1196,9 +1793,9 @@ * * @see #COMPARE_CODES */ - public static ResultCodeEnum[] getCompareCodes() + public static Set getCompareCodes() { - return ( ResultCodeEnum[] ) COMPARE_CODES.clone() ; + return COMPARE_CODES; } @@ -1210,9 +1807,9 @@ * * @see #EXTENDED_CODES */ - public static ResultCodeEnum[] getExtendedCodes() + public static Set getExtendedCodes() { - return ( ResultCodeEnum[] ) EXTENDED_CODES.clone() ; + return EXTENDED_CODES; } @@ -1223,10 +1820,10 @@ * * @see #ALL_CODES */ - public static ResultCodeEnum[] getAllCodes() + public static Set getAllCodes() { // Must clone to prevent array content tampering. - return ( ResultCodeEnum[] ) ALL_CODES.clone() ; + return ALL_CODES; } @@ -1238,13 +1835,13 @@ * Gets the result code enumeration object associated with a result code * value. * - * @param a_value the result code constant. + * @param value the result code constant. * @return the result code with a_value, or null if no enumeration exists * for an (undefined) value. */ - public static ResultCodeEnum getResultCodeEnum( int a_value ) + public static ResultCodeEnum getResultCodeEnum( int value ) { - switch ( a_value ) + switch ( value ) { case ( SUCCESS_VAL ): return SUCCESS ; @@ -1273,7 +1870,8 @@ case ( STRONGAUTHREQUIRED_VAL ): return STRONGAUTHREQUIRED ; - // -- 9 reserved -- + case ( PARTIALRESULTS_VAL ): + return PARTIALRESULTS ; case ( REFERRAL_VAL ): return REFERRAL ; @@ -1384,5 +1982,579 @@ default: return null ; } + } + + + // ------------------------------------------------------------------------ + // JNDI Exception to ResultCodeEnum Mappings + // ------------------------------------------------------------------------ + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] NamingException}. + * + * <ul> + * <li><a href="#OPERATIONSERROR">operationsError(1)</a></li> + * <li><a href="#ALIASPROBLEM">aliasProblem(33)</a></li> + * <li><a href="#ALIASDEREFERENCINGPROBLEM">aliasDereferencingProblem(36)</a></li> + * <li><a href="#LOOPDETECT">loopDetect(54)</a></li> + * <li><a href="#AFFECTSMULTIPLEDSAS">affectsMultipleDSAs(71)</a></li> + * <li><a href="#OTHER">other(80)</a></li> + * </ul> + */ + public static final Set NAMINGEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.OPERATIONSERROR ); + set.add( ResultCodeEnum.ALIASPROBLEM ); + set.add( ResultCodeEnum.ALIASDEREFERENCINGPROBLEM ); + set.add( ResultCodeEnum.LOOPDETECT ); + set.add( ResultCodeEnum.AFFECTSMULTIPLEDSAS ); + set.add( ResultCodeEnum.OTHER ); + NAMINGEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#AUTHMETHODNOTSUPPORTED">authMethodNotSupported(7)</a></li> + * <li><a href="#STRONGAUTHREQUIRED">strongAuthRequired(8)</a></li> + * <li><a href="#CONFIDENTIALITYREQUIRED">confidentialityRequired(13)</a></li> + * <li><a href="#INAPPROPRIATEAUTHENTICATION">inappropriateAuthentication(48)</a></li> + * </ul> + */ + public static final Set AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.AUTHMETHODNOTSUPPORTED ); + set.add( ResultCodeEnum.STRONGAUTHREQUIRED ); + set.add( ResultCodeEnum.CONFIDENTIALITYREQUIRED ); + set.add( ResultCodeEnum.INAPPROPRIATEAUTHENTICATION ); + AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#BUSY">busy(51)</a></li> + * <li><a href="#UNAVAILABLE">unavailable(52)</a></li> + * </ul> + */ + public static final Set SERVICEUNAVAILABLE_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.BUSY ); + set.add( ResultCodeEnum.UNAVAILABLE ); + SERVICEUNAVAILABLE_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#CONSTRAINTVIOLATION">constraintViolation(19)</a></li> + * <li><a href="#INVALIDATTRIBUTESYNTAX">invalidAttributeSyntax(21)</a></li> + * </ul> + */ + public static final Set INVALIDATTRIBUTEVALUEEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.CONSTRAINTVIOLATION ); + set.add( ResultCodeEnum.INVALIDATTRIBUTESYNTAX ); + INVALIDATTRIBUTEVALUEEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#PARTIALRESULTS">partialResults(9)</a></li> + * <li><a href="#REFERRAL">referral(10)</a></li> + * </ul> + */ + public static final Set PARTIALRESULTSEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.PARTIALRESULTS ); + set.add( ResultCodeEnum.REFERRAL ); + PARTIALRESULTSEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#REFERRAL">referal(9)</a></li> + * <li><a href="#ADMINLIMITEXCEEDED">adminLimitExceeded(11)</a></li> + * </ul> + */ + public static final Set LIMITEXCEEDEDEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.REFERRAL ); + set.add( ResultCodeEnum.ADMINLIMITEXCEEDED ); + LIMITEXCEEDEDEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#UNAVAILABLECRITICALEXTENTION">unavailableCriticalExtention(12)</a></li> + * <li><a href="#UNWILLINGTOPERFORM">unwillingToPerform(53)</a></li> + * </ul> + */ + public static final Set OPERATIONNOTSUPPOERTEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.UNAVAILABLECRITICALEXTENSION ); + set.add( ResultCodeEnum.UNWILLINGTOPERFORM ); + OPERATIONNOTSUPPOERTEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] Exception}. + * + * <ul> + * <li><a href="#INVALIDDNSYNTAX">invalidDNSyntax(34)</a></li> + * <li><a href="#NAMINGVIOLATION">namingViolation(64)</a></li> + * </ul> + */ + public static final Set INVALIDNAMEEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.INVALIDDNSYNTAX ); + set.add( ResultCodeEnum.NAMINGVIOLATION ); + INVALIDNAMEEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + /** + * A set of ResultCodes containing those that may correspond to a + * [EMAIL PROTECTED] javax.naming.directory.SchemaViolationException}. + * + * <ul> + * <li><a href="#OBJECTCLASSVIOLATION">objectClassViolation(65)</a></li> + * <li><a href="#NOTALLOWEDONRDN">notAllowedOnRDN(67)</a></li> + * <li><a href="#OBJECTCLASSMODSPROHIBITED">objectClassModsProhibited(69)</a></li> + * </ul> + */ + public static final Set SCHEMAVIOLATIONEXCEPTION_CODES; + static + { + HashSet set = new HashSet(); + set.add( ResultCodeEnum.OBJECTCLASSVIOLATION ); + set.add( ResultCodeEnum.NOTALLOWEDONRDN ); + set.add( ResultCodeEnum.OBJECTCLASSMODSPROHIBITED ); + SCHEMAVIOLATIONEXCEPTION_CODES = Collections.unmodifiableSet( set ); + } + + + /** + * Takes a guess at the result code to use if it cannot figure it out from + * known Throwable to result code mappings. Some however are ambiguous + * mapping the same Throwable to multiple codes. If no code can be resolved + * then [EMAIL PROTECTED] ResultCodeEnum#OTHER} is returned. + * + * @param t the throwable to estimate a result code for + * @param type the type of operation being performed + * @return the result code or a good estimate of one + */ + public static ResultCodeEnum getBestEstimate( Throwable t, MessageTypeEnum type ) + { + Set set = getResultCodes( t ); + + if ( set.isEmpty() ) + { + return ResultCodeEnum.OTHER; + } + + if ( set.size() == 1 ) + { + return ( ResultCodeEnum ) set.iterator().next(); + } + + if ( type == null ) + { + HashSet tmp = new HashSet(); + tmp.addAll( set ); + tmp.removeAll( NON_ERRONEOUS_CODES ); + + if ( tmp.isEmpty() ) + { + return ResultCodeEnum.OTHER; + } + + return ( ResultCodeEnum ) tmp.iterator().next(); + } + + Set candidates = Collections.EMPTY_SET; + switch( type.getValue() ) + { + case( MessageTypeEnum.ABANDONREQUEST_VAL ): + return ( ResultCodeEnum ) set.iterator().next(); + case( MessageTypeEnum.ADDREQUEST_VAL ): + candidates = intersection( set, ADD_CODES ); + break; + case( MessageTypeEnum.ADDRESPONSE_VAL ): + candidates = intersection( set, ADD_CODES ); + break; + case( MessageTypeEnum.BINDREQUEST_VAL ): + candidates = intersection( set, BIND_CODES ); + break; + case( MessageTypeEnum.BINDRESPONSE_VAL ): + candidates = intersection( set, BIND_CODES ); + break; + case( MessageTypeEnum.COMPAREREQUEST_VAL ): + candidates = intersection( set, COMPARE_CODES ); + break; + case( MessageTypeEnum.COMPARERESPONSE_VAL ): + candidates = intersection( set, COMPARE_CODES ); + break; + case( MessageTypeEnum.DELREQUEST_VAL ): + candidates = intersection( set, DELETE_CODES ); + break; + case( MessageTypeEnum.DELRESPONSE_VAL ): + candidates = intersection( set, DELETE_CODES ); + break; + case( MessageTypeEnum.EXTENDEDREQ_VAL ): + candidates = intersection( set, EXTENDED_CODES ); + break; + case( MessageTypeEnum.EXTENDEDRESP_VAL ): + candidates = intersection( set, EXTENDED_CODES ); + break; + case( MessageTypeEnum.MODDNREQUEST_VAL ): + candidates = intersection( set, MODIFYDN_CODES ); + break; + case( MessageTypeEnum.MODDNRESPONSE_VAL ): + candidates = intersection( set, MODIFYDN_CODES ); + break; + case( MessageTypeEnum.MODIFYREQUEST_VAL ): + candidates = intersection( set, MODIFY_CODES ); + break; + case( MessageTypeEnum.MODIFYRESPONSE_VAL ): + candidates = intersection( set, MODIFY_CODES ); + break; + case( MessageTypeEnum.SEARCHREQUEST_VAL ): + candidates = intersection( set, SEARCH_CODES ); + break; + case( MessageTypeEnum.SEARCHRESDONE_VAL ): + candidates = intersection( set, SEARCH_CODES ); + break; + case( MessageTypeEnum.SEARCHRESENTRY_VAL ): + candidates = intersection( set, SEARCH_CODES ); + break; + case( MessageTypeEnum.SEARCHRESREF_VAL ): + candidates = intersection( set, SEARCH_CODES ); + break; + case( MessageTypeEnum.UNBINDREQUEST_VAL ): + return ( ResultCodeEnum ) set.iterator().next(); + } + + // we don't want any codes that do not have anything to do w/ errors + candidates.removeAll( NON_ERRONEOUS_CODES ); + + if ( candidates.isEmpty() ) + { + return ResultCodeEnum.OTHER; + } + + return ( ResultCodeEnum ) candidates.iterator().next(); + } + + + private static Set intersection( Set s1, Set s2 ) + { + if ( s1.isEmpty() || s2.isEmpty() ) + { + return Collections.EMPTY_SET; + } + + Set intersection = new HashSet(); + if ( s1.size() <= s2.size() ) + { + Iterator items = s1.iterator(); + while ( items.hasNext() ) + { + Object item = items.next(); + if ( s2.contains( item ) ) + { + intersection.add( item ); + } + } + } + else + { + Iterator items = s2.iterator(); + while ( items.hasNext() ) + { + Object item = items.next(); + if ( s1.contains( item ) ) + { + intersection.add( item ); + } + } + } + + return intersection; + } + + + /** + * Gets the set of result codes a Throwable may map to. If the throwable + * does not map to any result code at all an empty set is returned. The + * following Throwables and their subclasses map to result codes: + * + * <pre> + * + * Unambiguous Exceptions + * ====================== + * + * CommunicationException ==> operationsError(1) + * TimeLimitExceededException ==> timeLimitExceeded(3) + * SizeLimitExceededException ==> sizeLimitExceeded(4) + * AuthenticationException ==> invalidCredentials(49) + * NoPermissionException ==> insufficientAccessRights(50) + * NoSuchAttributeException ==> noSuchAttribute(16) + * InvalidAttributeIdentifierException ==> undefinedAttributeType(17) + * InvalidSearchFilterException ==> inappropriateMatching(18) + * AttributeInUseException ==> attributeOrValueExists(20) + * NameNotFoundException ==> noSuchObject(32) + * NameAlreadyBoundException ==> entryAlreadyExists(68) + * ContextNotEmptyException ==> notAllowedOnNonLeaf(66) + * + * + * Ambiguous Exceptions + * ==================== + * + * NamingException + * --------------- + * operationsError(1) + * aliasProblem(33) + * aliasDereferencingProblem(36) + * loopDetect(54) + * affectsMultipleDSAs(71) + * other(80) + * + * AuthenticationNotSupportedException + * ----------------------------------- + * authMethodNotSupported (7) + * strongAuthRequired (8) + * confidentialityRequired (13) + * inappropriateAuthentication(48) + * + * ServiceUnavailableException + * --------------------------- + * busy(51) + * unavailable(52) + * + * InvalidAttributeValueException + * ------------------------------ + * constraintViolation(19) + * invalidAttributeSyntax(21) + * + * PartialResultException + * ---------------------- + * partialResults(9) + * referral(10) + * + * LimitExceededException + * ---------------------- + * referal(9) + * adminLimitExceeded(11) + * + * OperationNotSupportedException + * ------------------------------ + * unavailableCriticalExtention(12) + * unwillingToPerform(53) + * + * InvalidNameException + * -------------------- + * invalidDNSyntax(34) + * namingViolation(64) + * + * SchemaViolationException + * ------------------------ + * objectClassViolation(65) + * notAllowedOnRDN(67) + * objectClassModsProhibited(69) + * + * </pre> + * + * @param t the Throwable to find the result code mappings for + * @return the set of mapped result codes + */ + public static Set getResultCodes( Throwable t ) + { + ResultCodeEnum rc; + if ( ( rc = getResultCode( t ) ) != null ) + { + return Collections.singleton( rc ); + } + + if ( t instanceof SchemaViolationException ) + { + return SCHEMAVIOLATIONEXCEPTION_CODES; + } + + if ( t instanceof InvalidNameException ) + { + return INVALIDNAMEEXCEPTION_CODES; + } + + if ( t instanceof OperationNotSupportedException ) + { + return OPERATIONNOTSUPPOERTEXCEPTION_CODES; + } + + if ( t instanceof LimitExceededException ) + { + return LIMITEXCEEDEDEXCEPTION_CODES; + } + + if ( t instanceof PartialResultException ) + { + return PARTIALRESULTSEXCEPTION_CODES; + } + + if ( t instanceof InvalidAttributeValueException ) + { + return INVALIDATTRIBUTEVALUEEXCEPTION_CODES; + } + + if ( t instanceof ServiceUnavailableException ) + { + return SERVICEUNAVAILABLE_CODES; + } + + if ( t instanceof AuthenticationNotSupportedException ) + { + return AUTHENTICATIONNOTSUPPOERTEDEXCEPTION_CODES; + } + + // keep this last because others are subtypes and thier evaluation + // may be shorted otherwise by this comparison here + if ( t instanceof NamingException ) + { + return NAMINGEXCEPTION_CODES; + } + + return Collections.EMPTY_SET; + } + + + /** + * Gets an LDAP result code from a Throwable if it can resolve it + * unambiguously or returns null if it cannot resolve the exception to + * a single ResultCode. If the Throwable is an instance of LdapException + * this is already done for us, otherwise we use the following mapping: + * <pre> + * + * Unambiguous Exceptions + * ====================== + * + * CommunicationException ==> operationsError(1) + * TimeLimitExceededException ==> timeLimitExceeded(3) + * SizeLimitExceededException ==> sizeLimitExceeded(4) + * AuthenticationException ==> invalidCredentials(49) + * NoPermissionException ==> insufficientAccessRights(50) + * NoSuchAttributeException ==> noSuchAttribute(16) + * InvalidAttributeIdentifierException ==> undefinedAttributeType(17) + * InvalidSearchFilterException ==> inappropriateMatching(18) + * AttributeInUseException ==> attributeOrValueExists(20) + * NameNotFoundException ==> noSuchObject(32) + * NameAlreadyBoundException ==> entryAlreadyExists(68) + * ContextNotEmptyException ==> notAllowedOnNonLeaf(66) + * </pre> + * + * If we cannot find a mapping then null is returned. + * + * @param t + * @return + */ + public static ResultCodeEnum getResultCode( Throwable t ) + { + if ( t instanceof LdapException ) + { + return ( ( LdapException ) t ).getResultCode(); + } + + if ( t instanceof CommunicationException ) + { + return ResultCodeEnum.PROTOCOLERROR; + } + + if ( t instanceof TimeLimitExceededException ) + { + return ResultCodeEnum.TIMELIMITEXCEEDED; + } + + if ( t instanceof SizeLimitExceededException ) + { + return ResultCodeEnum.SIZELIMITEXCEEDED; + } + + if ( t instanceof AuthenticationException ) + { + return ResultCodeEnum.INVALIDCREDENTIALS; + } + + if ( t instanceof NoPermissionException ) + { + return ResultCodeEnum.INSUFFICIENTACCESSRIGHTS; + } + + if ( t instanceof NoSuchAttributeException ) + { + return ResultCodeEnum.NOSUCHATTRIBUTE; + } + + if ( t instanceof InvalidAttributeIdentifierException ) + { + return ResultCodeEnum.UNDEFINEDATTRIBUTETYPE; + } + + if ( t instanceof InvalidSearchFilterException ) + { + return ResultCodeEnum.INAPPROPRIATEMATCHING; + } + + if ( t instanceof AttributeInUseException ) + { + return ResultCodeEnum.ATTRIBUTEORVALUEEXISTS; + } + + if ( t instanceof NameNotFoundException ) + { + return ResultCodeEnum.NOSUCHOBJECT; + } + + if ( t instanceof NameAlreadyBoundException ) + { + return ResultCodeEnum.ENTRYALREADYEXISTS; + } + + if ( t instanceof ContextNotEmptyException ) + { + return ResultCodeEnum.NOTALLOWEDONNONLEAF; + } + + return null; } } Modified: incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java ============================================================================== --- incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java (original) +++ incubator/directory/ldap/trunk/common/src/java/org/apache/ldap/common/util/ExceptionUtils.java Wed Nov 3 16:50:45 2004 @@ -15,6 +15,7 @@ */ package org.apache.ldap.common.util; + import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; @@ -22,31 +23,23 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.StringTokenizer; +import java.util.*; /** - * <p>Provides utilities for manipulating and examining - * <code>Throwable</code> objects.</p> + * <p>Provides utilities for manipulating and examining <code>Throwable</code> + * objects.</p> * - * @author <a href="mailto:[email protected]">Daniel Rall</a> - * @author Dmitri Plotnikov - * @author Stephen Colebourne - * @author <a href="mailto:[EMAIL PROTECTED]">Gary Gregory</a> - * @author Pete Gieser - * @since 1.0 - * @version $Id: ExceptionUtils.java,v 1.39 2004/07/04 03:24:57 bayard Exp $ + * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a> + * @version $Rev$ */ -public class ExceptionUtils { - +public class ExceptionUtils +{ + /** - * <p>Used when printing stack frames to denote the start of a - * wrapped exception.</p> - * + * <p>Used when printing stack frames to denote the start of a wrapped + * exception.</p> + * <p/> * <p>Package private for accessibility by test suite.</p> */ static final String WRAPPED_MARKER = " [wrapped] "; @@ -73,218 +66,273 @@ * <p>The Method object for JDK1.4 getCause.</p> */ private static final Method THROWABLE_CAUSE_METHOD; - static { + + + static + { Method getCauseMethod; - try { - getCauseMethod = Throwable.class.getMethod("getCause", null); - } catch (Exception e) { + try + { + getCauseMethod = Throwable.class.getMethod( "getCause", null ); + } + catch ( Exception e ) + { getCauseMethod = null; } THROWABLE_CAUSE_METHOD = getCauseMethod; } - + + /** * <p>Public constructor allows an instance of <code>ExceptionUtils</code> * to be created, although that is not normally necessary.</p> */ - public ExceptionUtils() { + public ExceptionUtils() + { } + /** * <p>Checks if a String is not empty ("") and not null.</p> * - * @param str the String to check, may be null + * @param str the String to check, may be null * @return <code>true</code> if the String is not empty and not null */ - private static boolean isNotEmpty(String str) { - return (str != null && str.length() > 0); + private static boolean isNotEmpty( String str ) + { + return ( str != null && str.length() > 0 ); } //----------------------------------------------------------------------- /** - * <p>Adds to the list of method names used in the search for <code>Throwable</code> - * objects.</p> - * - * @param methodName the methodName to add to the list, <code>null</code> - * and empty strings are ignored + * <p>Adds to the list of method names used in the search for + * <code>Throwable</code> objects.</p> + * + * @param methodName the methodName to add to the list, <code>null</code> + * and empty strings are ignored * @since 2.0 */ - public static void addCauseMethodName(String methodName) { - if (isNotEmpty(methodName)) { - List list = new ArrayList(Arrays.asList(CAUSE_METHOD_NAMES)); - list.add(methodName); - CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]); + public static void addCauseMethodName( String methodName ) + { + if ( isNotEmpty( methodName ) ) + { + List list = new ArrayList( Arrays.asList( CAUSE_METHOD_NAMES ) ); + list.add( methodName ); + CAUSE_METHOD_NAMES = ( String[] ) list.toArray( new String[list.size()] ); } } + /** * <p>Introspects the <code>Throwable</code> to obtain the cause.</p> - * - * <p>The method searches for methods with specific names that return a - * <code>Throwable</code> object. This will pick up most wrapping exceptions, - * including those from JDK 1.4, and - * The method names can be added to using [EMAIL PROTECTED] #addCauseMethodName(String)}.</p> - * - * <p>The default list searched for are:</p> - * <ul> - * <li><code>getCause()</code></li> - * <li><code>getNextException()</code></li> - * <li><code>getTargetException()</code></li> - * <li><code>getException()</code></li> - * <li><code>getSourceException()</code></li> - * <li><code>getRootCause()</code></li> - * <li><code>getCausedByException()</code></li> - * <li><code>getNested()</code></li> - * </ul> - * + * <p/> + * <p>The method searches for methods with specific names that return a + * <code>Throwable</code> object. This will pick up most wrapping + * exceptions, including those from JDK 1.4, and The method names can be + * added to using [EMAIL PROTECTED] #addCauseMethodName(String)}.</p> + * <p/> + * <p>The default list searched for are:</p> <ul> <li><code>getCause()</code></li> + * <li><code>getNextException()</code></li> <li><code>getTargetException()</code></li> + * <li><code>getException()</code></li> <li><code>getSourceException()</code></li> + * <li><code>getRootCause()</code></li> <li><code>getCausedByException()</code></li> + * <li><code>getNested()</code></li> </ul> + * <p/> * <p>In the absence of any such method, the object is inspected for a * <code>detail</code> field assignable to a <code>Throwable</code>.</p> - * + * <p/> * <p>If none of the above is found, returns <code>null</code>.</p> * - * @param throwable the throwable to introspect for a cause, may be null - * @return the cause of the <code>Throwable</code>, - * <code>null</code> if none found or null throwable input + * @param throwable the throwable to introspect for a cause, may be null + * @return the cause of the <code>Throwable</code>, <code>null</code> if + * none found or null throwable input * @since 1.0 */ - public static Throwable getCause(Throwable throwable) { - return getCause(throwable, CAUSE_METHOD_NAMES); + public static Throwable getCause( Throwable throwable ) + { + return getCause( throwable, CAUSE_METHOD_NAMES ); } + /** * <p>Introspects the <code>Throwable</code> to obtain the cause.</p> - * - * <ol> - * <li>Try known exception types.</li> - * <li>Try the supplied array of method names.</li> - * <li>Try the field 'detail'.</li> - * </ol> - * - * <p>A <code>null</code> set of method names means use the default set. - * A <code>null</code> in the set of method names will be ignored.</p> - * - * @param throwable the throwable to introspect for a cause, may be null - * @param methodNames the method names, null treated as default set - * @return the cause of the <code>Throwable</code>, - * <code>null</code> if none found or null throwable input + * <p/> + * <ol> <li>Try known exception types.</li> <li>Try the supplied array of + * method names.</li> <li>Try the field 'detail'.</li> </ol> + * <p/> + * <p>A <code>null</code> set of method names means use the default set. A + * <code>null</code> in the set of method names will be ignored.</p> + * + * @param throwable the throwable to introspect for a cause, may be null + * @param methodNames the method names, null treated as default set + * @return the cause of the <code>Throwable</code>, <code>null</code> if + * none found or null throwable input * @since 1.0 */ - public static Throwable getCause(Throwable throwable, String[] methodNames) { - if (throwable == null) { + public static Throwable getCause( Throwable throwable, String[] methodNames ) + { + if ( throwable == null ) + { return null; } - Throwable cause = getCauseUsingWellKnownTypes(throwable); - if (cause == null) { - if (methodNames == null) { + Throwable cause = getCauseUsingWellKnownTypes( throwable ); + if ( cause == null ) + { + if ( methodNames == null ) + { methodNames = CAUSE_METHOD_NAMES; } - for (int i = 0; i < methodNames.length; i++) { + for ( int i = 0; i < methodNames.length; i++ ) + { String methodName = methodNames[i]; - if (methodName != null) { - cause = getCauseUsingMethodName(throwable, methodName); - if (cause != null) { + if ( methodName != null ) + { + cause = getCauseUsingMethodName( throwable, methodName ); + if ( cause != null ) + { break; } } } - if (cause == null) { - cause = getCauseUsingFieldName(throwable, "detail"); + if ( cause == null ) + { + cause = getCauseUsingFieldName( throwable, "detail" ); } } return cause; } + /** * <p>Introspects the <code>Throwable</code> to obtain the root cause.</p> - * + * <p/> * <p>This method walks through the exception chain to the last element, - * "root" of the tree, using [EMAIL PROTECTED] #getCause(Throwable)}, and - * returns that exception.</p> + * "root" of the tree, using [EMAIL PROTECTED] #getCause(Throwable)}, and returns that + * exception.</p> * - * @param throwable the throwable to get the root cause for, may be null - * @return the root cause of the <code>Throwable</code>, - * <code>null</code> if none found or null throwable input - */ - public static Throwable getRootCause(Throwable throwable) { - Throwable cause = getCause(throwable); - if (cause != null) { + * @param throwable the throwable to get the root cause for, may be null + * @return the root cause of the <code>Throwable</code>, <code>null</code> + * if none found or null throwable input + */ + public static Throwable getRootCause( Throwable throwable ) + { + Throwable cause = getCause( throwable ); + if ( cause != null ) + { throwable = cause; - while ((throwable = getCause(throwable)) != null) { + while ( ( throwable = getCause( throwable ) ) != null ) + { cause = throwable; } } return cause; } + /** * <p>Finds a <code>Throwable</code> for known types.</p> - * - * <p>Uses <code>instanceof</code> checks to examine the exception, - * looking for well known types which could contain chained or - * wrapped exceptions.</p> + * <p/> + * <p>Uses <code>instanceof</code> checks to examine the exception, looking + * for well known types which could contain chained or wrapped + * exceptions.</p> * - * @param throwable the exception to examine + * @param throwable the exception to examine * @return the wrapped exception, or <code>null</code> if not found */ - private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) { - if (throwable instanceof Nestable) { - return ((Nestable) throwable).getCause(); - } else if (throwable instanceof SQLException) { - return ((SQLException) throwable).getNextException(); - } else if (throwable instanceof InvocationTargetException) { - return ((InvocationTargetException) throwable).getTargetException(); - } else { + private static Throwable getCauseUsingWellKnownTypes( Throwable throwable ) + { + if ( throwable instanceof Nestable ) + { + return ( ( Nestable ) throwable ).getCause(); + } + else if ( throwable instanceof SQLException ) + { + return ( ( SQLException ) throwable ).getNextException(); + } + else if ( throwable instanceof InvocationTargetException ) + { + return ( ( InvocationTargetException ) throwable ).getTargetException(); + } + else + { return null; } } + /** * <p>Finds a <code>Throwable</code> by method name.</p> - * + * * @param throwable the exception to examine - * @param methodName the name of the method to find and invoke + * @param methodName the name of the method to find and invoke * @return the wrapped exception, or <code>null</code> if not found */ - private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) { + private static Throwable getCauseUsingMethodName( Throwable throwable, String methodName ) + { Method method = null; - try { - method = throwable.getClass().getMethod(methodName, null); - } catch (NoSuchMethodException ignored) { - } catch (SecurityException ignored) { + try + { + method = throwable.getClass().getMethod( methodName, null ); + } + catch ( NoSuchMethodException ignored ) + { + } + catch ( SecurityException ignored ) + { } - if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) { - try { - return (Throwable) method.invoke(throwable, ArrayUtils.EMPTY_OBJECT_ARRAY); - } catch (IllegalAccessException ignored) { - } catch (IllegalArgumentException ignored) { - } catch (InvocationTargetException ignored) { + if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) + { + try + { + return ( Throwable ) method.invoke( throwable, ArrayUtils.EMPTY_OBJECT_ARRAY ); + } + catch ( IllegalAccessException ignored ) + { + } + catch ( IllegalArgumentException ignored ) + { + } + catch ( InvocationTargetException ignored ) + { } } return null; } + /** * <p>Finds a <code>Throwable</code> by field name.</p> - * - * @param throwable the exception to examine - * @param fieldName the name of the attribute to examine + * + * @param throwable the exception to examine + * @param fieldName the name of the attribute to examine * @return the wrapped exception, or <code>null</code> if not found */ - private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) { + private static Throwable getCauseUsingFieldName( Throwable throwable, String fieldName ) + { Field field = null; - try { - field = throwable.getClass().getField(fieldName); - } catch (NoSuchFieldException ignored) { - } catch (SecurityException ignored) { + try + { + field = throwable.getClass().getField( fieldName ); + } + catch ( NoSuchFieldException ignored ) + { + } + catch ( SecurityException ignored ) + { } - if (field != null && Throwable.class.isAssignableFrom(field.getType())) { - try { - return (Throwable) field.get(throwable); - } catch (IllegalAccessException ignored) { - } catch (IllegalArgumentException ignored) { + if ( field != null && Throwable.class.isAssignableFrom( field.getType() ) ) + { + try + { + return ( Throwable ) field.get( throwable ); + } + catch ( IllegalAccessException ignored ) + { + } + catch ( IllegalArgumentException ignored ) + { } } return null; @@ -293,59 +341,85 @@ //----------------------------------------------------------------------- /** * <p>Checks if the Throwable class has a <code>getCause</code> method.</p> - * + * <p/> * <p>This is true for JDK 1.4 and above.</p> - * + * * @return true if Throwable is nestable * @since 2.0 */ - public static boolean isThrowableNested() { - return (THROWABLE_CAUSE_METHOD != null); + public static boolean isThrowableNested() + { + return ( THROWABLE_CAUSE_METHOD != null ); } - + + /** - * <p>Checks whether this <code>Throwable</code> class can store a cause.</p> - * - * <p>This method does <b>not</b> check whether it actually does store a cause.<p> + * <p>Checks whether this <code>Throwable</code> class can store a + * cause.</p> + * <p/> + * <p>This method does <b>not</b> check whether it actually does store a + * cause.<p> * - * @param throwable the <code>Throwable</code> to examine, may be null + * @param throwable the <code>Throwable</code> to examine, may be null * @return boolean <code>true</code> if nested otherwise <code>false</code> * @since 2.0 */ - public static boolean isNestedThrowable(Throwable throwable) { - if (throwable == null) { + public static boolean isNestedThrowable( Throwable throwable ) + { + if ( throwable == null ) + { return false; } - if (throwable instanceof Nestable) { + if ( throwable instanceof Nestable ) + { return true; - } else if (throwable instanceof SQLException) { + } + else if ( throwable instanceof SQLException ) + { return true; - } else if (throwable instanceof InvocationTargetException) { + } + else if ( throwable instanceof InvocationTargetException ) + { return true; - } else if (isThrowableNested()) { + } + else if ( isThrowableNested() ) + { return true; } Class cls = throwable.getClass(); - for (int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++) { - try { - Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], null); - if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) { + for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ ) + { + try + { + Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null ); + if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) + { return true; } - } catch (NoSuchMethodException ignored) { - } catch (SecurityException ignored) { + } + catch ( NoSuchMethodException ignored ) + { + } + catch ( SecurityException ignored ) + { } } - try { - Field field = cls.getField("detail"); - if (field != null) { + try + { + Field field = cls.getField( "detail" ); + if ( field != null ) + { return true; } - } catch (NoSuchFieldException ignored) { - } catch (SecurityException ignored) { + } + catch ( NoSuchFieldException ignored ) + { + } + catch ( SecurityException ignored ) + { } return false; @@ -353,94 +427,107 @@ //----------------------------------------------------------------------- /** - * <p>Counts the number of <code>Throwable</code> objects in the - * exception chain.</p> - * - * <p>A throwable without cause will return <code>1</code>. - * A throwable with one cause will return <code>2</code> and so on. - * A <code>null</code> throwable will return <code>0</code>.</p> - * - * @param throwable the throwable to inspect, may be null + * <p>Counts the number of <code>Throwable</code> objects in the exception + * chain.</p> + * <p/> + * <p>A throwable without cause will return <code>1</code>. A throwable with + * one cause will return <code>2</code> and so on. A <code>null</code> + * throwable will return <code>0</code>.</p> + * + * @param throwable the throwable to inspect, may be null * @return the count of throwables, zero if null input */ - public static int getThrowableCount(Throwable throwable) { + public static int getThrowableCount( Throwable throwable ) + { int count = 0; - while (throwable != null) { + while ( throwable != null ) + { count++; - throwable = ExceptionUtils.getCause(throwable); + throwable = ExceptionUtils.getCause( throwable ); } return count; } + /** - * <p>Returns the list of <code>Throwable</code> objects in the - * exception chain.</p> - * - * <p>A throwable without cause will return an array containing - * one element - the input throwable. - * A throwable with one cause will return an array containing - * two elements. - the input throwable and the cause throwable. - * A <code>null</code> throwable will return an array size zero.</p> + * <p>Returns the list of <code>Throwable</code> objects in the exception + * chain.</p> + * <p/> + * <p>A throwable without cause will return an array containing one element + * - the input throwable. A throwable with one cause will return an array + * containing two elements. - the input throwable and the cause throwable. A + * <code>null</code> throwable will return an array size zero.</p> * - * @param throwable the throwable to inspect, may be null + * @param throwable the throwable to inspect, may be null * @return the array of throwables, never null */ - public static Throwable[] getThrowables(Throwable throwable) { + public static Throwable[] getThrowables( Throwable throwable ) + { List list = new ArrayList(); - while (throwable != null) { - list.add(throwable); - throwable = ExceptionUtils.getCause(throwable); + while ( throwable != null ) + { + list.add( throwable ); + throwable = ExceptionUtils.getCause( throwable ); } - return (Throwable[]) list.toArray(new Throwable[list.size()]); + return ( Throwable[] ) list.toArray( new Throwable[list.size()] ); } //----------------------------------------------------------------------- /** * <p>Returns the (zero based) index of the first <code>Throwable</code> * that matches the specified type in the exception chain.</p> - * - * <p>A <code>null</code> throwable returns <code>-1</code>. - * A <code>null</code> type returns <code>-1</code>. - * No match in the chain returns <code>-1</code>.</p> + * <p/> + * <p>A <code>null</code> throwable returns <code>-1</code>. A + * <code>null</code> type returns <code>-1</code>. No match in the chain + * returns <code>-1</code>.</p> * - * @param throwable the throwable to inspect, may be null - * @param type the type to search for + * @param throwable the throwable to inspect, may be null + * @param type the type to search for * @return the index into the throwable chain, -1 if no match or null input */ - public static int indexOfThrowable(Throwable throwable, Class type) { - return indexOfThrowable(throwable, type, 0); + public static int indexOfThrowable( Throwable throwable, Class type ) + { + return indexOfThrowable( throwable, type, 0 ); } + /** * <p>Returns the (zero based) index of the first <code>Throwable</code> - * that matches the specified type in the exception chain from - * a specified index.</p> - * - * <p>A <code>null</code> throwable returns <code>-1</code>. - * A <code>null</code> type returns <code>-1</code>. - * No match in the chain returns <code>-1</code>. - * A negative start index is treated as zero. - * A start index greater than the number of throwables returns <code>-1</code>.</p> - * - * @param throwable the throwable to inspect, may be null - * @param type the type to search for - * @param fromIndex the (zero based) index of the starting position, - * negative treated as zero, larger than chain size returns -1 + * that matches the specified type in the exception chain from a specified + * index.</p> + * <p/> + * <p>A <code>null</code> throwable returns <code>-1</code>. A + * <code>null</code> type returns <code>-1</code>. No match in the chain + * returns <code>-1</code>. A negative start index is treated as zero. A + * start index greater than the number of throwables returns + * <code>-1</code>.</p> + * + * @param throwable the throwable to inspect, may be null + * @param type the type to search for + * @param fromIndex the (zero based) index of the starting position, + * negative treated as zero, larger than chain size returns + * -1 * @return the index into the throwable chain, -1 if no match or null input */ - public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) { - if (throwable == null) { + public static int indexOfThrowable( Throwable throwable, Class type, int fromIndex ) + { + if ( throwable == null ) + { return -1; } - if (fromIndex < 0) { + if ( fromIndex < 0 ) + { fromIndex = 0; } - Throwable[] throwables = ExceptionUtils.getThrowables(throwable); - if (fromIndex >= throwables.length) { + Throwable[] throwables = ExceptionUtils.getThrowables( throwable ); + if ( fromIndex >= throwables.length ) + { return -1; } - for (int i = fromIndex; i < throwables.length; i++) { - if (throwables[i].getClass().equals(type)) { + for ( int i = fromIndex; i < throwables.length; i++ ) + { + if ( throwables[i].getClass().equals( type ) ) + { return i; } } @@ -449,80 +536,91 @@ //----------------------------------------------------------------------- /** - * <p>Prints a compact stack trace for the root cause of a throwable - * to <code>System.err</code>.</p> - * - * <p>The compact stack trace starts with the root cause and prints - * stack frames up to the place where it was caught and wrapped. - * Then it prints the wrapped exception and continues with stack frames - * until the wrapper exception is caught and wrapped again, etc.</p> - * - * <p>The method is equivalent to <code>printStackTrace</code> for throwables - * that don't have nested causes.</p> - * - * @param throwable the throwable to output + * <p>Prints a compact stack trace for the root cause of a throwable to + * <code>System.err</code>.</p> + * <p/> + * <p>The compact stack trace starts with the root cause and prints stack + * frames up to the place where it was caught and wrapped. Then it prints + * the wrapped exception and continues with stack frames until the wrapper + * exception is caught and wrapped again, etc.</p> + * <p/> + * <p>The method is equivalent to <code>printStackTrace</code> for + * throwables that don't have nested causes.</p> + * + * @param throwable the throwable to output * @since 2.0 */ - public static void printRootCauseStackTrace(Throwable throwable) { - printRootCauseStackTrace(throwable, System.err); + public static void printRootCauseStackTrace( Throwable throwable ) + { + printRootCauseStackTrace( throwable, System.err ); } + /** * <p>Prints a compact stack trace for the root cause of a throwable.</p> + * <p/> + * <p>The compact stack trace starts with the root cause and prints stack + * frames up to the place where it was caught and wrapped. Then it prints + * the wrapped exception and continues with stack frames until the wrapper + * exception is caught and wrapped again, etc.</p> + * <p/> + * <p>The method is equivalent to <code>printStackTrace</code> for + * throwables that don't have nested causes.</p> * - * <p>The compact stack trace starts with the root cause and prints - * stack frames up to the place where it was caught and wrapped. - * Then it prints the wrapped exception and continues with stack frames - * until the wrapper exception is caught and wrapped again, etc.</p> - * - * <p>The method is equivalent to <code>printStackTrace</code> for throwables - * that don't have nested causes.</p> - * - * @param throwable the throwable to output, may be null - * @param stream the stream to output to, may not be null + * @param throwable the throwable to output, may be null + * @param stream the stream to output to, may not be null * @throws IllegalArgumentException if the stream is <code>null</code> * @since 2.0 */ - public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) { - if (throwable == null) { + public static void printRootCauseStackTrace( Throwable throwable, PrintStream stream ) + { + if ( throwable == null ) + { return; } - if (stream == null) { - throw new IllegalArgumentException("The PrintStream must not be null"); - } - String trace[] = getRootCauseStackTrace(throwable); - for (int i = 0; i < trace.length; i++) { - stream.println(trace[i]); + if ( stream == null ) + { + throw new IllegalArgumentException( "The PrintStream must not be null" ); + } + String trace[] = getRootCauseStackTrace( throwable ); + for ( int i = 0; i < trace.length; i++ ) + { + stream.println( trace[i] ); } stream.flush(); } + /** * <p>Prints a compact stack trace for the root cause of a throwable.</p> + * <p/> + * <p>The compact stack trace starts with the root cause and prints stack + * frames up to the place where it was caught and wrapped. Then it prints + * the wrapped exception and continues with stack frames until the wrapper + * exception is caught and wrapped again, etc.</p> + * <p/> + * <p>The method is equivalent to <code>printStackTrace</code> for + * throwables that don't have nested causes.</p> * - * <p>The compact stack trace starts with the root cause and prints - * stack frames up to the place where it was caught and wrapped. - * Then it prints the wrapped exception and continues with stack frames - * until the wrapper exception is caught and wrapped again, etc.</p> - * - * <p>The method is equivalent to <code>printStackTrace</code> for throwables - * that don't have nested causes.</p> - * - * @param throwable the throwable to output, may be null - * @param writer the writer to output to, may not be null + * @param throwable the throwable to output, may be null + * @param writer the writer to output to, may not be null * @throws IllegalArgumentException if the writer is <code>null</code> * @since 2.0 */ - public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) { - if (throwable == null) { + public static void printRootCauseStackTrace( Throwable throwable, PrintWriter writer ) + { + if ( throwable == null ) + { return; } - if (writer == null) { - throw new IllegalArgumentException("The PrintWriter must not be null"); - } - String trace[] = getRootCauseStackTrace(throwable); - for (int i = 0; i < trace.length; i++) { - writer.println(trace[i]); + if ( writer == null ) + { + throw new IllegalArgumentException( "The PrintWriter must not be null" ); + } + String trace[] = getRootCauseStackTrace( throwable ); + for ( int i = 0; i < trace.length; i++ ) + { + writer.println( trace[i] ); } writer.flush(); } @@ -531,58 +629,72 @@ /** * <p>Creates a compact stack trace for the root cause of the supplied * <code>Throwable</code>.</p> - * - * @param throwable the throwable to examine, may be null + * + * @param throwable the throwable to examine, may be null * @return an array of stack trace frames, never null * @since 2.0 */ - public static String[] getRootCauseStackTrace(Throwable throwable) { - if (throwable == null) { + public static String[] getRootCauseStackTrace( Throwable throwable ) + { + if ( throwable == null ) + { return ArrayUtils.EMPTY_STRING_ARRAY; } - Throwable throwables[] = getThrowables(throwable); + Throwable throwables[] = getThrowables( throwable ); int count = throwables.length; ArrayList frames = new ArrayList(); - List nextTrace = getStackFrameList(throwables[count - 1]); - for (int i = count; --i >= 0;) { + List nextTrace = getStackFrameList( throwables[count - 1] ); + for ( int i = count; --i >= 0; ) + { List trace = nextTrace; - if (i != 0) { - nextTrace = getStackFrameList(throwables[i - 1]); - removeCommonFrames(trace, nextTrace); + if ( i != 0 ) + { + nextTrace = getStackFrameList( throwables[i - 1] ); + removeCommonFrames( trace, nextTrace ); } - if (i == count - 1) { - frames.add(throwables[i].toString()); - } else { - frames.add(WRAPPED_MARKER + throwables[i].toString()); + if ( i == count - 1 ) + { + frames.add( throwables[i].toString() ); } - for (int j = 0; j < trace.size(); j++) { - frames.add(trace.get(j)); + else + { + frames.add( WRAPPED_MARKER + throwables[i].toString() ); + } + for ( int j = 0; j < trace.size(); j++ ) + { + frames.add( trace.get( j ) ); } } - return (String[]) frames.toArray(new String[0]); + return ( String[] ) frames.toArray( new String[0] ); } + /** - * <p>Removes common frames from the cause trace given the two stack traces.</p> - * - * @param causeFrames stack trace of a cause throwable - * @param wrapperFrames stack trace of a wrapper throwable + * <p>Removes common frames from the cause trace given the two stack + * traces.</p> + * + * @param causeFrames stack trace of a cause throwable + * @param wrapperFrames stack trace of a wrapper throwable * @throws IllegalArgumentException if either argument is null * @since 2.0 */ - public static void removeCommonFrames(List causeFrames, List wrapperFrames) { - if (causeFrames == null || wrapperFrames == null) { - throw new IllegalArgumentException("The List must not be null"); + public static void removeCommonFrames( List causeFrames, List wrapperFrames ) + { + if ( causeFrames == null || wrapperFrames == null ) + { + throw new IllegalArgumentException( "The List must not be null" ); } int causeFrameIndex = causeFrames.size() - 1; int wrapperFrameIndex = wrapperFrames.size() - 1; - while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) { + while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 ) + { // Remove the frame from the cause trace if it is the same // as in the wrapper trace - String causeFrame = (String) causeFrames.get(causeFrameIndex); - String wrapperFrame = (String) wrapperFrames.get(wrapperFrameIndex); - if (causeFrame.equals(wrapperFrame)) { - causeFrames.remove(causeFrameIndex); + String causeFrame = ( String ) causeFrames.get( causeFrameIndex ); + String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex ); + if ( causeFrame.equals( wrapperFrame ) ) + { + causeFrames.remove( causeFrameIndex ); } causeFrameIndex--; wrapperFrameIndex--; @@ -593,31 +705,36 @@ /** * <p>Gets the stack trace from a Throwable as a String.</p> * - * @param throwable the <code>Throwable</code> to be examined + * @param throwable the <code>Throwable</code> to be examined * @return the stack trace as generated by the exception's - * <code>printStackTrace(PrintWriter)</code> method + * <code>printStackTrace(PrintWriter)</code> method */ - public static String getStackTrace(Throwable throwable) { + public static String getStackTrace( Throwable throwable ) + { StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw, true); - throwable.printStackTrace(pw); + PrintWriter pw = new PrintWriter( sw, true ); + throwable.printStackTrace( pw ); return sw.getBuffer().toString(); } + /** * <p>A way to get the entire nested stack-trace of an throwable.</p> * - * @param throwable the <code>Throwable</code> to be examined + * @param throwable the <code>Throwable</code> to be examined * @return the nested stack trace, with the root cause first * @since 2.0 */ - public static String getFullStackTrace(Throwable throwable) { + public static String getFullStackTrace( Throwable throwable ) + { StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw, true); - Throwable[] ts = getThrowables(throwable); - for (int i = 0; i < ts.length; i++) { - ts[i].printStackTrace(pw); - if (isNestedThrowable(ts[i])) { + PrintWriter pw = new PrintWriter( sw, true ); + Throwable[] ts = getThrowables( throwable ); + for ( int i = 0; i < ts.length; i++ ) + { + ts[i].printStackTrace( pw ); + if ( isNestedThrowable( ts[i] ) ) + { break; } } @@ -627,62 +744,71 @@ //----------------------------------------------------------------------- /** * <p>Captures the stack trace associated with the specified - * <code>Throwable</code> object, decomposing it into a list of - * stack frames.</p> + * <code>Throwable</code> object, decomposing it into a list of stack + * frames.</p> * - * @param throwable the <code>Throwable</code> to examine, may be null + * @param throwable the <code>Throwable</code> to examine, may be null * @return an array of strings describing each stack frame, never null */ - public static String[] getStackFrames(Throwable throwable) { - if (throwable == null) { + public static String[] getStackFrames( Throwable throwable ) + { + if ( throwable == null ) + { return ArrayUtils.EMPTY_STRING_ARRAY; } - return getStackFrames(getStackTrace(throwable)); + return getStackFrames( getStackTrace( throwable ) ); } + /** - * <p>Functionality shared between the - * <code>getStackFrames(Throwable)</code> methods of this and the + * <p>Functionality shared between the <code>getStackFrames(Throwable)</code> + * methods of this and the */ - static String[] getStackFrames(String stackTrace) { + static String[] getStackFrames( String stackTrace ) + { String linebreak = SystemUtils.LINE_SEPARATOR; - StringTokenizer frames = new StringTokenizer(stackTrace, linebreak); + StringTokenizer frames = new StringTokenizer( stackTrace, linebreak ); List list = new LinkedList(); - while (frames.hasMoreTokens()) { - list.add(frames.nextToken()); + while ( frames.hasMoreTokens() ) + { + list.add( frames.nextToken() ); } - return (String[]) list.toArray(new String[list.size()]); + return ( String[] ) list.toArray( new String[list.size()] ); } + /** - * <p>Produces a <code>List</code> of stack frames - the message - * is not included.</p> + * <p>Produces a <code>List</code> of stack frames - the message is not + * included.</p> + * <p/> + * <p>This works in most cases - it will only fail if the exception message + * contains a line that starts with: <code>" at".</code></p> * - * <p>This works in most cases - it will only fail if the exception - * message contains a line that starts with: - * <code>" at".</code></p> - * * @param t is any throwable * @return List of stack frames */ - static List getStackFrameList(Throwable t) { - String stackTrace = getStackTrace(t); + static List getStackFrameList( Throwable t ) + { + String stackTrace = getStackTrace( t ); String linebreak = SystemUtils.LINE_SEPARATOR; - StringTokenizer frames = new StringTokenizer(stackTrace, linebreak); + StringTokenizer frames = new StringTokenizer( stackTrace, linebreak ); List list = new LinkedList(); boolean traceStarted = false; - while (frames.hasMoreTokens()) { + while ( frames.hasMoreTokens() ) + { String token = frames.nextToken(); // Determine if the line starts with <whitespace>at - int at = token.indexOf("at"); - if (at != -1 && token.substring(0, at).trim().length() == 0) { + int at = token.indexOf( "at" ); + if ( at != -1 && token.substring( 0, at ).trim().length() == 0 ) + { traceStarted = true; - list.add(token); - } else if (traceStarted) { + list.add( token ); + } + else if ( traceStarted ) + { break; } } return list; } - }
