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