001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020
021package org.apache.directory.shared.ldap.model.message;
022
023import org.apache.directory.shared.ldap.model.name.Dn;
024
025
026/**
027 * The LdapResult implementation. RFC 4511 definition for a LdapResult is given below. <br>
028 * 
029 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
030 */
031public class LdapResultImpl implements LdapResult
032{
033    /** Lowest matched entry Dn - defaults to empty string */
034    private Dn matchedDn;
035
036    /** Referral associated with this LdapResult if the errorCode is REFERRAL */
037    private Referral referral;
038
039    /** Decriptive diagnostic message - defaults to empty string */
040    private String diagnosticMessage;
041
042    /** Resultant operation error code - defaults to SUCCESS */
043    private ResultCodeEnum resultCode = ResultCodeEnum.SUCCESS;
044
045
046    // ------------------------------------------------------------------------
047    // LdapResult Interface Method Implementations
048    // ------------------------------------------------------------------------
049    /**
050     * {@inheritDoc}
051     */
052    public String getDiagnosticMessage()
053    {
054        return diagnosticMessage;
055    }
056
057
058    /**
059     * {@inheritDoc}
060     */
061    public void setDiagnosticMessage( String diagnosticMessage )
062    {
063        this.diagnosticMessage = diagnosticMessage;
064    }
065
066
067    /**
068     * {@inheritDoc}
069     */
070    public Dn getMatchedDn()
071    {
072        return matchedDn;
073    }
074
075
076    /**
077     * {@inheritDoc}
078     */
079    public void setMatchedDn( Dn matchedDn )
080    {
081        this.matchedDn = matchedDn;
082    }
083
084
085    /**
086     * {@inheritDoc}
087     */
088    public ResultCodeEnum getResultCode()
089    {
090        return resultCode;
091    }
092
093
094    /**
095     * {@inheritDoc}
096     */
097    public void setResultCode( ResultCodeEnum resultCode )
098    {
099        this.resultCode = resultCode;
100    }
101
102
103    /**
104     * {@inheritDoc}
105     */
106    public Referral getReferral()
107    {
108        return referral;
109    }
110
111
112    /**
113     * {@inheritDoc}
114     */
115    public boolean isReferral()
116    {
117        return referral != null;
118    }
119
120
121    /**
122     * {@inheritDoc}
123     */
124    public void setReferral( Referral referral )
125    {
126        this.referral = referral;
127    }
128
129
130    /**
131     * @see Object#hashCode()
132     * @return the instance's hash code 
133     */
134    public int hashCode()
135    {
136        int hash = 37;
137        
138        if ( referral != null )
139        {
140            hash = hash * 17 + referral.hashCode();
141        }
142        
143        hash = hash * 17 + resultCode.hashCode();
144        
145        if ( diagnosticMessage != null )
146        {
147            hash = hash * 17 + diagnosticMessage.hashCode();
148        }
149        
150        if ( matchedDn != null )
151        {
152            hash = hash * 17 + matchedDn.hashCode();
153        }
154
155        return hash;
156    }
157
158
159    /**
160     * @param obj The object to compare with
161     * @return <code>true</code> if both objects are equals
162     */
163    public boolean equals( Object obj )
164    {
165        // quickly return true if this is the obj
166        if ( obj == this )
167        {
168            return true;
169        }
170
171        // return false if object does not implement interface
172        if ( !( obj instanceof LdapResult ) )
173        {
174            return false;
175        }
176
177        // compare all the like elements of the two LdapResult objects
178        LdapResult result = ( LdapResult ) obj;
179
180        if ( referral == null && result.getReferral() != null )
181        {
182            return false;
183        }
184
185        if ( result.getReferral() == null && referral != null )
186        {
187            return false;
188        }
189
190        if ( referral != null && result.getReferral() != null && !referral.equals( result.getReferral() ) )
191        {
192            return false;
193        }
194
195        if ( !resultCode.equals( result.getResultCode() ) )
196        {
197            return false;
198        }
199
200        // Handle diagnostic Messages where "" is considered equivalent to null
201        String errMsg0 = diagnosticMessage;
202        String errMsg1 = result.getDiagnosticMessage();
203
204        if ( errMsg0 == null )
205        {
206            errMsg0 = "";
207        }
208
209        if ( errMsg1 == null )
210        {
211            errMsg1 = "";
212        }
213
214        if ( !errMsg0.equals( errMsg1 ) )
215        {
216            return false;
217        }
218
219        if ( matchedDn != null )
220        {
221            if ( !matchedDn.equals( result.getMatchedDn() ) )
222            {
223                return false;
224            }
225        }
226        else if ( result.getMatchedDn() != null ) // one is null other is not
227        {
228            return false;
229        }
230
231        return true;
232    }
233
234
235    /**
236     * Get a String representation of a LdapResult
237     * 
238     * @return A LdapResult String
239     */
240    public String toString()
241    {
242        StringBuilder sb = new StringBuilder();
243
244        sb.append( "        Ldap Result\n" );
245        sb.append( "            Result code : (" ).append( resultCode ).append( ')' );
246
247        switch ( resultCode )
248        {
249
250            case SUCCESS:
251                sb.append( " success\n" );
252                break;
253
254            case OPERATIONS_ERROR:
255                sb.append( " operationsError\n" );
256                break;
257
258            case PROTOCOL_ERROR:
259                sb.append( " protocolError\n" );
260                break;
261
262            case TIME_LIMIT_EXCEEDED:
263                sb.append( " timeLimitExceeded\n" );
264                break;
265
266            case SIZE_LIMIT_EXCEEDED:
267                sb.append( " sizeLimitExceeded\n" );
268                break;
269
270            case COMPARE_FALSE:
271                sb.append( " compareFalse\n" );
272                break;
273
274            case COMPARE_TRUE:
275                sb.append( " compareTrue\n" );
276                break;
277
278            case AUTH_METHOD_NOT_SUPPORTED:
279                sb.append( " authMethodNotSupported\n" );
280                break;
281
282            case STRONG_AUTH_REQUIRED:
283                sb.append( " strongAuthRequired\n" );
284                break;
285
286            case REFERRAL:
287                sb.append( " referral -- new\n" );
288                break;
289
290            case ADMIN_LIMIT_EXCEEDED:
291                sb.append( " adminLimitExceeded -- new\n" );
292                break;
293
294            case UNAVAILABLE_CRITICAL_EXTENSION:
295                sb.append( " unavailableCriticalExtension -- new\n" );
296                break;
297
298            case CONFIDENTIALITY_REQUIRED:
299                sb.append( " confidentialityRequired -- new\n" );
300                break;
301
302            case SASL_BIND_IN_PROGRESS:
303                sb.append( " saslBindInProgress -- new\n" );
304                break;
305
306            case NO_SUCH_ATTRIBUTE:
307                sb.append( " noSuchAttribute\n" );
308                break;
309
310            case UNDEFINED_ATTRIBUTE_TYPE:
311                sb.append( " undefinedAttributeType\n" );
312                break;
313
314            case INAPPROPRIATE_MATCHING:
315                sb.append( " inappropriateMatching\n" );
316                break;
317
318            case CONSTRAINT_VIOLATION:
319                sb.append( " constraintViolation\n" );
320                break;
321
322            case ATTRIBUTE_OR_VALUE_EXISTS:
323                sb.append( " attributeOrValueExists\n" );
324                break;
325
326            case INVALID_ATTRIBUTE_SYNTAX:
327                sb.append( " invalidAttributeSyntax\n" );
328                break;
329
330            case NO_SUCH_OBJECT:
331                sb.append( " noSuchObject\n" );
332                break;
333
334            case ALIAS_PROBLEM:
335                sb.append( " aliasProblem\n" );
336                break;
337
338            case INVALID_DN_SYNTAX:
339                sb.append( " invalidDNSyntax\n" );
340                break;
341
342            case ALIAS_DEREFERENCING_PROBLEM:
343                sb.append( " aliasDereferencingProblem\n" );
344                break;
345
346            case INAPPROPRIATE_AUTHENTICATION:
347                sb.append( " inappropriateAuthentication\n" );
348                break;
349
350            case INVALID_CREDENTIALS:
351                sb.append( " invalidCredentials\n" );
352                break;
353
354            case INSUFFICIENT_ACCESS_RIGHTS:
355                sb.append( " insufficientAccessRights\n" );
356                break;
357
358            case BUSY:
359                sb.append( " busy\n" );
360                break;
361
362            case UNAVAILABLE:
363                sb.append( " unavailable\n" );
364                break;
365
366            case UNWILLING_TO_PERFORM:
367                sb.append( " unwillingToPerform\n" );
368                break;
369
370            case LOOP_DETECT:
371                sb.append( " loopDetect\n" );
372                break;
373
374            case NAMING_VIOLATION:
375                sb.append( " namingViolation\n" );
376                break;
377
378            case OBJECT_CLASS_VIOLATION:
379                sb.append( " objectClassViolation\n" );
380                break;
381
382            case NOT_ALLOWED_ON_NON_LEAF:
383                sb.append( " notAllowedOnNonLeaf\n" );
384                break;
385
386            case NOT_ALLOWED_ON_RDN:
387                sb.append( " notAllowedOnRDN\n" );
388                break;
389
390            case ENTRY_ALREADY_EXISTS:
391                sb.append( " entryAlreadyExists\n" );
392                break;
393
394            case OBJECT_CLASS_MODS_PROHIBITED:
395                sb.append( " objectClassModsProhibited\n" );
396                break;
397
398            case AFFECTS_MULTIPLE_DSAS:
399                sb.append( " affectsMultipleDSAs -- new\n" );
400                break;
401
402            case E_SYNC_REFRESH_REQUIRED:
403                sb.append( " eSyncRefreshRequired\n" );
404                break;
405
406            case OTHER:
407                sb.append( " other\n" );
408                break;
409
410            default:
411                switch ( resultCode.getResultCode() )
412                {
413                    case 9:
414                        sb.append( " -- 9 reserved --\n" );
415                        break;
416
417                    case 22:
418                    case 23:
419                    case 24:
420                    case 25:
421                    case 26:
422                    case 27:
423                    case 28:
424                    case 29:
425                    case 30:
426                    case 31:
427                        sb.append( " -- 22-31 unused --\n" );
428                        break;
429
430                    case 35:
431                        sb.append( " -- 35 reserved for undefined isLeaf --\n" );
432                        break;
433
434                    case 37:
435                    case 38:
436                    case 39:
437                    case 40:
438                    case 41:
439                    case 42:
440                    case 43:
441                    case 44:
442                    case 45:
443                    case 46:
444                    case 47:
445                        sb.append( " -- 37-47 unused --\n" );
446                        break;
447
448                    case 55:
449                    case 56:
450                    case 57:
451                    case 58:
452                    case 59:
453                    case 60:
454                    case 61:
455                    case 62:
456                    case 63:
457                        sb.append( " -- 55-63 unused --\n" );
458                        break;
459
460                    case 70:
461                        sb.append( " -- 70 reserved for CLDAP --\n" );
462                        break;
463
464                    case 72:
465                    case 73:
466                    case 74:
467                    case 75:
468                    case 76:
469                    case 77:
470                    case 78:
471                    case 79:
472                        sb.append( " -- 72-79 unused --\n" );
473                        break;
474
475                    case 81:
476                    case 82:
477                    case 83:
478                    case 84:
479                    case 85:
480                    case 86:
481                    case 87:
482                    case 88:
483                    case 89:
484                    case 90:
485                        sb.append( " -- 81-90 reserved for APIs --" );
486                        break;
487
488                    default:
489                        sb.append( "Unknown error code : " ).append( resultCode );
490                        break;
491                }
492        }
493
494        sb.append( "            Matched Dn : '" ).append( matchedDn ).append( "'\n" );
495        sb.append( "            Diagnostic message : '" ).append( diagnosticMessage ).append( "'\n" );
496
497        if ( referral != null )
498        {
499            sb.append( "            Referrals :\n" );
500
501            sb.append( "                Referral :" ).append( referral.toString() ).append( '\n' );
502        }
503
504        return sb.toString();
505    }
506}