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