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}