001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2024 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) 2009-2024 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.migrate.ldapjdk; 037 038 039 040import java.io.Serializable; 041import java.util.Arrays; 042import java.util.Enumeration; 043import java.util.Set; 044 045import com.unboundid.ldap.sdk.Attribute; 046import com.unboundid.util.Mutable; 047import com.unboundid.util.NotExtensible; 048import com.unboundid.util.NotNull; 049import com.unboundid.util.Nullable; 050import com.unboundid.util.StaticUtils; 051import com.unboundid.util.ThreadSafety; 052import com.unboundid.util.ThreadSafetyLevel; 053 054 055 056/** 057 * This class provides a data structure that holds information about an LDAP 058 * attribute, including an attribute description (a base name or OID and 059 * optional set of options) and zero or more values. 060 * <BR><BR> 061 * This class is primarily intended to be used in the process of updating 062 * applications which use the Netscape Directory SDK for Java to switch to or 063 * coexist with the UnboundID LDAP SDK for Java. For applications not written 064 * using the Netscape Directory SDK for Java, the {@link Attribute} class should 065 * be used instead. 066 */ 067@NotExtensible() 068@Mutable() 069@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 070public class LDAPAttribute 071 implements Serializable 072{ 073 /** 074 * The serial version UID for this serializable attribute. 075 */ 076 private static final long serialVersionUID = 839217229050750570L; 077 078 079 080 // The Attribute object wrapped by this LDAPAttribute. 081 @NotNull private Attribute attribute; 082 083 084 085 /** 086 * Creates a new LDAP attribute from the provided {@link Attribute} object. 087 * 088 * @param attr The LDAP attribute to use to create this attribute. 089 */ 090 public LDAPAttribute(@NotNull final Attribute attr) 091 { 092 attribute = attr; 093 } 094 095 096 097 /** 098 * Creates a new LDAP attribute that is a duplicate of the provided attribute. 099 * 100 * @param attr The LDAP attribute to use to create this attribute. 101 */ 102 public LDAPAttribute(@NotNull final LDAPAttribute attr) 103 { 104 attribute = attr.attribute; 105 } 106 107 108 109 /** 110 * Creates a new LDAP attribute with the specified name and no values. 111 * 112 * @param attrName The name for this attribute. 113 */ 114 public LDAPAttribute(@NotNull final String attrName) 115 { 116 attribute = new Attribute(attrName); 117 } 118 119 120 121 /** 122 * Creates a new LDAP attribute with the specified name and value. 123 * 124 * @param attrName The name for this attribute. 125 * @param attrBytes The value for this attribute. 126 */ 127 public LDAPAttribute(@NotNull final String attrName, 128 @NotNull final byte[] attrBytes) 129 { 130 attribute = new Attribute(attrName, attrBytes); 131 } 132 133 134 135 /** 136 * Creates a new LDAP attribute with the specified name and value. 137 * 138 * @param attrName The name for this attribute. 139 * @param attrString The value for this attribute. 140 */ 141 public LDAPAttribute(@NotNull final String attrName, 142 @NotNull final String attrString) 143 { 144 attribute = new Attribute(attrName, attrString); 145 } 146 147 148 149 /** 150 * Creates a new LDAP attribute with the specified name and values. 151 * 152 * @param attrName The name for this attribute. 153 * @param attrStrings The values for this attribute. 154 */ 155 public LDAPAttribute(@NotNull final String attrName, 156 @NotNull final String[] attrStrings) 157 { 158 attribute = new Attribute(attrName, attrStrings); 159 } 160 161 162 163 /** 164 * Retrieves the name for this attribute. 165 * 166 * @return The name for this attribute. 167 */ 168 @NotNull() 169 public String getName() 170 { 171 return attribute.getName(); 172 } 173 174 175 176 /** 177 * Retrieves the base name for this attribute, without any options. 178 * 179 * @return The base name for this attribute. 180 */ 181 @NotNull() 182 public String getBaseName() 183 { 184 return attribute.getBaseName(); 185 } 186 187 188 189 /** 190 * Retrieves the base name for the attribute with the provided name. 191 * 192 * @param attrName The attribute name for which to retrieve the base name. 193 * 194 * @return The base name for the attribute with the provided name. 195 */ 196 @NotNull() 197 public static String getBaseName(@NotNull final String attrName) 198 { 199 return Attribute.getBaseName(attrName); 200 } 201 202 203 204 /** 205 * Retrieves the subtypes (i.e., attribute options) contained in the name for 206 * this attribute. 207 * 208 * @return The subtypes contained in the name for this attribute, or 209 * {@code null} if there are none. 210 */ 211 @Nullable() 212 public String[] getSubtypes() 213 { 214 final Set<String> optionSet = attribute.getOptions(); 215 if (optionSet.isEmpty()) 216 { 217 return null; 218 } 219 220 final String[] options = new String[optionSet.size()]; 221 return optionSet.toArray(options); 222 } 223 224 225 226 /** 227 * Retrieves the subtypes (i.e., attribute options) contained in the provided 228 * attribute name. 229 * 230 * @param attrName The attribute name from which to extract the subtypes. 231 * 232 * @return The subtypes contained in the provided attribute name, or 233 * {@code null} if there are none. 234 */ 235 @Nullable() 236 public static String[] getSubtypes(@NotNull final String attrName) 237 { 238 return new LDAPAttribute(attrName).getSubtypes(); 239 } 240 241 242 243 /** 244 * Retrieves the language subtype (i.e., the attribute option which begins 245 * with "lang-") for this attribute, if present. 246 * 247 * @return The language subtype for this attribute, or {@code null} if there 248 * is none. 249 */ 250 @Nullable() 251 public String getLangSubtype() 252 { 253 for (final String s : attribute.getOptions()) 254 { 255 final String lowerName = StaticUtils.toLowerCase(s); 256 if (lowerName.startsWith("lang-")) 257 { 258 return s; 259 } 260 } 261 262 return null; 263 } 264 265 266 267 /** 268 * Indicates whether this attribute contains the specified subtype. 269 * 270 * @param subtype The subtype for which to make the determination. 271 * 272 * @return {@code true} if this option has the specified subtype, or 273 * {@code false} if not. 274 */ 275 public boolean hasSubtype(@NotNull final String subtype) 276 { 277 return attribute.hasOption(subtype); 278 } 279 280 281 282 /** 283 * Indicates whether this attribute contains all of the specified subtypes. 284 * 285 * @param subtypes The subtypes for which to make the determination. 286 * 287 * @return {@code true} if this option has all of the specified subtypes, or 288 * {@code false} if not. 289 */ 290 public boolean hasSubtypes(@NotNull final String[] subtypes) 291 { 292 for (final String s : subtypes) 293 { 294 if (! attribute.hasOption(s)) 295 { 296 return false; 297 } 298 } 299 300 return true; 301 } 302 303 304 305 /** 306 * Retrieves an enumeration over the string values for this attribute. 307 * 308 * @return An enumeration over the string values for this attribute. 309 */ 310 @NotNull() 311 public Enumeration<String> getStringValues() 312 { 313 return new IterableEnumeration<>(Arrays.asList(attribute.getValues())); 314 } 315 316 317 318 /** 319 * Retrieves an array of the values for this attribute. 320 * 321 * @return An array of the values for this attribute. 322 */ 323 @NotNull() 324 public String[] getStringValueArray() 325 { 326 return attribute.getValues(); 327 } 328 329 330 331 /** 332 * Retrieves an enumeration over the binary values for this attribute. 333 * 334 * @return An enumeration over the binary values for this attribute. 335 */ 336 @NotNull() 337 public Enumeration<byte[]> getByteValues() 338 { 339 return new IterableEnumeration<>( 340 Arrays.asList(attribute.getValueByteArrays())); 341 } 342 343 344 345 /** 346 * Retrieves an array of the values for this attribute. 347 * 348 * @return An array of the values for this attribute. 349 */ 350 @NotNull() 351 public byte[][] getByteValueArray() 352 { 353 return attribute.getValueByteArrays(); 354 } 355 356 357 358 /** 359 * Adds the provided value to the set of values for this attribute. 360 * 361 * @param attrString The value to add to this attribute. 362 */ 363 public void addValue(@NotNull final String attrString) 364 { 365 attribute = Attribute.mergeAttributes(attribute, 366 new Attribute(attribute.getName(), attrString)); 367 } 368 369 370 371 /** 372 * Adds the provided value to the set of values for this attribute. 373 * 374 * @param attrBytes The value to add to this attribute. 375 */ 376 public void addValue(@NotNull final byte[] attrBytes) 377 { 378 attribute = Attribute.mergeAttributes(attribute, 379 new Attribute(attribute.getName(), attrBytes)); 380 } 381 382 383 384 /** 385 * Removes the provided value from this attribute. 386 * 387 * @param attrValue The value to remove. 388 */ 389 public void removeValue(@NotNull final String attrValue) 390 { 391 attribute = Attribute.removeValues(attribute, 392 new Attribute(attribute.getName(), attrValue)); 393 } 394 395 396 397 /** 398 * Removes the provided value from this attribute. 399 * 400 * @param attrValue The value to remove. 401 */ 402 public void removeValue(@NotNull final byte[] attrValue) 403 { 404 attribute = Attribute.removeValues(attribute, 405 new Attribute(attribute.getName(), attrValue)); 406 } 407 408 409 410 /** 411 * Retrieves the number of values for this attribute. 412 * 413 * @return The number of values for this attribute. 414 */ 415 public int size() 416 { 417 return attribute.size(); 418 } 419 420 421 422 /** 423 * Converts this LDAP attribute to an {@link Attribute} object. 424 * 425 * @return The {@code Attribute} object which corresponds to this LDAP 426 * attribute. 427 */ 428 @NotNull() 429 public final Attribute toAttribute() 430 { 431 return attribute; 432 } 433 434 435 436 /** 437 * Retrieves a string representation of this LDAP attribute. 438 * 439 * @return A string representation of this LDAP attribute. 440 */ 441 @Override() 442 @NotNull() 443 public String toString() 444 { 445 return attribute.toString(); 446 } 447}