001 /* 002 * Copyright 2007-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2008-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldif; 022 023 024 025 import java.util.ArrayList; 026 import java.util.Collection; 027 import java.util.HashSet; 028 import java.util.Iterator; 029 import java.util.List; 030 031 import com.unboundid.asn1.ASN1OctetString; 032 import com.unboundid.ldap.sdk.AddRequest; 033 import com.unboundid.ldap.sdk.Attribute; 034 import com.unboundid.ldap.sdk.ChangeType; 035 import com.unboundid.ldap.sdk.Control; 036 import com.unboundid.ldap.sdk.Entry; 037 import com.unboundid.ldap.sdk.LDAPException; 038 import com.unboundid.ldap.sdk.LDAPInterface; 039 import com.unboundid.ldap.sdk.LDAPResult; 040 import com.unboundid.util.ByteStringBuffer; 041 042 import static com.unboundid.util.Debug.*; 043 import static com.unboundid.util.StaticUtils.*; 044 import static com.unboundid.util.Validator.*; 045 046 047 048 /** 049 * This class defines an LDIF add change record, which can be used to represent 050 * an LDAP add request. See the documentation for the {@code LDIFChangeRecord} 051 * class for an example demonstrating the process for interacting with LDIF 052 * change records. 053 */ 054 public final class LDIFAddChangeRecord 055 extends LDIFChangeRecord 056 { 057 /** 058 * The serial version UID for this serializable class. 059 */ 060 private static final long serialVersionUID = 4722916031463878423L; 061 062 063 064 // The set of attributes for this add change record. 065 private final Attribute[] attributes; 066 067 068 069 /** 070 * Creates a new LDIF add change record with the provided DN and attributes. 071 * 072 * @param dn The DN for this LDIF add change record. It must not be 073 * {@code null}. 074 * @param attributes The set of attributes for this LDIF add change record. 075 * It must not be {@code null} or empty. 076 */ 077 public LDIFAddChangeRecord(final String dn, final Attribute... attributes) 078 { 079 this(dn, attributes, null); 080 } 081 082 083 084 /** 085 * Creates a new LDIF add change record with the provided DN and attributes. 086 * 087 * @param dn The DN for this LDIF add change record. It must not be 088 * {@code null}. 089 * @param attributes The set of attributes for this LDIF add change record. 090 * It must not be {@code null} or empty. 091 * @param controls The set of controls for this LDIF add change record. 092 * It may be {@code null} or empty if there are no 093 * controls. 094 */ 095 public LDIFAddChangeRecord(final String dn, final Attribute[] attributes, 096 final List<Control> controls) 097 { 098 super(dn, controls); 099 100 ensureNotNull(attributes); 101 ensureTrue(attributes.length > 0, 102 "LDIFAddChangeRecord.attributes must not be empty."); 103 104 this.attributes = attributes; 105 } 106 107 108 109 /** 110 * Creates a new LDIF add change record with the provided DN and attributes. 111 * 112 * @param dn The DN for this LDIF add change record. It must not be 113 * {@code null}. 114 * @param attributes The set of attributes for this LDIF add change record. 115 * It must not be {@code null} or empty. 116 */ 117 public LDIFAddChangeRecord(final String dn, final List<Attribute> attributes) 118 { 119 this(dn, attributes, null); 120 } 121 122 123 124 /** 125 * Creates a new LDIF add change record with the provided DN and attributes. 126 * 127 * @param dn The DN for this LDIF add change record. It must not be 128 * {@code null}. 129 * @param attributes The set of attributes for this LDIF add change record. 130 * It must not be {@code null} or empty. 131 * @param controls The set of controls for this LDIF add change record. 132 * It may be {@code null} or empty if there are no 133 * controls. 134 */ 135 public LDIFAddChangeRecord(final String dn, final List<Attribute> attributes, 136 final List<Control> controls) 137 { 138 super(dn, controls); 139 140 ensureNotNull(attributes); 141 ensureFalse(attributes.isEmpty(), 142 "LDIFAddChangeRecord.attributes must not be empty."); 143 144 this.attributes = new Attribute[attributes.size()]; 145 attributes.toArray(this.attributes); 146 } 147 148 149 150 /** 151 * Creates a new LDIF add change record from the provided entry. 152 * 153 * @param entry The entry to use to create this LDIF add change record. It 154 * must not be {@code null}. 155 */ 156 public LDIFAddChangeRecord(final Entry entry) 157 { 158 this(entry, null); 159 } 160 161 162 163 /** 164 * Creates a new LDIF add change record from the provided entry. 165 * 166 * @param entry The entry to use to create this LDIF add change record. 167 * It must not be {@code null}. 168 * @param controls The set of controls for this LDIF add change record. It 169 * may be {@code null} or empty if there are no controls. 170 */ 171 public LDIFAddChangeRecord(final Entry entry, final List<Control> controls) 172 { 173 super(entry.getDN(), controls); 174 175 final Collection<Attribute> attrs = entry.getAttributes(); 176 attributes = new Attribute[attrs.size()]; 177 178 final Iterator<Attribute> iterator = attrs.iterator(); 179 for (int i=0; i < attributes.length; i++) 180 { 181 attributes[i] = iterator.next(); 182 } 183 } 184 185 186 187 /** 188 * Creates a new LDIF add change record from the provided add request. 189 * 190 * @param addRequest The add request to use to create this LDIF add change 191 * record. It must not be {@code null}. 192 */ 193 public LDIFAddChangeRecord(final AddRequest addRequest) 194 { 195 super(addRequest.getDN(), addRequest.getControlList()); 196 197 final List<Attribute> attrs = addRequest.getAttributes(); 198 attributes = new Attribute[attrs.size()]; 199 200 final Iterator<Attribute> iterator = attrs.iterator(); 201 for (int i=0; i < attributes.length; i++) 202 { 203 attributes[i] = iterator.next(); 204 } 205 } 206 207 208 209 /** 210 * Retrieves the set of attributes for this add change record. 211 * 212 * @return The set of attributes for this add change record. 213 */ 214 public Attribute[] getAttributes() 215 { 216 return attributes; 217 } 218 219 220 221 /** 222 * Retrieves the entry that would be created by this add change record. 223 * 224 * @return The entry that would be created by this add change record. 225 */ 226 public Entry getEntryToAdd() 227 { 228 return new Entry(getDN(), attributes); 229 } 230 231 232 233 /** 234 * Creates an add request from this LDIF add change record. Any controls 235 * included in this change record will be included in the request. 236 * 237 * @return The add request created from this LDIF add change record. 238 */ 239 public AddRequest toAddRequest() 240 { 241 return toAddRequest(true); 242 } 243 244 245 246 /** 247 * Creates an add request from this LDIF add change record, optionally 248 * including any change record controls in the request. 249 * 250 * @param includeControls Indicates whether to include any controls in the 251 * request. 252 * 253 * @return The add request created from this LDIF add change record. 254 */ 255 public AddRequest toAddRequest(final boolean includeControls) 256 { 257 final AddRequest addRequest = new AddRequest(getDN(), attributes); 258 if (includeControls) 259 { 260 addRequest.setControls(getControls()); 261 } 262 263 return addRequest; 264 } 265 266 267 268 /** 269 * {@inheritDoc} 270 */ 271 @Override() 272 public ChangeType getChangeType() 273 { 274 return ChangeType.ADD; 275 } 276 277 278 279 /** 280 * {@inheritDoc} 281 */ 282 @Override() 283 public LDAPResult processChange(final LDAPInterface connection, 284 final boolean includeControls) 285 throws LDAPException 286 { 287 return connection.add(toAddRequest(includeControls)); 288 } 289 290 291 292 /** 293 * {@inheritDoc} 294 */ 295 @Override() 296 public String[] toLDIF(final int wrapColumn) 297 { 298 List<String> ldifLines = new ArrayList<String>(2*attributes.length); 299 ldifLines.add(LDIFWriter.encodeNameAndValue("dn", 300 new ASN1OctetString(getDN()))); 301 302 for (final Control c : getControls()) 303 { 304 ldifLines.add(LDIFWriter.encodeNameAndValue("control", 305 encodeControlString(c))); 306 } 307 308 ldifLines.add("changetype: add"); 309 310 for (final Attribute a : attributes) 311 { 312 final String name = a.getName(); 313 for (final ASN1OctetString value : a.getRawValues()) 314 { 315 ldifLines.add(LDIFWriter.encodeNameAndValue(name, value)); 316 } 317 } 318 319 if (wrapColumn > 2) 320 { 321 ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines); 322 } 323 324 final String[] ldifArray = new String[ldifLines.size()]; 325 ldifLines.toArray(ldifArray); 326 return ldifArray; 327 } 328 329 330 331 /** 332 * {@inheritDoc} 333 */ 334 @Override() 335 public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn) 336 { 337 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer, 338 wrapColumn); 339 buffer.append(EOL_BYTES); 340 341 for (final Control c : getControls()) 342 { 343 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer, 344 wrapColumn); 345 buffer.append(EOL_BYTES); 346 } 347 348 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"), 349 buffer, wrapColumn); 350 buffer.append(EOL_BYTES); 351 352 for (final Attribute a : attributes) 353 { 354 final String name = a.getName(); 355 for (final ASN1OctetString value : a.getRawValues()) 356 { 357 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn); 358 buffer.append(EOL_BYTES); 359 } 360 } 361 } 362 363 364 365 /** 366 * {@inheritDoc} 367 */ 368 @Override() 369 public void toLDIFString(final StringBuilder buffer, final int wrapColumn) 370 { 371 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer, 372 wrapColumn); 373 buffer.append(EOL); 374 375 for (final Control c : getControls()) 376 { 377 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer, 378 wrapColumn); 379 buffer.append(EOL); 380 } 381 382 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"), 383 buffer, wrapColumn); 384 buffer.append(EOL); 385 386 for (final Attribute a : attributes) 387 { 388 final String name = a.getName(); 389 for (final ASN1OctetString value : a.getRawValues()) 390 { 391 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn); 392 buffer.append(EOL); 393 } 394 } 395 } 396 397 398 399 /** 400 * {@inheritDoc} 401 */ 402 @Override() 403 public int hashCode() 404 { 405 try 406 { 407 int hashCode = getParsedDN().hashCode(); 408 for (final Attribute a : attributes) 409 { 410 hashCode += a.hashCode(); 411 } 412 413 return hashCode; 414 } 415 catch (final Exception e) 416 { 417 debugException(e); 418 return new Entry(getDN(), attributes).hashCode(); 419 } 420 } 421 422 423 424 /** 425 * {@inheritDoc} 426 */ 427 @Override() 428 public boolean equals(final Object o) 429 { 430 if (o == null) 431 { 432 return false; 433 } 434 435 if (o == this) 436 { 437 return true; 438 } 439 440 if (! (o instanceof LDIFAddChangeRecord)) 441 { 442 return false; 443 } 444 445 final LDIFAddChangeRecord r = (LDIFAddChangeRecord) o; 446 447 final HashSet<Control> c1 = new HashSet<Control>(getControls()); 448 final HashSet<Control> c2 = new HashSet<Control>(r.getControls()); 449 if (! c1.equals(c2)) 450 { 451 return false; 452 } 453 454 final Entry e1 = new Entry(getDN(), attributes); 455 final Entry e2 = new Entry(r.getDN(), r.attributes); 456 return e1.equals(e2); 457 } 458 459 460 461 /** 462 * {@inheritDoc} 463 */ 464 @Override() 465 public void toString(final StringBuilder buffer) 466 { 467 buffer.append("LDIFAddChangeRecord(dn='"); 468 buffer.append(getDN()); 469 buffer.append("', attrs={"); 470 471 for (int i=0; i < attributes.length; i++) 472 { 473 if (i > 0) 474 { 475 buffer.append(", "); 476 } 477 attributes[i].toString(buffer); 478 } 479 buffer.append('}'); 480 481 final List<Control> controls = getControls(); 482 if (! controls.isEmpty()) 483 { 484 buffer.append(", controls={"); 485 486 final Iterator<Control> iterator = controls.iterator(); 487 while (iterator.hasNext()) 488 { 489 iterator.next().toString(buffer); 490 if (iterator.hasNext()) 491 { 492 buffer.append(','); 493 } 494 } 495 496 buffer.append('}'); 497 } 498 499 buffer.append(')'); 500 } 501 }