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