001/*
002 * Copyright 2009-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2009-2014 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 */
021package com.unboundid.ldap.sdk.migrate.ldapjdk;
022
023
024
025import java.io.Serializable;
026import java.util.ArrayList;
027import java.util.Arrays;
028import java.util.Enumeration;
029import java.util.Iterator;
030
031import com.unboundid.util.Mutable;
032import com.unboundid.util.NotExtensible;
033import com.unboundid.util.ThreadSafety;
034import com.unboundid.util.ThreadSafetyLevel;
035
036import static com.unboundid.util.StaticUtils.*;
037
038
039
040/**
041 * This class provides a data structure that contains a set of LDAP attribute
042 * objects.
043 * <BR><BR>
044 * This class is primarily intended to be used in the process of updating
045 * applications which use the Netscape Directory SDK for Java to switch to or
046 * coexist with the UnboundID LDAP SDK for Java.  For applications not written
047 * using the Netscape Directory SDK for Java, arrays or collections of
048 * {@link com.unboundid.ldap.sdk.Attribute} objects should be used instead.
049 */
050@NotExtensible()
051@Mutable()
052@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
053public class LDAPAttributeSet
054       implements Serializable
055{
056  /**
057   * The serial version UID for this serializable class.
058   */
059  private static final long serialVersionUID = -4872457565092606186L;
060
061
062
063  // The list of LDAPAttribute objects.
064  private final ArrayList<LDAPAttribute> attributes;
065
066
067
068  /**
069   * Creates a new LDAP attribute set with no attributes.
070   */
071  public LDAPAttributeSet()
072  {
073    attributes = new ArrayList<LDAPAttribute>();
074  }
075
076
077
078  /**
079   * Creates a new LDAP attribute set with the provided attributes.
080   *
081   * @param  attrs  The set of attributes to include in the set.
082   */
083  public LDAPAttributeSet(final LDAPAttribute[] attrs)
084  {
085    attributes = new ArrayList<LDAPAttribute>(Arrays.asList(attrs));
086  }
087
088
089
090  /**
091   * Creates a new LDAP attribute set with the provided attributes.
092   *
093   * @param  attrs  The set of attributes to include in the set.
094   */
095  private LDAPAttributeSet(final ArrayList<LDAPAttribute> attrs)
096  {
097    attributes = new ArrayList<LDAPAttribute>(attrs);
098  }
099
100
101
102  /**
103   * Retrieves an enumeration of the attributes in this set.
104   *
105   * @return  An enumeration of the attributes in this set.
106   */
107  public Enumeration<LDAPAttribute> getAttributes()
108  {
109    return new IterableEnumeration<LDAPAttribute>(attributes);
110  }
111
112
113
114  /**
115   * Retrieves a subset of the attributes in this attribute set which contain
116   * the specified subtype.
117   *
118   * @param  subtype  The subtype for which to retrieve all of the attributes.
119   *
120   * @return  A new attribute set with all attributes from this set containing
121   *          the specified subtype.
122   */
123  public LDAPAttributeSet getSubset(final String subtype)
124  {
125    final ArrayList<LDAPAttribute> subset =
126         new ArrayList<LDAPAttribute>(attributes.size());
127
128    for (final LDAPAttribute a : attributes)
129    {
130      if (a.hasSubtype(subtype))
131      {
132        subset.add(a);
133      }
134    }
135
136    return new LDAPAttributeSet(subset);
137  }
138
139
140
141  /**
142   * Retrieves the attribute from this set whose name exactly matches the
143   * provided name.
144   *
145   * @param  attrName  The name of the attribute to retrieve.
146   *
147   * @return  The requested attribute, or {@code null} if there is no such
148   *          attribute in this set.
149   */
150  public LDAPAttribute getAttribute(final String attrName)
151  {
152    for (final LDAPAttribute a : attributes)
153    {
154      if (a.getName().equalsIgnoreCase(attrName))
155      {
156        return a;
157      }
158    }
159
160    return null;
161  }
162
163
164
165  /**
166   * Retrieves the attribute with the specified base name and the specified
167   * language subtype.
168   *
169   * @param  attrName  The base name for the attribute to retrieve.
170   * @param  lang      The language subtype to retrieve, or {@code null} if
171   *                   there should not be a language subtype.
172   *
173   * @return  The attribute with the specified base name and language subtype,
174   *          or {@code null} if there is no such attribute.
175   */
176  public LDAPAttribute getAttribute(final String attrName, final String lang)
177  {
178    if (lang == null)
179    {
180      return getAttribute(attrName);
181    }
182
183    final String lowerLang = toLowerCase(lang);
184
185    for (final LDAPAttribute a : attributes)
186    {
187      if (a.getBaseName().equalsIgnoreCase(attrName))
188      {
189        final String[] subtypes = a.getSubtypes();
190        if (subtypes != null)
191        {
192          for (final String s : subtypes)
193          {
194            final String lowerOption = toLowerCase(s);
195            if (lowerOption.equals(lowerLang) ||
196                lowerOption.startsWith(lang + '-'))
197            {
198              return a;
199            }
200          }
201        }
202      }
203    }
204
205    return null;
206  }
207
208
209
210  /**
211   * Retrieves the attribute at the specified position in this attribute set.
212   *
213   * @param  index  The position of the attribute to retrieve.
214   *
215   * @return  The attribute at the specified position.
216   *
217   * @throws  IndexOutOfBoundsException  If the provided index invalid.
218   */
219  public LDAPAttribute elementAt(final int index)
220         throws IndexOutOfBoundsException
221  {
222    return attributes.get(index);
223  }
224
225
226
227  /**
228   * Adds the provided attribute to this attribute set.
229   *
230   * @param  attr  The attribute to be added to this set.
231   */
232  public void add(final LDAPAttribute attr)
233  {
234    for (final LDAPAttribute a : attributes)
235    {
236      if (attr.getName().equalsIgnoreCase(a.getName()))
237      {
238        for (final byte[] value : attr.getByteValueArray())
239        {
240          a.addValue(value);
241        }
242        return;
243      }
244    }
245
246    attributes.add(attr);
247  }
248
249
250
251  /**
252   * Removes the attribute with the specified name.
253   *
254   * @param  name  The name of the attribute to remove.
255   */
256  public void remove(final String name)
257  {
258    final Iterator<LDAPAttribute> iterator = attributes.iterator();
259    while (iterator.hasNext())
260    {
261      final LDAPAttribute a = iterator.next();
262      if (name.equalsIgnoreCase(a.getName()))
263      {
264        iterator.remove();
265        return;
266      }
267    }
268  }
269
270
271
272  /**
273   * Removes the attribute at the specified position in this attribute set.
274   *
275   * @param  index  The position of the attribute to remove.
276   *
277   * @throws  IndexOutOfBoundsException  If the provided index is invalid.
278   */
279  public void removeElementAt(final int index)
280         throws IndexOutOfBoundsException
281  {
282    attributes.remove(index);
283  }
284
285
286
287  /**
288   * Retrieves the number of attributes contained in this attribute set.
289   *
290   * @return  The number of attributes contained in this attribute set.
291   */
292  public int size()
293  {
294    return attributes.size();
295  }
296
297
298
299  /**
300   * Creates a duplicate of this attribute set.
301   *
302   * @return  A duplicate of this attribute set.
303   */
304  public LDAPAttributeSet duplicate()
305  {
306    return new LDAPAttributeSet(attributes);
307  }
308
309
310
311  /**
312   * Retrieves a string representation of this attribute set.
313   *
314   * @return  A string representation of this attribute set.
315   */
316  @Override()
317  public String toString()
318  {
319    return attributes.toString();
320  }
321}