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.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 (final LDAPException le) 138 { 139 debugException(le); 140 throw le; 141 } 142 catch (final 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 @Override() 181 public byte getProtocolOpType() 182 { 183 return LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST; 184 } 185 186 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override() 192 public ASN1Element encodeProtocolOp() 193 { 194 final ArrayList<ASN1Element> modElements = 195 new ArrayList<ASN1Element>(modifications.size()); 196 for (final Modification m : modifications) 197 { 198 modElements.add(m.encode()); 199 } 200 201 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST, 202 new ASN1OctetString(dn), 203 new ASN1Sequence(modElements)); 204 } 205 206 207 208 /** 209 * Decodes the provided ASN.1 element as a modify request protocol op. 210 * 211 * @param element The ASN.1 element to be decoded. 212 * 213 * @return The decoded modify request protocol op. 214 * 215 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 216 * a modify request protocol op. 217 */ 218 public static ModifyRequestProtocolOp decodeProtocolOp( 219 final ASN1Element element) 220 throws LDAPException 221 { 222 try 223 { 224 final ASN1Element[] elements = 225 ASN1Sequence.decodeAsSequence(element).elements(); 226 final String dn = 227 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 228 229 final ASN1Element[] modElements = 230 ASN1Sequence.decodeAsSequence(elements[1]).elements(); 231 final ArrayList<Modification> mods = 232 new ArrayList<Modification>(modElements.length); 233 for (final ASN1Element e : modElements) 234 { 235 mods.add(Modification.decode(ASN1Sequence.decodeAsSequence(e))); 236 } 237 238 return new ModifyRequestProtocolOp(dn, mods); 239 } 240 catch (final Exception e) 241 { 242 debugException(e); 243 throw new LDAPException(ResultCode.DECODING_ERROR, 244 ERR_MODIFY_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), 245 e); 246 } 247 } 248 249 250 251 /** 252 * {@inheritDoc} 253 */ 254 @Override() 255 public void writeTo(final ASN1Buffer writer) 256 { 257 final ASN1BufferSequence opSequence = 258 writer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST); 259 writer.addOctetString(dn); 260 261 final ASN1BufferSequence modSequence = writer.beginSequence(); 262 for (final Modification m : modifications) 263 { 264 m.writeTo(writer); 265 } 266 modSequence.end(); 267 opSequence.end(); 268 } 269 270 271 272 /** 273 * Creates a modify request from this protocol op. 274 * 275 * @param controls The set of controls to include in the modify request. 276 * It may be empty or {@code null} if no controls should be 277 * included. 278 * 279 * @return The modify request that was created. 280 */ 281 public ModifyRequest toModifyRequest(final Control... controls) 282 { 283 return new ModifyRequest(dn, modifications, controls); 284 } 285 286 287 288 /** 289 * Retrieves a string representation of this protocol op. 290 * 291 * @return A string representation of this protocol op. 292 */ 293 @Override() 294 public String toString() 295 { 296 final StringBuilder buffer = new StringBuilder(); 297 toString(buffer); 298 return buffer.toString(); 299 } 300 301 302 303 /** 304 * {@inheritDoc} 305 */ 306 @Override() 307 public void toString(final StringBuilder buffer) 308 { 309 buffer.append("ModifyRequestProtocolOp(dn='"); 310 buffer.append(dn); 311 buffer.append("', mods={"); 312 313 final Iterator<Modification> iterator = modifications.iterator(); 314 while (iterator.hasNext()) 315 { 316 iterator.next().toString(buffer); 317 if (iterator.hasNext()) 318 { 319 buffer.append(','); 320 } 321 } 322 323 buffer.append("})"); 324 } 325}