001 /* 002 * Copyright 2007-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 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.sdk.unboundidds.extensions; 022 023 024 025 import com.unboundid.asn1.ASN1Boolean; 026 import com.unboundid.asn1.ASN1Element; 027 import com.unboundid.asn1.ASN1OctetString; 028 import com.unboundid.asn1.ASN1Sequence; 029 import com.unboundid.ldap.sdk.Control; 030 import com.unboundid.ldap.sdk.ExtendedRequest; 031 import com.unboundid.ldap.sdk.ExtendedResult; 032 import com.unboundid.ldap.sdk.LDAPConnection; 033 import com.unboundid.ldap.sdk.LDAPException; 034 import com.unboundid.ldap.sdk.ResultCode; 035 import com.unboundid.util.NotMutable; 036 import com.unboundid.util.ThreadSafety; 037 import com.unboundid.util.ThreadSafetyLevel; 038 039 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 040 import static com.unboundid.util.Debug.*; 041 import static com.unboundid.util.Validator.*; 042 043 044 045 /** 046 * <BLOCKQUOTE> 047 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 048 * LDAP SDK for Java. It is not available for use in applications that 049 * include only the Standard Edition of the LDAP SDK, and is not supported for 050 * use in conjunction with non-UnboundID products. 051 * </BLOCKQUOTE> 052 * This class provides an implementation of the end batched transaction extended 053 * request. It may be used to either commit or abort a transaction that was 054 * created using the start batched transaction request. See the documentation 055 * for the {@link StartBatchedTransactionExtendedRequest} for an example of 056 * processing a batched transaction. 057 */ 058 @NotMutable() 059 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 060 public final class EndBatchedTransactionExtendedRequest 061 extends ExtendedRequest 062 { 063 /** 064 * The OID (1.3.6.1.4.1.30221.2.6.2) for the end batched transaction extended 065 * request. 066 */ 067 public static final String END_BATCHED_TRANSACTION_REQUEST_OID = 068 "1.3.6.1.4.1.30221.2.6.2"; 069 070 071 072 /** 073 * The serial version UID for this serializable class. 074 */ 075 private static final long serialVersionUID = -8569129721687583552L; 076 077 078 079 // The transaction ID for the associated transaction. 080 private final ASN1OctetString transactionID; 081 082 // Indicates whether to commit or abort the associated transaction. 083 private final boolean commit; 084 085 086 087 /** 088 * Creates a new end batched transaction extended request with the provided 089 * information. 090 * 091 * @param transactionID The transaction ID for the transaction to commit or 092 * abort. It must not be {@code null}. 093 * @param commit {@code true} if the transaction should be committed, 094 * or {@code false} if the transaction should be 095 * aborted. 096 */ 097 public EndBatchedTransactionExtendedRequest( 098 final ASN1OctetString transactionID, final boolean commit) 099 { 100 this(transactionID, commit, null); 101 } 102 103 104 105 /** 106 * Creates a new end batched transaction extended request with the provided 107 * information. 108 * 109 * @param transactionID The transaction ID for the transaction to commit or 110 * abort. It must not be {@code null}. 111 * @param commit {@code true} if the transaction should be committed, 112 * or {@code false} if the transaction should be 113 * aborted. 114 * @param controls The set of controls to include in the request. 115 */ 116 public EndBatchedTransactionExtendedRequest( 117 final ASN1OctetString transactionID, final boolean commit, 118 final Control[] controls) 119 { 120 super(END_BATCHED_TRANSACTION_REQUEST_OID, 121 encodeValue(transactionID, commit), 122 controls); 123 124 this.transactionID = transactionID; 125 this.commit = commit; 126 } 127 128 129 130 /** 131 * Creates a new end batched transaction extended request from the provided 132 * generic extended request. 133 * 134 * @param extendedRequest The generic extended request to use to create this 135 * end batched transaction extended request. 136 * 137 * @throws LDAPException If a problem occurs while decoding the request. 138 */ 139 public EndBatchedTransactionExtendedRequest( 140 final ExtendedRequest extendedRequest) 141 throws LDAPException 142 { 143 super(extendedRequest); 144 145 final ASN1OctetString value = extendedRequest.getValue(); 146 if (value == null) 147 { 148 throw new LDAPException(ResultCode.DECODING_ERROR, 149 ERR_END_TXN_REQUEST_NO_VALUE.get()); 150 } 151 152 try 153 { 154 final ASN1Element valueElement = ASN1Element.decode(value.getValue()); 155 final ASN1Element[] elements = 156 ASN1Sequence.decodeAsSequence(valueElement).elements(); 157 if (elements.length == 1) 158 { 159 commit = true; 160 transactionID = ASN1OctetString.decodeAsOctetString(elements[0]); 161 } 162 else 163 { 164 commit = ASN1Boolean.decodeAsBoolean(elements[0]).booleanValue(); 165 transactionID = ASN1OctetString.decodeAsOctetString(elements[1]); 166 } 167 } 168 catch (Exception e) 169 { 170 debugException(e); 171 throw new LDAPException(ResultCode.DECODING_ERROR, 172 ERR_END_TXN_REQUEST_CANNOT_DECODE.get(e), e); 173 } 174 } 175 176 177 178 /** 179 * Generates the value to include in this extended request. 180 * 181 * @param transactionID The transaction ID for the transaction to commit or 182 * abort. It must not be {@code null}. 183 * @param commit {@code true} if the transaction should be committed, 184 * or {@code false} if the transaction should be 185 * aborted. 186 * 187 * @return The ASN.1 octet string containing the encoded request value. 188 */ 189 private static ASN1OctetString 190 encodeValue(final ASN1OctetString transactionID, 191 final boolean commit) 192 { 193 ensureNotNull(transactionID); 194 195 final ASN1Element[] valueElements; 196 if (commit) 197 { 198 valueElements = new ASN1Element[] 199 { 200 transactionID 201 }; 202 } 203 else 204 { 205 valueElements = new ASN1Element[] 206 { 207 new ASN1Boolean(commit), 208 transactionID 209 }; 210 } 211 212 return new ASN1OctetString(new ASN1Sequence(valueElements).encode()); 213 } 214 215 216 217 /** 218 * Retrieves the transaction ID for the transaction to commit or abort. 219 * 220 * @return The transaction ID for the transaction to commit or abort. 221 */ 222 public ASN1OctetString getTransactionID() 223 { 224 return transactionID; 225 } 226 227 228 229 /** 230 * Indicates whether the transaction should be committed or aborted. 231 * 232 * @return {@code true} if the transaction should be committed, or 233 * {@code false} if it should be aborted. 234 */ 235 public boolean commit() 236 { 237 return commit; 238 } 239 240 241 242 /** 243 * {@inheritDoc} 244 */ 245 @Override() 246 public EndBatchedTransactionExtendedResult process( 247 final LDAPConnection connection, final int depth) 248 throws LDAPException 249 { 250 final ExtendedResult extendedResponse = super.process(connection, depth); 251 return new EndBatchedTransactionExtendedResult(extendedResponse); 252 } 253 254 255 256 /** 257 * {@inheritDoc} 258 */ 259 @Override() 260 public EndBatchedTransactionExtendedRequest duplicate() 261 { 262 return duplicate(getControls()); 263 } 264 265 266 267 /** 268 * {@inheritDoc} 269 */ 270 @Override() 271 public EndBatchedTransactionExtendedRequest duplicate( 272 final Control[] controls) 273 { 274 final EndBatchedTransactionExtendedRequest r = 275 new EndBatchedTransactionExtendedRequest(transactionID, commit, 276 controls); 277 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 278 return r; 279 } 280 281 282 283 /** 284 * {@inheritDoc} 285 */ 286 @Override() 287 public String getExtendedRequestName() 288 { 289 return INFO_EXTENDED_REQUEST_NAME_END_BATCHED_TXN.get(); 290 } 291 292 293 294 /** 295 * {@inheritDoc} 296 */ 297 @Override() 298 public void toString(final StringBuilder buffer) 299 { 300 buffer.append("EndBatchedTransactionExtendedRequest(transactionID='"); 301 buffer.append(transactionID.stringValue()); 302 buffer.append("', commit="); 303 buffer.append(commit); 304 305 final Control[] controls = getControls(); 306 if (controls.length > 0) 307 { 308 buffer.append("controls={"); 309 for (int i=0; i < controls.length; i++) 310 { 311 if (i > 0) 312 { 313 buffer.append(", "); 314 } 315 316 buffer.append(controls[i]); 317 } 318 buffer.append('}'); 319 } 320 321 buffer.append(')'); 322 } 323 }