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