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