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 2006-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014 ForgeRock AS. 016 */ 017package org.opends.server.types; 018 019import java.io.IOException; 020import java.util.ArrayList; 021 022import org.forgerock.i18n.LocalizableMessage; 023import org.forgerock.i18n.slf4j.LocalizedLogger; 024import org.forgerock.opendj.io.ASN1Reader; 025import org.forgerock.opendj.io.ASN1Writer; 026import org.forgerock.opendj.ldap.ByteString; 027import org.forgerock.opendj.ldap.ModificationType; 028import org.opends.server.protocols.ldap.LDAPModification; 029 030import static org.opends.messages.ProtocolMessages.*; 031import static org.opends.server.protocols.ldap.LDAPConstants.*; 032import static org.opends.server.protocols.ldap.LDAPResultCode.*; 033 034/** 035 * This class defines the data structures and methods to use when 036 * interacting with a raw modification, which describes a change that 037 * should be made to an attribute. 038 */ 039@org.opends.server.types.PublicAPI( 040 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 041 mayInstantiate=true, 042 mayExtend=false, 043 mayInvoke=true) 044public abstract class RawModification 045{ 046 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 047 048 /** 049 * Creates a new raw modification with the provided type and 050 * attribute. 051 * 052 * @param modificationType The modification type for this 053 * modification. 054 * @param attribute The attribute for this modification. 055 * 056 * @return The constructed raw modification. 057 */ 058 public static RawModification 059 create(ModificationType modificationType, 060 RawAttribute attribute) 061 { 062 return new LDAPModification(modificationType, attribute); 063 } 064 065 066 067 /** 068 * Creates a new raw modification with the provided type and 069 * attribute. 070 * 071 * @param modificationType The modification type for this 072 * modification. 073 * @param attributeType The name of the attribute type for this 074 * modification. 075 * 076 * @return The constructed raw modification. 077 */ 078 public static RawModification 079 create(ModificationType modificationType, 080 String attributeType) 081 { 082 RawAttribute rawAttribute = RawAttribute.create(attributeType); 083 084 return new LDAPModification(modificationType, rawAttribute); 085 } 086 087 088 089 /** 090 * Creates a new raw modification with the provided type and 091 * attribute. 092 * 093 * @param modificationType The modification type for this 094 * modification. 095 * @param attributeType The name of the attribute type for this 096 * modification. 097 * @param attributeValue The attribute value for this 098 * modification. 099 * 100 * @return The constructed raw modification. 101 */ 102 public static RawModification 103 create(ModificationType modificationType, 104 String attributeType, 105 String attributeValue) 106 { 107 RawAttribute rawAttribute = 108 RawAttribute.create(attributeType, attributeValue); 109 110 return new LDAPModification(modificationType, rawAttribute); 111 } 112 113 114 115 /** 116 * Creates a new raw modification with the provided type and 117 * attribute. 118 * 119 * @param modificationType The modification type for this 120 * modification. 121 * @param attributeType The name of the attribute type for this 122 * modification. 123 * @param attributeValue The attribute value for this 124 * modification. 125 * 126 * @return The constructed raw modification. 127 */ 128 public static RawModification 129 create(ModificationType modificationType, 130 String attributeType, 131 ByteString attributeValue) 132 { 133 RawAttribute rawAttribute = 134 RawAttribute.create(attributeType, attributeValue); 135 136 return new LDAPModification(modificationType, rawAttribute); 137 } 138 139 140 141 /** 142 * Creates a new raw modification with the provided type and 143 * attribute. 144 * 145 * @param modificationType The modification type for this 146 * modification. 147 * @param attributeType The name of the attribute type for this 148 * modification. 149 * @param attributeValues The set of attribute values for this 150 * modification. 151 * 152 * @return The constructed raw modification. 153 */ 154 public static RawModification 155 create(ModificationType modificationType, 156 String attributeType, 157 ArrayList<ByteString> attributeValues) 158 { 159 RawAttribute rawAttribute = 160 RawAttribute.create(attributeType, attributeValues); 161 162 return new LDAPModification(modificationType, rawAttribute); 163 } 164 165 166 167 /** 168 * Retrieves the modification type for this modification. 169 * 170 * @return The modification type for this modification. 171 */ 172 public abstract ModificationType getModificationType(); 173 174 175 176 /** 177 * Specifies the modification type for this modification. 178 * 179 * @param modificationType The modification type for this 180 * modification. 181 */ 182 public abstract void setModificationType( 183 ModificationType modificationType); 184 185 186 187 /** 188 * Retrieves the attribute for this modification. 189 * 190 * @return The attribute for this modification. 191 */ 192 public abstract RawAttribute getAttribute(); 193 194 195 196 /** 197 * Specifies the attribute for this modification. 198 * 199 * @param attribute The attribute for this modification. 200 */ 201 public abstract void setAttribute(RawAttribute attribute); 202 203 204 205 /** 206 * Writes this modification to an ASN.1 stream. 207 * 208 * @param stream The ASN.1 output stream to write to. 209 * @throws IOException If a problem occurs while writing to the 210 * stream. 211 */ 212 public void write(ASN1Writer stream) throws IOException 213 { 214 stream.writeStartSequence(); 215 stream.writeEnumerated(getModificationType().intValue()); 216 getAttribute().write(stream); 217 stream.writeEndSequence(); 218 } 219 220 221 /** 222 * Decodes the elements from the provided ASN.1 reader as an 223 * LDAP modification. 224 * 225 * @param reader The ASN.1 reader. 226 * 227 * @return The decoded LDAP modification. 228 * 229 * @throws LDAPException If a problem occurs while attempting to 230 * decode the provided ASN.1 element as a 231 * raw modification. 232 */ 233 public static LDAPModification decode(ASN1Reader reader) 234 throws LDAPException 235 { 236 try 237 { 238 reader.readStartSequence(); 239 } 240 catch (Exception e) 241 { 242 logger.traceException(e); 243 244 LocalizableMessage message = ERR_LDAP_MODIFICATION_DECODE_SEQUENCE.get(e); 245 throw new LDAPException(PROTOCOL_ERROR, message, e); 246 } 247 248 249 ModificationType modificationType; 250 try 251 { 252 int type = (int)reader.readInteger(); 253 switch (type) 254 { 255 case MOD_TYPE_ADD: 256 modificationType = ModificationType.ADD; 257 break; 258 case MOD_TYPE_DELETE: 259 modificationType = ModificationType.DELETE; 260 break; 261 case MOD_TYPE_REPLACE: 262 modificationType = ModificationType.REPLACE; 263 break; 264 case MOD_TYPE_INCREMENT: 265 modificationType = ModificationType.INCREMENT; 266 break; 267 default: 268 LocalizableMessage message = 269 ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE. 270 get(type); 271 throw new LDAPException(PROTOCOL_ERROR, message); 272 } 273 } 274 catch (LDAPException le) 275 { 276 throw le; 277 } 278 catch (Exception e) 279 { 280 logger.traceException(e); 281 282 LocalizableMessage message = ERR_LDAP_MODIFICATION_DECODE_MOD_TYPE.get(e); 283 throw new LDAPException(PROTOCOL_ERROR, message, e); 284 } 285 286 287 RawAttribute attribute; 288 try 289 { 290 attribute = RawAttribute.decode(reader); 291 } 292 catch (Exception e) 293 { 294 logger.traceException(e); 295 296 LocalizableMessage message = ERR_LDAP_MODIFICATION_DECODE_ATTR.get(e); 297 throw new LDAPException(PROTOCOL_ERROR, message, e); 298 } 299 300 try 301 { 302 reader.readEndSequence(); 303 } 304 catch (Exception e) 305 { 306 logger.traceException(e); 307 308 LocalizableMessage message = ERR_LDAP_MODIFICATION_DECODE_SEQUENCE.get(e); 309 throw new LDAPException(PROTOCOL_ERROR, message, e); 310 } 311 312 313 return new LDAPModification(modificationType, attribute); 314 } 315 316 317 318 /** 319 * Creates a new core {@code Modification} object from this raw 320 * modification. 321 * 322 * @return The decoded modification. 323 * 324 * @throws LDAPException If a problem occurs while trying to 325 * convert the raw modification to a core 326 * {@code Modification}. 327 */ 328 public abstract Modification toModification() 329 throws LDAPException; 330 331 332 333 /** 334 * Retrieves a string representation of this modification. 335 * 336 * @return A string representation of this modification. 337 */ 338 @Override 339 public String toString() 340 { 341 StringBuilder buffer = new StringBuilder(); 342 toString(buffer); 343 return buffer.toString(); 344 } 345 346 347 348 /** 349 * Appends a string representation of this modification to the 350 * provided buffer. 351 * 352 * @param buffer The buffer to which the information should be 353 * appended. 354 */ 355 public abstract void toString(StringBuilder buffer); 356 357 358 359 /** 360 * Appends a multi-line string representation of this LDAP 361 * modification to the provided buffer. 362 * 363 * @param buffer The buffer to which the information should be 364 * appended. 365 * @param indent The number of spaces from the margin that the 366 * lines should be indented. 367 */ 368 public abstract void toString(StringBuilder buffer, int indent); 369} 370