001    /*
002     * Copyright 2013-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk.unboundidds.controls;
022    
023    
024    
025    import java.util.ArrayList;
026    import java.util.Collection;
027    import java.util.Collections;
028    import java.util.Iterator;
029    import java.util.List;
030    
031    import com.unboundid.asn1.ASN1Boolean;
032    import com.unboundid.asn1.ASN1Element;
033    import com.unboundid.asn1.ASN1Enumerated;
034    import com.unboundid.asn1.ASN1OctetString;
035    import com.unboundid.asn1.ASN1Sequence;
036    import com.unboundid.ldap.sdk.Control;
037    import com.unboundid.ldap.sdk.DecodeableControl;
038    import com.unboundid.ldap.sdk.LDAPException;
039    import com.unboundid.ldap.sdk.LDAPResult;
040    import com.unboundid.ldap.sdk.ResultCode;
041    import com.unboundid.util.Debug;
042    import com.unboundid.util.NotMutable;
043    import com.unboundid.util.StaticUtils;
044    import com.unboundid.util.ThreadSafety;
045    import com.unboundid.util.ThreadSafetyLevel;
046    
047    import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
048    
049    
050    
051    /**
052     * <BLOCKQUOTE>
053     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
054     *   LDAP SDK for Java.  It is not available for use in applications that
055     *   include only the Standard Edition of the LDAP SDK, and is not supported for
056     *   use in conjunction with non-UnboundID products.
057     * </BLOCKQUOTE>
058     * This class provides an implementation of an LDAP control that can be included
059     * in add, bind, modify, modify DN, and certain extended responses to provide
060     * information about the result of replication assurance processing for that
061     * operation.
062     * <BR><BR>
063     * The OID for this control is 1.3.6.1.4.1.30221.2.5.29.  It will have a
064     * criticality of FALSE, and will have a value with the following encoding:
065     * <PRE>
066     *   AssuredReplicationResponse ::= SEQUENCE {
067     *        localLevel                   [0] LocalLevel OPTIONAL,
068     *        localAssuranceSatisfied      [1] BOOLEAN,
069     *        localAssuranceMessage        [2] OCTET STRING OPTIONAL,
070     *        remoteLevel                  [3] RemoteLevel OPTIONAL,
071     *        remoteAssuranceSatisfied     [4] BOOLEAN,
072     *        remoteAssuranceMessage       [5] OCTET STRING OPTIONAL,
073     *        csn                          [6] OCTET STRING OPTIONAL,
074     *        serverResults                [7] SEQUENCE OF ServerResult OPTIONAL,
075     *        ... }
076     *
077     *   ServerResult ::= SEQUENCE {
078     *        resultCode              [0] ENUMERATED {
079     *             complete           (0),
080     *             timeout            (1),
081     *             conflict           (2),
082     *             serverShutdown     (3),
083     *             unavailable        (4),
084     *             duplicate          (5),
085     *             ... },
086     *        replicationServerID     [1] INTEGER OPTIONAL,
087     *        replicaID               [2] INTEGER OPTIONAL,
088     *        ... }
089     * </PRE>
090     *
091     * @see  AssuredReplicationRequestControl
092     */
093    @NotMutable()
094    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
095    public final class AssuredReplicationResponseControl
096           extends Control
097           implements DecodeableControl
098    {
099      /**
100       * The OID (1.3.6.1.4.1.30221.2.5.29) for the assured replication response
101       * control.
102       */
103      public static final String ASSURED_REPLICATION_RESPONSE_OID =
104           "1.3.6.1.4.1.30221.2.5.29";
105    
106    
107      /**
108       * The BER type for the local level element.
109       */
110      private static final byte TYPE_LOCAL_LEVEL = (byte) 0x80;
111    
112    
113      /**
114       * The BER type for the local assurance satisfied element.
115       */
116      private static final byte TYPE_LOCAL_SATISFIED = (byte) 0x81;
117    
118    
119      /**
120       * The BER type for the local message element.
121       */
122      private static final byte TYPE_LOCAL_MESSAGE = (byte) 0x82;
123    
124    
125      /**
126       * The BER type for the remote level element.
127       */
128      private static final byte TYPE_REMOTE_LEVEL = (byte) 0x83;
129    
130    
131      /**
132       * The BER type for the remote assurance satisfied element.
133       */
134      private static final byte TYPE_REMOTE_SATISFIED = (byte) 0x84;
135    
136    
137      /**
138       * The BER type for the remote message element.
139       */
140      private static final byte TYPE_REMOTE_MESSAGE = (byte) 0x85;
141    
142    
143      /**
144       * The BER type for the CSN element.
145       */
146      private static final byte TYPE_CSN = (byte) 0x86;
147    
148    
149      /**
150       * The BER type for the server results element.
151       */
152      private static final byte TYPE_SERVER_RESULTS = (byte) 0xA7;
153    
154    
155    
156      /**
157       * The serial version UID for this serializable class.
158       */
159      private static final long serialVersionUID = -4521456074629871607L;
160    
161    
162    
163      // The assurance level for local processing.
164      private final AssuredReplicationLocalLevel localLevel;
165    
166      // The assurance level for remote processing.
167      private final AssuredReplicationRemoteLevel remoteLevel;
168    
169      // Indicates whether the desired local assurance has been satisfied.
170      private final boolean localAssuranceSatisfied;
171    
172      // Indicates whether the desired remote assurance has been satisfied.
173      private final boolean remoteAssuranceSatisfied;
174    
175      // The results from individual replication and/or directory servers.
176      private final List<AssuredReplicationServerResult> serverResults;
177    
178      // The replication change sequence number for the associated operation.
179      private final String csn;
180    
181      // An optional message with additional information about local assurance
182      // processing.
183      private final String localAssuranceMessage;
184    
185      // An optional message with additional information about local assurance
186      // processing.
187      private final String remoteAssuranceMessage;
188    
189    
190    
191      /**
192       * Creates a new empty control instance that is intended to be used only for
193       * decoding controls via the {@code DecodeableControl} interface.
194       */
195      AssuredReplicationResponseControl()
196      {
197        localLevel = null;
198        localAssuranceSatisfied = false;
199        localAssuranceMessage = null;
200        remoteLevel = null;
201        remoteAssuranceSatisfied = false;
202        remoteAssuranceMessage = null;
203        csn = null;
204        serverResults = null;
205      }
206    
207    
208    
209      /**
210       * Creates a new assured replication response control with the provided
211       * information.
212       *
213       * @param  localLevel                The local assurance level selected by the
214       *                                   server for the associated operation.  It
215       *                                   may be {@code null} if this is not
216       *                                   available.
217       * @param  localAssuranceSatisfied   Indicates whether the desired local level
218       *                                   of assurance is known to have been
219       *                                   satisfied.
220       * @param  localAssuranceMessage     An optional message providing additional
221       *                                   information about local assurance
222       *                                   processing.  This may be {@code null} if
223       *                                   no additional message is needed.
224       * @param  remoteLevel               The remote assurance level selected by
225       *                                   the server for the associated operation.
226       *                                   It may be {@code null} if this is not
227       *                                   available.
228       * @param  remoteAssuranceSatisfied  Indicates whether the desired remote
229       *                                   level of assurance is known to have been
230       *                                   satisfied.
231       * @param  remoteAssuranceMessage    An optional message providing additional
232       *                                   information about remote assurance
233       *                                   processing.  This may be {@code null} if
234       *                                   no additional message is needed.
235       * @param  csn                       The change sequence number (CSN) that has
236       *                                   been assigned to the associated
237       *                                   operation.  It may be {@code null} if no
238       *                                   CSN is available.
239       * @param  serverResults             The set of individual results from the
240       *                                   local and/or remote replication servers
241       *                                   and/or directory servers used in
242       *                                   assurance processing.  This may be
243       *                                   {@code null} or empty if no server
244       *                                   results are available.
245       */
246      public AssuredReplicationResponseControl(
247                  final AssuredReplicationLocalLevel localLevel,
248                  final boolean localAssuranceSatisfied,
249                  final String localAssuranceMessage,
250                  final AssuredReplicationRemoteLevel remoteLevel,
251                  final boolean remoteAssuranceSatisfied,
252                  final String remoteAssuranceMessage, final String csn,
253                  final Collection<AssuredReplicationServerResult> serverResults)
254      {
255        super(ASSURED_REPLICATION_RESPONSE_OID, false,
256             encodeValue(localLevel, localAssuranceSatisfied,
257                  localAssuranceMessage, remoteLevel, remoteAssuranceSatisfied,
258                  remoteAssuranceMessage, csn, serverResults));
259    
260        this.localLevel               = localLevel;
261        this.localAssuranceSatisfied  = localAssuranceSatisfied;
262        this.localAssuranceMessage    = localAssuranceMessage;
263        this.remoteLevel              = remoteLevel;
264        this.remoteAssuranceSatisfied = remoteAssuranceSatisfied;
265        this.remoteAssuranceMessage   = remoteAssuranceMessage;
266        this.csn                      = csn;
267    
268        if (serverResults == null)
269        {
270          this.serverResults = Collections.emptyList();
271        }
272        else
273        {
274          this.serverResults = Collections.unmodifiableList(
275               new ArrayList<AssuredReplicationServerResult>(serverResults));
276        }
277      }
278    
279    
280    
281      /**
282       * Creates a new assured replication response control with the provided
283       * information.
284       *
285       * @param  oid         The OID for the control.
286       * @param  isCritical  Indicates whether the control should be marked
287       *                     critical.
288       * @param  value       The encoded value for the control.  This may be
289       *                     {@code null} if no value was provided.
290       *
291       * @throws  LDAPException  If the provided control cannot be decoded as an
292       *                         assured replication response control.
293       */
294      public AssuredReplicationResponseControl(final String oid,
295                                               final boolean isCritical,
296                                               final ASN1OctetString value)
297             throws LDAPException
298      {
299        super(oid, isCritical, value);
300    
301        if (value == null)
302        {
303          throw new LDAPException(ResultCode.DECODING_ERROR,
304               ERR_ASSURED_REPLICATION_RESPONSE_NO_VALUE.get());
305        }
306    
307        AssuredReplicationLocalLevel         lLevel     = null;
308        Boolean                              lSatisfied = null;
309        String                               lMessage   = null;
310        AssuredReplicationRemoteLevel        rLevel     = null;
311        Boolean                              rSatisfied = null;
312        String                               rMessage   = null;
313        String                               seqNum     = null;
314        List<AssuredReplicationServerResult> sResults   = Collections.emptyList();
315    
316        try
317        {
318          for (final ASN1Element e :
319               ASN1Sequence.decodeAsSequence(value.getValue()).elements())
320          {
321            switch (e.getType())
322            {
323              case TYPE_LOCAL_LEVEL:
324                int intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
325                lLevel = AssuredReplicationLocalLevel.valueOf(intValue);
326                if (lLevel == null)
327                {
328                  throw new LDAPException(ResultCode.DECODING_ERROR,
329                       ERR_ASSURED_REPLICATION_RESPONSE_INVALID_LOCAL_LEVEL.get(
330                            intValue));
331                }
332                break;
333    
334              case TYPE_LOCAL_SATISFIED:
335                lSatisfied = ASN1Boolean.decodeAsBoolean(e).booleanValue();
336                break;
337    
338              case TYPE_LOCAL_MESSAGE:
339                lMessage = ASN1OctetString.decodeAsOctetString(e).stringValue();
340                break;
341    
342              case TYPE_REMOTE_LEVEL:
343                intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
344                rLevel = AssuredReplicationRemoteLevel.valueOf(intValue);
345                if (lLevel == null)
346                {
347                  throw new LDAPException(ResultCode.DECODING_ERROR,
348                       ERR_ASSURED_REPLICATION_RESPONSE_INVALID_REMOTE_LEVEL.get(
349                            intValue));
350                }
351                break;
352    
353              case TYPE_REMOTE_SATISFIED:
354                rSatisfied = ASN1Boolean.decodeAsBoolean(e).booleanValue();
355                break;
356    
357              case TYPE_REMOTE_MESSAGE:
358                rMessage = ASN1OctetString.decodeAsOctetString(e).stringValue();
359                break;
360    
361              case TYPE_CSN:
362                seqNum = ASN1OctetString.decodeAsOctetString(e).stringValue();
363                break;
364    
365              case TYPE_SERVER_RESULTS:
366                final ASN1Element[] srElements =
367                     ASN1Sequence.decodeAsSequence(e).elements();
368                final ArrayList<AssuredReplicationServerResult> srList =
369                     new ArrayList<AssuredReplicationServerResult>(
370                          srElements.length);
371                for (final ASN1Element srElement : srElements)
372                {
373                  try
374                  {
375                    srList.add(AssuredReplicationServerResult.decode(srElement));
376                  }
377                  catch (final Exception ex)
378                  {
379                    Debug.debugException(ex);
380                    throw new LDAPException(ResultCode.DECODING_ERROR,
381                         ERR_ASSURED_REPLICATION_RESPONSE_ERROR_DECODING_SR.get(
382                              StaticUtils.getExceptionMessage(ex)),
383                         ex);
384                  }
385                }
386                sResults = Collections.unmodifiableList(srList);
387                break;
388    
389              default:
390                throw new LDAPException(ResultCode.DECODING_ERROR,
391                     ERR_ASSURED_REPLICATION_RESPONSE_UNEXPECTED_ELEMENT_TYPE.get(
392                          StaticUtils.toHex(e.getType())));
393            }
394          }
395        }
396        catch (final LDAPException le)
397        {
398          Debug.debugException(le);
399          throw le;
400        }
401        catch (final Exception e)
402        {
403          Debug.debugException(e);
404          throw new LDAPException(ResultCode.DECODING_ERROR,
405               ERR_ASSURED_REPLICATION_RESPONSE_ERROR_DECODING_VALUE.get(
406                    StaticUtils.getExceptionMessage(e)),
407               e);
408        }
409    
410        if (lSatisfied == null)
411        {
412          throw new LDAPException(ResultCode.DECODING_ERROR,
413               ERR_ASSURED_REPLICATION_RESPONSE_NO_LOCAL_SATISFIED.get());
414        }
415    
416        if (rSatisfied == null)
417        {
418          throw new LDAPException(ResultCode.DECODING_ERROR,
419               ERR_ASSURED_REPLICATION_RESPONSE_NO_REMOTE_SATISFIED.get());
420        }
421    
422        localLevel               = lLevel;
423        localAssuranceSatisfied  = lSatisfied;
424        localAssuranceMessage    = lMessage;
425        remoteLevel              = rLevel;
426        remoteAssuranceSatisfied = rSatisfied;
427        remoteAssuranceMessage   = rMessage;
428        csn                      = seqNum;
429        serverResults            = sResults;
430      }
431    
432    
433    
434      /**
435       * Encodes the provided information to an ASN.1 octet string suitable for
436       * use as an assured replication response control value.
437       *
438       * @param  localLevel                The local assurance level selected by the
439       *                                   server for the associated operation.  It
440       *                                   may be {@code null} if this is not
441       *                                   available.
442       * @param  localAssuranceSatisfied   Indicates whether the desired local level
443       *                                   of assurance is known to have been
444       *                                   satisfied.
445       * @param  localAssuranceMessage     An optional message providing additional
446       *                                   information about local assurance
447       *                                   processing.  This may be {@code null} if
448       *                                   no additional message is needed.
449       * @param  remoteLevel               The remote assurance level selected by
450       *                                   the server for the associated operation.
451       *                                   It may be {@code null} if this is not
452       *                                   available.
453       * @param  remoteAssuranceSatisfied  Indicates whether the desired remote
454       *                                   level of assurance is known to have been
455       *                                   satisfied.
456       * @param  remoteAssuranceMessage    An optional message providing additional
457       *                                   information about remote assurance
458       *                                   processing.  This may be {@code null} if
459       *                                   no additional message is needed.
460       * @param  csn                       The change sequence number (CSN) that has
461       *                                   been assigned to the associated
462       *                                   operation.  It may be {@code null} if no
463       *                                   CSN is available.
464       * @param  serverResults             The set of individual results from the
465       *                                   local and/or remote replication servers
466       *                                   and/or directory servers used in
467       *                                   assurance processing.  This may be
468       *                                   {@code null} or empty if no server
469       *                                   results are available.
470       *
471       * @return  The ASN.1 octet string containing the encoded value.
472       */
473      private static ASN1OctetString encodeValue(
474                   final AssuredReplicationLocalLevel localLevel,
475                   final boolean localAssuranceSatisfied,
476                   final String localAssuranceMessage,
477                   final AssuredReplicationRemoteLevel remoteLevel,
478                   final boolean remoteAssuranceSatisfied,
479                   final String remoteAssuranceMessage, final String csn,
480                   final Collection<AssuredReplicationServerResult> serverResults)
481      {
482        final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(8);
483    
484        if (localLevel != null)
485        {
486          elements.add(new ASN1Enumerated(TYPE_LOCAL_LEVEL, localLevel.intValue()));
487        }
488    
489        elements.add(new ASN1Boolean(TYPE_LOCAL_SATISFIED,
490             localAssuranceSatisfied));
491    
492        if (localAssuranceMessage != null)
493        {
494          elements.add(new ASN1OctetString(TYPE_LOCAL_MESSAGE,
495               localAssuranceMessage));
496        }
497    
498        if (remoteLevel != null)
499        {
500          elements.add(new ASN1Enumerated(TYPE_REMOTE_LEVEL,
501               remoteLevel.intValue()));
502        }
503    
504        elements.add(new ASN1Boolean(TYPE_REMOTE_SATISFIED,
505             remoteAssuranceSatisfied));
506    
507        if (remoteAssuranceMessage != null)
508        {
509          elements.add(new ASN1OctetString(TYPE_REMOTE_MESSAGE,
510               remoteAssuranceMessage));
511        }
512    
513        if (csn != null)
514        {
515          elements.add(new ASN1OctetString(TYPE_CSN, csn));
516        }
517    
518        if ((serverResults !=  null) && (! serverResults.isEmpty()))
519        {
520          final ArrayList<ASN1Element> srElements =
521               new ArrayList<ASN1Element>(serverResults.size());
522          for (final AssuredReplicationServerResult r : serverResults)
523          {
524            srElements.add(r.encode());
525          }
526          elements.add(new ASN1Sequence(TYPE_SERVER_RESULTS, srElements));
527        }
528    
529        return new ASN1OctetString(new ASN1Sequence(elements).encode());
530      }
531    
532    
533    
534      /**
535       * {@inheritDoc}
536       */
537      public AssuredReplicationResponseControl decodeControl(final String oid,
538                                                    final boolean isCritical,
539                                                    final ASN1OctetString value)
540             throws LDAPException
541      {
542        return new AssuredReplicationResponseControl(oid, isCritical, value);
543      }
544    
545    
546    
547      /**
548       * Extracts an assured replication response control from the provided LDAP
549       * result.  If there are multiple assured replication response controls
550       * included in the result, then only the first will be returned.
551       *
552       * @param  result  The LDAP result from which to retrieve the assured
553       *                 replication response control.
554       *
555       * @return  The assured replication response control contained in the provided
556       *          LDAP result, or {@code null} if the result did not contain an
557       *          assured replication response control.
558       *
559       * @throws  LDAPException  If a problem is encountered while attempting to
560       *                         decode the assured replication response control
561       *                         contained in the provided result.
562       */
563      public static AssuredReplicationResponseControl get(final LDAPResult result)
564             throws LDAPException
565      {
566        final Control c =
567             result.getResponseControl(ASSURED_REPLICATION_RESPONSE_OID);
568        if (c == null)
569        {
570          return null;
571        }
572    
573        if (c instanceof AssuredReplicationResponseControl)
574        {
575          return (AssuredReplicationResponseControl) c;
576        }
577        else
578        {
579          return new AssuredReplicationResponseControl(c.getOID(), c.isCritical(),
580               c.getValue());
581        }
582      }
583    
584    
585    
586      /**
587       * Extracts an assured replication response control from the provided LDAP
588       * result.  If there are multiple assured replication response controls
589       * included in the result, then only the first will be returned.
590       *
591       * @param  result  The LDAP result from which to retrieve the assured
592       *                 replication response control.
593       *
594       * @return  The assured replication response control contained in the provided
595       *          LDAP result, or {@code null} if the result did not contain an
596       *          assured replication response control.
597       *
598       * @throws  LDAPException  If a problem is encountered while attempting to
599       *                         decode the assured replication response control
600       *                         contained in the provided result.
601       */
602      public static List<AssuredReplicationResponseControl> getAll(
603                         final LDAPResult result)
604             throws LDAPException
605      {
606        final Control[] controls = result.getResponseControls();
607        final ArrayList<AssuredReplicationResponseControl> decodedControls =
608             new ArrayList<AssuredReplicationResponseControl>(controls.length);
609        for (final Control c : controls)
610        {
611          if (c.getOID().equals(ASSURED_REPLICATION_RESPONSE_OID))
612          {
613            if (c instanceof AssuredReplicationResponseControl)
614            {
615              decodedControls.add((AssuredReplicationResponseControl) c);
616            }
617            else
618            {
619              decodedControls.add(new AssuredReplicationResponseControl(c.getOID(),
620                   c.isCritical(), c.getValue()));
621            }
622          }
623        }
624    
625        return Collections.unmodifiableList(decodedControls);
626      }
627    
628    
629    
630      /**
631       * Retrieves the local assurance level selected by the server for the
632       * associated operation, if available.
633       *
634       * @return  The local assurance level selected by the server for the
635       *          associated operation, or {@code null} if this is not available.
636       */
637      public AssuredReplicationLocalLevel getLocalLevel()
638      {
639        return localLevel;
640      }
641    
642    
643    
644      /**
645       * Indicates whether the desired local level of assurance is known to have
646       * been satisfied.
647       *
648       * @return  {@code true} if the desired local level of assurance is known to
649       *          have been satisfied, or {@code false} if not.
650       */
651      public boolean localAssuranceSatisfied()
652      {
653        return localAssuranceSatisfied;
654      }
655    
656    
657    
658      /**
659       * Retrieves a message with additional information about local assurance
660       * processing, if available.
661       *
662       * @return  A message with additional information about local assurance
663       *          processing, or {@code null} if none is available.
664       */
665      public String getLocalAssuranceMessage()
666      {
667        return localAssuranceMessage;
668      }
669    
670    
671    
672      /**
673       * Retrieves the remote assurance level selected by the server for the
674       * associated operation, if available.
675       *
676       * @return  The remote assurance level selected by the server for the
677       *          associated operation, or {@code null} if the remote assurance
678       *          level is not available.
679       */
680      public AssuredReplicationRemoteLevel getRemoteLevel()
681      {
682        return remoteLevel;
683      }
684    
685    
686    
687      /**
688       * Indicates whether the desired remote level of assurance is known to have
689       * been satisfied.
690       *
691       * @return  {@code true} if the desired remote level of assurance is known to
692       *          have been satisfied, or {@code false} if not.
693       */
694      public boolean remoteAssuranceSatisfied()
695      {
696        return remoteAssuranceSatisfied;
697      }
698    
699    
700    
701      /**
702       * Retrieves a message with additional information about remote assurance
703       * processing, if available.
704       *
705       * @return  A message with additional information about remote assurance
706       *          processing, or {@code null} if none is available.
707       */
708      public String getRemoteAssuranceMessage()
709      {
710        return remoteAssuranceMessage;
711      }
712    
713    
714    
715      /**
716       * Retrieves the replication change sequence number (CSN) assigned to the
717       * associated operation, if available.
718       *
719       * @return  The replication CSN assigned to the associated operation, or
720       *          {@code null} if the CSN is not available.
721       */
722      public String getCSN()
723      {
724        return csn;
725      }
726    
727    
728    
729      /**
730       * Retrieves a list of the results from individual replication servers and/or
731       * directory servers used in assurance processing.  It may be empty if no
732       * server results are available.
733       *
734       * @return  A list of the results from individual replication servers and/or
735       *          directory servers used in assurance processing.
736       */
737      public List<AssuredReplicationServerResult> getServerResults()
738      {
739        return serverResults;
740      }
741    
742    
743    
744      /**
745       * {@inheritDoc}
746       */
747      @Override()
748      public String getControlName()
749      {
750        return INFO_CONTROL_NAME_ASSURED_REPLICATION_RESPONSE.get();
751      }
752    
753    
754    
755      /**
756       * {@inheritDoc}
757       */
758      @Override()
759      public void toString(final StringBuilder buffer)
760      {
761        buffer.append("AssuredReplicationResponseControl(isCritical=");
762        buffer.append(isCritical());
763    
764        if (localLevel != null)
765        {
766          buffer.append(", localLevel=");
767          buffer.append(localLevel.name());
768        }
769    
770        buffer.append(", localAssuranceSatisfied=");
771        buffer.append(localAssuranceSatisfied);
772    
773        if (localAssuranceMessage != null)
774        {
775          buffer.append(", localMessage='");
776          buffer.append(localAssuranceMessage);
777          buffer.append('\'');
778        }
779    
780        if (remoteLevel != null)
781        {
782          buffer.append(", remoteLevel=");
783          buffer.append(remoteLevel.name());
784        }
785    
786        buffer.append(", remoteAssuranceSatisfied=");
787        buffer.append(remoteAssuranceSatisfied);
788    
789        if (remoteAssuranceMessage != null)
790        {
791          buffer.append(", remoteMessage='");
792          buffer.append(remoteAssuranceMessage);
793          buffer.append('\'');
794        }
795    
796        if (csn != null)
797        {
798          buffer.append(", csn='");
799          buffer.append(csn);
800          buffer.append('\'');
801        }
802    
803        if ((serverResults != null) && (! serverResults.isEmpty()))
804        {
805          buffer.append(", serverResults={");
806    
807          final Iterator<AssuredReplicationServerResult> iterator =
808               serverResults.iterator();
809          while (iterator.hasNext())
810          {
811            if (iterator.hasNext())
812            {
813              iterator.next().toString(buffer);
814              buffer.append(", ");
815            }
816          }
817    
818          buffer.append('}');
819        }
820    
821        buffer.append(')');
822      }
823    }