001/* 002 * Copyright 2009-2017 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2017 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 */ 021package com.unboundid.ldap.protocol; 022 023 024 025import java.util.ArrayList; 026import java.util.Collections; 027import java.util.Iterator; 028import java.util.List; 029 030import com.unboundid.asn1.ASN1Buffer; 031import com.unboundid.asn1.ASN1BufferSequence; 032import com.unboundid.asn1.ASN1Element; 033import com.unboundid.asn1.ASN1OctetString; 034import com.unboundid.asn1.ASN1Sequence; 035import com.unboundid.asn1.ASN1StreamReader; 036import com.unboundid.asn1.ASN1StreamReaderSequence; 037import com.unboundid.ldap.sdk.Control; 038import com.unboundid.ldap.sdk.LDAPException; 039import com.unboundid.ldap.sdk.Modification; 040import com.unboundid.ldap.sdk.ModifyRequest; 041import com.unboundid.ldap.sdk.ResultCode; 042import com.unboundid.util.NotMutable; 043import com.unboundid.util.InternalUseOnly; 044import com.unboundid.util.ThreadSafety; 045import com.unboundid.util.ThreadSafetyLevel; 046 047import static com.unboundid.ldap.protocol.ProtocolMessages.*; 048import static com.unboundid.util.Debug.*; 049import static com.unboundid.util.StaticUtils.*; 050import static com.unboundid.util.Validator.*; 051 052 053 054/** 055 * This class provides an implementation of an LDAP modify request protocol op. 056 */ 057@InternalUseOnly() 058@NotMutable() 059@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 060public final class ModifyRequestProtocolOp 061 implements ProtocolOp 062{ 063 /** 064 * The serial version UID for this serializable class. 065 */ 066 private static final long serialVersionUID = -6294739625253826184L; 067 068 069 070 // The list of modifications for this modify request. 071 private final List<Modification> modifications; 072 073 // The entry DN for this modify request. 074 private final String dn; 075 076 077 078 /** 079 * Creates a new modify request protocol op with the provided information. 080 * 081 * @param dn The entry DN for this modify request. 082 * @param modifications The list of modifications to include in this modify 083 * request. 084 */ 085 public ModifyRequestProtocolOp(final String dn, 086 final List<Modification> modifications) 087 { 088 this.dn = dn; 089 this.modifications = Collections.unmodifiableList(modifications); 090 } 091 092 093 094 /** 095 * Creates a new modify request protocol op from the provided modify request 096 * object. 097 * 098 * @param request The modify request object to use to create this protocol 099 * op. 100 */ 101 public ModifyRequestProtocolOp(final ModifyRequest request) 102 { 103 dn = request.getDN(); 104 modifications = request.getModifications(); 105 } 106 107 108 109 /** 110 * Creates a new modify request protocol op read from the provided ASN.1 111 * stream reader. 112 * 113 * @param reader The ASN.1 stream reader from which to read the modify 114 * request protocol op. 115 * 116 * @throws LDAPException If a problem occurs while reading or parsing the 117 * modify request. 118 */ 119 ModifyRequestProtocolOp(final ASN1StreamReader reader) 120 throws LDAPException 121 { 122 try 123 { 124 reader.beginSequence(); 125 dn = reader.readString(); 126 ensureNotNull(dn); 127 128 final ArrayList<Modification> mods = new ArrayList<Modification>(5); 129 final ASN1StreamReaderSequence modSequence = reader.beginSequence(); 130 while (modSequence.hasMoreElements()) 131 { 132 mods.add(Modification.readFrom(reader)); 133 } 134 135 modifications = Collections.unmodifiableList(mods); 136 } 137 catch (LDAPException le) 138 { 139 debugException(le); 140 throw le; 141 } 142 catch (Exception e) 143 { 144 debugException(e); 145 146 throw new LDAPException(ResultCode.DECODING_ERROR, 147 ERR_MODIFY_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), e); 148 } 149 } 150 151 152 153 /** 154 * Retrieves the target entry DN for this modify request. 155 * 156 * @return The target entry DN for this modify request. 157 */ 158 public String getDN() 159 { 160 return dn; 161 } 162 163 164 165 /** 166 * Retrieves the list of modifications for this modify request. 167 * 168 * @return The list of modifications for this modify request. 169 */ 170 public List<Modification> getModifications() 171 { 172 return modifications; 173 } 174 175 176 177 /** 178 * {@inheritDoc} 179 */ 180 public byte getProtocolOpType() 181 { 182 return LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST; 183 } 184 185 186 187 /** 188 * {@inheritDoc} 189 */ 190 public ASN1Element encodeProtocolOp() 191 { 192 final ArrayList<ASN1Element> modElements = 193 new ArrayList<ASN1Element>(modifications.size()); 194 for (final Modification m : modifications) 195 { 196 modElements.add(m.encode()); 197 } 198 199 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST, 200 new ASN1OctetString(dn), 201 new ASN1Sequence(modElements)); 202 } 203 204 205 206 /** 207 * Decodes the provided ASN.1 element as a modify request protocol op. 208 * 209 * @param element The ASN.1 element to be decoded. 210 * 211 * @return The decoded modify request protocol op. 212 * 213 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 214 * a modify request protocol op. 215 */ 216 public static ModifyRequestProtocolOp decodeProtocolOp( 217 final ASN1Element element) 218 throws LDAPException 219 { 220 try 221 { 222 final ASN1Element[] elements = 223 ASN1Sequence.decodeAsSequence(element).elements(); 224 final String dn = 225 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 226 227 final ASN1Element[] modElements = 228 ASN1Sequence.decodeAsSequence(elements[1]).elements(); 229 final ArrayList<Modification> mods = 230 new ArrayList<Modification>(modElements.length); 231 for (final ASN1Element e : modElements) 232 { 233 mods.add(Modification.decode(ASN1Sequence.decodeAsSequence(e))); 234 } 235 236 return new ModifyRequestProtocolOp(dn, mods); 237 } 238 catch (final Exception e) 239 { 240 debugException(e); 241 throw new LDAPException(ResultCode.DECODING_ERROR, 242 ERR_MODIFY_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), 243 e); 244 } 245 } 246 247 248 249 /** 250 * {@inheritDoc} 251 */ 252 public void writeTo(final ASN1Buffer writer) 253 { 254 final ASN1BufferSequence opSequence = 255 writer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST); 256 writer.addOctetString(dn); 257 258 final ASN1BufferSequence modSequence = writer.beginSequence(); 259 for (final Modification m : modifications) 260 { 261 m.writeTo(writer); 262 } 263 modSequence.end(); 264 opSequence.end(); 265 } 266 267 268 269 /** 270 * Creates a modify request from this protocol op. 271 * 272 * @param controls The set of controls to include in the modify request. 273 * It may be empty or {@code null} if no controls should be 274 * included. 275 * 276 * @return The modify request that was created. 277 */ 278 public ModifyRequest toModifyRequest(final Control... controls) 279 { 280 return new ModifyRequest(dn, modifications, controls); 281 } 282 283 284 285 /** 286 * Retrieves a string representation of this protocol op. 287 * 288 * @return A string representation of this protocol op. 289 */ 290 @Override() 291 public String toString() 292 { 293 final StringBuilder buffer = new StringBuilder(); 294 toString(buffer); 295 return buffer.toString(); 296 } 297 298 299 300 /** 301 * {@inheritDoc} 302 */ 303 public void toString(final StringBuilder buffer) 304 { 305 buffer.append("ModifyRequestProtocolOp(dn='"); 306 buffer.append(dn); 307 buffer.append("', mods={"); 308 309 final Iterator<Modification> iterator = modifications.iterator(); 310 while (iterator.hasNext()) 311 { 312 iterator.next().toString(buffer); 313 if (iterator.hasNext()) 314 { 315 buffer.append(','); 316 } 317 } 318 319 buffer.append("})"); 320 } 321}