001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2011-2016 ForgeRock AS. 015 */ 016 017package org.forgerock.opendj.ldif; 018 019import static com.forgerock.opendj.ldap.CoreMessages.REJECTED_CHANGE_FAIL_ADD_DUPE; 020import static com.forgerock.opendj.ldap.CoreMessages.REJECTED_CHANGE_FAIL_MODIFYDN_DUPE; 021 022import org.forgerock.i18n.LocalizableMessage; 023import org.forgerock.opendj.ldap.DecodeException; 024import org.forgerock.opendj.ldap.Entry; 025import org.forgerock.opendj.ldap.requests.AddRequest; 026import org.forgerock.opendj.ldap.requests.DeleteRequest; 027import org.forgerock.opendj.ldap.requests.ModifyDNRequest; 028import org.forgerock.opendj.ldap.requests.ModifyRequest; 029 030/** 031 * A listener interface which is notified whenever a change record cannot be 032 * applied to an entry. This may occur when an attempt is made to update a 033 * non-existent entry, or add an entry which already exists. 034 * <p> 035 * By default the {@link #FAIL_FAST} listener is used. 036 */ 037public interface RejectedChangeRecordListener { 038 /** 039 * A handler which terminates processing by throwing a 040 * {@code DecodeException} as soon as a change is rejected. 041 */ 042 RejectedChangeRecordListener FAIL_FAST = new RejectedChangeRecordListener() { 043 044 @Override 045 public Entry handleDuplicateEntry(final AddRequest change, final Entry existingEntry) throws DecodeException { 046 throw DecodeException.error(REJECTED_CHANGE_FAIL_ADD_DUPE.get(change.getName())); 047 } 048 049 @Override 050 public Entry handleDuplicateEntry(final ModifyDNRequest change, final Entry existingEntry, 051 final Entry renamedEntry) throws DecodeException { 052 throw DecodeException.error(REJECTED_CHANGE_FAIL_MODIFYDN_DUPE.get(renamedEntry.getName())); 053 } 054 055 @Override 056 public void handleRejectedChangeRecord(final AddRequest change, final LocalizableMessage reason) 057 throws DecodeException { 058 throw DecodeException.error(reason); 059 } 060 061 @Override 062 public void handleRejectedChangeRecord(final DeleteRequest change, final LocalizableMessage reason) 063 throws DecodeException { 064 throw DecodeException.error(reason); 065 } 066 067 @Override 068 public void handleRejectedChangeRecord(final ModifyRequest change, final LocalizableMessage reason) 069 throws DecodeException { 070 throw DecodeException.error(reason); 071 } 072 073 @Override 074 public void handleRejectedChangeRecord(final ModifyDNRequest change, final LocalizableMessage reason) 075 throws DecodeException { 076 throw DecodeException.error(reason); 077 } 078 079 }; 080 081 /** 082 * The default handler which ignores changes applied to missing entries and 083 * tolerates duplicate entries by overwriting the existing entry with the 084 * new entry. 085 */ 086 RejectedChangeRecordListener OVERWRITE = new RejectedChangeRecordListener() { 087 088 @Override 089 public Entry handleDuplicateEntry(final AddRequest change, final Entry existingEntry) throws DecodeException { 090 // Overwrite existing entries. 091 return change; 092 } 093 094 @Override 095 public Entry handleDuplicateEntry(final ModifyDNRequest change, final Entry existingEntry, 096 final Entry renamedEntry) throws DecodeException { 097 // Overwrite existing entries. 098 return renamedEntry; 099 } 100 101 @Override 102 public void handleRejectedChangeRecord(AddRequest change, LocalizableMessage reason) throws DecodeException { 103 // Ignore. 104 } 105 106 @Override 107 public void handleRejectedChangeRecord(DeleteRequest change, LocalizableMessage reason) 108 throws DecodeException { 109 // Ignore. 110 } 111 112 @Override 113 public void handleRejectedChangeRecord(ModifyRequest change, LocalizableMessage reason) 114 throws DecodeException { 115 // Ignore. 116 } 117 118 @Override 119 public void handleRejectedChangeRecord(ModifyDNRequest change, LocalizableMessage reason) 120 throws DecodeException { 121 // Ignore. 122 } 123 124 }; 125 126 /** 127 * Invoked when an attempt was made to add an entry which already exists. 128 * 129 * @param change 130 * The conflicting add request. 131 * @param existingEntry 132 * The pre-existing entry. 133 * @return The entry which should be kept. 134 * @throws DecodeException 135 * If processing should terminate. 136 */ 137 Entry handleDuplicateEntry(AddRequest change, Entry existingEntry) throws DecodeException; 138 139 /** 140 * Invoked when an attempt was made to rename an entry which already exists. 141 * 142 * @param change 143 * The conflicting add request. 144 * @param existingEntry 145 * The pre-existing entry. 146 * @param renamedEntry 147 * The renamed entry. 148 * @return The entry which should be kept. 149 * @throws DecodeException 150 * If processing should terminate. 151 */ 152 Entry handleDuplicateEntry(ModifyDNRequest change, Entry existingEntry, Entry renamedEntry) 153 throws DecodeException; 154 155 /** 156 * Invoked when an attempt to add an entry was rejected. This may be because 157 * the target parent entry was not found, or controls provided with the 158 * request are not supported. This method will not be called when the entry 159 * to be added already exists, since this is handled by 160 * {@link #handleDuplicateEntry(AddRequest, Entry)}. 161 * 162 * @param change 163 * The rejected add request. 164 * @param reason 165 * The reason why the record was rejected. 166 * @throws DecodeException 167 * If processing should terminate. 168 */ 169 void handleRejectedChangeRecord(AddRequest change, LocalizableMessage reason) 170 throws DecodeException; 171 172 /** 173 * Invoked when an attempt to delete an entry was rejected. This may be 174 * because the target entry was not found, or controls provided with the 175 * request are not supported. 176 * 177 * @param change 178 * The rejected delete request. 179 * @param reason 180 * The reason why the record was rejected. 181 * @throws DecodeException 182 * If processing should terminate. 183 */ 184 void handleRejectedChangeRecord(DeleteRequest change, LocalizableMessage reason) 185 throws DecodeException; 186 187 /** 188 * Invoked when an attempt to modify an entry was rejected. This may be 189 * because the target entry was not found, or controls provided with the 190 * request are not supported. 191 * 192 * @param change 193 * The rejected modify request. 194 * @param reason 195 * The reason why the record was rejected. 196 * @throws DecodeException 197 * If processing should terminate. 198 */ 199 void handleRejectedChangeRecord(ModifyRequest change, LocalizableMessage reason) 200 throws DecodeException; 201 202 /** 203 * Invoked when an attempt to rename an entry was rejected. This may be 204 * because the target entry was not found, or controls provided with the 205 * request are not supported. This method will not be called when a renamed 206 * entry already exists, since this is handled by 207 * {@link #handleDuplicateEntry(ModifyDNRequest, Entry, Entry)}. 208 * 209 * @param change 210 * The rejected modify DN request. 211 * @param reason 212 * The reason why the record was rejected. 213 * @throws DecodeException 214 * If processing should terminate. 215 */ 216 void handleRejectedChangeRecord(ModifyDNRequest change, LocalizableMessage reason) 217 throws DecodeException; 218 219}