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 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.types; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.ArrayList; 033 import java.util.List; 034 035 import org.opends.server.protocols.asn1.ASN1Element; 036 import org.opends.server.protocols.asn1.ASN1Enumerated; 037 import org.opends.server.protocols.asn1.ASN1Sequence; 038 import org.opends.server.protocols.ldap.LDAPModification; 039 040 import static org.opends.server.loggers.debug.DebugLogger.*; 041 import org.opends.server.loggers.debug.DebugTracer; 042 import static org.opends.messages.ProtocolMessages.*; 043 import static org.opends.server.protocols.ldap.LDAPConstants.*; 044 import static org.opends.server.protocols.ldap.LDAPResultCode.*; 045 import static org.opends.server.util.ServerConstants.*; 046 047 048 049 /** 050 * This class defines the data structures and methods to use when 051 * interacting with a raw modification, which describes a change that 052 * should be made to an attribute. 053 */ 054 @org.opends.server.types.PublicAPI( 055 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 056 mayInstantiate=true, 057 mayExtend=false, 058 mayInvoke=true) 059 public abstract class RawModification 060 { 061 /** 062 * The tracer object for the debug logger. 063 */ 064 private static final DebugTracer TRACER = getTracer(); 065 066 /** 067 * Creates a new raw modification with the provided type and 068 * attribute. 069 * 070 * @param modificationType The modification type for this 071 * modification. 072 * @param attribute The attribute for this modification. 073 * 074 * @return The constructed raw modification. 075 */ 076 public static RawModification 077 create(ModificationType modificationType, 078 RawAttribute attribute) 079 { 080 return new LDAPModification(modificationType, attribute); 081 } 082 083 084 085 /** 086 * Creates a new raw modification with the provided type and 087 * attribute. 088 * 089 * @param modificationType The modification type for this 090 * modification. 091 * @param attributeType The name of the attribute type for this 092 * modification. 093 * 094 * @return The constructed raw modification. 095 */ 096 public static RawModification 097 create(ModificationType modificationType, 098 String attributeType) 099 { 100 RawAttribute rawAttribute = RawAttribute.create(attributeType); 101 102 return new LDAPModification(modificationType, rawAttribute); 103 } 104 105 106 107 /** 108 * Creates a new raw modification with the provided type and 109 * attribute. 110 * 111 * @param modificationType The modification type for this 112 * modification. 113 * @param attributeType The name of the attribute type for this 114 * modification. 115 * @param attributeValue The attribute value for this 116 * modification. 117 * 118 * @return The constructed raw modification. 119 */ 120 public static RawModification 121 create(ModificationType modificationType, 122 String attributeType, 123 String attributeValue) 124 { 125 RawAttribute rawAttribute = 126 RawAttribute.create(attributeType, attributeValue); 127 128 return new LDAPModification(modificationType, rawAttribute); 129 } 130 131 132 133 /** 134 * Creates a new raw modification with the provided type and 135 * attribute. 136 * 137 * @param modificationType The modification type for this 138 * modification. 139 * @param attributeType The name of the attribute type for this 140 * modification. 141 * @param attributeValue The attribute value for this 142 * modification. 143 * 144 * @return The constructed raw modification. 145 */ 146 public static RawModification 147 create(ModificationType modificationType, 148 String attributeType, 149 ByteString attributeValue) 150 { 151 RawAttribute rawAttribute = 152 RawAttribute.create(attributeType, attributeValue); 153 154 return new LDAPModification(modificationType, rawAttribute); 155 } 156 157 158 159 /** 160 * Creates a new raw modification with the provided type and 161 * attribute. 162 * 163 * @param modificationType The modification type for this 164 * modification. 165 * @param attributeType The name of the attribute type for this 166 * modification. 167 * @param attributeValues The set of attribute values for this 168 * modification. 169 * 170 * @return The constructed raw modification. 171 */ 172 public static RawModification 173 create(ModificationType modificationType, 174 String attributeType, 175 List<ByteString> attributeValues) 176 { 177 RawAttribute rawAttribute = 178 RawAttribute.create(attributeType, attributeValues); 179 180 return new LDAPModification(modificationType, rawAttribute); 181 } 182 183 184 185 /** 186 * Retrieves the modification type for this modification. 187 * 188 * @return The modification type for this modification. 189 */ 190 public abstract ModificationType getModificationType(); 191 192 193 194 /** 195 * Specifies the modification type for this modification. 196 * 197 * @param modificationType The modification type for this 198 * modification. 199 */ 200 public abstract void setModificationType( 201 ModificationType modificationType); 202 203 204 205 /** 206 * Retrieves the attribute for this modification. 207 * 208 * @return The attribute for this modification. 209 */ 210 public abstract RawAttribute getAttribute(); 211 212 213 214 /** 215 * Specifies the attribute for this modification. 216 * 217 * @param attribute The attribute for this modification. 218 */ 219 public abstract void setAttribute(RawAttribute attribute); 220 221 222 223 /** 224 * Encodes this modification to an ASN.1 element. 225 * 226 * @return The ASN.1 element containing the encoded modification. 227 */ 228 public final ASN1Element encode() 229 { 230 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2); 231 elements.add(new ASN1Enumerated( 232 getModificationType().intValue())); 233 elements.add(getAttribute().encode()); 234 235 return new ASN1Sequence(elements); 236 } 237 238 239 240 /** 241 * Decodes the provided ASN.1 element as an LDAP modification. 242 * 243 * @param element The ASN.1 element to decode. 244 * 245 * @return The decoded LDAP modification. 246 * 247 * @throws LDAPException If a problem occurs while attempting to 248 * decode the provided ASN.1 element as a 249 * raw modification. 250 */ 251 public static LDAPModification decode(ASN1Element element) 252 throws LDAPException 253 { 254 ArrayList<ASN1Element> elements; 255 try 256 { 257 elements = element.decodeAsSequence().elements(); 258 } 259 catch (Exception e) 260 { 261 if (debugEnabled()) 262 { 263 TRACER.debugCaught(DebugLogLevel.ERROR, e); 264 } 265 266 Message message = ERR_LDAP_MODIFICATION_DECODE_SEQUENCE.get( 267 String.valueOf(e)); 268 throw new LDAPException(PROTOCOL_ERROR, message, e); 269 } 270 271 272 int numElements = elements.size(); 273 if (numElements != 2) 274 { 275 Message message = 276 ERR_LDAP_MODIFICATION_DECODE_INVALID_ELEMENT_COUNT. 277 get(numElements); 278 throw new LDAPException(PROTOCOL_ERROR, message); 279 } 280 281 282 ModificationType modificationType; 283 try 284 { 285 switch (elements.get(0).decodeAsEnumerated().intValue()) 286 { 287 case MOD_TYPE_ADD: 288 modificationType = ModificationType.ADD; 289 break; 290 case MOD_TYPE_DELETE: 291 modificationType = ModificationType.DELETE; 292 break; 293 case MOD_TYPE_REPLACE: 294 modificationType = ModificationType.REPLACE; 295 break; 296 case MOD_TYPE_INCREMENT: 297 modificationType = ModificationType.INCREMENT; 298 break; 299 default: 300 int intValue = 301 elements.get(0).decodeAsEnumerated().intValue(); 302 Message message = 303 ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE. 304 get(intValue); 305 throw new LDAPException(PROTOCOL_ERROR, message); 306 } 307 } 308 catch (LDAPException le) 309 { 310 throw le; 311 } 312 catch (Exception e) 313 { 314 if (debugEnabled()) 315 { 316 TRACER.debugCaught(DebugLogLevel.ERROR, e); 317 } 318 319 Message message = ERR_LDAP_MODIFICATION_DECODE_MOD_TYPE.get( 320 String.valueOf(e)); 321 throw new LDAPException(PROTOCOL_ERROR, message, e); 322 } 323 324 325 RawAttribute attribute; 326 try 327 { 328 attribute = RawAttribute.decode(elements.get(1)); 329 } 330 catch (Exception e) 331 { 332 if (debugEnabled()) 333 { 334 TRACER.debugCaught(DebugLogLevel.ERROR, e); 335 } 336 337 Message message = 338 ERR_LDAP_MODIFICATION_DECODE_ATTR.get(String.valueOf(e)); 339 throw new LDAPException(PROTOCOL_ERROR, message, e); 340 } 341 342 343 return new LDAPModification(modificationType, attribute); 344 } 345 346 347 348 /** 349 * Creates a new core {@code Modification} object from this raw 350 * modification. 351 * 352 * @return The decoded modification. 353 * 354 * @throws LDAPException If a problem occurs while trying to 355 * convert the raw modification to a core 356 * {@code Modification}. 357 */ 358 public abstract Modification toModification() 359 throws LDAPException; 360 361 362 363 /** 364 * Retrieves a string representation of this modification. 365 * 366 * @return A string representation of this modification. 367 */ 368 public String toString() 369 { 370 StringBuilder buffer = new StringBuilder(); 371 toString(buffer); 372 return buffer.toString(); 373 } 374 375 376 377 /** 378 * Appends a string representation of this modification to the 379 * provided buffer. 380 * 381 * @param buffer The buffer to which the information should be 382 * appended. 383 */ 384 public abstract void toString(StringBuilder buffer); 385 386 387 388 /** 389 * Appends a multi-line string representation of this LDAP 390 * modification to the provided buffer. 391 * 392 * @param buffer The buffer to which the information should be 393 * appended. 394 * @param indent The number of spaces from the margin that the 395 * lines should be indented. 396 */ 397 public abstract void toString(StringBuilder buffer, int indent); 398 } 399