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 }