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