001/* 002 * Copyright 2025 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2025 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2025 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.unboundidds.controls; 037 038 039 040import java.io.Serializable; 041import java.util.ArrayList; 042import java.util.List; 043 044import com.unboundid.asn1.ASN1Element; 045import com.unboundid.asn1.ASN1Enumerated; 046import com.unboundid.asn1.ASN1OctetString; 047import com.unboundid.asn1.ASN1Sequence; 048import com.unboundid.ldap.sdk.LDAPException; 049import com.unboundid.ldap.sdk.ResultCode; 050import com.unboundid.util.Debug; 051import com.unboundid.util.Mutable; 052import com.unboundid.util.NotNull; 053import com.unboundid.util.Nullable; 054import com.unboundid.util.StaticUtils; 055import com.unboundid.util.ThreadSafety; 056import com.unboundid.util.ThreadSafetyLevel; 057 058import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 059 060 061 062/** 063 * This class provides a data structure that holds information that may be used 064 * if the server needs to acquire a scoped lock that may apply to a subset of 065 * related requests within a backend, without affecting other unrelated 066 * operations being processed in that backend. 067 * <BR> 068 * <BLOCKQUOTE> 069 * <B>NOTE:</B> This class, and other classes within the 070 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 071 * supported for use against Ping Identity, UnboundID, and 072 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 073 * for proprietary functionality or for external specifications that are not 074 * considered stable or mature enough to be guaranteed to work in an 075 * interoperable way with other types of LDAP servers. 076 * </BLOCKQUOTE> 077 */ 078@Mutable() 079@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 080public final class TransactionSettingsScopedLockDetails 081 implements Serializable 082{ 083 /** 084 * The BER type for the element used to contain the scope identifier. 085 */ 086 private static final byte TYPE_SCOPE_IDENTIFIER = (byte) 0x89; 087 088 089 090 /** 091 * The BER type for the element used to contain the scoped lock behavior. 092 */ 093 private static final byte TYPE_LOCK_BEHAVIOR = (byte) 0x8A; 094 095 096 097 /** 098 * The serial version UID for this serializable class. 099 */ 100 private static final long serialVersionUID = -1374000956873071172L; 101 102 103 104 // A string that identifies which scoped lock to acquire. 105 @NotNull private final String scopeIdentifier; 106 107 // The behavior that should be used when acquiring the lock. 108 @NotNull private final TransactionSettingsBackendLockBehavior lockBehavior; 109 110 111 112 /** 113 * Creates a new scoped lock details object with the provided information. 114 * 115 * @param scopeIdentifier A string that identifies which scoped lock to 116 * acquire. It must not be {@code null}. 117 * @param lockBehavior The behavior that indicates when the server 118 * should attempt to acquire the scoped lock. It 119 * must not be {@code null}, and should not be 120 * {@code DO_NOT_ACQUIRE}. 121 */ 122 public TransactionSettingsScopedLockDetails( 123 @NotNull final String scopeIdentifier, 124 @NotNull final TransactionSettingsBackendLockBehavior lockBehavior) 125 { 126 this.scopeIdentifier = scopeIdentifier; 127 this.lockBehavior = lockBehavior; 128 } 129 130 131 132 /** 133 * Retrieves s string that identifies which scoped lock to acquire. 134 * 135 * @return A string that identifies which scoped lock to acquire. 136 */ 137 @NotNull() 138 public String getScopeIdentifier() 139 { 140 return scopeIdentifier; 141 } 142 143 144 145 /** 146 * Retrieves the behavior that indicates when the lock should be acquired. 147 * 148 * @return The behavior that indicates when the lock should be acquired. 149 */ 150 @NotNull() 151 public TransactionSettingsBackendLockBehavior getLockBehavior() 152 { 153 return lockBehavior; 154 } 155 156 157 158 /** 159 * Encodes the scoped lock details into an ASN.1 element for inclusion in a 160 * transaction settings request control. 161 * 162 * @return The ASN.1 element containing the encoded scoped lock details, or 163 * {@code null} if no scoped lock is needed (as indicated by a 164 * lock behavior of {@code DO_NOT_ACQUIRE}). 165 */ 166 @Nullable() 167 public ASN1Element encode() 168 { 169 if (lockBehavior == TransactionSettingsBackendLockBehavior.DO_NOT_ACQUIRE) 170 { 171 return null; 172 } 173 174 final List<ASN1Element> elements = new ArrayList<>(2); 175 elements.add(new ASN1OctetString(TYPE_SCOPE_IDENTIFIER, scopeIdentifier)); 176 elements.add(new ASN1Enumerated(TYPE_LOCK_BEHAVIOR, 177 lockBehavior.intValue())); 178 179 return new ASN1Sequence( 180 TransactionSettingsRequestControl.TYPE_SCOPED_LOCK_DETAILS, elements); 181 } 182 183 184 185 /** 186 * Decodes the provided ASN.1 element as a set of scoped lock settings. 187 * 188 * @param element The ASN.1 element to decode as a set of scoped lock 189 * settings. It may be {@code null} if the associated 190 * transaction settings request control did not include any 191 * scoped lock settings. 192 * 193 * @return The decoded scoped lock settings. 194 * 195 * @throws LDAPException If a problem occurs while attempting to decode the 196 * provided ASN.1 element as a set of scoped lock 197 * settings. 198 */ 199 @Nullable() 200 public static TransactionSettingsScopedLockDetails decode( 201 @Nullable final ASN1Element element) 202 throws LDAPException 203 { 204 if (element == null) 205 { 206 return null; 207 } 208 209 try 210 { 211 final ASN1Element[] elements = element.decodeAsSequence().elements(); 212 final String scopeIdentifier = 213 elements[0].decodeAsOctetString().stringValue(); 214 215 final int lockBehaviorIntValue = 216 elements[1].decodeAsEnumerated().intValue(); 217 final TransactionSettingsBackendLockBehavior lockBehavior = 218 TransactionSettingsBackendLockBehavior.valueOf(lockBehaviorIntValue); 219 220 return new TransactionSettingsScopedLockDetails(scopeIdentifier, 221 lockBehavior); 222 } 223 catch (final Exception e) 224 { 225 Debug.debugException(e); 226 throw new LDAPException(ResultCode.PROTOCOL_ERROR, 227 ERR_TXN_SETTINGS_SCOPED_LOCK_DETAILS_CANNOT_DECODE.get( 228 StaticUtils.getExceptionMessage(e)), 229 e); 230 } 231 } 232 233 234 235 /** 236 * Retrieves a string representation of the scoped lock details. 237 * 238 * @return A string representation of the scoped lock details. 239 */ 240 @Override() 241 @NotNull() 242 public String toString() 243 { 244 final StringBuilder buffer = new StringBuilder(); 245 toString(buffer); 246 return buffer.toString(); 247 } 248 249 250 251 /** 252 * Appends a string representation of the scoped lock details to the provided 253 * buffer. 254 * 255 * @param buffer The buffer to which the string representation should be 256 * appended. 257 */ 258 public void toString(@NotNull final StringBuilder buffer) 259 { 260 buffer.append("TransactionSettingsScopedLockDetails(scopeIdentifier='"); 261 buffer.append(scopeIdentifier); 262 buffer.append("', lockBehavior='"); 263 buffer.append(lockBehavior.name()); 264 buffer.append("')"); 265 } 266}