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}