001/* 002 * Copyright 2009-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2018 Ping Identity Corporation 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.Debug; 043import com.unboundid.util.InternalUseOnly; 044import com.unboundid.util.NotMutable; 045import com.unboundid.util.StaticUtils; 046import com.unboundid.util.ThreadSafety; 047import com.unboundid.util.ThreadSafetyLevel; 048import com.unboundid.util.Validator; 049 050import static com.unboundid.ldap.protocol.ProtocolMessages.*; 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 Validator.ensureNotNull(dn); 127 128 final ArrayList<Modification> mods = new ArrayList<>(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 (final LDAPException le) 138 { 139 Debug.debugException(le); 140 throw le; 141 } 142 catch (final Exception e) 143 { 144 Debug.debugException(e); 145 146 throw new LDAPException(ResultCode.DECODING_ERROR, 147 ERR_MODIFY_REQUEST_CANNOT_DECODE.get( 148 StaticUtils.getExceptionMessage(e)), 149 e); 150 } 151 } 152 153 154 155 /** 156 * Retrieves the target entry DN for this modify request. 157 * 158 * @return The target entry DN for this modify request. 159 */ 160 public String getDN() 161 { 162 return dn; 163 } 164 165 166 167 /** 168 * Retrieves the list of modifications for this modify request. 169 * 170 * @return The list of modifications for this modify request. 171 */ 172 public List<Modification> getModifications() 173 { 174 return modifications; 175 } 176 177 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override() 183 public byte getProtocolOpType() 184 { 185 return LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST; 186 } 187 188 189 190 /** 191 * {@inheritDoc} 192 */ 193 @Override() 194 public ASN1Element encodeProtocolOp() 195 { 196 final ArrayList<ASN1Element> modElements = 197 new ArrayList<>(modifications.size()); 198 for (final Modification m : modifications) 199 { 200 modElements.add(m.encode()); 201 } 202 203 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST, 204 new ASN1OctetString(dn), 205 new ASN1Sequence(modElements)); 206 } 207 208 209 210 /** 211 * Decodes the provided ASN.1 element as a modify request protocol op. 212 * 213 * @param element The ASN.1 element to be decoded. 214 * 215 * @return The decoded modify request protocol op. 216 * 217 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 218 * a modify request protocol op. 219 */ 220 public static ModifyRequestProtocolOp decodeProtocolOp( 221 final ASN1Element element) 222 throws LDAPException 223 { 224 try 225 { 226 final ASN1Element[] elements = 227 ASN1Sequence.decodeAsSequence(element).elements(); 228 final String dn = 229 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 230 231 final ASN1Element[] modElements = 232 ASN1Sequence.decodeAsSequence(elements[1]).elements(); 233 final ArrayList<Modification> mods = new ArrayList<>(modElements.length); 234 for (final ASN1Element e : modElements) 235 { 236 mods.add(Modification.decode(ASN1Sequence.decodeAsSequence(e))); 237 } 238 239 return new ModifyRequestProtocolOp(dn, mods); 240 } 241 catch (final Exception e) 242 { 243 Debug.debugException(e); 244 throw new LDAPException(ResultCode.DECODING_ERROR, 245 ERR_MODIFY_REQUEST_CANNOT_DECODE.get( 246 StaticUtils.getExceptionMessage(e)), 247 e); 248 } 249 } 250 251 252 253 /** 254 * {@inheritDoc} 255 */ 256 @Override() 257 public void writeTo(final ASN1Buffer writer) 258 { 259 final ASN1BufferSequence opSequence = 260 writer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST); 261 writer.addOctetString(dn); 262 263 final ASN1BufferSequence modSequence = writer.beginSequence(); 264 for (final Modification m : modifications) 265 { 266 m.writeTo(writer); 267 } 268 modSequence.end(); 269 opSequence.end(); 270 } 271 272 273 274 /** 275 * Creates a modify request from this protocol op. 276 * 277 * @param controls The set of controls to include in the modify request. 278 * It may be empty or {@code null} if no controls should be 279 * included. 280 * 281 * @return The modify request that was created. 282 */ 283 public ModifyRequest toModifyRequest(final Control... controls) 284 { 285 return new ModifyRequest(dn, modifications, controls); 286 } 287 288 289 290 /** 291 * Retrieves a string representation of this protocol op. 292 * 293 * @return A string representation of this protocol op. 294 */ 295 @Override() 296 public String toString() 297 { 298 final StringBuilder buffer = new StringBuilder(); 299 toString(buffer); 300 return buffer.toString(); 301 } 302 303 304 305 /** 306 * {@inheritDoc} 307 */ 308 @Override() 309 public void toString(final StringBuilder buffer) 310 { 311 buffer.append("ModifyRequestProtocolOp(dn='"); 312 buffer.append(dn); 313 buffer.append("', mods={"); 314 315 final Iterator<Modification> iterator = modifications.iterator(); 316 while (iterator.hasNext()) 317 { 318 iterator.next().toString(buffer); 319 if (iterator.hasNext()) 320 { 321 buffer.append(','); 322 } 323 } 324 325 buffer.append("})"); 326 } 327}