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