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