001/*
002 * Copyright 2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2019 Ping Identity Corporation
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 */
021package com.unboundid.util;
022
023
024
025import java.io.Serializable;
026import java.util.Collections;
027import java.util.SortedMap;
028import java.util.TreeMap;
029
030import com.unboundid.ldap.sdk.DN;
031import com.unboundid.ldap.sdk.LDAPResult;
032import com.unboundid.ldap.sdk.SearchResult;
033
034
035
036/**
037 * This class provides a data structure with information about the results of
038 * a subtree delete attempt.
039 *
040 * @see  SubtreeDeleter
041 */
042@NotMutable()
043@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
044public final class SubtreeDeleterResult
045       implements Serializable
046{
047  /**
048   * The serial version UID for this serializable class.
049   */
050  private static final long serialVersionUID = -4801520019525316763L;
051
052
053
054  // Indicates whether the target subtree is inaccessible.
055  private final boolean subtreeInaccessible;
056
057  // An error that occurred during an attempt to make the target subtree
058  // inaccessible.
059  private final LDAPResult setSubtreeAccessibilityError;
060
061  // The number of entries that were successfully deleted.
062  private final long entriesDeleted;
063
064  // An error that occurred during search processing that prevented identifying
065  // all of the entries in the target subtree.
066  private final SearchResult searchError;
067
068  // A map that contains the DNs of the entries that could not be deleted,
069  // associated with a result indicating the reason for the delete failure.
070  // It will be sorted in descending order
071  private final TreeMap<DN,LDAPResult> deleteErrors;
072
073
074
075  /**
076   * Creates a new subtree deleter result with the provided information.
077   *
078   * @param  setSubtreeAccessibilityError
079   *              An {@code LDAPResult} object with information about an error
080   *              that occurred while trying to make the target subtree
081   *              inaccessible, or while trying to remove that accessibility
082   *              restriction after all other processing completed successfully
083   *              (and the two cases can be differentiated using the value of
084   *              the {@code subtreeInaccessible} argument).  This may be
085   *              {@code null} if no attempt was made to alter the accessibility
086   *              of the target subtree, or if its accessibility was
087   *              successfully altered.
088   * @param  subtreeInaccessible
089   *              Indicates whether the target subtree was left inaccessible
090   *              after processing completed.  If the subtree was made
091   *              inaccessible, it will be left in an inaccessible state if any
092   *              error occurs during search or delete processing.  The
093   *              accessibility restriction will be removed if all processing
094   *              completes successfully.
095   * @param  searchError
096   *              A search result with information about an error that occurred
097   *              during search processing that prevented identifying all of the
098   *              entries in the target subtree.  It may be {@code null} if
099   *              there was no error during search processing.
100   * @param  entriesDeleted
101   *              The number of entries that were successfully deleted.
102   * @param  deleteErrors
103   *              A map that contains the DNs of entries that could not be
104   *              deleted, associated with a result indicating the reason for
105   *              the delete failure.  It must not be {@code null} but may be
106   *              empty.
107   */
108  SubtreeDeleterResult(final LDAPResult setSubtreeAccessibilityError,
109                       final boolean subtreeInaccessible,
110                       final SearchResult searchError,
111                       final long entriesDeleted,
112                       final TreeMap<DN,LDAPResult> deleteErrors)
113  {
114    this.setSubtreeAccessibilityError = setSubtreeAccessibilityError;
115    this.subtreeInaccessible = subtreeInaccessible;
116    this.searchError = searchError;
117    this.entriesDeleted = entriesDeleted;
118    this.deleteErrors = deleteErrors;
119  }
120
121
122
123  /**
124   * Indicates whether the {@link SubtreeDeleter} processing was completely
125   * successful.
126   *
127   * @return  {@code true} if the subtree deleter processing was completely
128   *          successful, or {@code false} if not.
129   */
130  public boolean completelySuccessful()
131  {
132    return ((setSubtreeAccessibilityError == null) &&
133         (! subtreeInaccessible) &&
134         (searchError == null) &&
135         deleteErrors.isEmpty());
136  }
137
138
139
140  /**
141   * Retrieves an {@code LDAPResult} that provides information about an error
142   * that occurred while trying to make the target subtree inaccessible before
143   * subtree delete processing, or if an error occurred while trying to remove
144   * the subtree accessibility restriction after all other processing had
145   * completed successfully.  This may be {@code null} if no attempts was made
146   * to alter the subtree accessibility, or if no error occurred during
147   * processing.
148   * <BR><BR>
149   * If the return value is non-{@code null} and {@link #subtreeInaccessible}
150   * returns {@code false}, then the error occurred while attempting to make the
151   * target subtree inaccessible.  If the return value is non-{@code null} and
152   * {@code isSubtreeInaccessible} returns {@code true}, then the error occurred
153   * while attempting to remove the subtree accessibility restriction.
154   *
155   * @return  An {@code LDAPResult} that provides information about an error
156   *          that occurred while attempting to alter the accessibility of the
157   *          target subtree, or {@code null} if no such error occurred.
158   */
159  public LDAPResult getSetSubtreeAccessibilityError()
160  {
161    return setSubtreeAccessibilityError;
162  }
163
164
165
166  /**
167   * Indicates whether the target subtree was left in an inaccessible state
168   * after some error occurred during subtree delete processing.
169   *
170   * @return  {@code true} if the subtree was set inaccessible at the start of
171   *          subtree delete processing and remains inaccessible after an error
172   *          occurred during processing, or {@code false} if the subtree
173   *          accessibility was not altered or if the accessibility restriction
174   *          was removed after all processing completed successfully.
175   */
176  public boolean subtreeInaccessible()
177  {
178    return subtreeInaccessible;
179  }
180
181
182
183  /**
184   * Retrieves a search result with information about an error that occurred
185   * during search processing that prevented identifying all of the entries in
186   * the target subtree.
187   *
188   * @return  A search result with information about an error that occurred
189   *          during search processing that prevented identifying all of the
190   *          entries in the target subtree, or {@code null} if no error
191   *          occurred during search processing.
192   */
193  public SearchResult getSearchError()
194  {
195    return searchError;
196  }
197
198
199
200  /**
201   * Retrieves the number of entries that were successfully deleted.
202   *
203   * @return  The number of entries that were successfully deleted.
204   */
205  public long getEntriesDeleted()
206  {
207    return entriesDeleted;
208  }
209
210
211
212  /**
213   * Retrieves an unmodifiable sorted map of the DNs of entries that could not
214   * be successfully deleted, each of which is associated with an
215   * {@code LDAPResult} indicating the reason for the delete failure.  The map
216   * will be ordered in ascending order using the comparator provided by the
217   * {@code DN} class (that is, with ancestor entries before their descendants).
218   *
219   * @return  An unmodifiable sorted map of the DNs of the entries that could
220   *          not be deleted, each of which is associated with an
221   *          {@code LDAPResult} indicating the reason for the delete failure.
222   */
223  public SortedMap<DN,LDAPResult> getDeleteErrors()
224  {
225    return Collections.unmodifiableSortedMap(deleteErrors);
226  }
227
228
229
230  /**
231   * Retrieves an unmodifiable sorted map of the DNs of entries that could not
232   * be successfully deleted, each of which is associated with an
233   * {@code LDAPResult} indicating the reason for the delete failure.  The map
234   * will be ordered in descending order using the comparator provided by the
235   * {@code DN} class (that is, with descendant entries before their ancestors).
236   *
237   * @return  An unmodifiable sorted map of the DNs of the entries that could
238   *          not be deleted, each of which is associated with an
239   *          {@code LDAPResult} indicating the reason for the delete failure.
240   */
241  public SortedMap<DN,LDAPResult> getDeleteErrorsDescendingMap()
242  {
243    return Collections.unmodifiableSortedMap(deleteErrors.descendingMap());
244  }
245
246
247
248  /**
249   * Retrieves the delete errors as a {@code TreeMap}.
250   *
251   * @return  Retrieves the delete errors as a {@code TreeMap}.
252   */
253  TreeMap<DN,LDAPResult> getDeleteErrorsTreeMap()
254  {
255    return deleteErrors;
256  }
257
258
259
260  /**
261   * Retrieves a string representation of this subtree deleter result.
262   *
263   * @return  A string representation of this subtree deleter result.
264   */
265  @Override()
266  public String toString()
267  {
268    final StringBuilder buffer = new StringBuilder();
269    toString(buffer);
270    return buffer.toString();
271  }
272
273
274
275  /**
276   * Appends a string representation of this subtree deleter result to the
277   * provided buffer.
278   *
279   * @param  buffer  The buffer to which the string representation should be
280   *                 appended.
281   */
282  public void toString(final StringBuilder buffer)
283  {
284    buffer.append("SubtreeDeleterResult=(completelySuccessful=");
285    buffer.append(completelySuccessful());
286
287    if (setSubtreeAccessibilityError != null)
288    {
289      buffer.append(", setSubtreeAccessibilityError=");
290      setSubtreeAccessibilityError.toString(buffer);
291    }
292
293    if (subtreeInaccessible)
294    {
295      buffer.append(", subtreeInaccessible=true");
296    }
297
298    if (searchError != null)
299    {
300      buffer.append(", searchError=");
301      searchError.toString(buffer);
302    }
303
304    buffer.append(", entriesDeleted=");
305    buffer.append(entriesDeleted);
306
307    if (! deleteErrors.isEmpty())
308    {
309      buffer.append(", deleteErrors=");
310      buffer.append(deleteErrors);
311    }
312  }
313}